@iqai/adk-cli 0.3.19 → 0.3.22

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 (49) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/cli/run.command.d.ts +1 -3
  3. package/dist/cli/run.command.d.ts.map +1 -1
  4. package/dist/cli/run.command.js +375 -87
  5. package/dist/cli/run.command.js.map +1 -1
  6. package/dist/common/constants.d.ts +13 -0
  7. package/dist/common/constants.d.ts.map +1 -0
  8. package/dist/common/constants.js +16 -0
  9. package/dist/common/constants.js.map +1 -0
  10. package/dist/common/types.d.ts +30 -0
  11. package/dist/common/types.d.ts.map +1 -1
  12. package/dist/http/bootstrap.d.ts.map +1 -1
  13. package/dist/http/bootstrap.js +22 -2
  14. package/dist/http/bootstrap.js.map +1 -1
  15. package/dist/http/messaging/messaging.service.d.ts +3 -1
  16. package/dist/http/messaging/messaging.service.d.ts.map +1 -1
  17. package/dist/http/messaging/messaging.service.js +16 -2
  18. package/dist/http/messaging/messaging.service.js.map +1 -1
  19. package/dist/http/providers/agent-graph.service.d.ts.map +1 -1
  20. package/dist/http/providers/agent-graph.service.js +2 -1
  21. package/dist/http/providers/agent-graph.service.js.map +1 -1
  22. package/dist/http/providers/agent-loader.service.d.ts +11 -3
  23. package/dist/http/providers/agent-loader.service.d.ts.map +1 -1
  24. package/dist/http/providers/agent-loader.service.js +150 -53
  25. package/dist/http/providers/agent-loader.service.js.map +1 -1
  26. package/dist/http/providers/agent-loader.types.d.ts +99 -0
  27. package/dist/http/providers/agent-loader.types.d.ts.map +1 -0
  28. package/dist/http/providers/agent-loader.types.js +16 -0
  29. package/dist/http/providers/agent-loader.types.js.map +1 -0
  30. package/dist/http/providers/agent-manager.service.d.ts +68 -5
  31. package/dist/http/providers/agent-manager.service.d.ts.map +1 -1
  32. package/dist/http/providers/agent-manager.service.js +221 -94
  33. package/dist/http/providers/agent-manager.service.js.map +1 -1
  34. package/dist/http/reload/hot-reload.service.d.ts +3 -1
  35. package/dist/http/reload/hot-reload.service.d.ts.map +1 -1
  36. package/dist/http/reload/hot-reload.service.js +11 -6
  37. package/dist/http/reload/hot-reload.service.js.map +1 -1
  38. package/dist/http/sessions/sessions.controller.d.ts +13 -3
  39. package/dist/http/sessions/sessions.controller.d.ts.map +1 -1
  40. package/dist/http/sessions/sessions.service.d.ts +17 -5
  41. package/dist/http/sessions/sessions.service.d.ts.map +1 -1
  42. package/dist/http/sessions/sessions.service.js +123 -35
  43. package/dist/http/sessions/sessions.service.js.map +1 -1
  44. package/dist/http/state/state.controller.d.ts +5 -1
  45. package/dist/http/state/state.controller.d.ts.map +1 -1
  46. package/dist/http/state/state.service.d.ts +5 -1
  47. package/dist/http/state/state.service.d.ts.map +1 -1
  48. package/dist/http/state/state.service.js.map +1 -1
  49. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @iqai/adk-cli
2
2
 
3
+ ## 0.3.22
4
+
5
+ ### Patch Changes
6
+
7
+ - 1ec769a: fix: improve type safety across cli and adk package
8
+ - 9ba699c: fix: state persistence
9
+ - 4fbb724: Fix: state management
10
+ - 69d3431: fix: state persistence and allows initial state of agents to be passed down to proper sessions
11
+ - Updated dependencies [1ec769a]
12
+ - Updated dependencies [9ba699c]
13
+ - Updated dependencies [4fbb724]
14
+ - Updated dependencies [edfe628]
15
+ - @iqai/adk@0.5.3
16
+
17
+ ## 0.3.21
18
+
19
+ ### Patch Changes
20
+
21
+ - Updated dependencies [ae81c74]
22
+ - @iqai/adk@0.5.2
23
+
24
+ ## 0.3.20
25
+
26
+ ### Patch Changes
27
+
28
+ - 170dafc: fix: multiple cache file creation
29
+ - 31264cb: Improves the logging for adk run by silencing the logs from agent processes by default
30
+ - Updated dependencies [d8fd6e8]
31
+ - @iqai/adk@0.5.1
32
+
3
33
  ## 0.3.19
4
34
 
5
35
  ### Patch Changes
@@ -1,8 +1,6 @@
1
1
  import { CommandRunner } from "nest-commander";
2
- interface ServeLikeOptions {
2
+ interface RunOptions {
3
3
  host?: string;
4
- }
5
- interface RunOptions extends ServeLikeOptions {
6
4
  server?: boolean;
7
5
  verbose?: boolean;
8
6
  hot?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"run.command.d.ts","sourceRoot":"","sources":["../../src/cli/run.command.ts"],"names":[],"mappings":"AAKA,OAAO,EAAW,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAiBhE,UAAU,gBAAgB;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,UAAW,SAAQ,gBAAgB;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAsKD,qBAKa,UAAW,SAAQ,aAAa;IACtC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA4GhE,WAAW,IAAI,OAAO;IAQtB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAQ9B,YAAY,IAAI,OAAO;IAQvB,QAAQ,IAAI,OAAO;IASnB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;CAMjC"}
1
+ {"version":3,"file":"run.command.d.ts","sourceRoot":"","sources":["../../src/cli/run.command.ts"],"names":[],"mappings":"AAIA,OAAO,EAAW,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAQhE,UAAU,UAAU;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAueD,qBAKa,UAAW,SAAQ,aAAa;IACtC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAsHhE,WAAW,IAAI,OAAO;IAQtB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAQ9B,YAAY,IAAI,OAAO;IAQvB,QAAQ,IAAI,OAAO;IASnB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;CAMjC"}
@@ -47,28 +47,261 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
47
47
  Object.defineProperty(exports, "__esModule", { value: true });
48
48
  exports.RunCommand = void 0;
49
49
  const p = __importStar(require("@clack/prompts"));
50
- const prompts_1 = require("@clack/prompts");
51
50
  const chalk_1 = __importDefault(require("chalk"));
52
51
  const marked_1 = require("marked");
53
52
  const markedTerminal = __importStar(require("marked-terminal"));
54
53
  const nest_commander_1 = require("nest-commander");
55
54
  const bootstrap_1 = require("../http/bootstrap");
55
+ // Setup markdown terminal renderer
56
56
  const mt = markedTerminal.markedTerminal ?? markedTerminal;
57
57
  marked_1.marked.use(mt());
58
- /**
59
- * Render markdown to ANSI for terminal using 'marked' + 'marked-terminal'.
60
- * Simple static import and configuration as per package docs.
61
- */
62
- async function render(text) {
63
- const input = text ?? "";
64
- const out = marked_1.marked.parse(input);
65
- return typeof out === "string" ? out : String(out ?? "");
58
+ // Console management for quiet mode
59
+ class ConsoleManager {
60
+ originals = null;
61
+ originalStdoutWrite = null;
62
+ originalStderrWrite = null;
63
+ originalSpawn = null;
64
+ verbose;
65
+ outputAllowed = false;
66
+ isDestroyed = false;
67
+ constructor(verbose) {
68
+ this.verbose = verbose;
69
+ // Ensure cleanup on process exit
70
+ process.on("exit", () => this.restore());
71
+ process.on("SIGINT", () => this.restore());
72
+ process.on("SIGTERM", () => this.restore());
73
+ }
74
+ hookConsole() {
75
+ if (this.verbose || this.originals || this.isDestroyed)
76
+ return;
77
+ try {
78
+ this.originals = {
79
+ log: console.log,
80
+ info: console.info,
81
+ warn: console.warn,
82
+ error: console.error,
83
+ debug: console.debug,
84
+ };
85
+ this.originalStdoutWrite = process.stdout.write.bind(process.stdout);
86
+ this.originalStderrWrite = process.stderr.write.bind(process.stderr);
87
+ // Smart console method replacement - allow errors and warnings in verbose mode
88
+ const shouldSilenceConsole = (level) => {
89
+ if (this.outputAllowed)
90
+ return false;
91
+ // Always allow error and warn messages to prevent diagnostic issues
92
+ return !["error", "warn"].includes(level);
93
+ };
94
+ const createConsoleFn = (level, original) => {
95
+ return ((...args) => {
96
+ if (!shouldSilenceConsole(level)) {
97
+ original.apply(console, args);
98
+ }
99
+ });
100
+ };
101
+ console.log = createConsoleFn("log", this.originals.log);
102
+ console.info = createConsoleFn("info", this.originals.info);
103
+ console.warn = createConsoleFn("warn", this.originals.warn);
104
+ console.error = createConsoleFn("error", this.originals.error);
105
+ console.debug = createConsoleFn("debug", this.originals.debug);
106
+ // Smart stdout silencing - allow certain output patterns
107
+ const shouldSilenceStdout = (chunk) => {
108
+ if (this.outputAllowed)
109
+ return false;
110
+ return !this.isImportantOutput(chunk);
111
+ };
112
+ process.stdout.write = ((chunk, encoding, callback) => {
113
+ if (shouldSilenceStdout(chunk))
114
+ return true;
115
+ return this.originalStdoutWrite(chunk, encoding, callback);
116
+ });
117
+ // Allow stderr for error messages but filter out non-critical output
118
+ process.stderr.write = ((chunk, encoding, callback) => {
119
+ if (this.outputAllowed) {
120
+ return this.originalStderrWrite(chunk, encoding, callback);
121
+ }
122
+ // Allow error-like content through stderr
123
+ const str = String(chunk).toLowerCase();
124
+ if (str.includes("error") ||
125
+ str.includes("warning") ||
126
+ str.includes("failed")) {
127
+ return this.originalStderrWrite(chunk, encoding, callback);
128
+ }
129
+ return true;
130
+ });
131
+ }
132
+ catch (error) {
133
+ // If console hooking fails, continue without it to avoid breaking the app
134
+ if (this.verbose) {
135
+ console.error("Failed to hook console:", error);
136
+ }
137
+ }
138
+ }
139
+ isImportantOutput(chunk) {
140
+ const str = String(chunk);
141
+ // Allow spinner characters and UI elements
142
+ const spinnerChars = ["ā ‹", "ā ™", "ā ¹", "ā ø", "ā ¼", "ā “", "ā ¦", "ā §", "ā ‡", "ā "];
143
+ // Allow interactive prompts, errors, and control sequences
144
+ return (spinnerChars.some((char) => str.includes(char)) ||
145
+ str.includes("šŸ¤–") ||
146
+ str.includes("Thinking") ||
147
+ str.includes("\r") ||
148
+ str.includes("\x1b") ||
149
+ str.toLowerCase().includes("error") ||
150
+ str.toLowerCase().includes("warning") ||
151
+ str.includes("?") // Interactive prompts
152
+ );
153
+ }
154
+ hookChildProcessSilence() {
155
+ if (this.verbose || this.originalSpawn || this.isDestroyed)
156
+ return;
157
+ try {
158
+ const cp = require("node:child_process");
159
+ this.originalSpawn = cp.spawn;
160
+ const shouldSilenceProcess = (command, args) => {
161
+ if (!command)
162
+ return false;
163
+ const cmd = command.toLowerCase();
164
+ const allArgs = (args || []).map((a) => String(a).toLowerCase());
165
+ const fullCommand = [cmd, ...allArgs].join(" ");
166
+ // Only silence specific known noisy processes
167
+ const silencePatterns = [
168
+ "mcp-remote",
169
+ "@iqai/mcp",
170
+ "modelcontextprotocol",
171
+ "@modelcontextprotocol",
172
+ ];
173
+ return silencePatterns.some((pattern) => fullCommand.includes(pattern));
174
+ };
175
+ cp.spawn = ((command, args, options) => {
176
+ try {
177
+ const shouldSilence = shouldSilenceProcess(command, Array.isArray(args) ? args : options?.args);
178
+ if (shouldSilence) {
179
+ // Determine the correct options object
180
+ const opts = Array.isArray(args) ? options || {} : args || {};
181
+ // Create safer stdio configuration
182
+ const currentStdio = opts.stdio;
183
+ let newStdio;
184
+ if (Array.isArray(currentStdio)) {
185
+ newStdio = [
186
+ currentStdio[0] || "pipe",
187
+ "pipe", // stdout to pipe (can be handled)
188
+ "pipe", // stderr to pipe (allow error monitoring)
189
+ ];
190
+ }
191
+ else if (typeof currentStdio === "string") {
192
+ newStdio = ["pipe", "pipe", "pipe"];
193
+ }
194
+ else {
195
+ newStdio = ["pipe", "pipe", "pipe"];
196
+ }
197
+ const patchedOpts = { ...opts, stdio: newStdio };
198
+ if (Array.isArray(args)) {
199
+ return this.originalSpawn(command, args, patchedOpts);
200
+ }
201
+ return this.originalSpawn(command, patchedOpts);
202
+ }
203
+ }
204
+ catch (error) {
205
+ // Log error and continue with original spawn to avoid breaking functionality
206
+ if (this.verbose) {
207
+ console.error("Error in child process hook:", error);
208
+ }
209
+ }
210
+ return this.originalSpawn(command, args, options);
211
+ });
212
+ }
213
+ catch (error) {
214
+ if (this.verbose) {
215
+ console.error("Failed to hook child process:", error);
216
+ }
217
+ }
218
+ }
219
+ restore() {
220
+ if (this.isDestroyed)
221
+ return;
222
+ this.isDestroyed = true;
223
+ try {
224
+ if (this.originals) {
225
+ console.log = this.originals.log;
226
+ console.info = this.originals.info;
227
+ console.warn = this.originals.warn;
228
+ console.error = this.originals.error;
229
+ console.debug = this.originals.debug;
230
+ this.originals = null;
231
+ }
232
+ if (this.originalStdoutWrite) {
233
+ process.stdout.write = this.originalStdoutWrite;
234
+ this.originalStdoutWrite = null;
235
+ }
236
+ if (this.originalStderrWrite) {
237
+ process.stderr.write = this.originalStderrWrite;
238
+ this.originalStderrWrite = null;
239
+ }
240
+ if (this.originalSpawn) {
241
+ const cp = require("node:child_process");
242
+ cp.spawn = this.originalSpawn;
243
+ this.originalSpawn = null;
244
+ }
245
+ }
246
+ catch (error) {
247
+ // Use original console.error if available, fallback to process.stderr
248
+ if (this.originals?.error) {
249
+ this.originals.error("Error during ConsoleManager restore:", error);
250
+ }
251
+ else {
252
+ process.stderr.write(`Error during ConsoleManager restore: ${error}\n`);
253
+ }
254
+ }
255
+ }
256
+ writeOut(text) {
257
+ if (this.originalStdoutWrite) {
258
+ this.originalStdoutWrite(text);
259
+ }
260
+ else {
261
+ process.stdout.write(text);
262
+ }
263
+ }
264
+ writeErr(text) {
265
+ if (this.originalStderrWrite) {
266
+ this.originalStderrWrite(text);
267
+ }
268
+ else {
269
+ process.stderr.write(text);
270
+ }
271
+ }
272
+ async withAllowedOutput(fn) {
273
+ if (this.verbose || this.isDestroyed) {
274
+ return await fn();
275
+ }
276
+ const wasOutputAllowed = this.outputAllowed;
277
+ this.outputAllowed = true; // Allow output during this function
278
+ try {
279
+ return await fn();
280
+ }
281
+ finally {
282
+ this.outputAllowed = wasOutputAllowed; // Restore previous state
283
+ }
284
+ }
285
+ error(text) {
286
+ this.writeErr(chalk_1.default.red(text) + "\n");
287
+ }
288
+ renderMarkdown(text) {
289
+ const input = text ?? "";
290
+ const out = marked_1.marked.parse(input);
291
+ return typeof out === "string" ? out : String(out ?? "");
292
+ }
293
+ printAnswer(markdown) {
294
+ const rendered = this.renderMarkdown(markdown);
295
+ this.writeOut((rendered || "").trim() + "\n");
296
+ }
66
297
  }
67
298
  class AgentChatClient {
68
299
  apiUrl;
69
300
  selectedAgent = null;
70
- constructor(apiUrl) {
301
+ consoleManager;
302
+ constructor(apiUrl, consoleManager) {
71
303
  this.apiUrl = apiUrl;
304
+ this.consoleManager = consoleManager;
72
305
  }
73
306
  async connect() {
74
307
  try {
@@ -106,74 +339,118 @@ class AgentChatClient {
106
339
  if (agents.length === 1) {
107
340
  return agents[0];
108
341
  }
109
- const selectedAgent = await p.select({
110
- message: "Choose an agent to chat with:",
111
- options: agents.map((agent) => ({
112
- label: agent.name,
113
- value: agent,
114
- hint: agent.relativePath,
115
- })),
342
+ return await this.consoleManager.withAllowedOutput(async () => {
343
+ const choice = await p.select({
344
+ message: "Choose an agent to chat with:",
345
+ options: agents.map((agent) => ({
346
+ label: agent.name,
347
+ value: agent,
348
+ hint: agent.relativePath,
349
+ })),
350
+ });
351
+ if (p.isCancel(choice)) {
352
+ process.exit(0);
353
+ }
354
+ return choice;
116
355
  });
117
- if (p.isCancel(selectedAgent)) {
118
- p.cancel("Operation cancelled");
119
- process.exit(0);
120
- }
121
- return selectedAgent;
122
356
  }
123
357
  async sendMessage(message) {
124
358
  if (!this.selectedAgent) {
125
359
  throw new Error("No agent selected");
126
360
  }
127
- const s = (0, prompts_1.spinner)();
128
- s.start("šŸ¤– Thinking...");
129
- try {
130
- const response = await fetch(`${this.apiUrl}/api/agents/${encodeURIComponent(this.selectedAgent.relativePath)}/message`, {
131
- method: "POST",
132
- headers: { "Content-Type": "application/json" },
133
- body: JSON.stringify({ message }),
361
+ await this.consoleManager.withAllowedOutput(async () => {
362
+ const spinner = p.spinner();
363
+ spinner.start("šŸ¤– Thinking...");
364
+ // Save original methods for targeted silencing during the request
365
+ const savedStdout = process.stdout.write;
366
+ const savedStderr = process.stderr.write;
367
+ const savedConsoleLog = console.log;
368
+ const savedConsoleInfo = console.info;
369
+ const savedConsoleWarn = console.warn;
370
+ const savedConsoleError = console.error;
371
+ // Intelligent stdout filtering - allow spinner chars but block log messages
372
+ const spinnerChars = ["ā ‹", "ā ™", "ā ¹", "ā ø", "ā ¼", "ā “", "ā ¦", "ā §", "ā ‡", "ā "];
373
+ const isSpinnerOutput = (chunk) => {
374
+ const str = String(chunk);
375
+ return (spinnerChars.some((char) => str.includes(char)) ||
376
+ str.includes("šŸ¤– Thinking") ||
377
+ str.includes("\r") || // carriage returns for spinner updates
378
+ str.includes("\x1b")); // ANSI escape codes for colors/positioning
379
+ };
380
+ // Temporarily override output during the fetch
381
+ process.stdout.write = ((chunk, encoding, callback) => {
382
+ if (isSpinnerOutput(chunk)) {
383
+ return savedStdout.call(process.stdout, chunk, encoding, callback);
384
+ }
385
+ return true; // Block everything else
134
386
  });
135
- if (!response.ok) {
136
- const errorText = await response.text();
137
- s.stop("āŒ Failed to send message");
138
- throw new Error(`Failed to send message: ${errorText}`);
387
+ process.stderr.write = (() => true); // Block all stderr
388
+ console.log = (() => { });
389
+ console.info = (() => { });
390
+ console.warn = (() => { });
391
+ console.error = (() => { });
392
+ try {
393
+ if (!this.selectedAgent?.relativePath) {
394
+ throw new Error("No agent selected or agent path not available");
395
+ }
396
+ const response = await fetch(`${this.apiUrl}/api/agents/${encodeURIComponent(this.selectedAgent.relativePath)}/message`, {
397
+ method: "POST",
398
+ headers: { "Content-Type": "application/json" },
399
+ body: JSON.stringify({ message }),
400
+ });
401
+ if (!response.ok) {
402
+ const errorText = await response.text();
403
+ spinner.stop("āŒ Failed to send message");
404
+ throw new Error(`HTTP ${response.status}: ${errorText}`);
405
+ }
406
+ const result = (await response.json());
407
+ spinner.stop(`šŸ¤– ${result.agentName ?? "Assistant"}:`);
408
+ if (result.response) {
409
+ this.consoleManager.printAnswer(result.response);
410
+ }
139
411
  }
140
- const result = (await response.json());
141
- s.stop(`šŸ¤– ${result.agentName ?? "Assistant"}:`);
142
- if (result.response) {
143
- const formattedResponse = await render(result.response);
144
- p.log.message((formattedResponse || "").trim());
412
+ catch (error) {
413
+ spinner.stop("āŒ Error");
414
+ const errorMessage = error instanceof Error ? error.message : String(error);
415
+ this.consoleManager.error(`Failed to send message: ${errorMessage}`);
416
+ throw error;
145
417
  }
146
- }
147
- catch (_error) {
148
- p.log.error("Failed to send message");
149
- }
418
+ finally {
419
+ // Restore all methods
420
+ process.stdout.write = savedStdout;
421
+ process.stderr.write = savedStderr;
422
+ console.log = savedConsoleLog;
423
+ console.info = savedConsoleInfo;
424
+ console.warn = savedConsoleWarn;
425
+ console.error = savedConsoleError;
426
+ }
427
+ });
150
428
  }
151
429
  async startChat() {
152
430
  if (!this.selectedAgent) {
153
431
  throw new Error("Agent not selected");
154
432
  }
155
- // Add SIGINT handler for interactive chat mode
156
433
  const sigintHandler = () => {
157
- p.cancel("Chat ended");
434
+ this.consoleManager.withAllowedOutput(async () => {
435
+ p.outro("Chat ended");
436
+ });
158
437
  process.exit(0);
159
438
  };
160
439
  process.on("SIGINT", sigintHandler);
161
440
  try {
162
441
  while (true) {
163
442
  try {
164
- const message = await p.text({
165
- message: "šŸ’¬ Message:",
166
- placeholder: "Type your message here... (type 'exit' or 'quit' to end)",
443
+ const input = await this.consoleManager.withAllowedOutput(async () => {
444
+ const res = await p.text({
445
+ message: "šŸ’¬ Message:",
446
+ placeholder: "Type your message here... (type 'exit' or 'quit' to end)",
447
+ });
448
+ if (p.isCancel(res))
449
+ return "exit";
450
+ return typeof res === "symbol" ? String(res) : (res ?? "");
167
451
  });
168
- if (p.isCancel(message)) {
169
- sigintHandler();
170
- }
171
- const trimmed = typeof message === "symbol"
172
- ? String(message)
173
- : (message || "").trim();
174
- // Check for explicit exit commands
452
+ const trimmed = (input || "").trim();
175
453
  if (["exit", "quit"].includes(trimmed.toLowerCase())) {
176
- p.outro("Chat ended");
177
454
  process.exit(0);
178
455
  }
179
456
  if (trimmed) {
@@ -181,13 +458,13 @@ class AgentChatClient {
181
458
  }
182
459
  }
183
460
  catch (error) {
184
- console.error(chalk_1.default.red("Error in chat:"), error);
461
+ const errorMessage = error instanceof Error ? error.message : String(error);
462
+ this.consoleManager.error(`Error in chat: ${errorMessage}`);
185
463
  process.exit(1);
186
464
  }
187
465
  }
188
466
  }
189
467
  finally {
190
- // Clean up SIGINT handler
191
468
  process.removeListener("SIGINT", sigintHandler);
192
469
  }
193
470
  }
@@ -200,11 +477,18 @@ let RunCommand = class RunCommand extends nest_commander_1.CommandRunner {
200
477
  const agentPathArg = passed?.[0];
201
478
  const envVerbose = process.env.ADK_VERBOSE;
202
479
  const isVerbose = options?.verbose ?? (envVerbose === "1" || envVerbose === "true");
480
+ const consoleManager = new ConsoleManager(isVerbose);
481
+ // Hook console and child process only in non-verbose mode
482
+ if (!isVerbose) {
483
+ consoleManager.hookConsole();
484
+ consoleManager.hookChildProcessSilence();
485
+ }
203
486
  if (options?.server) {
204
- // Server-only mode
205
487
  const apiPort = 8042;
206
488
  const host = options.host || "localhost";
207
- console.log(chalk_1.default.blue("šŸš€ Starting ADK Server..."));
489
+ if (isVerbose) {
490
+ console.log(chalk_1.default.blue("šŸš€ Starting ADK Server..."));
491
+ }
208
492
  const server = await (0, bootstrap_1.startHttpServer)({
209
493
  port: apiPort,
210
494
  host,
@@ -213,7 +497,9 @@ let RunCommand = class RunCommand extends nest_commander_1.CommandRunner {
213
497
  hotReload: options?.hot,
214
498
  watchPaths: options?.watch,
215
499
  });
216
- console.log(chalk_1.default.cyan("Press Ctrl+C to stop the server"));
500
+ if (isVerbose) {
501
+ console.log(chalk_1.default.cyan("Press Ctrl+C to stop the server"));
502
+ }
217
503
  process.on("SIGINT", async () => {
218
504
  console.log(chalk_1.default.yellow("\nšŸ›‘ Stopping server..."));
219
505
  await server.stop();
@@ -224,12 +510,12 @@ let RunCommand = class RunCommand extends nest_commander_1.CommandRunner {
224
510
  }
225
511
  // Interactive chat mode
226
512
  const apiUrl = `http://${options?.host || "localhost"}:8042`;
227
- p.intro("šŸ¤– ADK Agent Chat");
228
- // Ensure server is up, else start it
513
+ await consoleManager.withAllowedOutput(async () => {
514
+ p.intro("šŸ¤– ADK Agent Chat");
515
+ });
516
+ // Start server if not running
229
517
  const healthResponse = await fetch(`${apiUrl}/health`).catch(() => null);
230
518
  if (!healthResponse || !healthResponse.ok) {
231
- const serverSpinner = (0, prompts_1.spinner)();
232
- serverSpinner.start("šŸš€ Starting server...");
233
519
  await (0, bootstrap_1.startHttpServer)({
234
520
  port: 8042,
235
521
  host: options?.host || "localhost",
@@ -239,18 +525,14 @@ let RunCommand = class RunCommand extends nest_commander_1.CommandRunner {
239
525
  watchPaths: options?.watch,
240
526
  });
241
527
  await new Promise((resolve) => setTimeout(resolve, 1000));
242
- serverSpinner.stop("āœ… Server ready");
243
528
  }
244
- const client = new AgentChatClient(apiUrl);
245
- await client.connect();
246
- const agentSpinner = (0, prompts_1.spinner)();
247
- agentSpinner.start("šŸ” Scanning for agents...");
529
+ const client = new AgentChatClient(apiUrl, consoleManager);
248
530
  try {
531
+ await client.connect();
249
532
  const agents = await client.fetchAgents();
250
533
  let selectedAgent;
251
534
  if (agents.length === 0) {
252
- agentSpinner.stop("āŒ No agents found");
253
- p.cancel("No agents found in the current directory");
535
+ consoleManager.error("No agents found in the current directory");
254
536
  process.exit(1);
255
537
  }
256
538
  else if (agents.length === 1 || agentPathArg) {
@@ -258,32 +540,38 @@ let RunCommand = class RunCommand extends nest_commander_1.CommandRunner {
258
540
  (agentPathArg &&
259
541
  agents.find((a) => a.relativePath === agentPathArg)) ||
260
542
  agents[0];
261
- agentSpinner.stop(`šŸ¤– Selected agent: ${selectedAgent.name}`);
262
543
  }
263
544
  else {
264
- agentSpinner.stop(`šŸ¤– Found ${agents.length} agents`);
265
- const choice = await p.select({
266
- message: "Choose an agent to chat with:",
267
- options: agents.map((agent) => ({
268
- label: agent.name,
269
- value: agent,
270
- hint: agent.relativePath,
271
- })),
545
+ selectedAgent = await consoleManager.withAllowedOutput(async () => {
546
+ const choice = await p.select({
547
+ message: "Choose an agent to chat with:",
548
+ options: agents.map((agent) => ({
549
+ label: agent.name,
550
+ value: agent,
551
+ hint: agent.relativePath,
552
+ })),
553
+ });
554
+ if (p.isCancel(choice)) {
555
+ process.exit(0);
556
+ }
557
+ return choice;
272
558
  });
273
- if (p.isCancel(choice)) {
274
- p.cancel("Operation cancelled");
275
- process.exit(0);
276
- }
277
- selectedAgent = choice;
278
559
  }
279
560
  client.setSelectedAgent(selectedAgent);
280
561
  await client.startChat();
281
- p.outro("Chat ended");
562
+ await consoleManager.withAllowedOutput(async () => {
563
+ p.outro("Chat ended");
564
+ });
282
565
  }
283
566
  catch (error) {
284
- p.cancel(`Error: ${error instanceof Error ? error.message : String(error)}`);
567
+ const errorMessage = error instanceof Error ? error.message : String(error);
568
+ consoleManager.error(`Error: ${errorMessage}`);
285
569
  process.exit(1);
286
570
  }
571
+ finally {
572
+ // Ensure cleanup happens
573
+ consoleManager.restore();
574
+ }
287
575
  }
288
576
  parseServer() {
289
577
  return true;