@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.
- package/README.md +201 -190
- package/dist/bin/ttt.js +4 -2
- package/dist/bin/ttt.js.map +1 -1
- package/dist/package.json +13 -2
- package/dist/src/commands/ask/AskApp.js +121 -0
- package/dist/src/commands/ask/AskApp.js.map +1 -0
- package/dist/src/commands/ask/components/AssistantResponse.js +31 -0
- package/dist/src/commands/ask/components/AssistantResponse.js.map +1 -0
- package/dist/src/commands/ask/components/Banner.js +15 -0
- package/dist/src/commands/ask/components/Banner.js.map +1 -0
- package/dist/src/commands/ask/components/ChatInput.js +93 -0
- package/dist/src/commands/ask/components/ChatInput.js.map +1 -0
- package/dist/src/commands/ask/components/Divider.js +17 -0
- package/dist/src/commands/ask/components/Divider.js.map +1 -0
- package/dist/src/commands/ask/components/IntroTips.js +19 -0
- package/dist/src/commands/ask/components/IntroTips.js.map +1 -0
- package/dist/src/commands/ask/components/MessageBubble.js +47 -0
- package/dist/src/commands/ask/components/MessageBubble.js.map +1 -0
- package/dist/src/commands/ask/components/SessionInfo.js +20 -0
- package/dist/src/commands/ask/components/SessionInfo.js.map +1 -0
- package/dist/src/commands/ask/components/StatusIndicator.js +67 -0
- package/dist/src/commands/ask/components/StatusIndicator.js.map +1 -0
- package/dist/src/commands/ask-ink.js +380 -0
- package/dist/src/commands/ask-ink.js.map +1 -0
- package/dist/src/commands/ask.js +73 -60
- package/dist/src/commands/ask.js.map +1 -1
- package/dist/src/commands/chat/ChatApp.js +125 -0
- package/dist/src/commands/chat/ChatApp.js.map +1 -0
- package/dist/src/commands/chat-ink.js +436 -0
- package/dist/src/commands/chat-ink.js.map +1 -0
- package/dist/src/commands/chat.js +82 -0
- package/dist/src/commands/chat.js.map +1 -0
- package/dist/src/commands/login.js +6 -4
- package/dist/src/commands/login.js.map +1 -1
- package/dist/src/commands/start-test.js +62 -88
- package/dist/src/commands/start-test.js.map +1 -1
- package/dist/src/commands/stream.js +9 -9
- package/dist/src/commands/stream.js.map +1 -1
- package/dist/src/commands/test.js +58 -125
- package/dist/src/commands/test.js.map +1 -1
- package/dist/src/lib/agent-orchestrator.js +546 -0
- package/dist/src/lib/agent-orchestrator.js.map +1 -0
- package/dist/src/lib/cloudinary-service.js +65 -0
- package/dist/src/lib/cloudinary-service.js.map +1 -0
- package/dist/src/lib/config.js +3 -2
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/events.js +73 -60
- package/dist/src/lib/events.js.map +1 -1
- package/dist/src/lib/http.js +34 -1
- package/dist/src/lib/http.js.map +1 -1
- package/dist/src/lib/legacy-chat-runner.js +37 -0
- package/dist/src/lib/legacy-chat-runner.js.map +1 -0
- package/dist/src/lib/local-tools/api/api-discovery.js +17 -0
- package/dist/src/lib/local-tools/api/api-discovery.js.map +1 -0
- package/dist/src/lib/local-tools/api/build-request.js +20 -0
- package/dist/src/lib/local-tools/api/build-request.js.map +1 -0
- package/dist/src/lib/local-tools/api/extract-response-fields.js +26 -0
- package/dist/src/lib/local-tools/api/extract-response-fields.js.map +1 -0
- package/dist/src/lib/local-tools/api/generate-api-test.js +20 -0
- package/dist/src/lib/local-tools/api/generate-api-test.js.map +1 -0
- package/dist/src/lib/local-tools/api/generate-curl.js +8 -0
- package/dist/src/lib/local-tools/api/generate-curl.js.map +1 -0
- package/dist/src/lib/local-tools/api/get-api-parameters.js +17 -0
- package/dist/src/lib/local-tools/api/get-api-parameters.js.map +1 -0
- package/dist/src/lib/local-tools/api/index.js +10 -0
- package/dist/src/lib/local-tools/api/index.js.map +1 -0
- package/dist/src/lib/local-tools/api/request.js +43 -0
- package/dist/src/lib/local-tools/api/request.js.map +1 -0
- package/dist/src/lib/local-tools/api/set-auth-header.js +8 -0
- package/dist/src/lib/local-tools/api/set-auth-header.js.map +1 -0
- package/dist/src/lib/local-tools/api/types.js +2 -0
- package/dist/src/lib/local-tools/api/types.js.map +1 -0
- package/dist/src/lib/local-tools/api/utils.js +33 -0
- package/dist/src/lib/local-tools/api/utils.js.map +1 -0
- package/dist/src/lib/local-tools/api/validate-response.js +41 -0
- package/dist/src/lib/local-tools/api/validate-response.js.map +1 -0
- package/dist/src/lib/local-tools/file-tools.js +45 -0
- package/dist/src/lib/local-tools/file-tools.js.map +1 -0
- package/dist/src/lib/local-tools/general/discover-local-services.js +95 -0
- package/dist/src/lib/local-tools/general/discover-local-services.js.map +1 -0
- package/dist/src/lib/local-tools/general/index.js +2 -0
- package/dist/src/lib/local-tools/general/index.js.map +1 -0
- package/dist/src/lib/local-tools/ui/click-element.js +105 -0
- package/dist/src/lib/local-tools/ui/click-element.js.map +1 -0
- package/dist/src/lib/local-tools/ui/dom-rag.js +201 -0
- package/dist/src/lib/local-tools/ui/dom-rag.js.map +1 -0
- package/dist/src/lib/local-tools/ui/find-element.js +31 -0
- package/dist/src/lib/local-tools/ui/find-element.js.map +1 -0
- package/dist/src/lib/local-tools/ui/hover-element.js +94 -0
- package/dist/src/lib/local-tools/ui/hover-element.js.map +1 -0
- package/dist/src/lib/local-tools/ui/index.js +3 -0
- package/dist/src/lib/local-tools/ui/index.js.map +1 -0
- package/dist/src/lib/local-tools/ui/manage-tab.js +65 -0
- package/dist/src/lib/local-tools/ui/manage-tab.js.map +1 -0
- package/dist/src/lib/local-tools/ui/navigate.js +35 -0
- package/dist/src/lib/local-tools/ui/navigate.js.map +1 -0
- package/dist/src/lib/local-tools/ui/page-discovery.js +32 -0
- package/dist/src/lib/local-tools/ui/page-discovery.js.map +1 -0
- package/dist/src/lib/local-tools/ui/playwright-mcp.js +217 -0
- package/dist/src/lib/local-tools/ui/playwright-mcp.js.map +1 -0
- package/dist/src/lib/local-tools/ui/screenshot.js +19 -0
- package/dist/src/lib/local-tools/ui/screenshot.js.map +1 -0
- package/dist/src/lib/local-tools/ui/search-interactive-elements.js +18 -0
- package/dist/src/lib/local-tools/ui/search-interactive-elements.js.map +1 -0
- package/dist/src/lib/local-tools/ui/selector-resolver.js +153 -0
- package/dist/src/lib/local-tools/ui/selector-resolver.js.map +1 -0
- package/dist/src/lib/local-tools/ui/snapshot-query.js +129 -0
- package/dist/src/lib/local-tools/ui/snapshot-query.js.map +1 -0
- package/dist/src/lib/local-tools/ui/type-text.js +40 -0
- package/dist/src/lib/local-tools/ui/type-text.js.map +1 -0
- package/dist/src/lib/local-tools/ui/types.js +2 -0
- package/dist/src/lib/local-tools/ui/types.js.map +1 -0
- package/dist/src/lib/local-tools/utility/finish-overall-test.js +12 -0
- package/dist/src/lib/local-tools/utility/finish-overall-test.js.map +1 -0
- package/dist/src/lib/local-tools/utility/index.js +2 -0
- package/dist/src/lib/local-tools/utility/index.js.map +1 -0
- package/dist/src/lib/prompts/builder.js +38 -0
- package/dist/src/lib/prompts/builder.js.map +1 -0
- package/dist/src/lib/prompts/index.js +7 -0
- package/dist/src/lib/prompts/index.js.map +1 -0
- package/dist/src/lib/prompts/templates.js +166 -0
- package/dist/src/lib/prompts/templates.js.map +1 -0
- package/dist/src/lib/session-manager.js +201 -0
- package/dist/src/lib/session-manager.js.map +1 -0
- package/dist/src/lib/socket.js +70 -9
- package/dist/src/lib/socket.js.map +1 -1
- package/dist/src/lib/testing-mode.js +33 -0
- package/dist/src/lib/testing-mode.js.map +1 -0
- package/dist/src/lib/tool-descriptions.js +59 -0
- package/dist/src/lib/tool-descriptions.js.map +1 -0
- package/dist/src/lib/tool-executor.js +537 -0
- package/dist/src/lib/tool-executor.js.map +1 -0
- package/dist/src/lib/tool-registry.js +803 -0
- package/dist/src/lib/tool-registry.js.map +1 -0
- package/dist/src/lib/tool-result-pruner.js +384 -0
- package/dist/src/lib/tool-result-pruner.js.map +1 -0
- package/dist/src/lib/tui/components/AskIntro.js +6 -0
- package/dist/src/lib/tui/components/AskIntro.js.map +1 -0
- package/dist/src/lib/tui/components/Banner.js +15 -0
- package/dist/src/lib/tui/components/Banner.js.map +1 -0
- package/dist/src/lib/tui/components/Divider.js +17 -0
- package/dist/src/lib/tui/components/Divider.js.map +1 -0
- package/dist/src/lib/tui/components/EventLine.js +110 -0
- package/dist/src/lib/tui/components/EventLine.js.map +1 -0
- package/dist/src/lib/tui/components/Header.js +15 -0
- package/dist/src/lib/tui/components/Header.js.map +1 -0
- package/dist/src/lib/tui/components/InputBox.js +9 -0
- package/dist/src/lib/tui/components/InputBox.js.map +1 -0
- package/dist/src/lib/tui/components/Mapping.js +8 -0
- package/dist/src/lib/tui/components/Mapping.js.map +1 -0
- package/dist/src/lib/tui/components/ProjectList.js +6 -0
- package/dist/src/lib/tui/components/ProjectList.js.map +1 -0
- package/dist/src/lib/tui/components/Spinner.js +20 -0
- package/dist/src/lib/tui/components/Spinner.js.map +1 -0
- package/dist/src/lib/tui/components/StatusBanner.js +12 -0
- package/dist/src/lib/tui/components/StatusBanner.js.map +1 -0
- package/dist/src/lib/tui/components/StatusBar.js +11 -0
- package/dist/src/lib/tui/components/StatusBar.js.map +1 -0
- package/dist/src/lib/tui/components/UserBubble.js +6 -0
- package/dist/src/lib/tui/components/UserBubble.js.map +1 -0
- package/dist/src/lib/tui/components/index.js +16 -0
- package/dist/src/lib/tui/components/index.js.map +1 -0
- package/dist/src/lib/tui/events.js +716 -76
- package/dist/src/lib/tui/events.js.map +1 -1
- package/dist/src/lib/tui/icons.js +14 -0
- package/dist/src/lib/tui/icons.js.map +1 -1
- package/dist/src/lib/tui/ink-print.js +41 -0
- package/dist/src/lib/tui/ink-print.js.map +1 -0
- package/dist/src/lib/tui/interactive-chat.js +345 -0
- package/dist/src/lib/tui/interactive-chat.js.map +1 -0
- package/dist/src/lib/tui/print.js +31 -26
- package/dist/src/lib/tui/print.js.map +1 -1
- package/dist/src/lib/tui/prompt.js +21 -18
- package/dist/src/lib/tui/prompt.js.map +1 -1
- package/dist/src/test-agent-flow.js +148 -0
- package/dist/src/test-agent-flow.js.map +1 -0
- package/dist/src/test-browser-session.js +152 -0
- package/dist/src/test-browser-session.js.map +1 -0
- package/dist/src/test-browser-snapshot.js +187 -0
- package/dist/src/test-browser-snapshot.js.map +1 -0
- package/dist/src/test-snapshot-detailed.js +219 -0
- package/dist/src/test-snapshot-detailed.js.map +1 -0
- package/dist/src/test-snapshot-simple.js +85 -0
- package/dist/src/test-snapshot-simple.js.map +1 -0
- package/dist/src/test-snapshot-tabs.js +110 -0
- package/dist/src/test-snapshot-tabs.js.map +1 -0
- 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":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,MAAM,EAAC,MAAM,KAAK,CAAC;AAE3B,OAAO,EAAC,gBAAgB,EAAC,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAC,aAAa,EAAE,YAAY,EAAE,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,GAEnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,uBAAuB,EAAC,MAAM,YAAY,CAAC;AACnD,OAAO,EAAC,MAAM,EAAC,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,MAAM,OAAO,CAAC;AAe1B,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KACrC,WAAW,CAAC,0DAA0D,CAAC;KACvE,MAAM,CAAC,mBAAmB,EAAE,wCAAwC,CAAC;KACrE,MAAM,CAAC,wBAAwB,EAAE,gCAAgC,CAAC;KAClE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,IAAI,CAAC;QACH,uBAAuB;QACvB,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;QAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CACV,yDAAyD,CAC1D,CACF,CAAC;YACF,IAAI,CAAC;gBACH,MAAM,uBAAuB,EAAE,CAAC;YAClC,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,IAAI,cAAc,CAAC,CAAC,CAAC;gBACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,IAAI,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAC9B,IAAI,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QACzC,IAAI,SAA6B,CAAC;QAElC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,CAAC;gBACvC,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CACP,yBAAyB,IAAI,CAAC,SAAS,oCAAoC,CAC5E,CACF,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,SAAS,GAAG,eAAe,CAAC;QAC9B,CAAC;QAED,IAAI,aAAa,GAAG,SAAS,CAAC;QAC9B,IAAI,gBAAoC,CAAC;QACzC,IAAI,gBAAgB,GAAG,SAAS,CAAC,CAAC,CAAC,WAAW,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACtE,IAAI,MAAW,CAAC;QAChB,IAAI,aAAa,GAAG,KAAK,CAAC,CAAC,kCAAkC;QAE7D,6BAA6B;QAC7B,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;YAC7C,gBAAgB,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;YACpE,aAAa,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,EAAE,YAAY,IAAI,SAAS,CAAC;YAErE,IAAI,CAAC,SAAS,IAAI,gBAAgB,EAAE,CAAC;gBACnC,MAAM,UAAU,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;gBACxD,IAAI,UAAU,EAAE,CAAC;oBACf,SAAS,GAAG,UAAU,CAAC;gBACzB,CAAC;YACH,CAAC;YAED,wDAAwD;YACxD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YACxD,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC;YACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC;gBAChD,CAAC,CAAC,WAAW,CAAC,KAAK;gBACnB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;oBAC1B,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,EAAE,CAAC;YAET,IAAI,CAAC,SAAS,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClD,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC,CAAC;gBACtE,MAAM,QAAQ,GAAG,WAAW,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC5C,IAAI,QAAQ,EAAE,EAAE,EAAE,CAAC;oBACjB,SAAS,GAAG,QAAQ,CAAC,EAAE,CAAC;oBACxB,gBAAgB,GAAG,QAAQ,CAAC,IAAI,IAAI,WAAW,SAAS,EAAE,CAAC;gBAC7D,CAAC;YACH,CAAC;YAED,uDAAuD;YACvD,IACE,SAAS;gBACT,CAAC,CAAC,gBAAgB,IAAI,gBAAgB,KAAK,SAAS,CAAC,EACrD,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;oBAC1D,gBAAgB,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,WAAW,SAAS,EAAE,CAAC;gBAC5D,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;gBACpE,gBAAgB,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,WAAW,SAAS,EAAE,CAAC;YACrE,CAAC;QACH,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC;YACvC,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;gBACrC,6CAA6C;gBAC7C,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CAAC,kDAAkD,CAAC,CACjE,CAAC;gBACF,IAAI,CAAC;oBACH,MAAM,uBAAuB,EAAE,CAAC;oBAChC,IAAI,GAAG,gBAAgB,EAAE,CAAC;oBAE1B,wCAAwC;oBACxC,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;oBAC7C,gBAAgB,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;oBACpE,aAAa;wBACX,EAAE,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,EAAE,YAAY,IAAI,SAAS,CAAC;oBAEvD,0BAA0B;oBAC1B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;oBACxD,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC;oBACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC;wBAChD,CAAC,CAAC,WAAW,CAAC,KAAK;wBACnB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;4BAC1B,CAAC,CAAC,WAAW;4BACb,CAAC,CAAC,EAAE,CAAC;oBAET,IAAI,CAAC,SAAS,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAClD,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAC/B,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CACnC,CAAC;wBACF,MAAM,QAAQ,GAAG,WAAW,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;wBAC5C,IAAI,QAAQ,EAAE,EAAE,EAAE,CAAC;4BACjB,SAAS,GAAG,QAAQ,CAAC,EAAE,CAAC;4BACxB,gBAAgB,GAAG,QAAQ,CAAC,IAAI,IAAI,WAAW,SAAS,EAAE,CAAC;wBAC7D,CAAC;oBACH,CAAC;oBAED,IAAI,SAAS,EAAE,CAAC;wBACd,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,GAAG,CAChC,oBAAoB,SAAS,EAAE,CAChC,CAAC;wBACF,gBAAgB;4BACd,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,WAAW,SAAS,EAAE,CAAC;oBACpD,CAAC;gBACH,CAAC;gBAAC,OAAO,WAAgB,EAAE,CAAC;oBAC1B,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CACP,6BAA6B,WAAW,EAAE,OAAO,IAAI,WAAW,EAAE,CACnE,CACF,CAAC;oBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CACR,uCAAuC,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,CACjE,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAEpC,wBAAwB;QACxB,MAAM,aAAa,GAA6B,EAAE,CAAC;QAEnD,MAAM,WAAW,GAA2B;YAC1C,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,+BAA+B;YAC5C,OAAO,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC;YAC/B,GAAG,EAAE,KAAK,IAAI,EAAE;gBACd,MAAM,QAAQ,GAAG,aAAa;qBAC3B,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;oBACX,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,MAAM;wBACjC,CAAC,CAAC,cAAc,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;wBAC7D,CAAC,CAAC,EAAE,CAAC;oBACP,OAAO,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,WAAW,GAAG,OAAO,EAAE,CAAC;gBACzD,CAAC,CAAC;qBACD,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEd,eAAe,EAAE,EAAE,UAAU,CAAC;oBAC5B,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;oBACzB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,oBAAoB,QAAQ,gEAAgE;iBACtG,CAAC,CAAC;gBACH,OAAO,UAAU,CAAC;YACpB,CAAC;SACF,CAAC;QAEF,MAAM,WAAW,GAA2B;YAC1C,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,sBAAsB;YACnC,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;YACxB,GAAG,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM;SACxB,CAAC;QAEF,MAAM,YAAY,GAA2B;YAC3C,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,kBAAkB;YAC/B,OAAO,EAAE,CAAC,KAAK,CAAC;YAChB,GAAG,EAAE,KAAK,IAAI,EAAE;gBACd,OAAO,CAAC,KAAK,EAAE,CAAC;gBAChB,OAAO,UAAU,CAAC;YACpB,CAAC;SACF,CAAC;QAEF,uCAAuC;QACvC,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;QAE3D,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkC,CAAC;QAChE,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAChC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACzC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBACjC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACpC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,mBAAmB,GAAG,KAAK,EAC/B,GAAW,EACX,IAAc,EACgB,EAAE;YAChC,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,eAAe,EAAE,EAAE,UAAU,CAAC;oBAC5B,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;oBACzB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,qBAAqB,GAAG,yCAAyC;iBAC3E,CAAC,CAAC;gBACH,OAAO,UAAU,CAAC;YACpB,CAAC;YACD,OAAO,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC,CAAC;QAEF,MAAM,eAAe,GAAG,GAAG,EAAE;YAC3B,OAAQ,UAAkB,CAAC,iBAAiB,CAAC;QAC/C,CAAC,CAAC;QAEF,MAAM,WAAW,GAAG,GAAG,EAAE;YACvB,IAAI,CAAC;gBACH,aAAa,GAAG,IAAI,CAAC,CAAC,wBAAwB;gBAC9C,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;gBACvC,YAAY,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,6BAA6B;gBACpE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC,4BAA4B;gBACzD,YAAY,EAAE,UAAU,CAAC;oBACvB,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;oBACzB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,uEAAuE;iBACjF,CAAC,CAAC;gBAEH,IAAI,MAAM,IAAI,cAAc,EAAE,CAAC;oBAC7B,WAAW,CAAC,MAAM,EAAE;wBAClB,YAAY,EAAE,KAAK;wBACnB,GAAG,EAAE,EAAC,eAAe,EAAE,cAAc,EAAC;qBAChC,CAAC,CAAC;gBACZ,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC,CAAC;QAEF,MAAM,oBAAoB,GAAG,CAAC,cAAmB,EAAE,EAAE;YACnD,2BAA2B,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE;gBACnD,+BAA+B;gBAC/B,qBAAqB;YACvB,CAAC,CAAC,CAAC;YAEF,cAAsB,CAAC,KAAK,EAAE,CAAC,CAAC,SAAiB,EAAE,IAAS,EAAE,EAAE;gBAC/D,MAAM,CAAC,GAAG,qBAAqB,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;gBACxD,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;gBAEvC,6CAA6C;gBAC7C,IAAI,aAAa,EAAE,CAAC;oBAClB,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC,KAAK,kBAAkB,EAAE,CAAC;oBAC7B,YAAY,EAAE,SAAS,CAAC;wBACtB,IAAI,EAAE,aAAa;wBACnB,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,CAAC,KAAK,kBAAkB,EAAE,CAAC;oBACpC,YAAY,EAAE,SAAS,CAAC;wBACtB,IAAI,EAAE,0BAA0B;wBAChC,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,CAAC,KAAK,eAAe,EAAE,CAAC;oBACjC,MAAM,GAAG,GACP,IAAI,EAAE,IAAI,EAAE,OAAO,IAAI,IAAI,EAAE,IAAI,EAAE,OAAO,IAAI,aAAa,CAAC;oBAC9D,YAAY,EAAE,SAAS,CAAC;wBACtB,IAAI,EAAE,GAAG;wBACT,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,CAAC,KAAK,iBAAiB,EAAE,CAAC;oBACnC,MAAM,GAAG,GACP,IAAI,EAAE,IAAI,EAAE,SAAS,IAAI,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC;oBAC7D,IAAI,GAAG,EAAE,CAAC;wBACR,YAAY,EAAE,UAAU,CAAC;4BACvB,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;4BACzB,IAAI,EAAE,QAAQ;4BACd,OAAO,EAAE,yBAAyB,GAAG,EAAE;yBACxC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,IAAI,CAAC,KAAK,YAAY,EAAE,CAAC;oBAC9B,MAAM,OAAO,GACX,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,WAAW,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,MAAM,KAAK,CAAC;oBAClE,YAAY,EAAE,SAAS,CAAC;wBACtB,IAAI,EAAE,OAAO;wBACb,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,CAAC,KAAK,aAAa,EAAE,CAAC;oBAC/B,wDAAwD;gBAC1D,CAAC;qBAAM,IAAI,CAAC,KAAK,mBAAmB,EAAE,CAAC;oBACrC,YAAY,EAAE,WAAW,EAAE,CAAC;oBAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,aAAa,CAAC;oBACpD,YAAY,EAAE,UAAU,CAAC;wBACvB,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;wBACzB,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,OAAO;qBACjB,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,CAAC,KAAK,eAAe,EAAE,CAAC;oBACjC,YAAY,EAAE,WAAW,EAAE,CAAC;oBAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,8BAA8B,CAAC;oBACjE,YAAY,EAAE,UAAU,CAAC;wBACvB,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;wBACzB,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,KAAK,KAAK,EAAE;wBACrB,OAAO,EAAE,IAAI;qBACd,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,eAAe,GAAG,CAAC,YAAoB,EAAE,EAAE;YAC/C,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;YAClC,oBAAoB,CAAC,SAAS,CAAC,CAAC;YAChC,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YACtC,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,iBAAiB,GAAG,KAAK,EAAE,OAAe,EAAE,EAAE;YAClD,IAAI,CAAC;gBACH,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;gBACvC,aAAa,GAAG,KAAK,CAAC,CAAC,0CAA0C;gBAEjE,uCAAuC;gBACvC,IAAI,CAAC,cAAc,EAAE,CAAC;oBACpB,YAAY,EAAE,SAAS,CAAC;wBACtB,IAAI,EAAE,0BAA0B;wBAChC,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;oBAEH,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,IAAI,CACjC,sBAAsB,EACtB;wBACE,QAAQ,EAAE,OAAO;wBACjB,UAAU,EAAE,SAAS;wBACrB,OAAO,EAAE,KAAK;qBACf,CACF,CAAC;oBACF,cAAc,GAAG,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC;oBAClD,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC;oBAExC,IAAI,gBAAgB,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;wBACtD,kBAAkB,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;oBAClD,CAAC;oBAED,8BAA8B;oBAC9B,MAAM,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;oBAEzC,YAAY,EAAE,SAAS,CAAC;wBACtB,IAAI,EAAE,0BAA0B;wBAChC,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,wCAAwC;oBACxC,YAAY,EAAE,SAAS,CAAC;wBACtB,IAAI,EAAE,YAAY;wBAClB,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;oBAEH,MAAM,IAAI,CAAC,IAAI,CAAC,wBAAwB,cAAc,UAAU,EAAE;wBAChE,OAAO,EAAE,OAAO;wBAChB,UAAU,EAAE,SAAS;wBACrB,OAAO,EAAE,KAAK;qBACf,CAAC,CAAC;oBAEH,YAAY,EAAE,SAAS,CAAC;wBACtB,IAAI,EAAE,0BAA0B;wBAChC,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;gBACvC,YAAY,EAAE,WAAW,EAAE,CAAC;gBAC5B,YAAY,EAAE,UAAU,CAAC;oBACvB,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;oBACzB,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,YAAY,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE;oBAC9C,OAAO,EAAE,IAAI;iBACd,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,UAAU,GAAG,GAAG,EAAE;YACtB,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC;QAEF,oCAAoC;QACpC,MAAM,kBAAkB,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACrD,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,KAAK,EAAE,GAAG,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,GAAG,CAAC,IAAI,EAAE;SACtB,CAAC,CAAC,CAAC;QAEJ,qBAAqB;QACrB,MAAM,EAAC,aAAa,EAAC,GAAG,MAAM,CAC5B,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE;YAC1B,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,gBAAgB;YACzB,aAAa;YACb,aAAa,EAAE,kBAAkB;YACjC,aAAa,EAAE,iBAAiB;YAChC,cAAc,EAAE,mBAAmB;YACnC,MAAM,EAAE,UAAU;YAClB,QAAQ,EAAE,WAAW;SACtB,CAAC,CACH,CAAC;QAEF,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
package/dist/src/commands/ask.js
CHANGED
|
@@ -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
|
|
130
|
-
|
|
131
|
-
|
|
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.
|
|
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
|
|
632
|
-
|
|
633
|
-
|
|
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
|
-
|
|
637
|
-
|
|
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
|
-
|
|
643
|
-
|
|
644
|
-
|
|
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
|
-
|
|
659
|
-
|
|
660
|
-
|
|
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
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
if (
|
|
677
|
-
spinner
|
|
678
|
-
|
|
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("
|
|
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("
|
|
867
|
-
socket.off("
|
|
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("
|
|
874
|
-
socket.off("
|
|
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("
|
|
880
|
-
socket.on("
|
|
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) => {
|