activo 0.4.4 → 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 (161) hide show
  1. package/README.md +203 -1
  2. package/data/2026-03-04_20-54.json +181 -0
  3. package/data/2026-03-04_20-56.json +181 -0
  4. package/data/apex-rulesets/egov.yaml +469 -0
  5. package/data/apex-rulesets/modernize.yaml +687 -0
  6. package/data/apex-rulesets/quality.yaml +1677 -0
  7. package/data/apex-rulesets/rule-schema.yaml +587 -0
  8. package/data/apex-rulesets/secure.yaml +1688 -0
  9. package/data/apex-rulesets/spring.yaml +455 -0
  10. package/data/apex-rulesets/sql-format.yaml +99 -0
  11. package/data/apex-rulesets/sql-oracle.yaml +281 -0
  12. package/data/apex-rulesets/sql.yaml +1660 -0
  13. package/dist/cli/headless.d.ts.map +1 -1
  14. package/dist/cli/headless.js +32 -10
  15. package/dist/cli/headless.js.map +1 -1
  16. package/dist/cli/index.js +31 -3
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/core/agent.d.ts +3 -3
  19. package/dist/core/agent.d.ts.map +1 -1
  20. package/dist/core/agent.js +203 -384
  21. package/dist/core/agent.js.map +1 -1
  22. package/dist/core/commands.d.ts +2 -1
  23. package/dist/core/commands.d.ts.map +1 -1
  24. package/dist/core/commands.js +61 -9
  25. package/dist/core/commands.js.map +1 -1
  26. package/dist/core/config.d.ts +14 -0
  27. package/dist/core/config.d.ts.map +1 -1
  28. package/dist/core/config.js +41 -4
  29. package/dist/core/config.js.map +1 -1
  30. package/dist/core/conversation.d.ts +2 -2
  31. package/dist/core/conversation.d.ts.map +1 -1
  32. package/dist/core/conversation.js.map +1 -1
  33. package/dist/core/intentRouter.d.ts +43 -0
  34. package/dist/core/intentRouter.d.ts.map +1 -0
  35. package/dist/core/intentRouter.js +804 -0
  36. package/dist/core/intentRouter.js.map +1 -0
  37. package/dist/core/llm/anthropic.d.ts +24 -0
  38. package/dist/core/llm/anthropic.d.ts.map +1 -0
  39. package/dist/core/llm/anthropic.js +226 -0
  40. package/dist/core/llm/anthropic.js.map +1 -0
  41. package/dist/core/llm/ollama.d.ts +5 -14
  42. package/dist/core/llm/ollama.d.ts.map +1 -1
  43. package/dist/core/llm/ollama.js +3 -0
  44. package/dist/core/llm/ollama.js.map +1 -1
  45. package/dist/core/llm/types.d.ts +22 -0
  46. package/dist/core/llm/types.d.ts.map +1 -0
  47. package/dist/core/llm/types.js +2 -0
  48. package/dist/core/llm/types.js.map +1 -0
  49. package/dist/core/mcp/client.d.ts +6 -0
  50. package/dist/core/mcp/client.d.ts.map +1 -1
  51. package/dist/core/mcp/client.js +16 -0
  52. package/dist/core/mcp/client.js.map +1 -1
  53. package/dist/core/mcp/init.d.ts +12 -0
  54. package/dist/core/mcp/init.d.ts.map +1 -0
  55. package/dist/core/mcp/init.js +55 -0
  56. package/dist/core/mcp/init.js.map +1 -0
  57. package/dist/core/mcp/logger.d.ts +14 -0
  58. package/dist/core/mcp/logger.d.ts.map +1 -0
  59. package/dist/core/mcp/logger.js +50 -0
  60. package/dist/core/mcp/logger.js.map +1 -0
  61. package/dist/core/tools/analyzePatterns.d.ts +3 -0
  62. package/dist/core/tools/analyzePatterns.d.ts.map +1 -0
  63. package/dist/core/tools/analyzePatterns.js +293 -0
  64. package/dist/core/tools/analyzePatterns.js.map +1 -0
  65. package/dist/core/tools/apexPaths.d.ts +14 -0
  66. package/dist/core/tools/apexPaths.d.ts.map +1 -0
  67. package/dist/core/tools/apexPaths.js +54 -0
  68. package/dist/core/tools/apexPaths.js.map +1 -0
  69. package/dist/core/tools/apexUtils.d.ts +36 -0
  70. package/dist/core/tools/apexUtils.d.ts.map +1 -0
  71. package/dist/core/tools/apexUtils.js +83 -0
  72. package/dist/core/tools/apexUtils.js.map +1 -0
  73. package/dist/core/tools/explainIssue.d.ts +3 -0
  74. package/dist/core/tools/explainIssue.d.ts.map +1 -0
  75. package/dist/core/tools/explainIssue.js +181 -0
  76. package/dist/core/tools/explainIssue.js.map +1 -0
  77. package/dist/core/tools/fixGen.d.ts +3 -0
  78. package/dist/core/tools/fixGen.d.ts.map +1 -0
  79. package/dist/core/tools/fixGen.js +338 -0
  80. package/dist/core/tools/fixGen.js.map +1 -0
  81. package/dist/core/tools/generateImprovements.d.ts +21 -0
  82. package/dist/core/tools/generateImprovements.d.ts.map +1 -0
  83. package/dist/core/tools/generateImprovements.js +602 -0
  84. package/dist/core/tools/generateImprovements.js.map +1 -0
  85. package/dist/core/tools/generateReport.d.ts +3 -0
  86. package/dist/core/tools/generateReport.d.ts.map +1 -0
  87. package/dist/core/tools/generateReport.js +315 -0
  88. package/dist/core/tools/generateReport.js.map +1 -0
  89. package/dist/core/tools/index.d.ts +7 -0
  90. package/dist/core/tools/index.d.ts.map +1 -1
  91. package/dist/core/tools/index.js +62 -23
  92. package/dist/core/tools/index.js.map +1 -1
  93. package/dist/core/tools/recommendProfile.d.ts +3 -0
  94. package/dist/core/tools/recommendProfile.d.ts.map +1 -0
  95. package/dist/core/tools/recommendProfile.js +334 -0
  96. package/dist/core/tools/recommendProfile.js.map +1 -0
  97. package/dist/core/tools/ruleGen.d.ts +3 -0
  98. package/dist/core/tools/ruleGen.d.ts.map +1 -0
  99. package/dist/core/tools/ruleGen.js +1103 -0
  100. package/dist/core/tools/ruleGen.js.map +1 -0
  101. package/dist/core/tools/standards.d.ts.map +1 -1
  102. package/dist/core/tools/standards.js +7 -3
  103. package/dist/core/tools/standards.js.map +1 -1
  104. package/dist/ui/App.d.ts.map +1 -1
  105. package/dist/ui/App.js +86 -35
  106. package/dist/ui/App.js.map +1 -1
  107. package/dist/ui/components/InputBox.d.ts +1 -3
  108. package/dist/ui/components/InputBox.d.ts.map +1 -1
  109. package/dist/ui/components/InputBox.js +146 -5
  110. package/dist/ui/components/InputBox.js.map +1 -1
  111. package/dist/ui/components/MessageList.d.ts +3 -1
  112. package/dist/ui/components/MessageList.d.ts.map +1 -1
  113. package/dist/ui/components/MessageList.js +13 -7
  114. package/dist/ui/components/MessageList.js.map +1 -1
  115. package/dist/ui/components/StatusBar.d.ts +1 -1
  116. package/dist/ui/components/StatusBar.d.ts.map +1 -1
  117. package/dist/ui/components/StatusBar.js +3 -2
  118. package/dist/ui/components/StatusBar.js.map +1 -1
  119. package/dist/ui/components/ToolStatus.d.ts +3 -1
  120. package/dist/ui/components/ToolStatus.d.ts.map +1 -1
  121. package/dist/ui/components/ToolStatus.js +19 -4
  122. package/dist/ui/components/ToolStatus.js.map +1 -1
  123. package/package.json +7 -1
  124. package/demo.gif +0 -0
  125. package/demo.tape +0 -53
  126. package/screenshot.png +0 -0
  127. package/src/cli/banner.ts +0 -38
  128. package/src/cli/headless.ts +0 -63
  129. package/src/cli/index.ts +0 -57
  130. package/src/core/agent.ts +0 -711
  131. package/src/core/commands.ts +0 -118
  132. package/src/core/config.ts +0 -98
  133. package/src/core/conversation.ts +0 -235
  134. package/src/core/llm/ollama.ts +0 -351
  135. package/src/core/mcp/client.ts +0 -143
  136. package/src/core/tools/analyzeAll.ts +0 -482
  137. package/src/core/tools/ast.ts +0 -826
  138. package/src/core/tools/builtIn.ts +0 -221
  139. package/src/core/tools/cache.ts +0 -570
  140. package/src/core/tools/cssAnalysis.ts +0 -324
  141. package/src/core/tools/dependencyAnalysis.ts +0 -363
  142. package/src/core/tools/embeddings.ts +0 -746
  143. package/src/core/tools/frontendAst.ts +0 -802
  144. package/src/core/tools/htmlAnalysis.ts +0 -466
  145. package/src/core/tools/index.ts +0 -160
  146. package/src/core/tools/javaAst.ts +0 -1030
  147. package/src/core/tools/javaQuality.integration.test.ts +0 -537
  148. package/src/core/tools/memory.ts +0 -655
  149. package/src/core/tools/mybatisAnalysis.ts +0 -322
  150. package/src/core/tools/openapiAnalysis.ts +0 -431
  151. package/src/core/tools/pythonAnalysis.ts +0 -477
  152. package/src/core/tools/sqlAnalysis.ts +0 -298
  153. package/src/core/tools/standards.test.ts +0 -186
  154. package/src/core/tools/standards.ts +0 -889
  155. package/src/core/tools/types.ts +0 -38
  156. package/src/ui/App.tsx +0 -334
  157. package/src/ui/components/InputBox.tsx +0 -37
  158. package/src/ui/components/MessageList.tsx +0 -80
  159. package/src/ui/components/StatusBar.tsx +0 -36
  160. package/src/ui/components/ToolStatus.tsx +0 -38
  161. package/tsconfig.json +0 -21
@@ -1,7 +1,148 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { Box, Text } from "ink";
3
- import TextInput from "ink-text-input";
4
- export function InputBox({ value, onChange, onSubmit, isProcessing, placeholder, }) {
5
- return (_jsxs(Box, { borderStyle: "round", borderColor: isProcessing ? "gray" : "cyan", paddingX: 1, children: [_jsxs(Text, { color: "green", bold: true, children: [isProcessing ? "⏳" : "❯", " "] }), isProcessing ? (_jsx(Text, { color: "gray", children: "Processing..." })) : (_jsx(TextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: placeholder }))] }));
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useState, useCallback } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ // Continue-style: mutable text buffer decoupled from React state
5
+ class TextBuffer {
6
+ _text = "";
7
+ _cursor = 0;
8
+ get text() { return this._text; }
9
+ get cursor() { return this._cursor; }
10
+ insertText(text) {
11
+ this._text = this._text.slice(0, this._cursor) + text + this._text.slice(this._cursor);
12
+ this._cursor += text.length;
13
+ }
14
+ // On Mac, backspace key registers as key.delete — both should delete backward
15
+ deleteBackward() {
16
+ if (this._cursor > 0) {
17
+ this._text = this._text.slice(0, this._cursor - 1) + this._text.slice(this._cursor);
18
+ this._cursor--;
19
+ }
20
+ }
21
+ moveLeft() {
22
+ if (this._cursor > 0)
23
+ this._cursor--;
24
+ }
25
+ moveRight() {
26
+ if (this._cursor < this._text.length)
27
+ this._cursor++;
28
+ }
29
+ moveToStart() {
30
+ this._cursor = 0;
31
+ }
32
+ moveToEnd() {
33
+ this._cursor = this._text.length;
34
+ }
35
+ clear() {
36
+ this._text = "";
37
+ this._cursor = 0;
38
+ }
39
+ deleteWordBackward() {
40
+ if (this._cursor === 0)
41
+ return;
42
+ let i = this._cursor - 1;
43
+ while (i > 0 && this._text[i - 1] === " ")
44
+ i--;
45
+ while (i > 0 && this._text[i - 1] !== " ")
46
+ i--;
47
+ this._text = this._text.slice(0, i) + this._text.slice(this._cursor);
48
+ this._cursor = i;
49
+ }
50
+ deleteLineBackward() {
51
+ this._text = this._text.slice(this._cursor);
52
+ this._cursor = 0;
53
+ }
6
54
  }
55
+ export const InputBox = React.memo(function InputBox({ onSubmit, isProcessing, placeholder, }) {
56
+ const [textBuffer] = useState(() => new TextBuffer());
57
+ const [inputText, setInputText] = useState("");
58
+ const [cursorPosition, setCursorPosition] = useState(0);
59
+ // Sync React state from TextBuffer (Continue-style: immediate, no debounce)
60
+ const syncState = useCallback(() => {
61
+ setInputText(textBuffer.text);
62
+ setCursorPosition(textBuffer.cursor);
63
+ }, [textBuffer]);
64
+ useInput((input, key) => {
65
+ if (isProcessing)
66
+ return;
67
+ // Enter: submit
68
+ if (key.return) {
69
+ const text = textBuffer.text.trim();
70
+ if (text) {
71
+ textBuffer.clear();
72
+ setInputText("");
73
+ setCursorPosition(0);
74
+ onSubmit(text);
75
+ }
76
+ return;
77
+ }
78
+ // Backspace/Delete: both delete backward (Mac sends key.delete for backspace)
79
+ if ((key.backspace || key.delete) && !key.meta) {
80
+ textBuffer.deleteBackward();
81
+ syncState();
82
+ return;
83
+ }
84
+ // Arrow keys
85
+ if (key.leftArrow) {
86
+ textBuffer.moveLeft();
87
+ syncState();
88
+ return;
89
+ }
90
+ if (key.rightArrow) {
91
+ textBuffer.moveRight();
92
+ syncState();
93
+ return;
94
+ }
95
+ // Ctrl+A: move to start
96
+ if (key.ctrl && input === "a") {
97
+ textBuffer.moveToStart();
98
+ syncState();
99
+ return;
100
+ }
101
+ // Ctrl+E: move to end
102
+ if (key.ctrl && input === "e") {
103
+ textBuffer.moveToEnd();
104
+ syncState();
105
+ return;
106
+ }
107
+ // Ctrl+W: delete word backward
108
+ if (key.ctrl && input === "w") {
109
+ textBuffer.deleteWordBackward();
110
+ syncState();
111
+ return;
112
+ }
113
+ // Ctrl+U: delete line backward
114
+ if (key.ctrl && input === "u") {
115
+ textBuffer.deleteLineBackward();
116
+ syncState();
117
+ return;
118
+ }
119
+ // Option+Backspace (macOS): delete word backward
120
+ const isOptionKey = input.startsWith("\u001b") && input.length > 1;
121
+ if (isOptionKey) {
122
+ const seq = input.slice(1);
123
+ if (seq === "\u007f" || seq === "\u0008") {
124
+ textBuffer.deleteWordBackward();
125
+ syncState();
126
+ return;
127
+ }
128
+ }
129
+ // Regular character input
130
+ if (input && !key.ctrl && !key.meta && !isOptionKey) {
131
+ textBuffer.insertText(input);
132
+ syncState();
133
+ return;
134
+ }
135
+ });
136
+ // Render text with cursor (Continue-style: inverse block cursor)
137
+ const renderInputText = () => {
138
+ if (inputText.length === 0) {
139
+ return (_jsxs(_Fragment, { children: [_jsx(Text, { inverse: true, children: " " }), _jsx(Text, { color: "gray", children: placeholder || "" })] }));
140
+ }
141
+ const before = inputText.slice(0, cursorPosition);
142
+ const atCursor = inputText.slice(cursorPosition, cursorPosition + 1);
143
+ const after = inputText.slice(cursorPosition + 1);
144
+ return (_jsxs(Text, { children: [before, _jsx(Text, { inverse: true, children: atCursor || " " }), after] }));
145
+ };
146
+ return (_jsxs(Box, { borderStyle: "round", borderColor: isProcessing ? "gray" : "cyan", paddingX: 1, children: [_jsxs(Text, { color: "green", bold: true, children: [isProcessing ? "⏳" : "❯", " "] }), isProcessing ? (_jsx(Text, { color: "gray", children: "Processing..." })) : (renderInputText())] }));
147
+ });
7
148
  //# sourceMappingURL=InputBox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InputBox.js","sourceRoot":"","sources":["../../../src/ui/components/InputBox.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAUvC,MAAM,UAAU,QAAQ,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,WAAW,GACG;IACd,OAAO,CACL,MAAC,GAAG,IAAC,WAAW,EAAC,OAAO,EAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,aAC/E,MAAC,IAAI,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI,mBACrB,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,IACzB,EACN,YAAY,CAAC,CAAC,CAAC,CACd,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,8BAAqB,CACxC,CAAC,CAAC,CAAC,CACF,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,GACxB,CACH,IACG,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"InputBox.js","sourceRoot":"","sources":["../../../src/ui/components/InputBox.tsx"],"names":[],"mappings":"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"}
@@ -3,8 +3,10 @@ interface ToolCall {
3
3
  tool: string;
4
4
  status: "running" | "complete" | "error";
5
5
  result?: string;
6
+ detail?: string;
6
7
  }
7
8
  interface Message {
9
+ id: string;
8
10
  role: "user" | "assistant";
9
11
  content: string;
10
12
  toolCalls?: ToolCall[];
@@ -12,6 +14,6 @@ interface Message {
12
14
  interface MessageListProps {
13
15
  messages: Message[];
14
16
  }
15
- export declare function MessageList({ messages }: MessageListProps): React.ReactElement;
17
+ export declare const MessageList: React.NamedExoticComponent<MessageListProps>;
16
18
  export {};
17
19
  //# sourceMappingURL=MessageList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/ui/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,OAAO;IACf,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB;AAED,UAAU,gBAAgB;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CAgB9E"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/ui/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,OAAO;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB;AAED,UAAU,gBAAgB;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,eAAO,MAAM,WAAW,8CA2BtB,CAAC"}
@@ -1,15 +1,21 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from "ink";
3
- export function MessageList({ messages }) {
2
+ import React from "react";
3
+ import { Box, Text, Static } from "ink";
4
+ export const MessageList = React.memo(function MessageList({ messages }) {
4
5
  if (messages.length === 0) {
5
6
  return (_jsx(Box, { marginY: 1, children: _jsx(Text, { color: "gray", children: "Start a conversation by typing below..." }) }));
6
7
  }
7
- return (_jsx(Box, { flexDirection: "column", children: messages.map((message, index) => (_jsx(MessageItem, { message: message }, index))) }));
8
- }
9
- function MessageItem({ message }) {
8
+ // Continue-style: completed messages <Static> (rendered once, never re-rendered by Ink)
9
+ // Only the last message stays in the dynamic area (can update for streaming/tool calls)
10
+ const stableCount = Math.max(0, messages.length - 1);
11
+ const stableMessages = messages.slice(0, stableCount);
12
+ const pendingMessages = messages.slice(stableCount);
13
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: stableMessages, children: (message) => (_jsx(MessageItem, { message: message }, message.id)) }), pendingMessages.map((message) => (_jsx(MessageItem, { message: message }, message.id)))] }));
14
+ });
15
+ const MessageItem = React.memo(function MessageItem({ message }) {
10
16
  const isUser = message.role === "user";
11
- return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Box, { children: _jsx(Text, { color: isUser ? "green" : "cyan", bold: true, children: isUser ? "You" : "ACTIVO" }) }), message.toolCalls && message.toolCalls.length > 0 && (_jsx(Box, { flexDirection: "column", marginLeft: 2, marginY: 1, children: message.toolCalls.map((tc, idx) => (_jsxs(Box, { children: [_jsxs(Text, { color: "gray", children: [tc.status === "running" ? "🔄" : tc.status === "complete" ? "" : "✗", " "] }), _jsx(Text, { color: tc.status === "error" ? "red" : "yellow", children: tc.tool }), tc.status === "complete" && tc.result && (_jsxs(Text, { color: "gray", children: [" - ", truncate(tc.result, 50)] }))] }, idx))) })), message.content && (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { wrap: "wrap", children: message.content }) }))] }));
12
- }
17
+ return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Box, { children: _jsx(Text, { color: isUser ? "green" : "cyan", bold: true, children: isUser ? "You" : "ACTIVO" }) }), message.toolCalls && message.toolCalls.length > 0 && (_jsx(Box, { flexDirection: "column", marginLeft: 2, marginY: 1, children: message.toolCalls.map((tc, idx) => (_jsxs(Box, { children: [_jsxs(Text, { color: "gray", children: [tc.status === "running" ? "" : tc.status === "complete" ? "" : "✗", " "] }), _jsx(Text, { color: tc.status === "error" ? "red" : "yellow", children: tc.tool }), tc.detail && (_jsxs(Text, { color: "gray", children: [" (", tc.detail, ")"] })), tc.status === "complete" && tc.result && (_jsxs(Text, { color: "gray", children: [" - ", truncate(tc.result, 50)] }))] }, idx))) })), message.content && (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { wrap: "wrap", children: message.content }) }))] }));
18
+ });
13
19
  function truncate(text, maxLength) {
14
20
  if (text.length <= maxLength)
15
21
  return text;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.js","sourceRoot":"","sources":["../../../src/ui/components/MessageList.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAkBhC,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAoB;IACxD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CACL,KAAC,GAAG,IAAC,OAAO,EAAE,CAAC,YACb,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,wDAA+C,GAC7D,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YACxB,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAChC,KAAC,WAAW,IAAa,OAAO,EAAE,OAAO,IAAvB,KAAK,CAAsB,CAC9C,CAAC,GACE,CACP,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,EAAE,OAAO,EAAwB;IACpD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC;IAEvC,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,aAEpC,KAAC,GAAG,cACF,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,kBACzC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,GACrB,GACH,EAGL,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CACpD,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,YAClD,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,MAAC,GAAG,eACF,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,aACf,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,IACtE,EACP,KAAC,IAAI,IAAC,KAAK,EAAE,EAAE,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,YAAG,EAAE,CAAC,IAAI,GAAQ,EACtE,EAAE,CAAC,MAAM,KAAK,UAAU,IAAI,EAAE,CAAC,MAAM,IAAI,CACxC,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,oBAAK,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAQ,CACvD,KAPO,GAAG,CAQP,CACP,CAAC,GACE,CACP,EAGA,OAAO,CAAC,OAAO,IAAI,CAClB,KAAC,GAAG,IAAC,UAAU,EAAE,CAAC,YAChB,KAAC,IAAI,IAAC,IAAI,EAAC,MAAM,YAAE,OAAO,CAAC,OAAO,GAAQ,GACtC,CACP,IACG,CACP,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,SAAiB;IAC/C,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"MessageList.js","sourceRoot":"","sources":["../../../src/ui/components/MessageList.tsx"],"names":[],"mappings":"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"}
@@ -4,6 +4,6 @@ interface StatusBarProps {
4
4
  isProcessing: boolean;
5
5
  messageCount: number;
6
6
  }
7
- export declare function StatusBar({ model, isProcessing, messageCount, }: StatusBarProps): React.ReactElement;
7
+ export declare const StatusBar: React.NamedExoticComponent<StatusBarProps>;
8
8
  export {};
9
9
  //# sourceMappingURL=StatusBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../../src/ui/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,YAAY,EACZ,YAAY,GACb,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,CAsBrC"}
1
+ {"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../../src/ui/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,SAAS,4CA0BpB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
2
3
  import { Box, Text } from "ink";
3
- export function StatusBar({ model, isProcessing, messageCount, }) {
4
+ export const StatusBar = React.memo(function StatusBar({ model, isProcessing, messageCount, }) {
4
5
  return (_jsxs(Box, { justifyContent: "space-between", paddingX: 1, marginTop: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "gray", children: "Model: " }), _jsx(Text, { color: "cyan", children: model })] }), _jsxs(Box, { children: [_jsx(Text, { color: "gray", children: "Messages: " }), _jsx(Text, { color: "white", children: messageCount })] }), _jsx(Box, { children: isProcessing ? (_jsx(Text, { color: "yellow", children: "\u25CF Processing" })) : (_jsx(Text, { color: "green", children: "\u25CF Ready" })) })] }));
5
- }
6
+ });
6
7
  //# sourceMappingURL=StatusBar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/ui/components/StatusBar.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAQhC,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EACL,YAAY,EACZ,YAAY,GACG;IACf,OAAO,CACL,MAAC,GAAG,IAAC,cAAc,EAAC,eAAe,EAAC,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,aAC3D,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,wBAAe,EACjC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,KAAK,GAAQ,IAC7B,EAEN,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,2BAAkB,EACpC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,YAAY,GAAQ,IACrC,EAEN,KAAC,GAAG,cACD,YAAY,CAAC,CAAC,CAAC,CACd,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,kCAAoB,CACzC,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,6BAAe,CACnC,GACG,IACF,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/ui/components/StatusBar.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAQhC,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,SAAS,CAAC,EACrD,KAAK,EACL,YAAY,EACZ,YAAY,GACG;IACf,OAAO,CACL,MAAC,GAAG,IAAC,cAAc,EAAC,eAAe,EAAC,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,aAC3D,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,wBAAe,EACjC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,KAAK,GAAQ,IAC7B,EAEN,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,2BAAkB,EACpC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,YAAY,GAAQ,IACrC,EAEN,KAAC,GAAG,cACD,YAAY,CAAC,CAAC,CAAC,CACd,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,kCAAoB,CACzC,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,6BAAe,CACnC,GACG,IACF,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -2,7 +2,9 @@ import React from "react";
2
2
  interface ToolStatusProps {
3
3
  tool: string;
4
4
  status: "running" | "complete" | "error";
5
+ detail?: string;
5
6
  }
6
- export declare function ToolStatus({ tool, status }: ToolStatusProps): React.ReactElement;
7
+ export declare function extractToolDetail(tool: string, args?: Record<string, unknown>): string | undefined;
8
+ export declare const ToolStatus: React.NamedExoticComponent<ToolStatusProps>;
7
9
  export {};
8
10
  //# sourceMappingURL=ToolStatus.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolStatus.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ToolStatus.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;CAC1C;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CA4BhF"}
1
+ {"version":3,"file":"ToolStatus.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ToolStatus.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAGD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CASlG;AAED,eAAO,MAAM,UAAU,6CAerB,CAAC"}
@@ -1,7 +1,22 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import React from "react";
2
3
  import { Box, Text } from "ink";
3
- import Spinner from "ink-spinner";
4
- export function ToolStatus({ tool, status }) {
5
- return (_jsx(Box, { marginY: 1, paddingX: 1, children: status === "running" ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { color: "cyan", children: " Using tool: " }), _jsx(Text, { color: "yellow", bold: true, children: tool })] })) : status === "complete" ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: "green", children: "\u2713 " }), _jsx(Text, { color: "gray", children: "Tool completed: " }), _jsx(Text, { color: "white", children: tool })] })) : (_jsxs(_Fragment, { children: [_jsx(Text, { color: "red", children: "\u2717 " }), _jsx(Text, { color: "gray", children: "Tool failed: " }), _jsx(Text, { color: "red", children: tool })] })) }));
4
+ // Extract a human-readable detail from tool args
5
+ export function extractToolDetail(tool, args) {
6
+ if (!args)
7
+ return undefined;
8
+ const primary = args.filepath || args.path || args.pattern || args.file || args.directory;
9
+ if (primary && typeof primary === "string") {
10
+ // Show only the filename or last path component
11
+ const parts = primary.split("/");
12
+ return parts[parts.length - 1] || primary;
13
+ }
14
+ return undefined;
6
15
  }
16
+ export const ToolStatus = React.memo(function ToolStatus({ tool, status, detail }) {
17
+ const icon = status === "running" ? "⟳" : status === "complete" ? "✓" : "✗";
18
+ const iconColor = status === "running" ? "cyan" : status === "complete" ? "green" : "red";
19
+ const label = status === "running" ? "Using tool:" : status === "complete" ? "Tool completed:" : "Tool failed:";
20
+ return (_jsxs(Box, { paddingX: 1, children: [_jsxs(Text, { color: iconColor, children: [icon, " "] }), _jsxs(Text, { color: status === "running" ? "cyan" : "gray", children: [label, " "] }), _jsx(Text, { color: status === "running" ? "yellow" : status === "error" ? "red" : "white", bold: status === "running", children: tool }), detail && _jsxs(Text, { color: "gray", children: [" (", detail, ")"] })] }));
21
+ });
7
22
  //# sourceMappingURL=ToolStatus.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolStatus.js","sourceRoot":"","sources":["../../../src/ui/components/ToolStatus.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,OAAO,MAAM,aAAa,CAAC;AAOlC,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAmB;IAC1D,OAAO,CACL,KAAC,GAAG,IAAC,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,YACzB,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CACtB,8BACE,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAChB,KAAC,OAAO,IAAC,IAAI,EAAC,MAAM,GAAG,GAClB,EACP,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,8BAAqB,EACvC,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,EAAC,IAAI,kBACtB,IAAI,GACA,IACN,CACJ,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,CAC1B,8BACE,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,wBAAU,EAC7B,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,iCAAwB,EAC1C,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,IAAI,GAAQ,IAChC,CACJ,CAAC,CAAC,CAAC,CACF,8BACE,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,wBAAU,EAC3B,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,8BAAqB,EACvC,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,YAAE,IAAI,GAAQ,IAC9B,CACJ,GACG,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"ToolStatus.js","sourceRoot":"","sources":["../../../src/ui/components/ToolStatus.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAQhC,iDAAiD;AACjD,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,IAA8B;IAC5E,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC;IAC1F,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC3C,gDAAgD;QAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,OAAO,CAAC;IAC5C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAmB;IAChG,MAAM,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5E,MAAM,SAAS,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1F,MAAM,KAAK,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,cAAc,CAAC;IAEhH,OAAO,CACL,MAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,aACd,MAAC,IAAI,IAAC,KAAK,EAAE,SAAS,aAAG,IAAI,SAAS,EACtC,MAAC,IAAI,IAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,aAAG,KAAK,SAAS,EACpE,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,SAAS,YAC5G,IAAI,GACA,EACN,MAAM,IAAI,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,mBAAI,MAAM,SAAS,IAC5C,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "activo",
3
- "version": "0.4.4",
3
+ "version": "0.5.0",
4
4
  "description": "AI-powered code quality analyzer with React Ink TUI, Tool Calling, and MCP support",
5
5
  "repository": {
6
6
  "type": "git",
@@ -10,6 +10,10 @@
10
10
  "main": "dist/index.js",
11
11
  "types": "dist/index.d.ts",
12
12
  "type": "module",
13
+ "files": [
14
+ "dist/",
15
+ "data/"
16
+ ],
13
17
  "bin": {
14
18
  "activo": "dist/cli/index.js"
15
19
  },
@@ -49,12 +53,14 @@
49
53
  "ink-spinner": "^5.0.0",
50
54
  "ink-text-input": "^6.0.0",
51
55
  "java-ast": "^0.4.1",
56
+ "js-yaml": "^4.1.1",
52
57
  "pdf-parse": "^1.1.1",
53
58
  "react": "^19.1.0",
54
59
  "uuid": "^10.0.0"
55
60
  },
56
61
  "devDependencies": {
57
62
  "@types/gradient-string": "^1.1.6",
63
+ "@types/js-yaml": "^4.0.9",
58
64
  "@types/node": "^22.10.0",
59
65
  "@types/pdf-parse": "^1.1.4",
60
66
  "@types/react": "^19.1.0",
package/demo.gif DELETED
Binary file
package/demo.tape DELETED
@@ -1,53 +0,0 @@
1
- # VHS Demo for ACTIVO - Full Feature Showcase
2
- Output demo.gif
3
-
4
- Set FontSize 13
5
- Set Width 900
6
- Set Height 600
7
- Set Theme "Dracula"
8
- Set TypingSpeed 50ms
9
-
10
- # 1. Start activo in centerpoint project
11
- Type "cd /Users/mhb8436/Workspaces/centerpoint/server && activo"
12
- Enter
13
- Sleep 3s
14
-
15
- # 2. Directory structure
16
- Type "프로젝트 구조 보여줘"
17
- Enter
18
- Sleep 6s
19
-
20
- # 3. Java code analysis
21
- Type "api-server 자바 코드 분석해줘"
22
- Enter
23
- Sleep 10s
24
-
25
- # 4. Spring pattern check
26
- Type "Spring 패턴 검사해줘"
27
- Enter
28
- Sleep 8s
29
-
30
- # 5. Dependency check
31
- Type "pom.xml 의존성 분석해줘"
32
- Enter
33
- Sleep 6s
34
-
35
- # 6. Find specific code
36
- Type "WebSecurityConfig 파일 찾아서 보여줘"
37
- Enter
38
- Sleep 6s
39
-
40
- # 7. SQL analysis
41
- Type "SQL 쿼리 분석해줘"
42
- Enter
43
- Sleep 6s
44
-
45
- # 8. Full analysis
46
- Type "전체 코드 품질 분석해줘"
47
- Enter
48
- Sleep 10s
49
-
50
- # 9. Exit
51
- Type "/exit"
52
- Enter
53
- Sleep 1s
package/screenshot.png DELETED
Binary file
package/src/cli/banner.ts DELETED
@@ -1,38 +0,0 @@
1
- import gradient from "gradient-string";
2
- import { createRequire } from "module";
3
-
4
- const require = createRequire(import.meta.url);
5
- const pkg = require("../../package.json");
6
-
7
- const ACTIVO_ASCII = `
8
- _ ____ _____ _____ _____
9
- / \\ / ___|_ _|_ _\\ \\ / / _ \\
10
- / _ \\| | | | | | \\ \\ / / | | |
11
- / ___ \\ |___ | | | | \\ V /| |_| |
12
- /_/ \\_\\____| |_| |___| \\_/ \\___/
13
- `;
14
-
15
- const SUBTITLE = "AI-Powered Code Quality Analyzer";
16
- const VERSION = `v${pkg.version}`;
17
-
18
- export function showBanner(): void {
19
- const activoGradient = gradient(["#00d4ff", "#7b2ff7", "#f107a3"]);
20
-
21
- console.log(activoGradient.multiline(ACTIVO_ASCII));
22
- console.log();
23
- console.log(` ${gradient(["#7b2ff7", "#00d4ff"])(SUBTITLE)} ${VERSION}`);
24
- console.log();
25
- console.log(" Type your request in natural language.");
26
- console.log(" Examples:");
27
- console.log(" • 이 프로젝트의 코드 품질을 분석해줘");
28
- console.log(" • PDF 파일을 마크다운 규칙으로 변환해줘");
29
- console.log(" • src 폴더의 명명규칙 위반을 찾아줘");
30
- console.log();
31
- console.log(" Press Ctrl+C twice to exit");
32
- console.log("─".repeat(50));
33
- console.log();
34
- }
35
-
36
- export function getShortBanner(): string {
37
- return gradient(["#00d4ff", "#7b2ff7"])("ACTIVO") + " - Code Quality Analyzer";
38
- }
@@ -1,63 +0,0 @@
1
- import { OllamaClient } from "../core/llm/ollama.js";
2
- import { processMessage } from "../core/agent.js";
3
- import { Config } from "../core/config.js";
4
- import chalk from "chalk";
5
- import {
6
- createSession,
7
- saveSession,
8
- getSessionContext,
9
- cleanOldSessions,
10
- } from "../core/conversation.js";
11
-
12
- export async function runHeadless(prompt: string | undefined, config: Config): Promise<void> {
13
- if (!prompt) {
14
- console.error(chalk.red("Error: Prompt is required in headless mode"));
15
- console.error(chalk.yellow("Usage: activo -p \"your prompt here\""));
16
- process.exit(1);
17
- }
18
-
19
- const client = new OllamaClient(config.ollama);
20
-
21
- // Check connection
22
- const isConnected = await client.isConnected();
23
- if (!isConnected) {
24
- console.error(chalk.red("Error: Cannot connect to Ollama"));
25
- console.error(chalk.yellow(`Make sure Ollama is running at ${config.ollama.baseUrl}`));
26
- process.exit(1);
27
- }
28
-
29
- // Load previous context
30
- let contextSummary = "";
31
- try {
32
- const { summary } = await getSessionContext(client, 5);
33
- contextSummary = summary;
34
- } catch {
35
- // Ignore context loading errors
36
- }
37
-
38
- // Create new session
39
- const session = createSession();
40
-
41
- try {
42
- const result = await processMessage(prompt, [], client, config, (event) => {
43
- if (event.type === "tool_use") {
44
- console.error(chalk.dim(`[Tool] ${event.tool}: ${event.status}`));
45
- } else if (event.type === "thinking") {
46
- // Skip thinking in headless mode
47
- }
48
- }, contextSummary);
49
-
50
- console.log(result.content);
51
-
52
- // Save conversation to session
53
- session.messages.push({ role: "user", content: prompt });
54
- session.messages.push({ role: "assistant", content: result.content });
55
- saveSession(session);
56
-
57
- // Clean old sessions
58
- cleanOldSessions(10);
59
- } catch (error) {
60
- console.error(chalk.red(`Error: ${error}`));
61
- process.exit(1);
62
- }
63
- }
package/src/cli/index.ts DELETED
@@ -1,57 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Command } from "commander";
4
- import { render } from "ink";
5
- import React from "react";
6
- import { createRequire } from "module";
7
- import { App } from "../ui/App.js";
8
- import { showBanner } from "./banner.js";
9
- import { loadConfig } from "../core/config.js";
10
-
11
- const require = createRequire(import.meta.url);
12
- const pkg = require("../../package.json");
13
-
14
- const program = new Command();
15
-
16
- program
17
- .name("activo")
18
- .description("AI-powered code quality analyzer with Tool Calling and MCP support")
19
- .version(pkg.version, "-v, --version", "Display version number");
20
-
21
- program
22
- .option("-p, --print", "Non-interactive mode (print and exit)")
23
- .option("--headless", "Headless mode for CI/CD")
24
- .option("--resume", "Resume from last session")
25
- .option("--model <model>", "Specify Ollama model")
26
- .argument("[prompt]", "Initial prompt")
27
- .action(async (prompt, options) => {
28
- // Show ASCII banner
29
- showBanner();
30
-
31
- // Load config
32
- const config = loadConfig();
33
-
34
- if (options.model) {
35
- config.ollama.model = options.model;
36
- }
37
-
38
- // Headless/print mode
39
- if (options.print || options.headless) {
40
- const { runHeadless } = await import("./headless.js");
41
- await runHeadless(prompt, config);
42
- return;
43
- }
44
-
45
- // Interactive TUI mode
46
- const { waitUntilExit } = render(
47
- React.createElement(App, {
48
- initialPrompt: prompt,
49
- config,
50
- resume: options.resume,
51
- })
52
- );
53
-
54
- await waitUntilExit();
55
- });
56
-
57
- program.parse();