@nexagent-cli/cli 0.3.1 → 0.5.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 (102) hide show
  1. package/README.md +117 -9
  2. package/dist/agent/loop.d.ts +2 -0
  3. package/dist/agent/loop.d.ts.map +1 -1
  4. package/dist/agent/loop.js +59 -27
  5. package/dist/agent/loop.js.map +1 -1
  6. package/dist/commands/chat.d.ts.map +1 -1
  7. package/dist/commands/chat.js +3 -1
  8. package/dist/commands/chat.js.map +1 -1
  9. package/dist/commands/completion.d.ts +2 -0
  10. package/dist/commands/completion.d.ts.map +1 -0
  11. package/dist/commands/completion.js +287 -0
  12. package/dist/commands/completion.js.map +1 -0
  13. package/dist/commands/dashboard.d.ts.map +1 -1
  14. package/dist/commands/dashboard.js +221 -12
  15. package/dist/commands/dashboard.js.map +1 -1
  16. package/dist/commands/run.d.ts.map +1 -1
  17. package/dist/commands/run.js +1 -0
  18. package/dist/commands/run.js.map +1 -1
  19. package/dist/commands/server.js +1 -1
  20. package/dist/commands/server.js.map +1 -1
  21. package/dist/commands/session.d.ts +1 -0
  22. package/dist/commands/session.d.ts.map +1 -1
  23. package/dist/commands/session.js +72 -1
  24. package/dist/commands/session.js.map +1 -1
  25. package/dist/config/loader.js +2 -2
  26. package/dist/config/loader.js.map +1 -1
  27. package/dist/db/database.js +96 -79
  28. package/dist/db/database.js.map +1 -1
  29. package/dist/index.js +14 -0
  30. package/dist/index.js.map +1 -1
  31. package/dist/llm/providers/anthropic.d.ts +1 -1
  32. package/dist/llm/providers/anthropic.d.ts.map +1 -1
  33. package/dist/llm/providers/anthropic.js.map +1 -1
  34. package/dist/llm/providers/google.d.ts +1 -0
  35. package/dist/llm/providers/google.d.ts.map +1 -1
  36. package/dist/llm/providers/google.js +3 -0
  37. package/dist/llm/providers/google.js.map +1 -1
  38. package/dist/llm/providers/ollama.d.ts +1 -0
  39. package/dist/llm/providers/ollama.d.ts.map +1 -1
  40. package/dist/llm/providers/ollama.js +3 -0
  41. package/dist/llm/providers/ollama.js.map +1 -1
  42. package/dist/llm/providers/openai.d.ts +1 -1
  43. package/dist/llm/providers/openai.d.ts.map +1 -1
  44. package/dist/llm/providers/openai.js.map +1 -1
  45. package/dist/llm/router.d.ts +1 -0
  46. package/dist/llm/router.d.ts.map +1 -1
  47. package/dist/llm/router.js +6 -0
  48. package/dist/llm/router.js.map +1 -1
  49. package/dist/mcp/catalog.js +5 -5
  50. package/dist/mcp/catalog.js.map +1 -1
  51. package/dist/mcp/index.d.ts +1 -0
  52. package/dist/mcp/index.d.ts.map +1 -1
  53. package/dist/mcp/index.js +1 -0
  54. package/dist/mcp/index.js.map +1 -1
  55. package/dist/mcp/installer.d.ts.map +1 -1
  56. package/dist/mcp/installer.js +13 -1
  57. package/dist/mcp/installer.js.map +1 -1
  58. package/dist/mcp/registry.d.ts +1 -1
  59. package/dist/mcp/registry.d.ts.map +1 -1
  60. package/dist/mcp/registry.js +8 -3
  61. package/dist/mcp/registry.js.map +1 -1
  62. package/dist/mcp/templates.d.ts +6 -0
  63. package/dist/mcp/templates.d.ts.map +1 -0
  64. package/dist/mcp/templates.js +185 -0
  65. package/dist/mcp/templates.js.map +1 -0
  66. package/dist/memory/manager.d.ts +5 -1
  67. package/dist/memory/manager.d.ts.map +1 -1
  68. package/dist/memory/manager.js +50 -7
  69. package/dist/memory/manager.js.map +1 -1
  70. package/dist/tools/custom-loader.d.ts +3 -0
  71. package/dist/tools/custom-loader.d.ts.map +1 -0
  72. package/dist/tools/custom-loader.js +119 -0
  73. package/dist/tools/custom-loader.js.map +1 -0
  74. package/dist/tools/file-write.d.ts +1 -0
  75. package/dist/tools/file-write.d.ts.map +1 -1
  76. package/dist/tools/file-write.js +1 -0
  77. package/dist/tools/file-write.js.map +1 -1
  78. package/dist/tools/registry.d.ts +8 -1
  79. package/dist/tools/registry.d.ts.map +1 -1
  80. package/dist/tools/registry.js +40 -0
  81. package/dist/tools/registry.js.map +1 -1
  82. package/dist/tools/shell-exec.d.ts +1 -0
  83. package/dist/tools/shell-exec.d.ts.map +1 -1
  84. package/dist/tools/shell-exec.js +28 -1
  85. package/dist/tools/shell-exec.js.map +1 -1
  86. package/dist/ui/ChatApp.d.ts +1 -0
  87. package/dist/ui/ChatApp.d.ts.map +1 -1
  88. package/dist/ui/ChatApp.js +34 -10
  89. package/dist/ui/ChatApp.js.map +1 -1
  90. package/dist/ui/InputBar.d.ts +2 -1
  91. package/dist/ui/InputBar.d.ts.map +1 -1
  92. package/dist/ui/InputBar.js +71 -11
  93. package/dist/ui/InputBar.js.map +1 -1
  94. package/dist/ui/StatusBar.d.ts +2 -1
  95. package/dist/ui/StatusBar.d.ts.map +1 -1
  96. package/dist/ui/StatusBar.js +3 -3
  97. package/dist/ui/StatusBar.js.map +1 -1
  98. package/dist/ui/SubagentPanel.d.ts +21 -0
  99. package/dist/ui/SubagentPanel.d.ts.map +1 -0
  100. package/dist/ui/SubagentPanel.js +21 -0
  101. package/dist/ui/SubagentPanel.js.map +1 -0
  102. package/package.json +77 -76
@@ -58,19 +58,19 @@ export class MemoryManager {
58
58
  if (blockId) {
59
59
  const existing = this.getBlock(blockId);
60
60
  if (existing) {
61
- this.db.prepare(`
62
- UPDATE memory_blocks
63
- SET content = ?, version = version + 1, token_estimate = ?, updated_at = ?
64
- WHERE id = ?
61
+ this.db.prepare(`
62
+ UPDATE memory_blocks
63
+ SET content = ?, version = version + 1, token_estimate = ?, updated_at = ?
64
+ WHERE id = ?
65
65
  `).run(content, tokenEstimate, now, blockId);
66
66
  return { ...existing, content, version: existing.version + 1, tokenEstimate, updatedAt: now };
67
67
  }
68
68
  }
69
69
  // Create new block
70
70
  const id = blockId ?? generateId();
71
- this.db.prepare(`
72
- INSERT INTO memory_blocks (id, agent_name, block_type, content, version, token_estimate, updated_at, pinned, archived, tags)
73
- VALUES (?, ?, ?, ?, 1, ?, ?, 0, 0, '[]')
71
+ this.db.prepare(`
72
+ INSERT INTO memory_blocks (id, agent_name, block_type, content, version, token_estimate, updated_at, pinned, archived, tags)
73
+ VALUES (?, ?, ?, ?, 1, ?, ?, 0, 0, '[]')
74
74
  `).run(id, this.agentName, blockType, content, tokenEstimate, now);
75
75
  return {
76
76
  id, blockType, content, version: 1,
@@ -97,6 +97,49 @@ export class MemoryManager {
97
97
  const rows = this.db.prepare(q).all(this.agentName);
98
98
  return rows.map(this.rowToBlock);
99
99
  }
100
+ /** Simple keyword search across all memory blocks for this agent */
101
+ search(query) {
102
+ const words = query.toLowerCase().split(/\s+/).filter(w => w.length > 0);
103
+ if (words.length === 0)
104
+ return [];
105
+ const rows = this.db.prepare('SELECT * FROM memory_blocks WHERE agent_name = ? AND archived = 0 ORDER BY updated_at DESC').all(this.agentName);
106
+ const scored = rows.map(row => {
107
+ const block = this.rowToBlock(row);
108
+ const contentLower = block.content.toLowerCase();
109
+ const score = words.reduce((s, w) => s + (contentLower.includes(w) ? 1 : 0), 0);
110
+ return { block, score };
111
+ });
112
+ return scored
113
+ .filter(({ score }) => score > 0)
114
+ .sort((a, b) => {
115
+ if (b.score !== a.score)
116
+ return b.score - a.score;
117
+ return b.block.updatedAt - a.block.updatedAt;
118
+ })
119
+ .slice(0, 20)
120
+ .map(({ block }) => block);
121
+ }
122
+ /** Summarize old memory blocks using an LLM and return the summary */
123
+ async compact(llm, model) {
124
+ const blocks = this.listAll(false);
125
+ if (blocks.length === 0)
126
+ return 'No memory blocks to compact.';
127
+ const context = blocks.map(b => `[${b.blockType}] ${b.content}`).join('\n\n---\n\n');
128
+ const res = await llm.complete({
129
+ model,
130
+ messages: [
131
+ { role: 'system', content: 'Summarize the following agent memory blocks into a concise recap. Include key facts, learned preferences, and open tasks. Be brief but complete.' },
132
+ { role: 'user', content: context },
133
+ ],
134
+ temperature: 0.3,
135
+ maxTokens: 1024,
136
+ });
137
+ const summary = res.content;
138
+ // Replace old blocks with a single conversation_summary block
139
+ this.db.prepare('DELETE FROM memory_blocks WHERE agent_name = ? AND archived = 0').run(this.agentName);
140
+ this.upsertBlock('conversation_summary', summary);
141
+ return summary;
142
+ }
100
143
  rowToBlock(row) {
101
144
  return {
102
145
  id: row.id,
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/memory/manager.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,sDAAsD;AACtD,mEAAmE;AACnE,+DAA+D;AAI/D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAQlD,MAAM,OAAO,aAAa;IAEd;IACA;IAFV,YACU,EAA4B,EAC5B,SAAiB;QADjB,OAAE,GAAF,EAAE,CAA0B;QAC5B,cAAS,GAAT,SAAS,CAAQ;IACxB,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,OAA0B,EAAE;QACrC,MAAM,EACJ,aAAa,EACb,eAAe,GAAG,KAAK,EACvB,KAAK,GAAa,EAAE,EACpB,WAAW,EACX,QAAQ,GAAU,IAAI,GACvB,GAAG,IAAI,CAAC;QAET,IAAI,KAAK,GAAI,kDAAkD,CAAC;QAChE,MAAM,MAAM,GAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE3C,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,KAAK,IAAI,mBAAmB,CAAC;QAC/B,CAAC;QAED,KAAK,IAAI,wCAAwC,CAAC;QAElD,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAgB,CAAC;QAClE,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEvC,wDAAwD;QACxD,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACpF,MAAM,GAAG,MAAM;iBACZ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACT,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aACzF,CAAC,CAAC;iBACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBACb,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM;oBAAE,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtE,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;YAC3B,CAAC,CAAC;iBACD,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QAED,qBAAqB;QACrB,IAAI,cAAc,GAAkB,EAAE,CAAC;QACvC,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,cAAc,CAAC,MAAM,IAAI,KAAK;gBAAE,MAAM;YAC1C,IAAI,WAAW,IAAI,UAAU,GAAG,KAAK,CAAC,aAAa,GAAG,WAAW;gBAAE,SAAS;YAC5E,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,UAAU,IAAI,KAAK,CAAC,aAAa,CAAC;QACpC,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,QAAQ,CAAC,OAAe;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CACzB,6DAA6D,CAC9D,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAA0B,CAAC;QACxD,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,CAAC;IAED,WAAW,CAAC,SAA0B,EAAE,OAAe,EAAE,OAAgB;QACvE,MAAM,GAAG,GAAY,IAAI,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEpD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;SAIf,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;gBAC7C,OAAO,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,GAAG,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;YAChG,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,MAAM,EAAE,GAAW,OAAO,IAAI,UAAU,EAAE,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;KAGf,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;QAEnE,OAAO;YACL,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;YAClC,aAAa,EAAE,SAAS,EAAE,GAAG;YAC7B,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;SACzC,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,OAAe;QACzB,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC;aACzE,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,YAAY,CAAC,OAAe;QAC1B,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,uEAAuE,CAAC;aACrF,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,QAAQ,CAAC,OAAe,EAAE,MAAe;QACvC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,qEAAqE,CAAC;aACnF,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,CAAC,eAAe,GAAG,KAAK;QAC7B,MAAM,CAAC,GAAG,eAAe;YACvB,CAAC,CAAC,wFAAwF;YAC1F,CAAC,CAAC,yGAAyG,CAAC;QAC9G,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAgB,CAAC;QACnE,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAEO,UAAU,CAAC,GAAc;QAC/B,OAAO;YACL,EAAE,EAAc,GAAG,CAAC,EAAE;YACtB,SAAS,EAAO,GAAG,CAAC,UAA6B;YACjD,OAAO,EAAS,GAAG,CAAC,OAAO;YAC3B,OAAO,EAAS,GAAG,CAAC,OAAO;YAC3B,aAAa,EAAG,GAAG,CAAC,cAAc;YAClC,SAAS,EAAO,GAAG,CAAC,UAAU;YAC9B,MAAM,EAAU,GAAG,CAAC,MAAM,KAAK,CAAC;YAChC,QAAQ,EAAQ,GAAG,CAAC,QAAQ,KAAK,CAAC;YAClC,IAAI,EAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAa;SACjD,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/memory/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Tool } from '@nexagent-cli/shared';
2
+ export declare function loadCustomTools(workspaceDir: string): Promise<Tool[]>;
3
+ //# sourceMappingURL=custom-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-loader.d.ts","sourceRoot":"","sources":["../../src/tools/custom-loader.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,IAAI,EAAyD,MAAM,sBAAsB,CAAC;AAiGxG,wBAAsB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CA6B3E"}
@@ -0,0 +1,119 @@
1
+ // ============================================================
2
+ // Custom Tool Loader — load user-defined tools from .nxagent/tools
3
+ // ============================================================
4
+ import { readdir, readFile } from 'node:fs/promises';
5
+ import { join, resolve } from 'node:path';
6
+ import { spawn } from 'node:child_process';
7
+ import { z } from 'zod';
8
+ import { parse as parseYaml } from 'yaml';
9
+ import { generateId } from '@nexagent-cli/shared';
10
+ const CustomToolSchema = z.object({
11
+ id: z.string(),
12
+ name: z.string(),
13
+ description: z.string(),
14
+ version: z.string(),
15
+ parameters: z.custom((val) => typeof val === 'object' && val !== null && 'type' in val && val.type === 'object'),
16
+ permissions: z.array(z.string()),
17
+ riskLevel: z.enum(['low', 'medium', 'high', 'critical']),
18
+ scriptPath: z.string(),
19
+ enabled: z.boolean(),
20
+ });
21
+ class CustomTool {
22
+ name;
23
+ version;
24
+ description;
25
+ parameters;
26
+ permissions;
27
+ riskLevel;
28
+ enabled;
29
+ cacheable = true;
30
+ scriptPath;
31
+ workspaceDir;
32
+ constructor(def, workspaceDir) {
33
+ this.name = def.name;
34
+ this.version = def.version;
35
+ this.description = def.description;
36
+ this.parameters = def.parameters;
37
+ this.permissions = def.permissions;
38
+ this.riskLevel = def.riskLevel;
39
+ this.enabled = def.enabled;
40
+ this.scriptPath = resolve(workspaceDir, def.scriptPath);
41
+ this.workspaceDir = workspaceDir;
42
+ }
43
+ async execute(args, _ctx) {
44
+ const executionId = generateId();
45
+ const start = Date.now();
46
+ return new Promise((resolve, reject) => {
47
+ const child = spawn(process.execPath, [this.scriptPath], {
48
+ cwd: this.workspaceDir,
49
+ stdio: ['pipe', 'pipe', 'pipe'],
50
+ });
51
+ let stdout = '';
52
+ let stderr = '';
53
+ child.stdout?.on('data', (d) => { stdout += d.toString(); });
54
+ child.stderr?.on('data', (d) => { stderr += d.toString(); });
55
+ child.stdin?.write(JSON.stringify(args));
56
+ child.stdin?.end();
57
+ child.on('close', (code) => {
58
+ const durationMs = Date.now() - start;
59
+ if (code !== 0) {
60
+ resolve({
61
+ success: false,
62
+ output: `Custom tool exited with code ${code}: ${stderr || stdout}`,
63
+ executionId,
64
+ durationMs,
65
+ });
66
+ return;
67
+ }
68
+ try {
69
+ const parsed = JSON.parse(stdout);
70
+ resolve({
71
+ success: parsed.success ?? true,
72
+ output: parsed.output ?? stdout,
73
+ data: parsed.data,
74
+ executionId,
75
+ durationMs,
76
+ });
77
+ }
78
+ catch {
79
+ resolve({
80
+ success: true,
81
+ output: stdout.trim(),
82
+ executionId,
83
+ durationMs,
84
+ });
85
+ }
86
+ });
87
+ child.on('error', (err) => {
88
+ reject(new Error(`Failed to spawn custom tool: ${err.message}`));
89
+ });
90
+ });
91
+ }
92
+ }
93
+ export async function loadCustomTools(workspaceDir) {
94
+ const toolsDir = join(workspaceDir, '.nxagent', 'tools');
95
+ const tools = [];
96
+ try {
97
+ const entries = await readdir(toolsDir, { withFileTypes: true });
98
+ const files = entries.filter(e => e.isFile() && (e.name.endsWith('.json') || e.name.endsWith('.yaml') || e.name.endsWith('.yml')));
99
+ for (const file of files) {
100
+ const raw = await readFile(join(toolsDir, file.name), 'utf-8');
101
+ const parsed = file.name.endsWith('.json') ? JSON.parse(raw) : parseYaml(raw);
102
+ const validated = CustomToolSchema.safeParse(parsed);
103
+ if (!validated.success) {
104
+ console.warn(`[custom-loader] Skipping invalid tool definition ${file.name}:`, validated.error.format());
105
+ continue;
106
+ }
107
+ tools.push(new CustomTool(validated.data, workspaceDir));
108
+ }
109
+ }
110
+ catch (err) {
111
+ if (err.code === 'ENOENT') {
112
+ // No custom tools directory — that's fine
113
+ return [];
114
+ }
115
+ throw err;
116
+ }
117
+ return tools;
118
+ }
119
+ //# sourceMappingURL=custom-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-loader.js","sourceRoot":"","sources":["../../src/tools/custom-loader.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ export declare class FileWriteTool implements Tool {
4
4
  version: string;
5
5
  description: string;
6
6
  enabled: boolean;
7
+ cacheable: boolean;
7
8
  riskLevel: "medium";
8
9
  permissions: readonly ["fs:write"];
9
10
  parameters: JSONSchemaObject;
@@ -1 +1 @@
1
- {"version":3,"file":"file-write.d.ts","sourceRoot":"","sources":["../../src/tools/file-write.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG5F,qBAAa,aAAc,YAAW,IAAI;IACxC,IAAI,SAAuB;IAC3B,OAAO,SAAe;IACtB,WAAW,SAA0G;IACrH,OAAO,UAAY;IACnB,SAAS,EAAK,QAAQ,CAAU;IAChC,WAAW,wBAAyB;IAEpC,UAAU,EAAE,gBAAgB,CAkB1B;IAEI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAwC7D,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/D,OAAO,CAAC,WAAW;CAQpB"}
1
+ {"version":3,"file":"file-write.d.ts","sourceRoot":"","sources":["../../src/tools/file-write.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG5F,qBAAa,aAAc,YAAW,IAAI;IACxC,IAAI,SAAuB;IAC3B,OAAO,SAAe;IACtB,WAAW,SAA0G;IACrH,OAAO,UAAY;IACnB,SAAS,UAAW;IACpB,SAAS,EAAK,QAAQ,CAAU;IAChC,WAAW,wBAAyB;IAEpC,UAAU,EAAE,gBAAgB,CAkB1B;IAEI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAwC7D,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/D,OAAO,CAAC,WAAW;CAQpB"}
@@ -12,6 +12,7 @@ export class FileWriteTool {
12
12
  version = '1.0.0';
13
13
  description = 'Write content to a file atomically. Creates parent directories as needed. Overwrites existing files.';
14
14
  enabled = true;
15
+ cacheable = false;
15
16
  riskLevel = 'medium';
16
17
  permissions = ['fs:write'];
17
18
  parameters = {
@@ -1 +1 @@
1
- {"version":3,"file":"file-write.js","sourceRoot":"","sources":["../../src/tools/file-write.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,mDAAmD;AACnD,oDAAoD;AACpD,+DAA+D;AAE/D,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAQ,WAAW,CAAC;AAEnC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,OAAO,aAAa;IACxB,IAAI,GAAU,YAAY,CAAC;IAC3B,OAAO,GAAO,OAAO,CAAC;IACtB,WAAW,GAAG,sGAAsG,CAAC;IACrH,OAAO,GAAO,IAAI,CAAC;IACnB,SAAS,GAAK,QAAiB,CAAC;IAChC,WAAW,GAAG,CAAC,UAAU,CAAU,CAAC;IAEpC,UAAU,GAAqB;QAC7B,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAS,QAAQ;gBACrB,WAAW,EAAE,gDAAgD;aAC9D;YACD,OAAO,EAAE;gBACP,IAAI,EAAS,QAAQ;gBACrB,WAAW,EAAE,4BAA4B;aAC1C;YACD,QAAQ,EAAE;gBACR,IAAI,EAAS,QAAQ;gBACrB,WAAW,EAAE,2BAA2B;gBACxC,IAAI,EAAS,CAAC,OAAO,EAAE,QAAQ,CAAC;aACjC;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;KAC9B,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,IAAa,EAAE,GAAgB;QAC3C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,EAAE,GAAG,IAE7C,CAAC;QACF,MAAM,WAAW,GAAG,UAAU,EAAE,CAAC;QAEjC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC;QAEzD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAM,IAAI;gBACjB,MAAM,EAAO,yBAAyB,OAAO,CAAC,MAAM,aAAa,IAAI,EAAE;gBACvE,IAAI,EAAS,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;gBAC1D,WAAW;gBACX,UAAU,EAAG,CAAC;aACf,CAAC;QACJ,CAAC;QAED,4BAA4B;QAC5B,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEnD,mCAAmC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,WAAW,EAAE,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAO,QAAQ,KAAK,QAAQ;YACnC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC;YAChC,CAAC,CAAC,OAAO,CAAC;QAEZ,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACzF,MAAM,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE/B,OAAO;YACL,OAAO,EAAQ,IAAI;YACnB,MAAM,EAAS,SAAS,OAAO,CAAC,MAAM,aAAa,IAAI,EAAE;YACzD,IAAI,EAAW,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE;YAC9C,WAAW;YACX,UAAU,EAAK,CAAC;YAChB,YAAY,EAAG,OAAO,CAAC,MAAM;SAC9B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAa,EAAE,IAAiB;QAC3C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAyC,CAAC;QACpE,OAAO,eAAe,OAAO,CAAC,MAAM,cAAc,IAAI,GAAG,CAAC;IAC5D,CAAC;IAEO,WAAW,CAAC,QAAgB,EAAE,YAAoB;QACxD,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACxC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,4BAA4B,CAAC,CAAC;QACnF,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
1
+ {"version":3,"file":"file-write.js","sourceRoot":"","sources":["../../src/tools/file-write.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,18 @@
1
- import type { Tool, LLMToolDefinition } from '@nexagent-cli/shared';
1
+ import type { Tool, LLMToolDefinition, ToolContext, ToolResult } from '@nexagent-cli/shared';
2
2
  export declare class ToolRegistry {
3
3
  private tools;
4
+ private cache;
4
5
  register(tool: Tool): void;
5
6
  get(name: string): Tool | undefined;
6
7
  list(): Tool[];
7
8
  /** Convert registered tools to LLM function-call format */
8
9
  toToolDefinitions(allowList: string[], blockList: string[]): LLMToolDefinition[];
10
+ /** Execute a tool with result caching */
11
+ executeWithCache(toolName: string, args: unknown, context: ToolContext): Promise<ToolResult>;
12
+ /** Clear the entire tool result cache */
13
+ clearCache(): void;
14
+ /** Invalidate cached results for a specific tool */
15
+ invalidateCache(toolName: string): void;
9
16
  }
10
17
  /** Create a pre-loaded registry with all default tools */
11
18
  export declare function createDefaultRegistry(): Promise<ToolRegistry>;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEpE,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA2B;IAExC,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAI1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAInC,IAAI,IAAI,IAAI,EAAE;IAId,2DAA2D;IAC3D,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE;CAiBjF;AAED,0DAA0D;AAC1D,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,YAAY,CAAC,CAyCnE"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAkB,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAK7G,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,KAAK,CAAqC;IAElD,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAI1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAInC,IAAI,IAAI,IAAI,EAAE;IAId,2DAA2D;IAC3D,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE;IAkBhF,yCAAyC;IACnC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IA8BlG,yCAAyC;IACzC,UAAU,IAAI,IAAI;IAIlB,oDAAoD;IACpD,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;CAOxC;AAED,0DAA0D;AAC1D,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,YAAY,CAAC,CAyCnE"}
@@ -1,8 +1,11 @@
1
1
  // ============================================================
2
2
  // Tool Registry — central registration and lookup
3
3
  // ============================================================
4
+ const DEFAULT_CACHE_TTL_MS = 60_000;
5
+ const NEVER_CACHE_TOOLS = new Set(['shell_exec', 'file_write']);
4
6
  export class ToolRegistry {
5
7
  tools = new Map();
8
+ cache = new Map();
6
9
  register(tool) {
7
10
  this.tools.set(tool.name, tool);
8
11
  }
@@ -33,6 +36,43 @@ export class ToolRegistry {
33
36
  },
34
37
  }));
35
38
  }
39
+ /** Execute a tool with result caching */
40
+ async executeWithCache(toolName, args, context) {
41
+ const tool = this.tools.get(toolName);
42
+ if (!tool) {
43
+ throw new Error(`Unknown tool: "${toolName}"`);
44
+ }
45
+ const cacheable = tool.cacheable !== false && !NEVER_CACHE_TOOLS.has(toolName);
46
+ const cacheKey = `${toolName}::${JSON.stringify(args)}`;
47
+ if (cacheable) {
48
+ const cached = this.cache.get(cacheKey);
49
+ if (cached && Date.now() - cached.cachedAt < cached.ttlMs) {
50
+ return cached.result;
51
+ }
52
+ }
53
+ const result = await tool.execute(args, context);
54
+ if (cacheable) {
55
+ this.cache.set(cacheKey, {
56
+ key: cacheKey,
57
+ result,
58
+ cachedAt: Date.now(),
59
+ ttlMs: DEFAULT_CACHE_TTL_MS,
60
+ });
61
+ }
62
+ return result;
63
+ }
64
+ /** Clear the entire tool result cache */
65
+ clearCache() {
66
+ this.cache.clear();
67
+ }
68
+ /** Invalidate cached results for a specific tool */
69
+ invalidateCache(toolName) {
70
+ for (const [key, entry] of this.cache) {
71
+ if (entry.key.startsWith(`${toolName}::`)) {
72
+ this.cache.delete(key);
73
+ }
74
+ }
75
+ }
36
76
  }
37
77
  /** Create a pre-loaded registry with all default tools */
38
78
  export async function createDefaultRegistry() {
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ export declare class ShellExecTool implements Tool {
4
4
  version: string;
5
5
  description: string;
6
6
  enabled: boolean;
7
+ cacheable: boolean;
7
8
  riskLevel: "high";
8
9
  permissions: readonly ["shell:exec"];
9
10
  parameters: JSONSchemaObject;
@@ -1 +1 @@
1
- {"version":3,"file":"shell-exec.d.ts","sourceRoot":"","sources":["../../src/tools/shell-exec.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG5F,qBAAa,aAAc,YAAW,IAAI;IACxC,IAAI,SAAuB;IAC3B,OAAO,SAAe;IACtB,WAAW,SAA4L;IACvM,OAAO,UAAY;IACnB,SAAS,EAAK,MAAM,CAAU;IAC9B,WAAW,0BAA2B;IAEtC,UAAU,EAAE,gBAAgB,CAqB1B;IAEI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAiF7D,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/D,OAAO,CAAC,WAAW;CASpB"}
1
+ {"version":3,"file":"shell-exec.d.ts","sourceRoot":"","sources":["../../src/tools/shell-exec.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAsB5F,qBAAa,aAAc,YAAW,IAAI;IACxC,IAAI,SAAuB;IAC3B,OAAO,SAAe;IACtB,WAAW,SAA4L;IACvM,OAAO,UAAY;IACnB,SAAS,UAAW;IACpB,SAAS,EAAK,MAAM,CAAU;IAC9B,WAAW,0BAA2B;IAEtC,UAAU,EAAE,gBAAgB,CAqB1B;IAEI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAgG7D,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/D,OAAO,CAAC,WAAW;CASpB"}
@@ -5,11 +5,24 @@
5
5
  import { spawn } from 'node:child_process';
6
6
  import { resolve } from 'node:path';
7
7
  import { generateId, GLOBAL_SHELL_BLOCKLIST } from '@nexagent-cli/shared';
8
+ /** Write an audit log entry for shell execution */
9
+ function writeAuditLog(db, sessionId, action, details, status) {
10
+ if (!db)
11
+ return;
12
+ try {
13
+ const stmt = db.prepare('INSERT INTO audit_log (id, session_id, tool_name, action, details, status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)');
14
+ stmt.run(generateId(), sessionId, 'shell_exec', action, JSON.stringify(details), status, Date.now());
15
+ }
16
+ catch {
17
+ // Audit logging is best-effort; never fail the tool execution
18
+ }
19
+ }
8
20
  export class ShellExecTool {
9
21
  name = 'shell_exec';
10
22
  version = '1.0.0';
11
23
  description = 'Execute a shell command in the workspace directory. Output is captured and returned. Long-running commands time out after timeout_ms. Dangerous commands are blocked by safety checks.';
12
24
  enabled = true;
25
+ cacheable = false;
13
26
  riskLevel = 'high';
14
27
  permissions = ['shell:exec'];
15
28
  parameters = {
@@ -77,12 +90,21 @@ export class ShellExecTool {
77
90
  const truncated = combined.length > 20_000
78
91
  ? combined.slice(0, 20_000) + '\n[...output truncated at 20k chars...]'
79
92
  : combined;
93
+ const success = code === 0;
94
+ const status = success ? 'success' : 'failed';
95
+ writeAuditLog(ctx.db, ctx.sessionId, 'execute', {
96
+ command: command.slice(0, 2000), // cap detail size
97
+ cwd: absCwd,
98
+ exitCode: code,
99
+ durationMs,
100
+ outputLength: combined.length,
101
+ }, status);
80
102
  if (code !== 0 && !stderr) {
81
103
  reject(new Error(`Command exited with code ${code}: ${truncated}`));
82
104
  return;
83
105
  }
84
106
  resolve_p({
85
- success: code === 0,
107
+ success,
86
108
  output: truncated || `(no output, exit code ${code})`,
87
109
  data: { exitCode: code, stdout, stderr, command, durationMs },
88
110
  executionId,
@@ -91,6 +113,11 @@ export class ShellExecTool {
91
113
  });
92
114
  proc.on('error', (err) => {
93
115
  clearTimeout(timer);
116
+ writeAuditLog(ctx.db, ctx.sessionId, 'spawn_error', {
117
+ command: command.slice(0, 2000),
118
+ cwd: absCwd,
119
+ error: err.message,
120
+ }, 'error');
94
121
  reject(new Error(`Failed to spawn process: ${err.message}`));
95
122
  });
96
123
  });
@@ -1 +1 @@
1
- {"version":3,"file":"shell-exec.js","sourceRoot":"","sources":["../../src/tools/shell-exec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shell-exec.js","sourceRoot":"","sources":["../../src/tools/shell-exec.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,7 @@ interface ChatAppProps {
22
22
  contextWindow: number;
23
23
  };
24
24
  countTokens(t: string, m: string): number;
25
+ estimateCost?(model: string, promptTokens: number, completionTokens: number): number;
25
26
  };
26
27
  }
27
28
  export declare function ChatApp({ agentName, model, sessionId, events, onUserInput, onQuickCommand, onExit, theme, llm, }: ChatAppProps): React.ReactElement;
@@ -1 +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;AA8BD,UAAU,YAAY;IACpB,SAAS,EAAO,MAAM,CAAC;IACvB,KAAK,EAAW,MAAM,CAAC;IACvB,SAAS,EAAO,MAAM,CAAC;IACvB,MAAM,EAAU,iBAAiB,CAAC;IAClC,WAAW,EAAK,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5F,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,EAAU,MAAM,IAAI,CAAC;IAC3B,KAAK,CAAC,EAAU,MAAM,GAAG,OAAO,CAAC;IACjC,GAAG,CAAC,EAAY;QAAE,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG;YAAE,aAAa,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACtH;AAED,wBAAgB,OAAO,CAAC,EACtB,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,KAAc,EAAE,GAAG,GAC9F,EAAE,YAAY,GAAG,KAAK,CAAC,YAAY,CAqMnC"}
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;AAW1D,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;AA8BD,UAAU,YAAY;IACpB,SAAS,EAAO,MAAM,CAAC;IACvB,KAAK,EAAW,MAAM,CAAC;IACvB,SAAS,EAAO,MAAM,CAAC;IACvB,MAAM,EAAU,iBAAiB,CAAC;IAClC,WAAW,EAAK,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5F,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,EAAU,MAAM,IAAI,CAAC;IAC3B,KAAK,CAAC,EAAU,MAAM,GAAG,OAAO,CAAC;IACjC,GAAG,CAAC,EAAY;QAAE,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG;YAAE,aAAa,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,YAAY,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC5M;AAED,wBAAgB,OAAO,CAAC,EACtB,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,KAAc,EAAE,GAAG,GAC9F,EAAE,YAAY,GAAG,KAAK,CAAC,YAAY,CAoOnC"}
@@ -1,6 +1,6 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  // ============================================================
3
- // ChatApp Root Ink TUI component for interactive chat
3
+ // ChatApp -- Root Ink TUI component for interactive chat
4
4
  // ============================================================
5
5
  import { useState, useEffect, useCallback, useRef } from 'react';
6
6
  import { Box, Text, useInput, useApp } from 'ink';
@@ -10,6 +10,7 @@ import { InputBar } from './InputBar.js';
10
10
  import { StatusBar } from './StatusBar.js';
11
11
  import { ToolPanel } from './ToolPanel.js';
12
12
  import { ConfirmDialog } from './ConfirmDialog.js';
13
+ import { SubagentPanel } from './SubagentPanel.js';
13
14
  function estimateContextTokens(messages, latestText, llm, model) {
14
15
  let total = 0;
15
16
  for (const m of messages) {
@@ -28,13 +29,16 @@ export function ChatApp({ agentName, model, sessionId, events, onUserInput, onQu
28
29
  const [confirmReq, setConfirmReq] = useState(null);
29
30
  const [sessionCost, setCost] = useState(0);
30
31
  const [contextTokens, setContextTokens] = useState(0);
32
+ const [subagentJobs, setSubagentJobs] = useState([]);
33
+ const [inputCostHint, setInputCostHint] = useState('');
34
+ const [currentInput, setCurrentInput] = useState('');
31
35
  const msgIdCounter = useRef(0);
32
36
  const isStreaming = agentStatus === 'streaming';
33
37
  const contextWindow = llm?.getCapabilities(model).contextWindow ?? 128_000;
34
38
  const contextPercent = Math.min(100, (contextTokens / contextWindow) * 100);
35
39
  const compactHint = contextPercent > 85;
36
40
  const nextId = () => `msg-${++msgIdCounter.current}`;
37
- // ── Subscribe to agent events ─────────────────────────────
41
+ // -- Subscribe to agent events --
38
42
  useEffect(() => {
39
43
  const addMsg = (msg) => setMessages(prev => [...prev, { ...msg, id: nextId(), timestamp: Date.now() }]);
40
44
  events.on('status:change', ({ status }) => setStatus(status));
@@ -75,16 +79,18 @@ export function ChatApp({ agentName, model, sessionId, events, onUserInput, onQu
75
79
  setStatus('error');
76
80
  });
77
81
  events.on('confirmation:request', ({ prompt, toolName, riskLevel }) => {
78
- // surfaced as a dialog resolved by user keypress
82
+ // surfaced as a dialog -- resolved by user keypress
79
83
  // The promise resolve is wired via the confirmFn below
80
84
  });
81
85
  events.on('subagent:spawn', ({ jobId, task }) => {
82
- addMsg({ role: 'system', content: `◈ Subagent [${String(jobId).slice(0, 8)}] spawned: ${task}` });
86
+ addMsg({ role: 'system', content: `Subagent [${String(jobId).slice(0, 8)}] spawned: ${task}` });
87
+ setSubagentJobs(prev => [...prev, { jobId, task, status: 'running', startTime: Date.now() }]);
83
88
  });
84
89
  events.on('subagent:progress', ({ jobId, chunk }) => {
85
90
  if (chunk) {
86
91
  setStreamBuf(prev => prev + chunk);
87
92
  }
93
+ setSubagentJobs(prev => prev.map(j => j.jobId === jobId ? { ...j, chunk: (j.chunk ?? '') + (chunk ?? '') } : j));
88
94
  });
89
95
  events.on('subagent:done', ({ jobId, status, output, artifacts, costUsd, durationMs }) => {
90
96
  setStreamBuf('');
@@ -93,21 +99,39 @@ export function ChatApp({ agentName, model, sessionId, events, onUserInput, onQu
93
99
  : '';
94
100
  addMsg({
95
101
  role: 'system',
96
- content: `◈ Subagent [${String(jobId).slice(0, 8)}] ${status} in ${(durationMs / 1000).toFixed(1)}s | $${costUsd.toFixed(5)}${artifactList}\n\n${output.slice(0, 800)}${output.length > 800 ? '' : ''}`,
102
+ content: `Subagent [${String(jobId).slice(0, 8)}] ${status} in ${(durationMs / 1000).toFixed(1)}s | $${costUsd.toFixed(5)}${artifactList}\n\n${output.slice(0, 800)}${output.length > 800 ? '...' : ''}`,
97
103
  });
104
+ setSubagentJobs(prev => prev.filter(j => j.jobId !== jobId));
98
105
  });
99
106
  events.on('subagent:error', ({ jobId, error }) => {
100
107
  addMsg({ role: 'system', content: `${SYM.ERROR} Subagent [${String(jobId).slice(0, 8)}] failed: ${error}` });
108
+ setSubagentJobs(prev => prev.filter(j => j.jobId !== jobId));
101
109
  });
102
110
  return () => { events.removeAllListeners(); };
103
111
  }, [events]);
104
- // ── Confirmation function passed to agent loop ────────────
112
+ // -- Cost hint derived from current input --
113
+ useEffect(() => {
114
+ if (!currentInput.trim() || !llm) {
115
+ setInputCostHint('');
116
+ return;
117
+ }
118
+ const tokens = llm.countTokens(currentInput, model);
119
+ let hint = `~${tokens} tokens`;
120
+ if (llm.estimateCost) {
121
+ const cost = llm.estimateCost(model, tokens, 0);
122
+ if (cost > 0) {
123
+ hint += ` · ~$${cost.toFixed(4)}`;
124
+ }
125
+ }
126
+ setInputCostHint(hint);
127
+ }, [currentInput, llm, model]);
128
+ // -- Confirmation function passed to agent loop --
105
129
  const confirmFn = useCallback((prompt) => {
106
130
  return new Promise(resolve => {
107
131
  setConfirmReq({ prompt, toolName: '', riskLevel: 'high', resolve });
108
132
  });
109
133
  }, []);
110
- // ── Handle user text submission ───────────────────────────
134
+ // -- Handle user text submission --
111
135
  const handleSubmit = useCallback(async (text) => {
112
136
  if (!text.trim())
113
137
  return;
@@ -136,16 +160,16 @@ export function ChatApp({ agentName, model, sessionId, events, onUserInput, onQu
136
160
  }]);
137
161
  await onUserInput(text, confirmFn);
138
162
  }, [onUserInput, onQuickCommand, confirmFn]);
139
- // ── Keyboard shortcuts ────────────────────────────────────
163
+ // -- Keyboard shortcuts --
140
164
  useInput((input, key) => {
141
165
  if (key.ctrl && input === 'c') {
142
166
  onExit();
143
167
  exit();
144
168
  }
145
169
  });
146
- 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) => {
170
+ 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: [" \u26A1 ", model] }), _jsxs(Text, { color: colors.muted, children: [" \uD83D\uDD11 ", 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 })), subagentJobs.length > 0 && (_jsx(SubagentPanel, { jobs: subagentJobs, colors: colors })), confirmReq && (_jsx(ConfirmDialog, { prompt: confirmReq.prompt, riskLevel: confirmReq.riskLevel, colors: colors, onConfirm: (approved) => {
147
171
  confirmReq.resolve(approved);
148
172
  setConfirmReq(null);
149
- } })), _jsx(StatusBar, { status: agentStatus, cost: sessionCost, colors: colors, contextPercent: contextPercent, compactHint: compactHint }), agentStatus === 'idle' || agentStatus === 'done' ? (_jsx(InputBar, { onSubmit: handleSubmit, colors: colors })) : null] }));
173
+ } })), _jsx(StatusBar, { status: agentStatus, cost: sessionCost, colors: colors, contextPercent: contextPercent, compactHint: compactHint, costHint: inputCostHint }), agentStatus === 'idle' || agentStatus === 'done' ? (_jsx(InputBar, { onSubmit: handleSubmit, onChange: setCurrentInput, colors: colors })) : null] }));
150
174
  }
151
175
  //# sourceMappingURL=ChatApp.js.map