@nexagent-cli/cli 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 (188) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/LICENSE +21 -0
  3. package/README.md +40 -0
  4. package/dist/agent/loop.d.ts +45 -0
  5. package/dist/agent/loop.d.ts.map +1 -0
  6. package/dist/agent/loop.js +270 -0
  7. package/dist/agent/loop.js.map +1 -0
  8. package/dist/agent/prompt.d.ts +3 -0
  9. package/dist/agent/prompt.d.ts.map +1 -0
  10. package/dist/agent/prompt.js +43 -0
  11. package/dist/agent/prompt.js.map +1 -0
  12. package/dist/commands/agent.d.ts +21 -0
  13. package/dist/commands/agent.d.ts.map +1 -0
  14. package/dist/commands/agent.js +111 -0
  15. package/dist/commands/agent.js.map +1 -0
  16. package/dist/commands/chat.d.ts +18 -0
  17. package/dist/commands/chat.d.ts.map +1 -0
  18. package/dist/commands/chat.js +115 -0
  19. package/dist/commands/chat.js.map +1 -0
  20. package/dist/commands/config.d.ts +10 -0
  21. package/dist/commands/config.d.ts.map +1 -0
  22. package/dist/commands/config.js +96 -0
  23. package/dist/commands/config.js.map +1 -0
  24. package/dist/commands/doctor.d.ts +8 -0
  25. package/dist/commands/doctor.d.ts.map +1 -0
  26. package/dist/commands/doctor.js +201 -0
  27. package/dist/commands/doctor.js.map +1 -0
  28. package/dist/commands/memory.d.ts +13 -0
  29. package/dist/commands/memory.d.ts.map +1 -0
  30. package/dist/commands/memory.js +97 -0
  31. package/dist/commands/memory.js.map +1 -0
  32. package/dist/commands/models.d.ts +2 -0
  33. package/dist/commands/models.d.ts.map +1 -0
  34. package/dist/commands/models.js +5 -0
  35. package/dist/commands/models.js.map +1 -0
  36. package/dist/commands/run.d.ts +13 -0
  37. package/dist/commands/run.d.ts.map +1 -0
  38. package/dist/commands/run.js +74 -0
  39. package/dist/commands/run.js.map +1 -0
  40. package/dist/commands/server.d.ts +8 -0
  41. package/dist/commands/server.d.ts.map +1 -0
  42. package/dist/commands/server.js +73 -0
  43. package/dist/commands/server.js.map +1 -0
  44. package/dist/commands/session.d.ts +11 -0
  45. package/dist/commands/session.d.ts.map +1 -0
  46. package/dist/commands/session.js +77 -0
  47. package/dist/commands/session.js.map +1 -0
  48. package/dist/commands/update.d.ts +17 -0
  49. package/dist/commands/update.d.ts.map +1 -0
  50. package/dist/commands/update.js +320 -0
  51. package/dist/commands/update.js.map +1 -0
  52. package/dist/config/loader.d.ts +4 -0
  53. package/dist/config/loader.d.ts.map +1 -0
  54. package/dist/config/loader.js +83 -0
  55. package/dist/config/loader.js.map +1 -0
  56. package/dist/config/wizard.d.ts +4 -0
  57. package/dist/config/wizard.d.ts.map +1 -0
  58. package/dist/config/wizard.js +131 -0
  59. package/dist/config/wizard.js.map +1 -0
  60. package/dist/db/database.d.ts +4 -0
  61. package/dist/db/database.d.ts.map +1 -0
  62. package/dist/db/database.js +130 -0
  63. package/dist/db/database.js.map +1 -0
  64. package/dist/db/session-store.d.ts +17 -0
  65. package/dist/db/session-store.d.ts.map +1 -0
  66. package/dist/db/session-store.js +117 -0
  67. package/dist/db/session-store.js.map +1 -0
  68. package/dist/index.d.ts +3 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +207 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/llm/providers/anthropic.d.ts +21 -0
  73. package/dist/llm/providers/anthropic.d.ts.map +1 -0
  74. package/dist/llm/providers/anthropic.js +186 -0
  75. package/dist/llm/providers/anthropic.js.map +1 -0
  76. package/dist/llm/providers/google.d.ts +13 -0
  77. package/dist/llm/providers/google.d.ts.map +1 -0
  78. package/dist/llm/providers/google.js +83 -0
  79. package/dist/llm/providers/google.js.map +1 -0
  80. package/dist/llm/providers/ollama.d.ts +12 -0
  81. package/dist/llm/providers/ollama.d.ts.map +1 -0
  82. package/dist/llm/providers/ollama.js +110 -0
  83. package/dist/llm/providers/ollama.js.map +1 -0
  84. package/dist/llm/providers/openai.d.ts +15 -0
  85. package/dist/llm/providers/openai.d.ts.map +1 -0
  86. package/dist/llm/providers/openai.js +180 -0
  87. package/dist/llm/providers/openai.js.map +1 -0
  88. package/dist/llm/router.d.ts +20 -0
  89. package/dist/llm/router.d.ts.map +1 -0
  90. package/dist/llm/router.js +52 -0
  91. package/dist/llm/router.js.map +1 -0
  92. package/dist/memory/manager.d.ts +16 -0
  93. package/dist/memory/manager.d.ts.map +1 -0
  94. package/dist/memory/manager.js +114 -0
  95. package/dist/memory/manager.js.map +1 -0
  96. package/dist/safety/gate.d.ts +14 -0
  97. package/dist/safety/gate.d.ts.map +1 -0
  98. package/dist/safety/gate.js +102 -0
  99. package/dist/safety/gate.js.map +1 -0
  100. package/dist/subagents/orchestrator.d.ts +20 -0
  101. package/dist/subagents/orchestrator.d.ts.map +1 -0
  102. package/dist/subagents/orchestrator.js +151 -0
  103. package/dist/subagents/orchestrator.js.map +1 -0
  104. package/dist/tools/file-delete.d.ts +15 -0
  105. package/dist/tools/file-delete.d.ts.map +1 -0
  106. package/dist/tools/file-delete.js +94 -0
  107. package/dist/tools/file-delete.js.map +1 -0
  108. package/dist/tools/file-edit.d.ts +19 -0
  109. package/dist/tools/file-edit.d.ts.map +1 -0
  110. package/dist/tools/file-edit.js +182 -0
  111. package/dist/tools/file-edit.js.map +1 -0
  112. package/dist/tools/file-list.d.ts +13 -0
  113. package/dist/tools/file-list.d.ts.map +1 -0
  114. package/dist/tools/file-list.js +92 -0
  115. package/dist/tools/file-list.js.map +1 -0
  116. package/dist/tools/file-read.d.ts +13 -0
  117. package/dist/tools/file-read.d.ts.map +1 -0
  118. package/dist/tools/file-read.js +68 -0
  119. package/dist/tools/file-read.js.map +1 -0
  120. package/dist/tools/file-search.d.ts +14 -0
  121. package/dist/tools/file-search.d.ts.map +1 -0
  122. package/dist/tools/file-search.js +133 -0
  123. package/dist/tools/file-search.js.map +1 -0
  124. package/dist/tools/file-write.d.ts +14 -0
  125. package/dist/tools/file-write.d.ts.map +1 -0
  126. package/dist/tools/file-write.js +80 -0
  127. package/dist/tools/file-write.js.map +1 -0
  128. package/dist/tools/memory-read.d.ts +22 -0
  129. package/dist/tools/memory-read.d.ts.map +1 -0
  130. package/dist/tools/memory-read.js +114 -0
  131. package/dist/tools/memory-read.js.map +1 -0
  132. package/dist/tools/memory-write.d.ts +2 -0
  133. package/dist/tools/memory-write.d.ts.map +1 -0
  134. package/dist/tools/memory-write.js +5 -0
  135. package/dist/tools/memory-write.js.map +1 -0
  136. package/dist/tools/registry.d.ts +12 -0
  137. package/dist/tools/registry.d.ts.map +1 -0
  138. package/dist/tools/registry.js +66 -0
  139. package/dist/tools/registry.js.map +1 -0
  140. package/dist/tools/shell-exec.d.ts +14 -0
  141. package/dist/tools/shell-exec.d.ts.map +1 -0
  142. package/dist/tools/shell-exec.js +112 -0
  143. package/dist/tools/shell-exec.js.map +1 -0
  144. package/dist/tools/web-fetch.d.ts +12 -0
  145. package/dist/tools/web-fetch.d.ts.map +1 -0
  146. package/dist/tools/web-fetch.js +91 -0
  147. package/dist/tools/web-fetch.js.map +1 -0
  148. package/dist/tools/web-search.d.ts +12 -0
  149. package/dist/tools/web-search.d.ts.map +1 -0
  150. package/dist/tools/web-search.js +88 -0
  151. package/dist/tools/web-search.js.map +1 -0
  152. package/dist/ui/ChatApp.d.ts +22 -0
  153. package/dist/ui/ChatApp.d.ts.map +1 -0
  154. package/dist/ui/ChatApp.js +94 -0
  155. package/dist/ui/ChatApp.js.map +1 -0
  156. package/dist/ui/ConfirmDialog.d.ts +20 -0
  157. package/dist/ui/ConfirmDialog.d.ts.map +1 -0
  158. package/dist/ui/ConfirmDialog.js +23 -0
  159. package/dist/ui/ConfirmDialog.js.map +1 -0
  160. package/dist/ui/InputBar.d.ts +15 -0
  161. package/dist/ui/InputBar.d.ts.map +1 -0
  162. package/dist/ui/InputBar.js +49 -0
  163. package/dist/ui/InputBar.js.map +1 -0
  164. package/dist/ui/MessageList.d.ts +21 -0
  165. package/dist/ui/MessageList.d.ts.map +1 -0
  166. package/dist/ui/MessageList.js +29 -0
  167. package/dist/ui/MessageList.js.map +1 -0
  168. package/dist/ui/Spinner.d.ts +8 -0
  169. package/dist/ui/Spinner.d.ts.map +1 -0
  170. package/dist/ui/Spinner.js +16 -0
  171. package/dist/ui/Spinner.js.map +1 -0
  172. package/dist/ui/StatusBar.d.ts +32 -0
  173. package/dist/ui/StatusBar.d.ts.map +1 -0
  174. package/dist/ui/StatusBar.js +42 -0
  175. package/dist/ui/StatusBar.js.map +1 -0
  176. package/dist/ui/ToolPanel.d.ts +2 -0
  177. package/dist/ui/ToolPanel.d.ts.map +1 -0
  178. package/dist/ui/ToolPanel.js +5 -0
  179. package/dist/ui/ToolPanel.js.map +1 -0
  180. package/dist/utils/changelog.d.ts +19 -0
  181. package/dist/utils/changelog.d.ts.map +1 -0
  182. package/dist/utils/changelog.js +111 -0
  183. package/dist/utils/changelog.js.map +1 -0
  184. package/dist/utils/env.d.ts +9 -0
  185. package/dist/utils/env.d.ts.map +1 -0
  186. package/dist/utils/env.js +37 -0
  187. package/dist/utils/env.js.map +1 -0
  188. package/package.json +72 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-exec.js","sourceRoot":"","sources":["../../../../src/tools/shell-exec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Tool, ToolContext, ToolResult, JSONSchemaObject } from '@nexagent-cli/shared';
2
+ export declare class WebFetchTool implements Tool {
3
+ name: string;
4
+ version: string;
5
+ description: string;
6
+ enabled: boolean;
7
+ riskLevel: "low";
8
+ permissions: readonly ["network:fetch"];
9
+ parameters: JSONSchemaObject;
10
+ execute(args: unknown, _ctx: ToolContext): Promise<ToolResult>;
11
+ }
12
+ //# sourceMappingURL=web-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../../../src/tools/web-fetch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG5F,qBAAa,YAAa,YAAW,IAAI;IACvC,IAAI,SAAsB;IAC1B,OAAO,SAAe;IACtB,WAAW,SAAoJ;IAC/J,OAAO,UAAY;IACnB,SAAS,EAAK,KAAK,CAAU;IAC7B,WAAW,6BAA8B;IAEzC,UAAU,EAAE,gBAAgB,CAkB1B;IAEI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAiErE"}
@@ -0,0 +1,91 @@
1
+ // ============================================================
2
+ // Tool: web_fetch — Fetch and extract content from a URL
3
+ // ============================================================
4
+ import { generateId } from '@nexagent-cli/shared';
5
+ export class WebFetchTool {
6
+ name = 'web_fetch';
7
+ version = '1.0.0';
8
+ description = 'Fetch content from a URL. Returns the page text (HTML stripped to readable text). Useful for reading documentation, APIs, or any web resource.';
9
+ enabled = true;
10
+ riskLevel = 'low';
11
+ permissions = ['network:fetch'];
12
+ parameters = {
13
+ type: 'object',
14
+ properties: {
15
+ url: {
16
+ type: 'string',
17
+ description: 'Full URL to fetch (must start with http:// or https://)',
18
+ },
19
+ extract: {
20
+ type: 'string',
21
+ description: 'What to extract: "text" (default, readable text), "html" (raw HTML), "links" (all href links)',
22
+ enum: ['text', 'html', 'links'],
23
+ },
24
+ max_chars: {
25
+ type: 'number',
26
+ description: 'Maximum characters to return (default: 10000)',
27
+ },
28
+ },
29
+ required: ['url'],
30
+ };
31
+ async execute(args, _ctx) {
32
+ const { url, extract = 'text', max_chars = 10_000 } = args;
33
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
34
+ throw new Error('URL must start with http:// or https://');
35
+ }
36
+ const response = await fetch(url, {
37
+ headers: {
38
+ 'User-Agent': 'NexAgent/0.1 (AI agent; +https://nexagent.dev)',
39
+ 'Accept': 'text/html,text/plain,application/json',
40
+ },
41
+ signal: AbortSignal.timeout(15_000),
42
+ });
43
+ if (!response.ok) {
44
+ throw new Error(`HTTP ${response.status} fetching ${url}`);
45
+ }
46
+ const contentType = response.headers.get('content-type') ?? '';
47
+ const rawBody = await response.text();
48
+ let output;
49
+ let data;
50
+ if (contentType.includes('application/json')) {
51
+ // Return JSON directly
52
+ output = rawBody.slice(0, max_chars);
53
+ data = { url, contentType, content: output };
54
+ }
55
+ else if (extract === 'html') {
56
+ output = rawBody.slice(0, max_chars);
57
+ data = { url, contentType, html: output };
58
+ }
59
+ else if (extract === 'links') {
60
+ const links = [...rawBody.matchAll(/href=["']([^"']+)["']/g)]
61
+ .map(m => m[1])
62
+ .filter(href => href.startsWith('http'));
63
+ output = links.slice(0, 100).join('\n');
64
+ data = { url, links };
65
+ }
66
+ else {
67
+ // Strip HTML tags to readable text
68
+ const text = rawBody
69
+ .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
70
+ .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
71
+ .replace(/<[^>]+>/g, ' ')
72
+ .replace(/&nbsp;/g, ' ')
73
+ .replace(/&amp;/g, '&')
74
+ .replace(/&lt;/g, '<')
75
+ .replace(/&gt;/g, '>')
76
+ .replace(/\s{2,}/g, ' ')
77
+ .trim()
78
+ .slice(0, max_chars);
79
+ output = text;
80
+ data = { url, text };
81
+ }
82
+ return {
83
+ success: true,
84
+ output: `Fetched ${url} — ${output.length} chars\n\n${output}`,
85
+ data,
86
+ executionId: generateId(),
87
+ durationMs: 0,
88
+ };
89
+ }
90
+ }
91
+ //# sourceMappingURL=web-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-fetch.js","sourceRoot":"","sources":["../../../../src/tools/web-fetch.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,yDAAyD;AACzD,+DAA+D;AAG/D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,OAAO,YAAY;IACvB,IAAI,GAAU,WAAW,CAAC;IAC1B,OAAO,GAAO,OAAO,CAAC;IACtB,WAAW,GAAG,gJAAgJ,CAAC;IAC/J,OAAO,GAAO,IAAI,CAAC;IACnB,SAAS,GAAK,KAAc,CAAC;IAC7B,WAAW,GAAG,CAAC,eAAe,CAAU,CAAC;IAEzC,UAAU,GAAqB;QAC7B,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,GAAG,EAAE;gBACH,IAAI,EAAS,QAAQ;gBACrB,WAAW,EAAE,yDAAyD;aACvE;YACD,OAAO,EAAE;gBACP,IAAI,EAAS,QAAQ;gBACrB,WAAW,EAAE,+FAA+F;gBAC5G,IAAI,EAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC;aACvC;YACD,SAAS,EAAE;gBACT,IAAI,EAAS,QAAQ;gBACrB,WAAW,EAAE,+CAA+C;aAC7D;SACF;QACD,QAAQ,EAAE,CAAC,KAAK,CAAC;KAClB,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,IAAa,EAAE,IAAiB;QAC5C,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,SAAS,GAAG,MAAM,EAAE,GAAG,IAErD,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9D,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE;gBACP,YAAY,EAAE,gDAAgD;gBAC9D,QAAQ,EAAM,uCAAuC;aACtD;YACD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/D,MAAM,OAAO,GAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAE1C,IAAI,MAAc,CAAC;QACnB,IAAI,IAAa,CAAC;QAElB,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC7C,uBAAuB;YACvB,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YACrC,IAAI,GAAK,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QACjD,CAAC;aAAM,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;YAC9B,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YACrC,IAAI,GAAK,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC9C,CAAC;aAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;iBAC1D,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC;iBACf,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3C,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,GAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,mCAAmC;YACnC,MAAM,IAAI,GAAG,OAAO;iBACjB,OAAO,CAAC,mCAAmC,EAAE,EAAE,CAAC;iBAChD,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC;iBAC9C,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;iBACxB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;iBACvB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;iBACtB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;iBACrB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;iBACrB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;iBACvB,IAAI,EAAE;iBACN,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YACvB,MAAM,GAAG,IAAI,CAAC;YACd,IAAI,GAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;QAED,OAAO;YACL,OAAO,EAAM,IAAI;YACjB,MAAM,EAAO,WAAW,GAAG,MAAM,MAAM,CAAC,MAAM,aAAa,MAAM,EAAE;YACnE,IAAI;YACJ,WAAW,EAAE,UAAU,EAAE;YACzB,UAAU,EAAG,CAAC;SACf,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { Tool, ToolContext, ToolResult, JSONSchemaObject } from '@nexagent-cli/shared';
2
+ export declare class WebSearchTool implements Tool {
3
+ name: string;
4
+ version: string;
5
+ description: string;
6
+ enabled: boolean;
7
+ riskLevel: "low";
8
+ permissions: readonly ["network:fetch"];
9
+ parameters: JSONSchemaObject;
10
+ execute(args: unknown, _ctx: ToolContext): Promise<ToolResult>;
11
+ }
12
+ //# sourceMappingURL=web-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../../../src/tools/web-search.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAa5F,qBAAa,aAAc,YAAW,IAAI;IACxC,IAAI,SAAuB;IAC3B,OAAO,SAAe;IACtB,WAAW,SAA6H;IACxI,OAAO,UAAY;IACnB,SAAS,EAAK,KAAK,CAAU;IAC7B,WAAW,6BAA8B;IAEzC,UAAU,EAAE,gBAAgB,CAiB1B;IAEI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CA+DrE"}
@@ -0,0 +1,88 @@
1
+ // ============================================================
2
+ // Tool: web_search — Search the web via DuckDuckGo JSON API
3
+ // No API key required for basic search
4
+ // ============================================================
5
+ import { generateId } from '@nexagent-cli/shared';
6
+ export class WebSearchTool {
7
+ name = 'web_search';
8
+ version = '1.0.0';
9
+ description = 'Search the web using DuckDuckGo. Returns a list of relevant results with titles, URLs, and snippets. No API key needed.';
10
+ enabled = true;
11
+ riskLevel = 'low';
12
+ permissions = ['network:fetch'];
13
+ parameters = {
14
+ type: 'object',
15
+ properties: {
16
+ query: {
17
+ type: 'string',
18
+ description: 'The search query',
19
+ },
20
+ max_results: {
21
+ type: 'number',
22
+ description: 'Maximum number of results to return (default: 8, max: 20)',
23
+ },
24
+ region: {
25
+ type: 'string',
26
+ description: 'Region code for results (e.g. "us-en", "gb-en", default: "us-en")',
27
+ },
28
+ },
29
+ required: ['query'],
30
+ };
31
+ async execute(args, _ctx) {
32
+ const { query, max_results = 8, region = 'us-en' } = args;
33
+ const url = `https://api.duckduckgo.com/?q=${encodeURIComponent(query)}&format=json&no_html=1&skip_disambig=1`;
34
+ const response = await fetch(url, {
35
+ headers: { 'User-Agent': 'NexAgent/0.1' },
36
+ signal: AbortSignal.timeout(10_000),
37
+ });
38
+ if (!response.ok) {
39
+ throw new Error(`DuckDuckGo API error: ${response.status}`);
40
+ }
41
+ const data = await response.json();
42
+ const results = [];
43
+ // Abstract result (Wikipedia-style)
44
+ if (data.AbstractText && data.AbstractURL) {
45
+ results.push({
46
+ title: 'Summary',
47
+ url: data.AbstractURL,
48
+ snippet: data.AbstractText,
49
+ });
50
+ }
51
+ // Related topics
52
+ for (const topic of data.RelatedTopics ?? []) {
53
+ if (results.length >= max_results)
54
+ break;
55
+ if (topic.Text && topic.FirstURL) {
56
+ results.push({
57
+ title: topic.FirstURL.split('/').pop() ?? topic.FirstURL,
58
+ url: topic.FirstURL,
59
+ snippet: topic.Text,
60
+ });
61
+ }
62
+ else if (topic.Topics) {
63
+ for (const sub of topic.Topics) {
64
+ if (results.length >= max_results)
65
+ break;
66
+ if (sub.Text && sub.FirstURL) {
67
+ results.push({
68
+ title: sub.FirstURL.split('/').pop() ?? sub.FirstURL,
69
+ url: sub.FirstURL,
70
+ snippet: sub.Text,
71
+ });
72
+ }
73
+ }
74
+ }
75
+ }
76
+ const summary = results
77
+ .map((r, i) => `${i + 1}. ${r.title}\n ${r.url}\n ${r.snippet}`)
78
+ .join('\n\n');
79
+ return {
80
+ success: true,
81
+ output: `Web search: "${query}" — ${results.length} results\n\n${summary}`,
82
+ data: { query, results },
83
+ executionId: generateId(),
84
+ durationMs: 0,
85
+ };
86
+ }
87
+ }
88
+ //# sourceMappingURL=web-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../../../src/tools/web-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import type { AgentEventEmitter } from '../agent/loop.js';
3
+ export interface ChatMessage {
4
+ id: string;
5
+ role: 'user' | 'assistant' | 'system' | 'tool';
6
+ content: string;
7
+ toolName?: string;
8
+ riskLevel?: string;
9
+ timestamp: number;
10
+ }
11
+ interface ChatAppProps {
12
+ agentName: string;
13
+ model: string;
14
+ sessionId: string;
15
+ events: AgentEventEmitter;
16
+ onUserInput: (text: string, confirmFn: (p: string) => Promise<boolean>) => Promise<void>;
17
+ onExit: () => void;
18
+ theme?: 'dark' | 'light';
19
+ }
20
+ export declare function ChatApp({ agentName, model, sessionId, events, onUserInput, onExit, theme, }: ChatAppProps): React.ReactElement;
21
+ export {};
22
+ //# sourceMappingURL=ChatApp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatApp.d.ts","sourceRoot":"","sources":["../../../../src/ui/ChatApp.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAU1D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAS,MAAM,CAAC;IAClB,IAAI,EAAO,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpD,OAAO,EAAI,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAgBD,UAAU,YAAY;IACpB,SAAS,EAAK,MAAM,CAAC;IACrB,KAAK,EAAS,MAAM,CAAC;IACrB,SAAS,EAAK,MAAM,CAAC;IACrB,MAAM,EAAQ,iBAAiB,CAAC;IAChC,WAAW,EAAG,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1F,MAAM,EAAQ,MAAM,IAAI,CAAC;IACzB,KAAK,CAAC,EAAQ,MAAM,GAAG,OAAO,CAAC;CAChC;AAED,wBAAgB,OAAO,CAAC,EACtB,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAc,GACzE,EAAE,YAAY,GAAG,KAAK,CAAC,YAAY,CA6InC"}
@@ -0,0 +1,94 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ // ============================================================
3
+ // ChatApp — Root Ink TUI component for interactive chat
4
+ // ============================================================
5
+ import { useState, useEffect, useCallback, useRef } from 'react';
6
+ import { Box, Text, useInput, useApp } from 'ink';
7
+ import { THEME, SYM } from '@nexagent-cli/shared';
8
+ import { MessageList } from './MessageList.js';
9
+ import { InputBar } from './InputBar.js';
10
+ import { StatusBar } from './StatusBar.js';
11
+ import { ToolPanel } from './ToolPanel.js';
12
+ import { ConfirmDialog } from './ConfirmDialog.js';
13
+ export function ChatApp({ agentName, model, sessionId, events, onUserInput, onExit, theme = 'dark', }) {
14
+ const { exit } = useApp();
15
+ const colors = THEME[theme];
16
+ const [messages, setMessages] = useState([]);
17
+ const [streamBuffer, setStreamBuf] = useState('');
18
+ const [agentStatus, setStatus] = useState('idle');
19
+ const [toolActivity, setToolAct] = useState([]);
20
+ const [confirmReq, setConfirmReq] = useState(null);
21
+ const [sessionCost, setCost] = useState(0);
22
+ const msgIdCounter = useRef(0);
23
+ const isStreaming = agentStatus === 'streaming';
24
+ const nextId = () => `msg-${++msgIdCounter.current}`;
25
+ // ── Subscribe to agent events ─────────────────────────────
26
+ useEffect(() => {
27
+ const addMsg = (msg) => setMessages(prev => [...prev, { ...msg, id: nextId(), timestamp: Date.now() }]);
28
+ events.on('status:change', ({ status }) => setStatus(status));
29
+ events.on('stream:text', ({ text }) => {
30
+ setStreamBuf(prev => prev + text);
31
+ });
32
+ events.on('stream:done', ({ fullText }) => {
33
+ setStreamBuf('');
34
+ addMsg({ role: 'assistant', content: fullText });
35
+ });
36
+ events.on('tool:start', ({ toolName, id }) => {
37
+ setToolAct(prev => [...prev, { id, name: toolName, status: 'running' }]);
38
+ });
39
+ events.on('tool:result', ({ toolCallId, toolName, output, error, durationMs, riskLevel }) => {
40
+ setToolAct(prev => prev.map(t => t.id === toolCallId
41
+ ? { ...t, status: error ? 'error' : 'success', duration: durationMs }
42
+ : t));
43
+ addMsg({
44
+ role: 'tool',
45
+ content: error ? `Error: ${error}` : String(output ?? ''),
46
+ toolName,
47
+ riskLevel,
48
+ });
49
+ });
50
+ events.on('tool:blocked', ({ toolName, reason }) => {
51
+ addMsg({ role: 'system', content: `${SYM.WARNING} ${toolName} blocked: ${reason}` });
52
+ });
53
+ events.on('session:end', ({ costUsd }) => {
54
+ setCost(prev => prev + costUsd);
55
+ });
56
+ events.on('error', ({ message, recoverable }) => {
57
+ addMsg({ role: 'system', content: `${SYM.ERROR} ${message}${recoverable ? ' (recoverable)' : ''}` });
58
+ if (!recoverable)
59
+ setStatus('error');
60
+ });
61
+ events.on('confirmation:request', ({ prompt, toolName, riskLevel }) => {
62
+ // surfaced as a dialog — resolved by user keypress
63
+ // The promise resolve is wired via the confirmFn below
64
+ });
65
+ return () => { events.removeAllListeners(); };
66
+ }, [events]);
67
+ // ── Confirmation function passed to agent loop ────────────
68
+ const confirmFn = useCallback((prompt) => {
69
+ return new Promise(resolve => {
70
+ setConfirmReq({ prompt, toolName: '', riskLevel: 'high', resolve });
71
+ });
72
+ }, []);
73
+ // ── Handle user text submission ───────────────────────────
74
+ const handleSubmit = useCallback(async (text) => {
75
+ if (!text.trim())
76
+ return;
77
+ setMessages(prev => [...prev, {
78
+ id: nextId(), role: 'user', content: text, timestamp: Date.now(),
79
+ }]);
80
+ await onUserInput(text, confirmFn);
81
+ }, [onUserInput, confirmFn]);
82
+ // ── Keyboard shortcuts ────────────────────────────────────
83
+ useInput((input, key) => {
84
+ if (key.ctrl && input === 'c') {
85
+ onExit();
86
+ exit();
87
+ }
88
+ });
89
+ return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [_jsxs(Box, { borderStyle: "round", borderColor: colors.primary, paddingX: 1, marginBottom: 0, children: [_jsxs(Text, { color: colors.primary, bold: true, children: [SYM.AGENT, " NexAgent"] }), _jsxs(Text, { color: colors.muted, children: [" ", agentName] }), _jsxs(Text, { color: colors.muted, children: [" \u00B7 ", model] }), _jsxs(Text, { color: colors.muted, children: [" \u00B7 ", sessionId.slice(0, 8)] })] }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, overflowY: "hidden", children: [_jsx(MessageList, { messages: messages, colors: colors }), isStreaming && streamBuffer && (_jsxs(Box, { paddingLeft: 2, children: [_jsx(Text, { color: colors.text, children: streamBuffer }), _jsx(Text, { color: colors.primary, children: SYM.SPIN[0] })] }))] }), toolActivity.length > 0 && (_jsx(ToolPanel, { activities: toolActivity, colors: colors })), confirmReq && (_jsx(ConfirmDialog, { prompt: confirmReq.prompt, riskLevel: confirmReq.riskLevel, colors: colors, onConfirm: (approved) => {
90
+ confirmReq.resolve(approved);
91
+ setConfirmReq(null);
92
+ } })), _jsx(StatusBar, { status: agentStatus, cost: sessionCost, colors: colors }), agentStatus === 'idle' || agentStatus === 'done' ? (_jsx(InputBar, { onSubmit: handleSubmit, colors: colors })) : null] }));
93
+ }
94
+ //# sourceMappingURL=ChatApp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatApp.js","sourceRoot":"","sources":["../../../../src/ui/ChatApp.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ interface Colors {
3
+ primary: string;
4
+ warning: string;
5
+ error: string;
6
+ muted: string;
7
+ text: string;
8
+ border: string;
9
+ accent: string;
10
+ success: string;
11
+ }
12
+ interface ConfirmDialogProps {
13
+ prompt: string;
14
+ riskLevel: string;
15
+ colors: Colors;
16
+ onConfirm: (approved: boolean) => void;
17
+ }
18
+ export declare function ConfirmDialog({ prompt, riskLevel, colors, onConfirm }: ConfirmDialogProps): React.ReactElement;
19
+ export {};
20
+ //# sourceMappingURL=ConfirmDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmDialog.d.ts","sourceRoot":"","sources":["../../../../src/ui/ConfirmDialog.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,MAAM;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;CAAE;AAEnJ,UAAU,kBAAkB;IAC1B,MAAM,EAAK,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAK,MAAM,CAAC;IAClB,SAAS,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,GAAG,KAAK,CAAC,YAAY,CA0C9G"}
@@ -0,0 +1,23 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from 'ink';
3
+ import { SYM } from '@nexagent-cli/shared';
4
+ export function ConfirmDialog({ prompt, riskLevel, colors, onConfirm }) {
5
+ const isCritical = riskLevel === 'critical';
6
+ const borderColor = isCritical ? colors.error : colors.warning;
7
+ useInput((_char, key) => {
8
+ if (key.return) {
9
+ // Default to NO for safety
10
+ onConfirm(false);
11
+ return;
12
+ }
13
+ });
14
+ // Listen for y/n
15
+ useInput((char) => {
16
+ if (char === 'y' || char === 'Y')
17
+ onConfirm(true);
18
+ if (char === 'n' || char === 'N')
19
+ onConfirm(false);
20
+ });
21
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "double", borderColor: borderColor, paddingX: 2, paddingY: 1, marginX: 2, children: [_jsx(Box, { flexDirection: "row", gap: 1, children: _jsxs(Text, { color: isCritical ? colors.error : colors.warning, bold: true, children: [isCritical ? SYM.ERROR : SYM.WARNING, " ", riskLevel.toUpperCase(), " RISK"] }) }), _jsx(Text, { color: colors.text, children: prompt }), _jsxs(Box, { marginTop: 1, flexDirection: "row", gap: 2, children: [_jsx(Text, { color: colors.muted, children: "Allow this action?" }), _jsx(Text, { color: colors.error, bold: true, children: "[y]" }), _jsx(Text, { color: colors.muted, children: "es" }), _jsx(Text, { color: colors.success, bold: true, children: " [N]" }), _jsx(Text, { color: colors.muted, children: "o (default)" })] })] }));
22
+ }
23
+ //# sourceMappingURL=ConfirmDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmDialog.js","sourceRoot":"","sources":["../../../../src/ui/ConfirmDialog.tsx"],"names":[],"mappings":";AAIA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAW3C,MAAM,UAAU,aAAa,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAsB;IACxF,MAAM,UAAU,GAAG,SAAS,KAAK,UAAU,CAAC;IAC5C,MAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IAE/D,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,2BAA2B;YAC3B,SAAS,CAAC,KAAK,CAAC,CAAC;YACjB,OAAO;QACT,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,iBAAiB;IACjB,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE;QAChB,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG;YAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG;YAAE,SAAS,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IACF,aAAa,EAAC,QAAQ,EACtB,WAAW,EAAC,QAAQ,EACpB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,CAAC,EACX,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,CAAC,aAEV,KAAC,GAAG,IAAC,aAAa,EAAC,KAAK,EAAC,GAAG,EAAE,CAAC,YAC7B,MAAC,IAAI,IAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,mBAC1D,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,OAAG,SAAS,CAAC,WAAW,EAAE,aAC1D,GACH,EACN,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,IAAI,YAAG,MAAM,GAAQ,EACzC,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,aAAa,EAAC,KAAK,EAAC,GAAG,EAAE,CAAC,aAC3C,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,KAAK,mCAA2B,EACpD,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,0BAAW,EAC1C,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,KAAK,mBAAW,EACpC,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,2BAAY,EAC7C,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,KAAK,4BAAoB,IACzC,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ interface Colors {
3
+ primary: string;
4
+ muted: string;
5
+ text: string;
6
+ border: string;
7
+ }
8
+ interface InputBarProps {
9
+ onSubmit: (text: string) => void;
10
+ colors: Colors;
11
+ placeholder?: string;
12
+ }
13
+ export declare function InputBar({ onSubmit, colors, placeholder }: InputBarProps): React.ReactElement;
14
+ export {};
15
+ //# sourceMappingURL=InputBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InputBar.d.ts","sourceRoot":"","sources":["../../../../src/ui/InputBar.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,UAAU,MAAM;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;CAAE;AAElF,UAAU,aAAa;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,MAAM,EAAI,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,WAA6B,EAAE,EAAE,aAAa,GAAG,KAAK,CAAC,YAAY,CA4D/G"}
@@ -0,0 +1,49 @@
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ // ============================================================
3
+ // InputBar — text input with readline-style editing
4
+ // ============================================================
5
+ import { useState } from 'react';
6
+ import { Box, Text, useInput } from 'ink';
7
+ import { SYM } from '@nexagent-cli/shared';
8
+ export function InputBar({ onSubmit, colors, placeholder = 'Ask anything…' }) {
9
+ const [input, setInput] = useState('');
10
+ const [cursor, setCursor] = useState(0);
11
+ useInput((char, key) => {
12
+ if (key.return) {
13
+ if (input.trim()) {
14
+ onSubmit(input.trim());
15
+ setInput('');
16
+ setCursor(0);
17
+ }
18
+ return;
19
+ }
20
+ if (key.backspace || key.delete) {
21
+ if (cursor > 0) {
22
+ setInput(prev => prev.slice(0, cursor - 1) + prev.slice(cursor));
23
+ setCursor(c => Math.max(0, c - 1));
24
+ }
25
+ return;
26
+ }
27
+ if (key.leftArrow) {
28
+ setCursor(c => Math.max(0, c - 1));
29
+ return;
30
+ }
31
+ if (key.rightArrow) {
32
+ setCursor(c => Math.min(input.length, c + 1));
33
+ return;
34
+ }
35
+ if (key.ctrl)
36
+ return; // skip Ctrl combos handled by parent
37
+ if (char && !key.meta) {
38
+ setInput(prev => prev.slice(0, cursor) + char + prev.slice(cursor));
39
+ setCursor(c => c + 1);
40
+ }
41
+ });
42
+ const before = input.slice(0, cursor);
43
+ const curChar = input[cursor] ?? ' ';
44
+ const after = input.slice(cursor + 1);
45
+ return (_jsxs(Box, { borderStyle: "round", borderColor: colors.primary, paddingX: 1, marginTop: 0, children: [_jsxs(Text, { color: colors.primary, children: [SYM.USER, " "] }), input.length === 0
46
+ ? _jsx(Text, { color: colors.muted, children: placeholder })
47
+ : (_jsxs(_Fragment, { children: [_jsx(Text, { color: colors.text, children: before }), _jsx(Text, { color: colors.primary, bold: true, children: curChar }), _jsx(Text, { color: colors.text, children: after })] }))] }));
48
+ }
49
+ //# sourceMappingURL=InputBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InputBar.js","sourceRoot":"","sources":["../../../../src/ui/InputBar.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import type { ChatMessage } from './ChatApp.js';
3
+ interface Colors {
4
+ primary: string;
5
+ secondary: string;
6
+ accent: string;
7
+ success: string;
8
+ warning: string;
9
+ error: string;
10
+ muted: string;
11
+ text: string;
12
+ border: string;
13
+ bg: string;
14
+ }
15
+ interface MessageListProps {
16
+ messages: ChatMessage[];
17
+ colors: Colors;
18
+ }
19
+ export declare function MessageList({ messages, colors }: MessageListProps): React.ReactElement;
20
+ export {};
21
+ //# sourceMappingURL=MessageList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../../src/ui/MessageList.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,UAAU,MAAM;IACd,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IACpE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;CACzF;AAED,UAAU,gBAAgB;IACxB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAI,MAAM,CAAC;CAClB;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CAQtF"}
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { SYM } from '@nexagent-cli/shared';
4
+ export function MessageList({ messages, colors }) {
5
+ return (_jsx(Box, { flexDirection: "column", paddingX: 1, children: messages.map(msg => (_jsx(MessageItem, { msg: msg, colors: colors }, msg.id))) }));
6
+ }
7
+ function MessageItem({ msg, colors }) {
8
+ const time = new Date(msg.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
9
+ switch (msg.role) {
10
+ case 'user':
11
+ return (_jsxs(Box, { flexDirection: "row", marginTop: 1, children: [_jsxs(Text, { color: colors.secondary, children: [SYM.USER, " "] }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Text, { color: colors.muted, children: time }), _jsx(Text, { color: colors.text, children: msg.content })] })] }));
12
+ case 'assistant':
13
+ return (_jsxs(Box, { flexDirection: "row", marginTop: 1, marginBottom: 1, children: [_jsxs(Text, { color: colors.primary, children: [SYM.AGENT, " "] }), _jsx(Box, { flexDirection: "column", flexGrow: 1, children: _jsx(Text, { color: colors.text, children: msg.content }) })] }));
14
+ case 'tool':
15
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 0, marginLeft: 3, borderStyle: "single", borderColor: colors.border, paddingX: 1, children: [_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: colors.accent, children: [SYM.TOOL, " ", msg.toolName ?? 'tool'] }), msg.riskLevel && _jsxs(Text, { color: riskColor(msg.riskLevel, colors), children: [" [", msg.riskLevel, "]"] })] }), _jsx(Text, { color: colors.muted, wrap: "truncate-end", children: msg.content.slice(0, 200) })] }));
16
+ case 'system':
17
+ return (_jsx(Box, { marginTop: 0, paddingLeft: 2, children: _jsx(Text, { color: colors.warning, children: msg.content }) }));
18
+ }
19
+ }
20
+ function riskColor(risk, colors) {
21
+ switch (risk) {
22
+ case 'low': return colors.success;
23
+ case 'medium': return colors.warning;
24
+ case 'high': return colors.error;
25
+ case 'critical': return colors.accent;
26
+ default: return colors.muted;
27
+ }
28
+ }
29
+ //# sourceMappingURL=MessageList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageList.js","sourceRoot":"","sources":["../../../../src/ui/MessageList.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ interface SpinnerProps {
3
+ color?: string;
4
+ label?: string;
5
+ }
6
+ export declare function Spinner({ color, label }: SpinnerProps): React.ReactElement;
7
+ export {};
8
+ //# sourceMappingURL=Spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../../../src/ui/Spinner.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,OAAO,CAAC,EAAE,KAAiB,EAAE,KAAK,EAAE,EAAE,YAAY,GAAG,KAAK,CAAC,YAAY,CAatF"}
@@ -0,0 +1,16 @@
1
+ import { jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================
3
+ // Spinner — animated dots indicator
4
+ // ============================================================
5
+ import { useState, useEffect } from 'react';
6
+ import { Text } from 'ink';
7
+ import { SYM } from '@nexagent-cli/shared';
8
+ export function Spinner({ color = '#7C6EE6', label }) {
9
+ const [frame, setFrame] = useState(0);
10
+ useEffect(() => {
11
+ const id = setInterval(() => setFrame(f => (f + 1) % SYM.SPIN.length), 80);
12
+ return () => clearInterval(id);
13
+ }, []);
14
+ return (_jsxs(Text, { color: color, children: [SYM.SPIN[frame], label ? ` ${label}` : ''] }));
15
+ }
16
+ //# sourceMappingURL=Spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../../../src/ui/Spinner.tsx"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,oCAAoC;AACpC,+DAA+D;AAC/D,OAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,GAAG,EAAE,MAAO,sBAAsB,CAAC;AAO5C,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,EAAE,KAAK,EAAgB;IAChE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEtC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3E,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,aACf,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IACtC,CACR,CAAC;AACJ,CAAC"}