attocode 0.1.2 → 0.1.4

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 (175) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/README.md +180 -0
  3. package/dist/src/agent.d.ts +78 -1
  4. package/dist/src/agent.d.ts.map +1 -1
  5. package/dist/src/agent.js +639 -36
  6. package/dist/src/agent.js.map +1 -1
  7. package/dist/src/analysis/feedback-loop.d.ts +115 -0
  8. package/dist/src/analysis/feedback-loop.d.ts.map +1 -0
  9. package/dist/src/analysis/feedback-loop.js +226 -0
  10. package/dist/src/analysis/feedback-loop.js.map +1 -0
  11. package/dist/src/analysis/index.d.ts +9 -0
  12. package/dist/src/analysis/index.d.ts.map +1 -0
  13. package/dist/src/analysis/index.js +9 -0
  14. package/dist/src/analysis/index.js.map +1 -0
  15. package/dist/src/analysis/prompt-templates.d.ts +36 -0
  16. package/dist/src/analysis/prompt-templates.d.ts.map +1 -0
  17. package/dist/src/analysis/prompt-templates.js +198 -0
  18. package/dist/src/analysis/prompt-templates.js.map +1 -0
  19. package/dist/src/analysis/trace-summary.d.ts +56 -0
  20. package/dist/src/analysis/trace-summary.d.ts.map +1 -0
  21. package/dist/src/analysis/trace-summary.js +261 -0
  22. package/dist/src/analysis/trace-summary.js.map +1 -0
  23. package/dist/src/commands/agents-commands.d.ts +24 -0
  24. package/dist/src/commands/agents-commands.d.ts.map +1 -0
  25. package/dist/src/commands/agents-commands.js +284 -0
  26. package/dist/src/commands/agents-commands.js.map +1 -0
  27. package/dist/src/commands/handler.d.ts.map +1 -1
  28. package/dist/src/commands/handler.js +329 -21
  29. package/dist/src/commands/handler.js.map +1 -1
  30. package/dist/src/commands/init-commands.d.ts +35 -0
  31. package/dist/src/commands/init-commands.d.ts.map +1 -0
  32. package/dist/src/commands/init-commands.js +187 -0
  33. package/dist/src/commands/init-commands.js.map +1 -0
  34. package/dist/src/commands/skills-commands.d.ts +26 -0
  35. package/dist/src/commands/skills-commands.d.ts.map +1 -0
  36. package/dist/src/commands/skills-commands.js +309 -0
  37. package/dist/src/commands/skills-commands.js.map +1 -0
  38. package/dist/src/commands/types.d.ts +13 -2
  39. package/dist/src/commands/types.d.ts.map +1 -1
  40. package/dist/src/config.d.ts +3 -0
  41. package/dist/src/config.d.ts.map +1 -1
  42. package/dist/src/config.js.map +1 -1
  43. package/dist/src/defaults.d.ts +31 -2
  44. package/dist/src/defaults.d.ts.map +1 -1
  45. package/dist/src/defaults.js +69 -2
  46. package/dist/src/defaults.js.map +1 -1
  47. package/dist/src/errors/index.d.ts +233 -0
  48. package/dist/src/errors/index.d.ts.map +1 -0
  49. package/dist/src/errors/index.js +427 -0
  50. package/dist/src/errors/index.js.map +1 -0
  51. package/dist/src/integrations/agent-registry.d.ts +68 -2
  52. package/dist/src/integrations/agent-registry.d.ts.map +1 -1
  53. package/dist/src/integrations/agent-registry.js +230 -23
  54. package/dist/src/integrations/agent-registry.js.map +1 -1
  55. package/dist/src/integrations/auto-compaction.d.ts +33 -0
  56. package/dist/src/integrations/auto-compaction.d.ts.map +1 -1
  57. package/dist/src/integrations/auto-compaction.js +47 -3
  58. package/dist/src/integrations/auto-compaction.js.map +1 -1
  59. package/dist/src/integrations/cancellation.d.ts +5 -0
  60. package/dist/src/integrations/cancellation.d.ts.map +1 -1
  61. package/dist/src/integrations/cancellation.js +7 -0
  62. package/dist/src/integrations/cancellation.js.map +1 -1
  63. package/dist/src/integrations/capabilities.d.ts +160 -0
  64. package/dist/src/integrations/capabilities.d.ts.map +1 -0
  65. package/dist/src/integrations/capabilities.js +426 -0
  66. package/dist/src/integrations/capabilities.js.map +1 -0
  67. package/dist/src/integrations/context-engineering.d.ts +6 -1
  68. package/dist/src/integrations/context-engineering.d.ts.map +1 -1
  69. package/dist/src/integrations/context-engineering.js +7 -0
  70. package/dist/src/integrations/context-engineering.js.map +1 -1
  71. package/dist/src/integrations/dead-letter-queue.d.ts +208 -0
  72. package/dist/src/integrations/dead-letter-queue.d.ts.map +1 -0
  73. package/dist/src/integrations/dead-letter-queue.js +458 -0
  74. package/dist/src/integrations/dead-letter-queue.js.map +1 -0
  75. package/dist/src/integrations/health-check.d.ts +218 -0
  76. package/dist/src/integrations/health-check.d.ts.map +1 -0
  77. package/dist/src/integrations/health-check.js +400 -0
  78. package/dist/src/integrations/health-check.js.map +1 -0
  79. package/dist/src/integrations/index.d.ts +11 -2
  80. package/dist/src/integrations/index.d.ts.map +1 -1
  81. package/dist/src/integrations/index.js +19 -2
  82. package/dist/src/integrations/index.js.map +1 -1
  83. package/dist/src/integrations/mcp-client.d.ts +9 -0
  84. package/dist/src/integrations/mcp-client.d.ts.map +1 -1
  85. package/dist/src/integrations/mcp-client.js +49 -7
  86. package/dist/src/integrations/mcp-client.js.map +1 -1
  87. package/dist/src/integrations/openrouter-pricing.d.ts +28 -3
  88. package/dist/src/integrations/openrouter-pricing.d.ts.map +1 -1
  89. package/dist/src/integrations/openrouter-pricing.js +57 -16
  90. package/dist/src/integrations/openrouter-pricing.js.map +1 -1
  91. package/dist/src/integrations/retry.d.ts +131 -0
  92. package/dist/src/integrations/retry.d.ts.map +1 -0
  93. package/dist/src/integrations/retry.js +233 -0
  94. package/dist/src/integrations/retry.js.map +1 -0
  95. package/dist/src/integrations/skill-executor.d.ts +113 -0
  96. package/dist/src/integrations/skill-executor.d.ts.map +1 -0
  97. package/dist/src/integrations/skill-executor.js +270 -0
  98. package/dist/src/integrations/skill-executor.js.map +1 -0
  99. package/dist/src/integrations/skills.d.ts +98 -7
  100. package/dist/src/integrations/skills.d.ts.map +1 -1
  101. package/dist/src/integrations/skills.js +210 -11
  102. package/dist/src/integrations/skills.js.map +1 -1
  103. package/dist/src/integrations/sqlite-store.d.ts +42 -0
  104. package/dist/src/integrations/sqlite-store.d.ts.map +1 -1
  105. package/dist/src/integrations/sqlite-store.js +111 -0
  106. package/dist/src/integrations/sqlite-store.js.map +1 -1
  107. package/dist/src/main.js +88 -7
  108. package/dist/src/main.js.map +1 -1
  109. package/dist/src/modes/repl.d.ts.map +1 -1
  110. package/dist/src/modes/repl.js +37 -1
  111. package/dist/src/modes/repl.js.map +1 -1
  112. package/dist/src/modes/tui.d.ts.map +1 -1
  113. package/dist/src/modes/tui.js +46 -5
  114. package/dist/src/modes/tui.js.map +1 -1
  115. package/dist/src/modes.d.ts.map +1 -1
  116. package/dist/src/modes.js +10 -3
  117. package/dist/src/modes.js.map +1 -1
  118. package/dist/src/persistence/schema.d.ts +4 -0
  119. package/dist/src/persistence/schema.d.ts.map +1 -1
  120. package/dist/src/persistence/schema.js +49 -0
  121. package/dist/src/persistence/schema.js.map +1 -1
  122. package/dist/src/providers/adapters/anthropic.d.ts +24 -2
  123. package/dist/src/providers/adapters/anthropic.d.ts.map +1 -1
  124. package/dist/src/providers/adapters/anthropic.js +184 -0
  125. package/dist/src/providers/adapters/anthropic.js.map +1 -1
  126. package/dist/src/tools/bash.d.ts.map +1 -1
  127. package/dist/src/tools/bash.js +7 -4
  128. package/dist/src/tools/bash.js.map +1 -1
  129. package/dist/src/tools/file.d.ts.map +1 -1
  130. package/dist/src/tools/file.js +31 -10
  131. package/dist/src/tools/file.js.map +1 -1
  132. package/dist/src/tools/permission.d.ts +12 -0
  133. package/dist/src/tools/permission.d.ts.map +1 -1
  134. package/dist/src/tools/permission.js +136 -0
  135. package/dist/src/tools/permission.js.map +1 -1
  136. package/dist/src/tools/registry.d.ts +23 -1
  137. package/dist/src/tools/registry.d.ts.map +1 -1
  138. package/dist/src/tools/registry.js +77 -17
  139. package/dist/src/tools/registry.js.map +1 -1
  140. package/dist/src/tools/standard.d.ts.map +1 -1
  141. package/dist/src/tools/standard.js +8 -0
  142. package/dist/src/tools/standard.js.map +1 -1
  143. package/dist/src/tools/types.d.ts +20 -1
  144. package/dist/src/tools/types.d.ts.map +1 -1
  145. package/dist/src/tools/types.js.map +1 -1
  146. package/dist/src/tracing/trace-collector.d.ts +198 -2
  147. package/dist/src/tracing/trace-collector.d.ts.map +1 -1
  148. package/dist/src/tracing/trace-collector.js +315 -3
  149. package/dist/src/tracing/trace-collector.js.map +1 -1
  150. package/dist/src/tracing/types.d.ts +470 -2
  151. package/dist/src/tracing/types.d.ts.map +1 -1
  152. package/dist/src/tracing/types.js +25 -0
  153. package/dist/src/tracing/types.js.map +1 -1
  154. package/dist/src/tui/app.d.ts.map +1 -1
  155. package/dist/src/tui/app.js +292 -18
  156. package/dist/src/tui/app.js.map +1 -1
  157. package/dist/src/tui/index.d.ts +1 -0
  158. package/dist/src/tui/index.d.ts.map +1 -1
  159. package/dist/src/tui/index.js +2 -0
  160. package/dist/src/tui/index.js.map +1 -1
  161. package/dist/src/tui/transparency-aggregator.d.ts +100 -0
  162. package/dist/src/tui/transparency-aggregator.d.ts.map +1 -0
  163. package/dist/src/tui/transparency-aggregator.js +234 -0
  164. package/dist/src/tui/transparency-aggregator.js.map +1 -0
  165. package/dist/src/types.d.ts +129 -0
  166. package/dist/src/types.d.ts.map +1 -1
  167. package/package.json +6 -3
  168. package/dist/src/hello.d.ts +0 -2
  169. package/dist/src/hello.d.ts.map +0 -1
  170. package/dist/src/hello.js +0 -4
  171. package/dist/src/hello.js.map +0 -1
  172. package/dist/src/test-sqlite.d.ts +0 -2
  173. package/dist/src/test-sqlite.d.ts.map +0 -1
  174. package/dist/src/test-sqlite.js +0 -114
  175. package/dist/src/test-sqlite.js.map +0 -1
@@ -13,6 +13,10 @@ import { Box, Text, useApp, useInput, Static } from 'ink';
13
13
  import { getTheme, getThemeNames } from './theme/index.js';
14
14
  import { ControlledCommandPalette } from './input/CommandPalette.js';
15
15
  import { ApprovalDialog } from './components/ApprovalDialog.js';
16
+ import { TransparencyAggregator } from './transparency-aggregator.js';
17
+ import { handleSkillsCommand } from '../commands/skills-commands.js';
18
+ import { handleAgentsCommand } from '../commands/agents-commands.js';
19
+ import { handleInitCommand } from '../commands/init-commands.js';
16
20
  // =============================================================================
17
21
  // PATTERN GENERATION FOR ALWAYS-ALLOW
18
22
  // =============================================================================
@@ -114,13 +118,13 @@ const ToolCallItem = memo(function ToolCallItem({ tc, expanded, colors }) {
114
118
  }
115
119
  return (_jsxs(Box, { marginLeft: 2, gap: 1, children: [_jsx(Text, { color: statusColor, children: icon }), _jsx(Text, { color: "#DDA0DD", bold: true, children: tc.name }), argsStr ? _jsx(Text, { color: colors.textMuted, dimColor: true, children: argsStr }) : null, tc.duration ? _jsxs(Text, { color: colors.textMuted, dimColor: true, children: ["(", tc.duration, "ms)"] }) : null] }));
116
120
  });
117
- const MemoizedInputArea = memo(function MemoizedInputArea({ onSubmit, disabled, borderColor, textColor, cursorColor, onCtrlC, onCtrlL, onCtrlP, onEscape, onToggleToolExpand, onToggleThinking, onPageUp, onPageDown, onHome, onEnd, commandPaletteOpen, onCommandPaletteInput, approvalDialogOpen, approvalDenyReasonMode, onApprovalApprove, onApprovalAlwaysAllow, onApprovalDeny, onApprovalDenyWithReason, onApprovalCancelDenyReason, onApprovalDenyReasonInput, }) {
121
+ const MemoizedInputArea = memo(function MemoizedInputArea({ onSubmit, disabled, borderColor, textColor, cursorColor, onCtrlC, onCtrlL, onCtrlP, onEscape, onToggleToolExpand, onToggleThinking, onToggleTransparency, onPageUp, onPageDown, onHome, onEnd, commandPaletteOpen, onCommandPaletteInput, approvalDialogOpen, approvalDenyReasonMode, onApprovalApprove, onApprovalAlwaysAllow, onApprovalDeny, onApprovalDenyWithReason, onApprovalCancelDenyReason, onApprovalDenyReasonInput, }) {
118
122
  const [value, setValue] = useState('');
119
123
  const [cursorPos, setCursorPos] = useState(0);
120
124
  // Store callbacks in refs so useInput doesn't re-subscribe on prop changes
121
125
  const callbacksRef = useRef({
122
126
  onSubmit, onCtrlC, onCtrlL, onCtrlP, onEscape,
123
- onToggleToolExpand, onToggleThinking,
127
+ onToggleToolExpand, onToggleThinking, onToggleTransparency,
124
128
  onPageUp, onPageDown, onHome, onEnd,
125
129
  commandPaletteOpen, onCommandPaletteInput,
126
130
  approvalDialogOpen, approvalDenyReasonMode,
@@ -129,7 +133,7 @@ const MemoizedInputArea = memo(function MemoizedInputArea({ onSubmit, disabled,
129
133
  });
130
134
  callbacksRef.current = {
131
135
  onSubmit, onCtrlC, onCtrlL, onCtrlP, onEscape,
132
- onToggleToolExpand, onToggleThinking,
136
+ onToggleToolExpand, onToggleThinking, onToggleTransparency,
133
137
  onPageUp, onPageDown, onHome, onEnd,
134
138
  commandPaletteOpen, onCommandPaletteInput,
135
139
  approvalDialogOpen, approvalDenyReasonMode,
@@ -167,6 +171,11 @@ const MemoizedInputArea = memo(function MemoizedInputArea({ onSubmit, disabled,
167
171
  cb.onToggleThinking?.();
168
172
  return;
169
173
  }
174
+ // Alt+I / Option+I - Toggle transparency panel
175
+ if (input === '\u00ee' || input === '\u0131' || (key.meta && input === 'i')) {
176
+ cb.onToggleTransparency?.();
177
+ return;
178
+ }
170
179
  // Command palette keyboard handling (when open)
171
180
  if (cb.commandPaletteOpen && cb.onCommandPaletteInput) {
172
181
  cb.onCommandPaletteInput(input, key);
@@ -298,6 +307,7 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
298
307
  // Display toggles
299
308
  const [toolCallsExpanded, setToolCallsExpanded] = useState(false);
300
309
  const [showThinking, setShowThinking] = useState(true);
310
+ const [transparencyExpanded, setTransparencyExpanded] = useState(false);
301
311
  // Command palette state
302
312
  const [commandPaletteOpen, setCommandPaletteOpen] = useState(false);
303
313
  const [commandPaletteQuery, setCommandPaletteQuery] = useState('');
@@ -308,6 +318,9 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
308
318
  const [denyReason, setDenyReason] = useState('');
309
319
  // Session-scoped always-allowed patterns (e.g., "bash:npm test", "write_file:/path")
310
320
  const [alwaysAllowed, setAlwaysAllowed] = useState(new Set());
321
+ // Transparency state
322
+ const [transparencyState, setTransparencyState] = useState(null);
323
+ const transparencyAggregatorRef = useRef(null);
311
324
  // Refs for stable callbacks
312
325
  const isProcessingRef = useRef(isProcessing);
313
326
  const messagesLengthRef = useRef(messages.length);
@@ -387,6 +400,23 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
387
400
  });
388
401
  }
389
402
  }, [approvalBridge, handleApprovalRequest]);
403
+ // Set up transparency aggregator and subscribe to agent events
404
+ useEffect(() => {
405
+ const aggregator = new TransparencyAggregator();
406
+ transparencyAggregatorRef.current = aggregator;
407
+ // Subscribe to state changes
408
+ const unsubscribeAggregator = aggregator.subscribe((state) => {
409
+ setTransparencyState(state);
410
+ });
411
+ // Subscribe to agent events
412
+ const unsubscribeAgent = agent.subscribe((event) => {
413
+ aggregator.processEvent(event);
414
+ });
415
+ return () => {
416
+ unsubscribeAggregator();
417
+ unsubscribeAgent();
418
+ };
419
+ }, [agent]);
390
420
  // =========================================================================
391
421
  // COMMAND HANDLER
392
422
  // =========================================================================
@@ -455,10 +485,18 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
455
485
  ' /mcp tools List MCP tools',
456
486
  ' /mcp search <q> Search & load tools',
457
487
  '',
458
- '> SUBAGENTS',
459
- ' /agents List available agents',
488
+ '> SKILLS & AGENTS',
489
+ ' /skills List all skills',
490
+ ' /skills new <n> Create new skill',
491
+ ' /skills info <n> Show skill details',
492
+ ' /agents List all agents',
493
+ ' /agents new <n> Create new agent',
494
+ ' /agents info <n> Show agent details',
460
495
  ' /spawn <a> <task> Run agent with task',
461
496
  '',
497
+ '> INITIALIZATION',
498
+ ' /init Setup .attocode/ directory',
499
+ '',
462
500
  '> PLAN MODE',
463
501
  ' /mode Show current mode',
464
502
  ' /plan Toggle plan mode',
@@ -466,12 +504,19 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
466
504
  ' /approve [n] Approve plan',
467
505
  ' /reject Reject plan',
468
506
  '',
507
+ '> TRACE ANALYSIS',
508
+ ' /trace Show trace summary',
509
+ ' /trace --analyze Run efficiency analysis',
510
+ ' /trace issues List detected issues',
511
+ ' /trace fixes List pending improvements',
512
+ '',
469
513
  '===== SHORTCUTS =====',
470
514
  ' Ctrl+C Exit',
471
515
  ' Ctrl+L Clear screen',
472
516
  ' Ctrl+P Help',
473
517
  ' Alt+T Toggle tool details',
474
518
  ' Alt+O Toggle thinking',
519
+ ' Alt+I Toggle transparency panel',
475
520
  '========================',
476
521
  ].join('\n'));
477
522
  return;
@@ -524,7 +569,7 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
524
569
  .filter((m) => m.role !== 'system')
525
570
  .reduce((sum, m) => sum + estimateTokens(typeof m.content === 'string' ? m.content : JSON.stringify(m.content)), 0);
526
571
  const totalTokens = systemTokens + mcpTokens + agentToolTokens + convTokens;
527
- const contextLimit = 80000;
572
+ const contextLimit = agent.getMaxContextTokens();
528
573
  const percent = Math.round((totalTokens / contextLimit) * 100);
529
574
  const bar = '='.repeat(Math.min(20, Math.round(percent / 5))) + '-'.repeat(Math.max(0, 20 - Math.round(percent / 5)));
530
575
  addMessage('system', [
@@ -819,16 +864,81 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
819
864
  case 'model':
820
865
  addMessage('system', `Model: ${model || 'auto'}\nRestart to change.`);
821
866
  return;
867
+ // Skills commands
868
+ case 'skills': {
869
+ const skillManager = agent.getSkillManager();
870
+ if (skillManager) {
871
+ // Create output adapter for TUI
872
+ const tuiOutput = {
873
+ log: (msg) => addMessage('system', msg),
874
+ error: (msg) => addMessage('error', msg),
875
+ clear: () => setMessages([]),
876
+ };
877
+ const ctx = {
878
+ agent,
879
+ sessionId: currentSessionId,
880
+ output: tuiOutput,
881
+ integrations: {
882
+ sessionStore,
883
+ mcpClient,
884
+ compactor,
885
+ skillManager,
886
+ },
887
+ };
888
+ await handleSkillsCommand(args, ctx, skillManager);
889
+ }
890
+ else {
891
+ addMessage('system', 'Skills not enabled');
892
+ }
893
+ return;
894
+ }
895
+ // Init command
896
+ case 'init': {
897
+ const tuiOutput = {
898
+ log: (msg) => addMessage('system', msg),
899
+ error: (msg) => addMessage('error', msg),
900
+ clear: () => setMessages([]),
901
+ };
902
+ const ctx = {
903
+ agent,
904
+ sessionId: currentSessionId,
905
+ output: tuiOutput,
906
+ integrations: {
907
+ sessionStore,
908
+ mcpClient,
909
+ compactor,
910
+ },
911
+ };
912
+ await handleInitCommand(args, ctx);
913
+ return;
914
+ }
822
915
  // Subagent commands
823
- case 'agents':
824
- try {
825
- const agentList = agent.formatAgentList();
826
- addMessage('system', `Available Agents:\n${agentList}`);
916
+ case 'agents': {
917
+ const agentRegistry = agent.getAgentRegistry();
918
+ if (agentRegistry) {
919
+ const tuiOutput = {
920
+ log: (msg) => addMessage('system', msg),
921
+ error: (msg) => addMessage('error', msg),
922
+ clear: () => setMessages([]),
923
+ };
924
+ const ctx = {
925
+ agent,
926
+ sessionId: currentSessionId,
927
+ output: tuiOutput,
928
+ integrations: {
929
+ sessionStore,
930
+ mcpClient,
931
+ compactor,
932
+ agentRegistry,
933
+ },
934
+ };
935
+ await handleAgentsCommand(args, ctx, agentRegistry);
827
936
  }
828
- catch (e) {
829
- addMessage('error', e.message);
937
+ else {
938
+ addMessage('system', 'Agents not enabled');
830
939
  }
831
940
  return;
941
+ }
832
942
  case 'spawn':
833
943
  if (args.length < 2) {
834
944
  addMessage('system', 'Usage: /spawn <agent-name> <task>');
@@ -848,6 +958,156 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
848
958
  setIsProcessing(false);
849
959
  setStatus(s => ({ ...s, mode: 'ready' }));
850
960
  return;
961
+ // Trace analysis commands
962
+ case 'trace': {
963
+ const traceCollector = agent.getTraceCollector();
964
+ if (args.length === 0) {
965
+ // Show current session trace summary
966
+ if (!traceCollector) {
967
+ addMessage('system', 'Tracing is not enabled. Start agent with --trace to enable.');
968
+ return;
969
+ }
970
+ const data = traceCollector.getSessionTrace();
971
+ if (!data || !data.iterations || data.iterations.length === 0) {
972
+ addMessage('system', 'No trace data collected yet.');
973
+ return;
974
+ }
975
+ addMessage('system', [
976
+ 'Trace Summary:',
977
+ ` Session ID: ${data.sessionId}`,
978
+ ` Status: ${data.status}`,
979
+ ` Iterations: ${data.iterations.length}`,
980
+ ` Duration: ${data.durationMs ? `${Math.round(data.durationMs / 1000)}s` : 'ongoing'}`,
981
+ '',
982
+ 'Metrics:',
983
+ ` Input tokens: ${data.metrics.inputTokens.toLocaleString()}`,
984
+ ` Output tokens: ${data.metrics.outputTokens.toLocaleString()}`,
985
+ ` Cache hit: ${Math.round(data.metrics.avgCacheHitRate * 100)}%`,
986
+ ` Tool calls: ${data.metrics.toolCalls}`,
987
+ ` Errors: ${data.metrics.errors}`,
988
+ ` Est. Cost: $${data.metrics.estimatedCost.toFixed(4)}`,
989
+ '',
990
+ 'Use: /trace --analyze for efficiency analysis',
991
+ ' /trace issues to see detected inefficiencies',
992
+ ].join('\n'));
993
+ }
994
+ else if (args[0] === '--analyze' || args[0] === 'analyze') {
995
+ if (!traceCollector) {
996
+ addMessage('system', 'Tracing is not enabled.');
997
+ return;
998
+ }
999
+ const data = traceCollector.getSessionTrace();
1000
+ if (!data || !data.iterations || data.iterations.length === 0) {
1001
+ addMessage('system', 'No trace data to analyze.');
1002
+ return;
1003
+ }
1004
+ addMessage('system', 'Analyzing trace...');
1005
+ try {
1006
+ const { createTraceSummaryGenerator } = await import('../analysis/trace-summary.js');
1007
+ const generator = createTraceSummaryGenerator(data);
1008
+ const summary = generator.generate();
1009
+ const lines = ['Efficiency Analysis:', '', `Anomalies Detected: ${summary.anomalies.length}`];
1010
+ if (summary.anomalies.length === 0) {
1011
+ lines.push(' No significant issues detected.');
1012
+ }
1013
+ else {
1014
+ for (const anomaly of summary.anomalies) {
1015
+ lines.push(` [${anomaly.severity.toUpperCase()}] ${anomaly.type}`);
1016
+ lines.push(` ${anomaly.description}`);
1017
+ }
1018
+ }
1019
+ lines.push('', 'Tool Patterns:');
1020
+ lines.push(` Unique tools used: ${Object.keys(summary.toolPatterns.frequency).length}`);
1021
+ lines.push(` Redundant calls: ${summary.toolPatterns.redundantCalls.length}`);
1022
+ lines.push(` Slow tools: ${summary.toolPatterns.slowTools.length}`);
1023
+ if (summary.codeLocations.length > 0) {
1024
+ lines.push('', 'Related Code Locations:');
1025
+ for (const loc of summary.codeLocations) {
1026
+ lines.push(` [${loc.relevance.toUpperCase()}] ${loc.file} - ${loc.component}`);
1027
+ }
1028
+ }
1029
+ addMessage('system', lines.join('\n'));
1030
+ }
1031
+ catch (e) {
1032
+ addMessage('error', `Analysis failed: ${e.message}`);
1033
+ }
1034
+ }
1035
+ else if (args[0] === 'issues') {
1036
+ if (!traceCollector) {
1037
+ addMessage('system', 'Tracing is not enabled.');
1038
+ return;
1039
+ }
1040
+ const data = traceCollector.getSessionTrace();
1041
+ if (!data || !data.iterations || data.iterations.length === 0) {
1042
+ addMessage('system', 'No trace data to analyze.');
1043
+ return;
1044
+ }
1045
+ try {
1046
+ const { createTraceSummaryGenerator } = await import('../analysis/trace-summary.js');
1047
+ const generator = createTraceSummaryGenerator(data);
1048
+ const summary = generator.generate();
1049
+ if (summary.anomalies.length === 0) {
1050
+ addMessage('system', 'No issues detected in current session.');
1051
+ }
1052
+ else {
1053
+ const lines = ['Detected Issues:'];
1054
+ summary.anomalies.forEach((anomaly, i) => {
1055
+ const icon = anomaly.severity === 'high' ? '!' : anomaly.severity === 'medium' ? '*' : '-';
1056
+ lines.push(` ${icon} ${i + 1}. ${anomaly.type} (${anomaly.severity})`);
1057
+ lines.push(` ${anomaly.description}`);
1058
+ });
1059
+ addMessage('system', lines.join('\n'));
1060
+ }
1061
+ }
1062
+ catch (e) {
1063
+ addMessage('error', `Analysis failed: ${e.message}`);
1064
+ }
1065
+ }
1066
+ else if (args[0] === 'fixes') {
1067
+ try {
1068
+ const { createFeedbackLoopManager } = await import('../analysis/feedback-loop.js');
1069
+ const feedbackManager = createFeedbackLoopManager();
1070
+ const pendingFixes = feedbackManager.getPendingFixes();
1071
+ const stats = feedbackManager.getSummaryStats();
1072
+ const lines = [
1073
+ 'Feedback Loop Summary:',
1074
+ ` Total analyses: ${stats.totalAnalyses}`,
1075
+ ` Avg efficiency: ${stats.avgEfficiencyScore}%`,
1076
+ ` Total fixes: ${stats.totalFixes}`,
1077
+ ` Implemented: ${stats.implementedFixes}`,
1078
+ ` Verified: ${stats.verifiedFixes}`,
1079
+ '',
1080
+ ];
1081
+ if (pendingFixes.length === 0) {
1082
+ lines.push('No pending fixes.');
1083
+ }
1084
+ else {
1085
+ lines.push('Pending Fixes:');
1086
+ for (const fix of pendingFixes.slice(0, 5)) {
1087
+ lines.push(` - ${fix.description}`);
1088
+ }
1089
+ if (pendingFixes.length > 5) {
1090
+ lines.push(` ... and ${pendingFixes.length - 5} more`);
1091
+ }
1092
+ }
1093
+ feedbackManager.close();
1094
+ addMessage('system', lines.join('\n'));
1095
+ }
1096
+ catch (e) {
1097
+ addMessage('error', `Error loading feedback data: ${e.message}`);
1098
+ }
1099
+ }
1100
+ else {
1101
+ addMessage('system', [
1102
+ 'Usage:',
1103
+ ' /trace - Show current session trace summary',
1104
+ ' /trace --analyze - Run efficiency analysis',
1105
+ ' /trace issues - List detected inefficiencies',
1106
+ ' /trace fixes - List pending improvements',
1107
+ ].join('\n'));
1108
+ }
1109
+ return;
1110
+ }
851
1111
  default:
852
1112
  addMessage('system', `Unknown: /${cmd}. Try /help`);
853
1113
  }
@@ -915,7 +1175,8 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
915
1175
  addMessage('system', `${subagentPrefix}* ${e.inputTokens.toLocaleString()} in, ${e.outputTokens.toLocaleString()} out${e.cost ? ` $${e.cost.toFixed(6)}` : ''}`);
916
1176
  }
917
1177
  else if (event.type === 'plan.change.queued') {
918
- addMessage('system', `[PLAN] Queued: ${event.tool}`);
1178
+ const summary = event.summary ? `: ${event.summary}` : '';
1179
+ addMessage('system', `[PLAN] Queued ${event.tool}${summary}`);
919
1180
  }
920
1181
  });
921
1182
  try {
@@ -927,7 +1188,7 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
927
1188
  const agentState = agent.getState();
928
1189
  const estimateTokens = (str) => Math.ceil(str.length / 3.2);
929
1190
  const currentContextTokens = agentState.messages.reduce((sum, m) => sum + estimateTokens(typeof m.content === 'string' ? m.content : JSON.stringify(m.content)), 0);
930
- const contextLimit = 80000;
1191
+ const contextLimit = agent.getMaxContextTokens();
931
1192
  const contextPct = Math.round((currentContextTokens / contextLimit) * 100);
932
1193
  const durationSec = (metrics.duration / 1000).toFixed(1);
933
1194
  // Format: Session total (cumulative cost) | Current context (compaction awareness)
@@ -1105,6 +1366,12 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
1105
1366
  return !prev;
1106
1367
  });
1107
1368
  }, [addMessage]);
1369
+ const handleToggleTransparency = useCallback(() => {
1370
+ setTransparencyExpanded(prev => {
1371
+ addMessage('system', !prev ? '[v] Transparency panel: visible' : '[^] Transparency panel: hidden');
1372
+ return !prev;
1373
+ });
1374
+ }, [addMessage]);
1108
1375
  // Update context tokens
1109
1376
  useEffect(() => {
1110
1377
  const agentState = agent.getState();
@@ -1130,18 +1397,23 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
1130
1397
  }
1131
1398
  }, [isProcessing]);
1132
1399
  const modelShort = (model || 'unknown').split('/').pop() || model || 'unknown';
1133
- const contextPct = Math.round((contextTokens / 80000) * 100);
1400
+ const contextPct = Math.round((contextTokens / agent.getMaxContextTokens()) * 100);
1134
1401
  const costStr = status.cost > 0 ? `$${status.cost.toFixed(4)}` : '$0.00';
1135
1402
  // =========================================================================
1136
1403
  // RENDER
1137
1404
  // =========================================================================
1138
- return (_jsxs(_Fragment, { children: [_jsx(Static, { items: messages, children: (m) => (_jsx(MessageItem, { msg: m, colors: colors }, m.id)) }), _jsxs(Box, { flexDirection: "column", children: [toolCalls.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: "#DDA0DD", bold: true, children: `Tools ${toolCallsExpanded ? '[-]' : '[+]'}` }), toolCalls.slice(-5).map(tc => (_jsx(ToolCallItem, { tc: tc, expanded: toolCallsExpanded, colors: colors }, `${tc.id}-${tc.status}`)))] })), pendingApproval && (_jsx(ApprovalDialog, { visible: true, request: {
1405
+ return (_jsxs(_Fragment, { children: [_jsx(Static, { items: messages, children: (m) => (_jsx(MessageItem, { msg: m, colors: colors }, m.id)) }), _jsxs(Box, { flexDirection: "column", children: [toolCalls.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: "#DDA0DD", bold: true, children: `Tools ${toolCallsExpanded ? '[-]' : '[+]'}` }), toolCalls.slice(-5).map(tc => (_jsx(ToolCallItem, { tc: tc, expanded: toolCallsExpanded, colors: colors }, `${tc.id}-${tc.status}`)))] })), transparencyExpanded && transparencyState && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, borderStyle: "single", borderColor: colors.border, paddingX: 1, children: [_jsx(Text, { color: colors.accent, bold: true, children: "[v] Transparency Panel" }), _jsxs(Box, { marginLeft: 2, flexDirection: "column", children: [_jsx(Text, { color: colors.text, children: "REASONING" }), transparencyState.lastRouting ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: colors.textMuted, children: [" Routing: ", transparencyState.lastRouting.model] }), _jsxs(Text, { color: colors.textMuted, children: [" ", transparencyState.lastRouting.reason] })] })) : (_jsx(Text, { color: colors.textMuted, children: " Routing: (no routing decisions yet)" })), transparencyState.lastPolicy && (_jsxs(Text, { color: transparencyState.lastPolicy.decision === 'blocked' ? colors.error :
1406
+ transparencyState.lastPolicy.decision === 'prompted' ? colors.warning : colors.success, children: ["Policy: ", transparencyState.lastPolicy.decision === 'allowed' ? '+' :
1407
+ transparencyState.lastPolicy.decision === 'blocked' ? 'x' : '?', " ", transparencyState.lastPolicy.tool] }))] }), _jsxs(Box, { marginLeft: 2, marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: colors.text, children: "CONTEXT" }), transparencyState.contextHealth ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: colors.textMuted, children: ' [' + '='.repeat(Math.round((transparencyState.contextHealth.percentUsed / 100) * 20)) +
1408
+ '-'.repeat(20 - Math.round((transparencyState.contextHealth.percentUsed / 100) * 20)) +
1409
+ '] ' + transparencyState.contextHealth.percentUsed + '%' }), _jsx(Text, { color: colors.textMuted, children: ' ' + (transparencyState.contextHealth.currentTokens / 1000).toFixed(1) + 'k / ' +
1410
+ (transparencyState.contextHealth.maxTokens / 1000).toFixed(0) + 'k tokens' }), _jsx(Text, { color: colors.textMuted, children: ' ~' + transparencyState.contextHealth.estimatedExchanges + ' exchanges remaining' })] })) : (_jsx(Text, { color: colors.textMuted, children: " (no context data yet)" }))] }), transparencyState.activeLearnings.length > 0 && (_jsxs(Box, { marginLeft: 2, marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: colors.text, children: "MEMORY" }), _jsxs(Text, { color: colors.textMuted, children: [" Learnings applied: ", transparencyState.activeLearnings.length] })] }))] })), pendingApproval && (_jsx(ApprovalDialog, { visible: true, request: {
1139
1411
  id: pendingApproval.id,
1140
1412
  tool: pendingApproval.tool || pendingApproval.action,
1141
1413
  args: pendingApproval.args || {},
1142
1414
  risk: pendingApproval.risk,
1143
1415
  context: pendingApproval.context,
1144
- }, onApprove: handleApprove, onDeny: handleDeny, colors: colors, denyReasonMode: denyReasonMode, denyReason: denyReason })), _jsx(MemoizedInputArea, { onSubmit: handleSubmit, disabled: isProcessing || !!pendingApproval, borderColor: pendingApproval ? '#FFD700' : '#87CEEB', textColor: "#98FB98", cursorColor: "#87CEEB", onCtrlC: handleCtrlC, onCtrlL: handleCtrlL, onCtrlP: handleCtrlP, onEscape: handleEscape, onToggleToolExpand: handleToggleToolExpand, onToggleThinking: handleToggleThinking, commandPaletteOpen: commandPaletteOpen, onCommandPaletteInput: handleCommandPaletteInput, approvalDialogOpen: !!pendingApproval, approvalDenyReasonMode: denyReasonMode, onApprovalApprove: handleApprove, onApprovalAlwaysAllow: handleAlwaysAllow, onApprovalDeny: handleDeny, onApprovalDenyWithReason: handleDenyWithReason, onApprovalCancelDenyReason: handleCancelDenyReason, onApprovalDenyReasonInput: handleApprovalDenyReasonInput }), commandPaletteOpen && (_jsx(ControlledCommandPalette, { theme: selectedTheme, items: filteredCommandItems, visible: commandPaletteOpen, query: commandPaletteQuery, selectedIndex: commandPaletteIndex, onQueryChange: setCommandPaletteQuery, onSelectItem: (item) => {
1416
+ }, onApprove: handleApprove, onDeny: handleDeny, colors: colors, denyReasonMode: denyReasonMode, denyReason: denyReason })), _jsx(MemoizedInputArea, { onSubmit: handleSubmit, disabled: isProcessing || !!pendingApproval, borderColor: pendingApproval ? '#FFD700' : '#87CEEB', textColor: "#98FB98", cursorColor: "#87CEEB", onCtrlC: handleCtrlC, onCtrlL: handleCtrlL, onCtrlP: handleCtrlP, onEscape: handleEscape, onToggleToolExpand: handleToggleToolExpand, onToggleThinking: handleToggleThinking, onToggleTransparency: handleToggleTransparency, commandPaletteOpen: commandPaletteOpen, onCommandPaletteInput: handleCommandPaletteInput, approvalDialogOpen: !!pendingApproval, approvalDenyReasonMode: denyReasonMode, onApprovalApprove: handleApprove, onApprovalAlwaysAllow: handleAlwaysAllow, onApprovalDeny: handleDeny, onApprovalDenyWithReason: handleDenyWithReason, onApprovalCancelDenyReason: handleCancelDenyReason, onApprovalDenyReasonInput: handleApprovalDenyReasonInput }), commandPaletteOpen && (_jsx(ControlledCommandPalette, { theme: selectedTheme, items: filteredCommandItems, visible: commandPaletteOpen, query: commandPaletteQuery, selectedIndex: commandPaletteIndex, onQueryChange: setCommandPaletteQuery, onSelectItem: (item) => {
1145
1417
  setCommandPaletteOpen(false);
1146
1418
  setCommandPaletteQuery('');
1147
1419
  setCommandPaletteIndex(0);
@@ -1150,7 +1422,9 @@ export function TUIApp({ agent, sessionStore, mcpClient, compactor, lspManager,
1150
1422
  setCommandPaletteOpen(false);
1151
1423
  setCommandPaletteQuery('');
1152
1424
  setCommandPaletteIndex(0);
1153
- } })), _jsxs(Box, { borderStyle: "single", borderColor: isProcessing ? colors.info : colors.textMuted, paddingX: 1, justifyContent: "space-between", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: isProcessing ? colors.info : '#98FB98', bold: isProcessing, children: isProcessing ? '[~]' : '[*]' }), _jsx(Text, { color: isProcessing ? colors.info : colors.text, bold: isProcessing, children: status.mode.length > 40 ? status.mode.slice(0, 37) + '...' : status.mode }), isProcessing && elapsedTime > 0 && _jsxs(Text, { color: colors.textMuted, dimColor: true, children: ["| ", elapsedTime, "s"] }), status.iter > 0 && _jsxs(Text, { color: colors.textMuted, dimColor: true, children: ["| iter ", status.iter] })] }), _jsxs(Box, { gap: 2, children: [_jsx(Text, { color: "#DDA0DD", dimColor: true, children: modelShort }), _jsx(Text, { color: contextPct > 70 ? '#FFD700' : colors.textMuted, dimColor: true, children: `${(contextTokens / 1000).toFixed(1)}k` }), _jsx(Text, { color: "#98FB98", dimColor: true, children: costStr }), gitBranch && _jsx(Text, { color: "#87CEEB", dimColor: true, children: gitBranch }), _jsx(Text, { color: colors.textMuted, dimColor: true, children: "ESC:cancel ^P:help" })] })] })] })] }));
1425
+ } })), _jsxs(Box, { borderStyle: "single", borderColor: isProcessing ? colors.info : colors.textMuted, paddingX: 1, justifyContent: "space-between", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: isProcessing ? colors.info : '#98FB98', bold: isProcessing, children: isProcessing ? '[~]' : '[*]' }), _jsx(Text, { color: isProcessing ? colors.info : colors.text, bold: isProcessing, children: status.mode.length > 40 ? status.mode.slice(0, 37) + '...' : status.mode }), isProcessing && elapsedTime > 0 && _jsxs(Text, { color: colors.textMuted, dimColor: true, children: ["| ", elapsedTime, "s"] }), status.iter > 0 && _jsxs(Text, { color: colors.textMuted, dimColor: true, children: ["| iter ", status.iter] })] }), _jsxs(Box, { gap: 2, children: [_jsx(Text, { color: "#DDA0DD", dimColor: true, children: modelShort }), _jsx(Text, { color: contextPct > 70 ? '#FFD700' : colors.textMuted, dimColor: true, children: '[' + '='.repeat(Math.min(8, Math.round((contextPct / 100) * 8))) +
1426
+ '-'.repeat(Math.max(0, 8 - Math.round((contextPct / 100) * 8))) + '] ' +
1427
+ contextPct + '%' }), _jsx(Text, { color: "#98FB98", dimColor: true, children: costStr }), gitBranch && _jsx(Text, { color: "#87CEEB", dimColor: true, children: gitBranch }), transparencyState?.activeLearnings && transparencyState.activeLearnings.length > 0 && (_jsxs(Text, { color: "#87CEEB", dimColor: true, children: ["L:", transparencyState.activeLearnings.length] })), _jsx(Text, { color: colors.textMuted, dimColor: true, children: "^P:help" })] })] })] })] }));
1154
1428
  }
1155
1429
  export default TUIApp;
1156
1430
  //# sourceMappingURL=app.js.map