@timetotest/cli 0.1.11 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +201 -190
  2. package/dist/bin/ttt.js +4 -2
  3. package/dist/bin/ttt.js.map +1 -1
  4. package/dist/package.json +13 -2
  5. package/dist/src/commands/ask/AskApp.js +121 -0
  6. package/dist/src/commands/ask/AskApp.js.map +1 -0
  7. package/dist/src/commands/ask/components/AssistantResponse.js +31 -0
  8. package/dist/src/commands/ask/components/AssistantResponse.js.map +1 -0
  9. package/dist/src/commands/ask/components/Banner.js +15 -0
  10. package/dist/src/commands/ask/components/Banner.js.map +1 -0
  11. package/dist/src/commands/ask/components/ChatInput.js +93 -0
  12. package/dist/src/commands/ask/components/ChatInput.js.map +1 -0
  13. package/dist/src/commands/ask/components/Divider.js +17 -0
  14. package/dist/src/commands/ask/components/Divider.js.map +1 -0
  15. package/dist/src/commands/ask/components/IntroTips.js +19 -0
  16. package/dist/src/commands/ask/components/IntroTips.js.map +1 -0
  17. package/dist/src/commands/ask/components/MessageBubble.js +47 -0
  18. package/dist/src/commands/ask/components/MessageBubble.js.map +1 -0
  19. package/dist/src/commands/ask/components/SessionInfo.js +20 -0
  20. package/dist/src/commands/ask/components/SessionInfo.js.map +1 -0
  21. package/dist/src/commands/ask/components/StatusIndicator.js +67 -0
  22. package/dist/src/commands/ask/components/StatusIndicator.js.map +1 -0
  23. package/dist/src/commands/ask-ink.js +380 -0
  24. package/dist/src/commands/ask-ink.js.map +1 -0
  25. package/dist/src/commands/ask.js +73 -60
  26. package/dist/src/commands/ask.js.map +1 -1
  27. package/dist/src/commands/chat/ChatApp.js +125 -0
  28. package/dist/src/commands/chat/ChatApp.js.map +1 -0
  29. package/dist/src/commands/chat-ink.js +436 -0
  30. package/dist/src/commands/chat-ink.js.map +1 -0
  31. package/dist/src/commands/chat.js +82 -0
  32. package/dist/src/commands/chat.js.map +1 -0
  33. package/dist/src/commands/login.js +6 -4
  34. package/dist/src/commands/login.js.map +1 -1
  35. package/dist/src/commands/start-test.js +62 -88
  36. package/dist/src/commands/start-test.js.map +1 -1
  37. package/dist/src/commands/stream.js +9 -9
  38. package/dist/src/commands/stream.js.map +1 -1
  39. package/dist/src/commands/test.js +58 -125
  40. package/dist/src/commands/test.js.map +1 -1
  41. package/dist/src/lib/agent-orchestrator.js +546 -0
  42. package/dist/src/lib/agent-orchestrator.js.map +1 -0
  43. package/dist/src/lib/cloudinary-service.js +65 -0
  44. package/dist/src/lib/cloudinary-service.js.map +1 -0
  45. package/dist/src/lib/config.js +3 -2
  46. package/dist/src/lib/config.js.map +1 -1
  47. package/dist/src/lib/events.js +73 -60
  48. package/dist/src/lib/events.js.map +1 -1
  49. package/dist/src/lib/http.js +34 -1
  50. package/dist/src/lib/http.js.map +1 -1
  51. package/dist/src/lib/legacy-chat-runner.js +37 -0
  52. package/dist/src/lib/legacy-chat-runner.js.map +1 -0
  53. package/dist/src/lib/local-tools/api/api-discovery.js +17 -0
  54. package/dist/src/lib/local-tools/api/api-discovery.js.map +1 -0
  55. package/dist/src/lib/local-tools/api/build-request.js +20 -0
  56. package/dist/src/lib/local-tools/api/build-request.js.map +1 -0
  57. package/dist/src/lib/local-tools/api/extract-response-fields.js +26 -0
  58. package/dist/src/lib/local-tools/api/extract-response-fields.js.map +1 -0
  59. package/dist/src/lib/local-tools/api/generate-api-test.js +20 -0
  60. package/dist/src/lib/local-tools/api/generate-api-test.js.map +1 -0
  61. package/dist/src/lib/local-tools/api/generate-curl.js +8 -0
  62. package/dist/src/lib/local-tools/api/generate-curl.js.map +1 -0
  63. package/dist/src/lib/local-tools/api/get-api-parameters.js +17 -0
  64. package/dist/src/lib/local-tools/api/get-api-parameters.js.map +1 -0
  65. package/dist/src/lib/local-tools/api/index.js +10 -0
  66. package/dist/src/lib/local-tools/api/index.js.map +1 -0
  67. package/dist/src/lib/local-tools/api/request.js +43 -0
  68. package/dist/src/lib/local-tools/api/request.js.map +1 -0
  69. package/dist/src/lib/local-tools/api/set-auth-header.js +8 -0
  70. package/dist/src/lib/local-tools/api/set-auth-header.js.map +1 -0
  71. package/dist/src/lib/local-tools/api/types.js +2 -0
  72. package/dist/src/lib/local-tools/api/types.js.map +1 -0
  73. package/dist/src/lib/local-tools/api/utils.js +33 -0
  74. package/dist/src/lib/local-tools/api/utils.js.map +1 -0
  75. package/dist/src/lib/local-tools/api/validate-response.js +41 -0
  76. package/dist/src/lib/local-tools/api/validate-response.js.map +1 -0
  77. package/dist/src/lib/local-tools/file-tools.js +45 -0
  78. package/dist/src/lib/local-tools/file-tools.js.map +1 -0
  79. package/dist/src/lib/local-tools/general/discover-local-services.js +95 -0
  80. package/dist/src/lib/local-tools/general/discover-local-services.js.map +1 -0
  81. package/dist/src/lib/local-tools/general/index.js +2 -0
  82. package/dist/src/lib/local-tools/general/index.js.map +1 -0
  83. package/dist/src/lib/local-tools/ui/click-element.js +105 -0
  84. package/dist/src/lib/local-tools/ui/click-element.js.map +1 -0
  85. package/dist/src/lib/local-tools/ui/dom-rag.js +201 -0
  86. package/dist/src/lib/local-tools/ui/dom-rag.js.map +1 -0
  87. package/dist/src/lib/local-tools/ui/find-element.js +31 -0
  88. package/dist/src/lib/local-tools/ui/find-element.js.map +1 -0
  89. package/dist/src/lib/local-tools/ui/hover-element.js +94 -0
  90. package/dist/src/lib/local-tools/ui/hover-element.js.map +1 -0
  91. package/dist/src/lib/local-tools/ui/index.js +3 -0
  92. package/dist/src/lib/local-tools/ui/index.js.map +1 -0
  93. package/dist/src/lib/local-tools/ui/manage-tab.js +65 -0
  94. package/dist/src/lib/local-tools/ui/manage-tab.js.map +1 -0
  95. package/dist/src/lib/local-tools/ui/navigate.js +35 -0
  96. package/dist/src/lib/local-tools/ui/navigate.js.map +1 -0
  97. package/dist/src/lib/local-tools/ui/page-discovery.js +32 -0
  98. package/dist/src/lib/local-tools/ui/page-discovery.js.map +1 -0
  99. package/dist/src/lib/local-tools/ui/playwright-mcp.js +217 -0
  100. package/dist/src/lib/local-tools/ui/playwright-mcp.js.map +1 -0
  101. package/dist/src/lib/local-tools/ui/screenshot.js +19 -0
  102. package/dist/src/lib/local-tools/ui/screenshot.js.map +1 -0
  103. package/dist/src/lib/local-tools/ui/search-interactive-elements.js +18 -0
  104. package/dist/src/lib/local-tools/ui/search-interactive-elements.js.map +1 -0
  105. package/dist/src/lib/local-tools/ui/selector-resolver.js +153 -0
  106. package/dist/src/lib/local-tools/ui/selector-resolver.js.map +1 -0
  107. package/dist/src/lib/local-tools/ui/snapshot-query.js +129 -0
  108. package/dist/src/lib/local-tools/ui/snapshot-query.js.map +1 -0
  109. package/dist/src/lib/local-tools/ui/type-text.js +40 -0
  110. package/dist/src/lib/local-tools/ui/type-text.js.map +1 -0
  111. package/dist/src/lib/local-tools/ui/types.js +2 -0
  112. package/dist/src/lib/local-tools/ui/types.js.map +1 -0
  113. package/dist/src/lib/local-tools/utility/finish-overall-test.js +12 -0
  114. package/dist/src/lib/local-tools/utility/finish-overall-test.js.map +1 -0
  115. package/dist/src/lib/local-tools/utility/index.js +2 -0
  116. package/dist/src/lib/local-tools/utility/index.js.map +1 -0
  117. package/dist/src/lib/prompts/builder.js +38 -0
  118. package/dist/src/lib/prompts/builder.js.map +1 -0
  119. package/dist/src/lib/prompts/index.js +7 -0
  120. package/dist/src/lib/prompts/index.js.map +1 -0
  121. package/dist/src/lib/prompts/templates.js +166 -0
  122. package/dist/src/lib/prompts/templates.js.map +1 -0
  123. package/dist/src/lib/session-manager.js +201 -0
  124. package/dist/src/lib/session-manager.js.map +1 -0
  125. package/dist/src/lib/socket.js +70 -9
  126. package/dist/src/lib/socket.js.map +1 -1
  127. package/dist/src/lib/testing-mode.js +33 -0
  128. package/dist/src/lib/testing-mode.js.map +1 -0
  129. package/dist/src/lib/tool-descriptions.js +59 -0
  130. package/dist/src/lib/tool-descriptions.js.map +1 -0
  131. package/dist/src/lib/tool-executor.js +537 -0
  132. package/dist/src/lib/tool-executor.js.map +1 -0
  133. package/dist/src/lib/tool-registry.js +803 -0
  134. package/dist/src/lib/tool-registry.js.map +1 -0
  135. package/dist/src/lib/tool-result-pruner.js +384 -0
  136. package/dist/src/lib/tool-result-pruner.js.map +1 -0
  137. package/dist/src/lib/tui/components/AskIntro.js +6 -0
  138. package/dist/src/lib/tui/components/AskIntro.js.map +1 -0
  139. package/dist/src/lib/tui/components/Banner.js +15 -0
  140. package/dist/src/lib/tui/components/Banner.js.map +1 -0
  141. package/dist/src/lib/tui/components/Divider.js +17 -0
  142. package/dist/src/lib/tui/components/Divider.js.map +1 -0
  143. package/dist/src/lib/tui/components/EventLine.js +110 -0
  144. package/dist/src/lib/tui/components/EventLine.js.map +1 -0
  145. package/dist/src/lib/tui/components/Header.js +15 -0
  146. package/dist/src/lib/tui/components/Header.js.map +1 -0
  147. package/dist/src/lib/tui/components/InputBox.js +9 -0
  148. package/dist/src/lib/tui/components/InputBox.js.map +1 -0
  149. package/dist/src/lib/tui/components/Mapping.js +8 -0
  150. package/dist/src/lib/tui/components/Mapping.js.map +1 -0
  151. package/dist/src/lib/tui/components/ProjectList.js +6 -0
  152. package/dist/src/lib/tui/components/ProjectList.js.map +1 -0
  153. package/dist/src/lib/tui/components/Spinner.js +20 -0
  154. package/dist/src/lib/tui/components/Spinner.js.map +1 -0
  155. package/dist/src/lib/tui/components/StatusBanner.js +12 -0
  156. package/dist/src/lib/tui/components/StatusBanner.js.map +1 -0
  157. package/dist/src/lib/tui/components/StatusBar.js +11 -0
  158. package/dist/src/lib/tui/components/StatusBar.js.map +1 -0
  159. package/dist/src/lib/tui/components/UserBubble.js +6 -0
  160. package/dist/src/lib/tui/components/UserBubble.js.map +1 -0
  161. package/dist/src/lib/tui/components/index.js +16 -0
  162. package/dist/src/lib/tui/components/index.js.map +1 -0
  163. package/dist/src/lib/tui/events.js +716 -76
  164. package/dist/src/lib/tui/events.js.map +1 -1
  165. package/dist/src/lib/tui/icons.js +14 -0
  166. package/dist/src/lib/tui/icons.js.map +1 -1
  167. package/dist/src/lib/tui/ink-print.js +41 -0
  168. package/dist/src/lib/tui/ink-print.js.map +1 -0
  169. package/dist/src/lib/tui/interactive-chat.js +345 -0
  170. package/dist/src/lib/tui/interactive-chat.js.map +1 -0
  171. package/dist/src/lib/tui/print.js +31 -26
  172. package/dist/src/lib/tui/print.js.map +1 -1
  173. package/dist/src/lib/tui/prompt.js +21 -18
  174. package/dist/src/lib/tui/prompt.js.map +1 -1
  175. package/dist/src/test-agent-flow.js +148 -0
  176. package/dist/src/test-agent-flow.js.map +1 -0
  177. package/dist/src/test-browser-session.js +152 -0
  178. package/dist/src/test-browser-session.js.map +1 -0
  179. package/dist/src/test-browser-snapshot.js +187 -0
  180. package/dist/src/test-browser-snapshot.js.map +1 -0
  181. package/dist/src/test-snapshot-detailed.js +219 -0
  182. package/dist/src/test-snapshot-detailed.js.map +1 -0
  183. package/dist/src/test-snapshot-simple.js +85 -0
  184. package/dist/src/test-snapshot-simple.js.map +1 -0
  185. package/dist/src/test-snapshot-tabs.js +110 -0
  186. package/dist/src/test-snapshot-tabs.js.map +1 -0
  187. package/package.json +13 -2
@@ -0,0 +1,380 @@
1
+ import { Command } from "commander";
2
+ import React from "react";
3
+ import { render } from "ink";
4
+ import { createHttpClient } from "../lib/http.js";
5
+ import { connectForAsk, subscribeAsk, stopSession } from "../lib/socket.js";
6
+ import { registerUnifiedEventLogging, canonicalizeEventType, } from "../lib/events.js";
7
+ import { getAuthToken, getUserLastProject, setUserLastProject, } from "../lib/config.js";
8
+ import { performInteractiveLogin } from "./login.js";
9
+ import { AskApp } from "./ask/AskApp.js";
10
+ import chalk from "chalk";
11
+ export const askInk = new Command("ask")
12
+ .description("Start interactive chat with TimetoTest AI agent (INK UI)")
13
+ .option("--project-id <id>", "Project ID to use for the conversation")
14
+ .option("--conversation-id <id>", "Continue existing conversation")
15
+ .action(async (opts) => {
16
+ try {
17
+ // Check authentication
18
+ const token = getAuthToken();
19
+ if (!token) {
20
+ console.log(chalk.yellow("You are not logged in. Opening browser to authenticate…"));
21
+ try {
22
+ await performInteractiveLogin();
23
+ }
24
+ catch (e) {
25
+ console.log(chalk.red(e?.message || "Login failed"));
26
+ process.exit(1);
27
+ }
28
+ }
29
+ let http = createHttpClient();
30
+ let conversationId = opts.conversationId;
31
+ let projectId;
32
+ if (opts.projectId !== undefined) {
33
+ const parsedProjectId = Number(opts.projectId);
34
+ if (!Number.isInteger(parsedProjectId)) {
35
+ console.log(chalk.red(`❌ Invalid project id '${opts.projectId}'. Please provide a numeric value.`));
36
+ process.exit(1);
37
+ }
38
+ projectId = parsedProjectId;
39
+ }
40
+ let lastKnownUser = "Unknown";
41
+ let lastKnownUserKey;
42
+ let lastKnownProject = projectId ? `Project ${projectId}` : "Not set";
43
+ let socket;
44
+ let userCancelled = false; // Flag to track user cancellation
45
+ // Load user info and project
46
+ try {
47
+ const me = await http.get("/api/v1/auth/me");
48
+ lastKnownUserKey = me.data?.email || String(me.data?.user_id || "");
49
+ lastKnownUser = me.data?.email || me.data?.display_name || "Unknown";
50
+ if (!projectId && lastKnownUserKey) {
51
+ const remembered = getUserLastProject(lastKnownUserKey);
52
+ if (remembered) {
53
+ projectId = remembered;
54
+ }
55
+ }
56
+ // Fetch user's projects and pick the default if present
57
+ const projectsResp = await http.get("/api/v1/projects");
58
+ const projectsRaw = projectsResp.data;
59
+ const projects = Array.isArray(projectsRaw?.items)
60
+ ? projectsRaw.items
61
+ : Array.isArray(projectsRaw)
62
+ ? projectsRaw
63
+ : [];
64
+ if (!projectId && projects && projects.length > 0) {
65
+ const defaultProj = projects.find((p) => p?.is_default === true);
66
+ const selected = defaultProj || projects[0];
67
+ if (selected?.id) {
68
+ projectId = selected.id;
69
+ lastKnownProject = selected.name || `Project ${projectId}`;
70
+ }
71
+ }
72
+ // If we loaded a remembered project, populate the name
73
+ if (projectId &&
74
+ (!lastKnownProject || lastKnownProject === "Not set")) {
75
+ try {
76
+ const p = await http.get(`/api/v1/projects/${projectId}`);
77
+ lastKnownProject = p.data?.name || `Project ${projectId}`;
78
+ }
79
+ catch { }
80
+ }
81
+ if (projectId) {
82
+ const projectResp = await http.get(`/api/v1/projects/${projectId}`);
83
+ lastKnownProject = projectResp.data.name || `Project ${projectId}`;
84
+ }
85
+ }
86
+ catch (error) {
87
+ const status = error?.response?.status;
88
+ if (status === 401 || status === 403) {
89
+ // Token expired or invalid - re-authenticate
90
+ console.log(chalk.yellow("Session expired or invalid. Re-authenticating..."));
91
+ try {
92
+ await performInteractiveLogin();
93
+ http = createHttpClient();
94
+ // Retry fetching user info and projects
95
+ const me = await http.get("/api/v1/auth/me");
96
+ lastKnownUserKey = me.data?.email || String(me.data?.user_id || "");
97
+ lastKnownUser =
98
+ me.data?.email || me.data?.display_name || "Unknown";
99
+ // Retry fetching projects
100
+ const projectsResp = await http.get("/api/v1/projects");
101
+ const projectsRaw = projectsResp.data;
102
+ const projects = Array.isArray(projectsRaw?.items)
103
+ ? projectsRaw.items
104
+ : Array.isArray(projectsRaw)
105
+ ? projectsRaw
106
+ : [];
107
+ if (!projectId && projects && projects.length > 0) {
108
+ const defaultProj = projects.find((p) => p?.is_default === true);
109
+ const selected = defaultProj || projects[0];
110
+ if (selected?.id) {
111
+ projectId = selected.id;
112
+ lastKnownProject = selected.name || `Project ${projectId}`;
113
+ }
114
+ }
115
+ if (projectId) {
116
+ const projectResp = await http.get(`/api/v1/projects/${projectId}`);
117
+ lastKnownProject =
118
+ projectResp.data.name || `Project ${projectId}`;
119
+ }
120
+ }
121
+ catch (reauthError) {
122
+ console.log(chalk.red(`❌ Failed to authenticate: ${reauthError?.message || reauthError}`));
123
+ process.exit(1);
124
+ }
125
+ }
126
+ else {
127
+ console.log(chalk.gray(`ℹ️ Unable to refresh session info: ${error?.message || error}`));
128
+ }
129
+ }
130
+ const workspacePath = process.cwd();
131
+ // Define slash commands
132
+ const slashCommands = [];
133
+ const helpCommand = {
134
+ name: "help",
135
+ description: "Show available slash commands",
136
+ aliases: ["?", "commands", "h"],
137
+ run: async () => {
138
+ const helpText = slashCommands
139
+ .map((cmd) => {
140
+ const aliases = cmd.aliases?.length
141
+ ? ` (aliases: ${cmd.aliases.map((a) => `/${a}`).join(", ")})`
142
+ : "";
143
+ return ` /${cmd.name} - ${cmd.description}${aliases}`;
144
+ })
145
+ .join("\n");
146
+ getAppInterface()?.addMessage({
147
+ id: Date.now().toString(),
148
+ type: "system",
149
+ content: `Slash commands:\n${helpText}\nPrefix commands with '/' (for example, /switch or /summary).`,
150
+ });
151
+ return "continue";
152
+ },
153
+ };
154
+ const exitCommand = {
155
+ name: "exit",
156
+ description: "End the conversation",
157
+ aliases: ["quit", "bye"],
158
+ run: async () => "exit",
159
+ };
160
+ const clearCommand = {
161
+ name: "clear",
162
+ description: "Clear the screen",
163
+ aliases: ["cls"],
164
+ run: async () => {
165
+ console.clear();
166
+ return "continue";
167
+ },
168
+ };
169
+ // Add more slash commands as needed...
170
+ slashCommands.push(helpCommand, exitCommand, clearCommand);
171
+ const commandLookup = new Map();
172
+ slashCommands.forEach((command) => {
173
+ commandLookup.set(command.name, command);
174
+ command.aliases?.forEach((alias) => {
175
+ commandLookup.set(alias, command);
176
+ });
177
+ });
178
+ const executeSlashCommand = async (cmd, args) => {
179
+ const command = commandLookup.get(cmd.toLowerCase());
180
+ if (!command) {
181
+ getAppInterface()?.addMessage({
182
+ id: Date.now().toString(),
183
+ type: "system",
184
+ content: `Unknown command: /${cmd}. Type /help to see available commands.`,
185
+ });
186
+ return "continue";
187
+ }
188
+ return await command.run(args);
189
+ };
190
+ const getAppInterface = () => {
191
+ return globalThis.__askAppInterface;
192
+ };
193
+ const sendAskStop = () => {
194
+ try {
195
+ userCancelled = true; // Set cancellation flag
196
+ const appInterface = getAppInterface();
197
+ appInterface?.setInputDisabled(false); // Ensure input stays enabled
198
+ appInterface?.clearStatus(); // Clear any status messages
199
+ appInterface?.addMessage({
200
+ id: Date.now().toString(),
201
+ type: "system",
202
+ content: "🛑 Cancelled — the assistant has stopped. Type whenever you're ready.",
203
+ });
204
+ if (socket && conversationId) {
205
+ stopSession(socket, {
206
+ session_kind: "ask",
207
+ ids: { conversation_id: conversationId },
208
+ });
209
+ }
210
+ }
211
+ catch { }
212
+ };
213
+ const attachSocketHandlers = (socketInstance) => {
214
+ registerUnifiedEventLogging(socketInstance, (line) => {
215
+ // Log to console for debugging
216
+ // console.log(line);
217
+ });
218
+ socketInstance.onAny?.((eventType, data) => {
219
+ const t = canonicalizeEventType(eventType) || eventType;
220
+ const appInterface = getAppInterface();
221
+ // Don't process events if user has cancelled
222
+ if (userCancelled) {
223
+ return;
224
+ }
225
+ if (t === "thinking_started") {
226
+ appInterface?.setStatus({
227
+ text: "Thinking...",
228
+ type: "loading",
229
+ });
230
+ }
231
+ else if (t === "thinking_stopped") {
232
+ appInterface?.setStatus({
233
+ text: "Waiting for assistant...",
234
+ type: "loading",
235
+ });
236
+ }
237
+ else if (t === "agent_thought") {
238
+ const msg = data?.data?.message || data?.data?.content || "Thinking...";
239
+ appInterface?.setStatus({
240
+ text: msg,
241
+ type: "loading",
242
+ });
243
+ }
244
+ else if (t === "tool_screenshot") {
245
+ const url = data?.data?.image_url || data?.data?.screenshot?.image_url;
246
+ if (url) {
247
+ appInterface?.addMessage({
248
+ id: Date.now().toString(),
249
+ type: "system",
250
+ content: `🖼️ Live screenshot: ${url}`,
251
+ });
252
+ }
253
+ }
254
+ else if (t === "tool_start") {
255
+ const message = data.data?.message || `Running ${data.data?.tool || "tool"}...`;
256
+ appInterface?.setStatus({
257
+ text: message,
258
+ type: "loading",
259
+ });
260
+ }
261
+ else if (t === "tool_result") {
262
+ // Tool completion intentionally silent to reduce noise.
263
+ }
264
+ else if (t === "session_completed") {
265
+ appInterface?.clearStatus();
266
+ const summary = data.data?.summary || "No response";
267
+ appInterface?.addMessage({
268
+ id: Date.now().toString(),
269
+ type: "assistant",
270
+ content: summary,
271
+ });
272
+ }
273
+ else if (t === "session_error") {
274
+ appInterface?.clearStatus();
275
+ const error = data.data?.error || "An unexpected issue occurred";
276
+ appInterface?.addMessage({
277
+ id: Date.now().toString(),
278
+ type: "assistant",
279
+ content: `❌ ${error}`,
280
+ isError: true,
281
+ });
282
+ }
283
+ });
284
+ };
285
+ const establishSocket = (conversation) => {
286
+ const newSocket = connectForAsk();
287
+ attachSocketHandlers(newSocket);
288
+ subscribeAsk(newSocket, conversation);
289
+ return newSocket;
290
+ };
291
+ if (conversationId) {
292
+ socket = establishSocket(conversationId);
293
+ }
294
+ const handleUserMessage = async (message) => {
295
+ try {
296
+ const appInterface = getAppInterface();
297
+ userCancelled = false; // Reset cancellation flag for new message
298
+ // Create conversation on first message
299
+ if (!conversationId) {
300
+ appInterface?.setStatus({
301
+ text: "Creating conversation...",
302
+ type: "loading",
303
+ });
304
+ const sessionResp = await http.post("/api/v1/ask/sessions", {
305
+ question: message,
306
+ project_id: projectId,
307
+ surface: "cli",
308
+ });
309
+ conversationId = sessionResp.data.conversation_id;
310
+ projectId = sessionResp.data.project_id;
311
+ if (lastKnownUserKey && typeof projectId === "number") {
312
+ setUserLastProject(lastKnownUserKey, projectId);
313
+ }
314
+ // Establish socket connection
315
+ socket = establishSocket(conversationId);
316
+ appInterface?.setStatus({
317
+ text: "Waiting for assistant...",
318
+ type: "loading",
319
+ });
320
+ }
321
+ else {
322
+ // Send message to existing conversation
323
+ appInterface?.setStatus({
324
+ text: "Sending...",
325
+ type: "loading",
326
+ });
327
+ await http.post(`/api/v1/ask/sessions/${conversationId}/message`, {
328
+ message: message,
329
+ project_id: projectId,
330
+ surface: "cli",
331
+ });
332
+ appInterface?.setStatus({
333
+ text: "Waiting for assistant...",
334
+ type: "loading",
335
+ });
336
+ }
337
+ }
338
+ catch (error) {
339
+ const appInterface = getAppInterface();
340
+ appInterface?.clearStatus();
341
+ appInterface?.addMessage({
342
+ id: Date.now().toString(),
343
+ type: "assistant",
344
+ content: `❌ Error: ${error?.message || error}`,
345
+ isError: true,
346
+ });
347
+ }
348
+ };
349
+ const handleExit = () => {
350
+ if (socket) {
351
+ socket.disconnect();
352
+ }
353
+ process.exit(0);
354
+ };
355
+ // Prepare slash commands for the UI
356
+ const slashCommandsForUI = slashCommands.map((cmd) => ({
357
+ name: cmd.name,
358
+ description: cmd.description,
359
+ value: cmd.name,
360
+ label: `/${cmd.name}`,
361
+ }));
362
+ // Render the INK app
363
+ const { waitUntilExit } = render(React.createElement(AskApp, {
364
+ user: lastKnownUser,
365
+ project: lastKnownProject,
366
+ workspacePath,
367
+ slashCommands: slashCommandsForUI,
368
+ onUserMessage: handleUserMessage,
369
+ onSlashCommand: executeSlashCommand,
370
+ onExit: handleExit,
371
+ onCancel: sendAskStop,
372
+ }));
373
+ await waitUntilExit();
374
+ }
375
+ catch (error) {
376
+ console.error(chalk.red(`❌ Error: ${error.message}`));
377
+ process.exit(1);
378
+ }
379
+ });
380
+ //# sourceMappingURL=ask-ink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask-ink.js","sourceRoot":"","sources":["../../../src/commands/ask-ink.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,8 @@ import chalk from "chalk";
3
3
  import ora from "ora";
4
4
  import os from "node:os";
5
5
  import { createHttpClient } from "../lib/http.js";
6
- import { connectForAsk } from "../lib/socket.js";
6
+ import { connectForAsk, subscribeAsk, stopSession } from "../lib/socket.js";
7
+ import { registerUnifiedEventLogging, canonicalizeEventType, } from "../lib/events.js";
7
8
  import { promptInBox, printDivider, formatStatusSegments, accentText, highlightText, printBanner, printUserBubble, printStatusBanner, } from "../lib/tui.js";
8
9
  import { getAuthToken, getUserLastProject, setUserLastProject, } from "../lib/config.js";
9
10
  import { clearAuthToken } from "../lib/config.js";
@@ -123,12 +124,22 @@ export const ask = new Command("ask")
123
124
  let spinner = null;
124
125
  let messageCount = 1;
125
126
  let socket;
127
+ let userCancelled = false;
126
128
  const sendAskStop = () => {
129
+ if (userCancelled)
130
+ return;
131
+ userCancelled = true;
127
132
  try {
133
+ if (spinner) {
134
+ spinner.stop();
135
+ spinner = null;
136
+ }
137
+ console.log(chalk.yellow("🛑 Cancelled — the assistant has stopped. Type whenever you're ready."));
128
138
  if (socket && conversationId) {
129
- socket.emit("ASK_STOP_SESSION", { conversation_id: conversationId });
130
- if (spinner)
131
- spinner.text = chalk.yellow("Stopping…");
139
+ stopSession(socket, {
140
+ session_kind: "ask",
141
+ ids: { conversation_id: conversationId },
142
+ });
132
143
  }
133
144
  }
134
145
  catch { }
@@ -512,7 +523,7 @@ export const ask = new Command("ask")
512
523
  console.log();
513
524
  printDivider("Conversations");
514
525
  items.forEach((c, i) => {
515
- const id = c.conversation_id || c.execution_id || c.id;
526
+ const id = c.conversation_id || c.id;
516
527
  const created = c.created_at || "";
517
528
  const status = c.status || "";
518
529
  const title = c.goal || c.title || "";
@@ -628,64 +639,65 @@ export const ask = new Command("ask")
628
639
  summarySpinner.stop();
629
640
  printStatusBanner("Assistant ready. Type /help to see available commands.", "success");
630
641
  const attachSocketHandlers = (socketInstance) => {
631
- socketInstance.on("ASK_THINKING_STARTED", () => {
632
- if (spinner) {
633
- spinner.text = chalk.cyan("🤔 Thinking...");
642
+ registerUnifiedEventLogging(socketInstance, (line) => console.log(line));
643
+ socketInstance.onAny?.((eventType, data) => {
644
+ const t = canonicalizeEventType(eventType) || eventType;
645
+ if (userCancelled)
646
+ return;
647
+ if (t === "thinking_started") {
648
+ if (spinner)
649
+ spinner.text = chalk.cyan("🤔 Thinking...");
634
650
  }
635
- });
636
- socketInstance.on("ASK_THINKING_STOPPED", () => {
637
- // Thinking stopped, ready for next input
638
- if (spinner && spinner.text?.includes("Thinking")) {
639
- spinner.text = "Waiting for assistant...";
651
+ else if (t === "thinking_stopped") {
652
+ if (spinner && spinner.text?.includes("Thinking"))
653
+ spinner.text = "Waiting for assistant...";
640
654
  }
641
- });
642
- socketInstance.on("ASK_AGENT_THOUGHT", (data) => {
643
- const msg = data?.data?.message || data?.data?.content || "Thinking...";
644
- if (spinner)
645
- spinner.text = chalk.cyan(`💭 ${msg}`);
646
- });
647
- socketInstance.on("ASK_TOOL_SCREENSHOT", (data) => {
648
- const url = data?.data?.image_url || data?.data?.screenshot?.image_url;
649
- if (url)
650
- console.log(chalk.gray(`🖼️ Live screenshot: ${url}`));
651
- });
652
- socketInstance.on("ASK_TOOL_START", (data) => {
653
- const message = data.data?.message || `Running ${data.data?.tool || "tool"}...`;
654
- if (spinner) {
655
- spinner.text = chalk.blue(`⚙️ ${message}`);
655
+ else if (t === "agent_thought") {
656
+ const msg = data?.data?.message || data?.data?.content || "Thinking...";
657
+ if (spinner)
658
+ spinner.text = chalk.cyan(`💭 ${msg}`);
656
659
  }
657
- });
658
- socketInstance.on("ASK_TOOL_RESULT", (data) => {
659
- const message = data.data?.message || `Completed ${data.data?.tool || "tool"}`;
660
- console.log(chalk.green(`✅ ${message}`));
661
- });
662
- // Note: ASK_AGENT_ANSWER is handled by ASK_SESSION_COMPLETED to avoid duplicates
663
- socketInstance.on("ASK_SESSION_COMPLETED", (data) => {
664
- if (spinner) {
665
- spinner.stop();
666
- spinner = null;
660
+ else if (t === "tool_screenshot") {
661
+ const url = data?.data?.image_url || data?.data?.screenshot?.image_url;
662
+ if (url)
663
+ console.log(chalk.gray(`🖼️ Live screenshot: ${url}`));
667
664
  }
668
- console.log();
669
- printDivider("Assistant");
670
- const summary = data.data?.summary || "No response";
671
- console.log(formatResponseText(summary));
672
- printDivider();
673
- console.log();
674
- });
675
- socketInstance.on("ASK_SESSION_ERROR", (data) => {
676
- if (spinner) {
677
- spinner.fail("An error occurred");
678
- spinner = null;
665
+ else if (t === "tool_start") {
666
+ const message = data.data?.message || `Running ${data.data?.tool || "tool"}...`;
667
+ if (spinner)
668
+ spinner.text = chalk.blue(`⚙️ ${message}`);
669
+ }
670
+ else if (t === "tool_result") {
671
+ // Tool completion intentionally silent to reduce noise.
672
+ }
673
+ else if (t === "session_completed") {
674
+ if (spinner) {
675
+ spinner.stop();
676
+ spinner = null;
677
+ }
678
+ console.log();
679
+ printDivider("Assistant");
680
+ const summary = data.data?.summary || "No response";
681
+ console.log(formatResponseText(summary));
682
+ printDivider();
683
+ console.log();
684
+ }
685
+ else if (t === "session_error") {
686
+ if (spinner) {
687
+ spinner.fail("Something went wrong");
688
+ spinner = null;
689
+ }
690
+ printDivider("Assistant Error");
691
+ console.log(chalk.red(`❌ ${data.data?.error || "An unexpected issue occurred"}`));
692
+ printDivider();
693
+ console.log();
679
694
  }
680
- printDivider("Assistant Error");
681
- console.log(chalk.red(`❌ ${data.data?.error || "Unknown error"}`));
682
- printDivider();
683
- console.log();
684
695
  });
685
696
  };
686
697
  const establishSocket = (conversation) => {
687
698
  const newSocket = connectForAsk();
688
699
  attachSocketHandlers(newSocket);
700
+ subscribeAsk(newSocket, conversation);
689
701
  return newSocket;
690
702
  };
691
703
  if (conversationId) {
@@ -784,6 +796,7 @@ export const ask = new Command("ask")
784
796
  }
785
797
  continue;
786
798
  }
799
+ userCancelled = false;
787
800
  // Create conversation and establish socket on first message
788
801
  if (!conversationId) {
789
802
  spinner = ora("Creating conversation...").start();
@@ -824,7 +837,7 @@ export const ask = new Command("ask")
824
837
  spinner.text = "Waiting for assistant...";
825
838
  }
826
839
  else {
827
- spinner.fail("Failed to create conversation");
840
+ spinner.fail("Unable to create conversation");
828
841
  throw e;
829
842
  }
830
843
  }
@@ -863,21 +876,21 @@ export const ask = new Command("ask")
863
876
  const waitForResponse = new Promise((resolve) => {
864
877
  const responseHandler = (data) => {
865
878
  // Remove the listener once we get a response
866
- socket.off("ASK_SESSION_COMPLETED", responseHandler);
867
- socket.off("ASK_SESSION_ERROR", errorHandler);
879
+ socket.off("session_completed", responseHandler);
880
+ socket.off("session_error", errorHandler);
868
881
  cleanupEsc();
869
882
  resolve();
870
883
  };
871
884
  const errorHandler = (data) => {
872
885
  // Remove the listener once we get an error
873
- socket.off("ASK_SESSION_COMPLETED", responseHandler);
874
- socket.off("ASK_SESSION_ERROR", errorHandler);
886
+ socket.off("session_completed", responseHandler);
887
+ socket.off("session_error", errorHandler);
875
888
  cleanupEsc();
876
889
  resolve();
877
890
  };
878
891
  // Listen for agent response
879
- socket.on("ASK_SESSION_COMPLETED", responseHandler);
880
- socket.on("ASK_SESSION_ERROR", errorHandler);
892
+ socket.on("session_completed", responseHandler);
893
+ socket.on("session_error", errorHandler);
881
894
  // Also allow ESC to stop the ask session
882
895
  let escArmed = true;
883
896
  const onKeypress = (_str, key) => {