agentk8 1.0.4 → 2.0.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.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { render } from 'ink';
4
+ import meow from 'meow';
5
+ import { App } from './components/App.js';
6
+ import { checkClaudeInstalled } from './lib/claude.js';
7
+ const VERSION = '2.0.0';
8
+ const cli = meow(`
9
+ Usage
10
+ $ agentk [options]
11
+
12
+ Options
13
+ --mode, -m Set mode: dev (default) or ml
14
+ --version, -v Show version
15
+ --help, -h Show this help
16
+
17
+ Examples
18
+ $ agentk Start dev mode
19
+ $ agentk --mode ml Start ML mode
20
+
21
+ Commands (inside app)
22
+ /help Show available commands
23
+ /status Show session status
24
+ /clear Clear chat history
25
+ /exit Exit AGENT-K
26
+
27
+ Keyboard
28
+ Ctrl+C Exit
29
+ Ctrl+U Clear input line
30
+ `, {
31
+ importMeta: import.meta,
32
+ flags: {
33
+ mode: {
34
+ type: 'string',
35
+ shortFlag: 'm',
36
+ default: 'dev',
37
+ },
38
+ version: {
39
+ type: 'boolean',
40
+ shortFlag: 'v',
41
+ },
42
+ },
43
+ });
44
+ async function main() {
45
+ // Handle version flag
46
+ if (cli.flags.version) {
47
+ console.log(`AGENT-K v${VERSION}`);
48
+ process.exit(0);
49
+ }
50
+ // Validate mode
51
+ const mode = cli.flags.mode;
52
+ if (mode !== 'dev' && mode !== 'ml') {
53
+ console.error(`Error: Invalid mode '${mode}'. Use 'dev' or 'ml'.`);
54
+ process.exit(1);
55
+ }
56
+ // Check if Claude is installed
57
+ const claudeInstalled = await checkClaudeInstalled();
58
+ if (!claudeInstalled) {
59
+ console.error('Error: Claude Code CLI is not installed.');
60
+ console.error('Install it from: https://claude.ai/code');
61
+ process.exit(1);
62
+ }
63
+ // Clear screen
64
+ console.clear();
65
+ // Render the app
66
+ const { waitUntilExit } = render(_jsx(App, { mode: mode, version: VERSION }));
67
+ await waitUntilExit();
68
+ // Show goodbye message
69
+ console.log('\n✦ Goodbye!\n');
70
+ }
71
+ main().catch((err) => {
72
+ console.error('Error:', err.message);
73
+ process.exit(1);
74
+ });
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ interface AppProps {
3
+ mode: 'dev' | 'ml';
4
+ version: string;
5
+ }
6
+ export declare const App: React.FC<AppProps>;
7
+ export default App;
@@ -0,0 +1,120 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Box, Text, useApp, useInput } from 'ink';
4
+ import { Banner } from './Banner.js';
5
+ import { ChatMessage } from './ChatMessage.js';
6
+ import { Input } from './Input.js';
7
+ import { StatusBar } from './StatusBar.js';
8
+ import { runClaude } from '../lib/claude.js';
9
+ import { colors, icons } from '../themes/retro.js';
10
+ export const App = ({ mode, version }) => {
11
+ const { exit } = useApp();
12
+ const [messages, setMessages] = useState([]);
13
+ const [isProcessing, setIsProcessing] = useState(false);
14
+ const [totalTokens, setTotalTokens] = useState(0);
15
+ const [startTime] = useState(new Date());
16
+ const [error, setError] = useState(null);
17
+ // Handle input submission
18
+ const handleSubmit = async (input) => {
19
+ // Check for commands
20
+ if (input.startsWith('/')) {
21
+ handleCommand(input);
22
+ return;
23
+ }
24
+ // Add user message
25
+ const userMessage = {
26
+ id: Date.now().toString(),
27
+ role: 'user',
28
+ content: input,
29
+ timestamp: new Date(),
30
+ };
31
+ setMessages(prev => [...prev, userMessage]);
32
+ setIsProcessing(true);
33
+ setError(null);
34
+ try {
35
+ // Call Claude
36
+ const result = await runClaude(input, mode);
37
+ // Add agent response
38
+ const agentMessage = {
39
+ id: (Date.now() + 1).toString(),
40
+ role: 'agent',
41
+ agentName: 'Orchestrator',
42
+ content: result.response,
43
+ tokens: result.tokens,
44
+ timestamp: new Date(),
45
+ };
46
+ setMessages(prev => [...prev, agentMessage]);
47
+ // Update token count
48
+ if (result.tokens) {
49
+ setTotalTokens(prev => prev + result.tokens.input + result.tokens.output);
50
+ }
51
+ }
52
+ catch (err) {
53
+ setError(err instanceof Error ? err.message : 'Unknown error');
54
+ }
55
+ finally {
56
+ setIsProcessing(false);
57
+ }
58
+ };
59
+ // Handle slash commands
60
+ const handleCommand = (cmd) => {
61
+ const [command, ...args] = cmd.slice(1).split(' ');
62
+ switch (command) {
63
+ case 'exit':
64
+ case 'quit':
65
+ exit();
66
+ break;
67
+ case 'clear':
68
+ setMessages([]);
69
+ break;
70
+ case 'help':
71
+ const helpMessage = {
72
+ id: Date.now().toString(),
73
+ role: 'agent',
74
+ agentName: 'System',
75
+ content: `Available commands:
76
+ /help - Show this help
77
+ /clear - Clear chat history
78
+ /status - Show agent status
79
+ /exit - Exit AGENT-K
80
+
81
+ Keyboard shortcuts:
82
+ Ctrl+C - Exit
83
+ Ctrl+U - Clear input line`,
84
+ timestamp: new Date(),
85
+ };
86
+ setMessages(prev => [...prev, helpMessage]);
87
+ break;
88
+ case 'status':
89
+ const statusMessage = {
90
+ id: Date.now().toString(),
91
+ role: 'agent',
92
+ agentName: 'System',
93
+ content: `Session Status:
94
+ ${icons.bullet} Mode: ${mode === 'dev' ? 'Development' : 'ML Research'}
95
+ ${icons.bullet} Messages: ${messages.length}
96
+ ${icons.bullet} Total Tokens: ${totalTokens}
97
+ ${icons.bullet} Session Time: ${formatElapsed(startTime)}`,
98
+ timestamp: new Date(),
99
+ };
100
+ setMessages(prev => [...prev, statusMessage]);
101
+ break;
102
+ default:
103
+ setError(`Unknown command: /${command}`);
104
+ }
105
+ };
106
+ // Handle Ctrl+C
107
+ useInput((input, key) => {
108
+ if (key.ctrl && input === 'c') {
109
+ exit();
110
+ }
111
+ });
112
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Banner, { version: version }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [messages.map(msg => (_jsx(ChatMessage, { role: msg.role, agentName: msg.agentName, content: msg.content, tokens: msg.tokens }, msg.id))), isProcessing && (_jsx(Box, { marginY: 1, children: _jsxs(Text, { color: colors.warning, children: [icons.sparkle, " Orchestrator is thinking..."] }) })), error && (_jsx(Box, { marginY: 1, children: _jsxs(Text, { color: colors.error, children: [icons.cross, " Error: ", error] }) }))] }), _jsx(Input, { onSubmit: handleSubmit, disabled: isProcessing, placeholder: "Type a message or /help for commands..." }), _jsx(StatusBar, { mode: mode, tokens: totalTokens, startTime: startTime, isProcessing: isProcessing })] }));
113
+ };
114
+ function formatElapsed(start) {
115
+ const secs = Math.floor((Date.now() - start.getTime()) / 1000);
116
+ const mins = Math.floor(secs / 60);
117
+ const remainingSecs = secs % 60;
118
+ return mins > 0 ? `${mins}m ${remainingSecs}s` : `${secs}s`;
119
+ }
120
+ export default App;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ interface BannerProps {
3
+ version: string;
4
+ }
5
+ export declare const Banner: React.FC<BannerProps>;
6
+ export default Banner;
@@ -0,0 +1,17 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { colors, boxDouble, icons } from '../themes/retro.js';
4
+ export const Banner = ({ version }) => {
5
+ const termWidth = process.stdout.columns || 80;
6
+ const bannerWidth = Math.min(termWidth - 2, 50);
7
+ const innerWidth = bannerWidth - 2;
8
+ const title = `${icons.star} A G E N T - K ${icons.star}`;
9
+ const subtitle = 'Multi-Agent Claude Code Suite';
10
+ const versionText = `v${version}`;
11
+ const centerPad = (text, width) => {
12
+ const pad = Math.max(0, Math.floor((width - text.length) / 2));
13
+ return ' '.repeat(pad) + text + ' '.repeat(width - pad - text.length);
14
+ };
15
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { color: colors.secondary, children: [boxDouble.topLeft, boxDouble.horizontal.repeat(innerWidth), boxDouble.topRight] }), _jsxs(Text, { color: colors.secondary, children: [boxDouble.vertical, _jsx(Text, { bold: true, color: colors.primary, children: centerPad(title, innerWidth) }), boxDouble.vertical] }), _jsxs(Text, { color: colors.secondary, children: [boxDouble.vertical, _jsx(Text, { dimColor: true, children: centerPad(subtitle, innerWidth) }), boxDouble.vertical] }), _jsxs(Text, { color: colors.secondary, children: [boxDouble.vertical, _jsx(Text, { dimColor: true, children: centerPad(versionText, innerWidth) }), boxDouble.vertical] }), _jsxs(Text, { color: colors.secondary, children: [boxDouble.bottomLeft, boxDouble.horizontal.repeat(innerWidth), boxDouble.bottomRight] })] }));
16
+ };
17
+ export default Banner;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface RetroBoxProps {
3
+ title?: string;
4
+ children: React.ReactNode;
5
+ color?: string;
6
+ width?: number | string;
7
+ }
8
+ export declare const RetroBox: React.FC<RetroBoxProps>;
9
+ export default RetroBox;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { Box as InkBox, Text } from 'ink';
4
+ import { box, colors } from '../themes/retro.js';
5
+ export const RetroBox = ({ title, children, color = colors.secondary, width = '100%', }) => {
6
+ const termWidth = process.stdout.columns || 80;
7
+ const boxWidth = typeof width === 'number' ? width : Math.min(termWidth - 2, 80);
8
+ const titleText = title ? ` ${title} ` : '';
9
+ const topLineWidth = boxWidth - 2 - titleText.length;
10
+ const topLine = box.horizontal.repeat(Math.max(0, topLineWidth));
11
+ return (_jsxs(InkBox, { flexDirection: "column", width: boxWidth, children: [_jsxs(Text, { color: color, children: [box.topLeft, box.horizontal, title && _jsx(Text, { bold: true, children: titleText }), topLine, box.topRight] }), _jsx(InkBox, { flexDirection: "column", paddingX: 1, children: React.Children.map(children, (child) => (_jsxs(InkBox, { children: [_jsx(Text, { color: color, children: box.vertical }), _jsx(InkBox, { flexGrow: 1, paddingX: 1, children: child }), _jsx(Text, { color: color, children: box.vertical })] }))) }), _jsxs(Text, { color: color, children: [box.bottomLeft, box.horizontal.repeat(boxWidth - 2), box.bottomRight] })] }));
12
+ };
13
+ export default RetroBox;
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ interface ChatMessageProps {
3
+ role: 'user' | 'agent';
4
+ agentName?: string;
5
+ content: string;
6
+ tokens?: {
7
+ input: number;
8
+ output: number;
9
+ };
10
+ timestamp?: Date;
11
+ }
12
+ export declare const ChatMessage: React.FC<ChatMessageProps>;
13
+ export default ChatMessage;
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { box, colors, icons } from '../themes/retro.js';
4
+ export const ChatMessage = ({ role, agentName = 'Agent', content, tokens, timestamp, }) => {
5
+ const isUser = role === 'user';
6
+ const color = isUser ? colors.primary : colors.secondary;
7
+ const title = isUser ? 'You' : agentName;
8
+ const termWidth = process.stdout.columns || 80;
9
+ const boxWidth = Math.min(termWidth - 2, 78);
10
+ const contentWidth = boxWidth - 4;
11
+ // Word wrap content
12
+ const lines = wrapText(content, contentWidth);
13
+ const titleText = ` ${title} `;
14
+ const topLineWidth = boxWidth - 2 - titleText.length;
15
+ return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsxs(Text, { color: color, children: [box.topLeft, box.horizontal, _jsx(Text, { bold: true, children: titleText }), box.horizontal.repeat(Math.max(0, topLineWidth)), box.topRight] }), lines.map((line, i) => (_jsxs(Text, { color: color, children: [box.vertical, " ", _jsx(Text, { color: "white", children: line.padEnd(contentWidth) }), " ", box.vertical] }, i))), tokens && tokens.input + tokens.output > 0 && (_jsxs(Text, { color: color, children: [box.vertical, " ", _jsxs(Text, { dimColor: true, children: [icons.arrow, " ", tokens.input + tokens.output, " tokens (in: ", tokens.input, ", out: ", tokens.output, ")"] }), ' '.repeat(Math.max(0, contentWidth - 40)), " ", box.vertical] })), _jsxs(Text, { color: color, children: [box.bottomLeft, box.horizontal.repeat(boxWidth - 2), box.bottomRight] })] }));
16
+ };
17
+ // Simple word wrap function
18
+ function wrapText(text, width) {
19
+ const lines = [];
20
+ const paragraphs = text.split('\n');
21
+ for (const para of paragraphs) {
22
+ if (para.length <= width) {
23
+ lines.push(para);
24
+ }
25
+ else {
26
+ const words = para.split(' ');
27
+ let currentLine = '';
28
+ for (const word of words) {
29
+ if ((currentLine + ' ' + word).trim().length <= width) {
30
+ currentLine = (currentLine + ' ' + word).trim();
31
+ }
32
+ else {
33
+ if (currentLine)
34
+ lines.push(currentLine);
35
+ currentLine = word;
36
+ }
37
+ }
38
+ if (currentLine)
39
+ lines.push(currentLine);
40
+ }
41
+ }
42
+ return lines.length > 0 ? lines : [''];
43
+ }
44
+ export default ChatMessage;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface InputProps {
3
+ onSubmit: (value: string) => void;
4
+ placeholder?: string;
5
+ prefix?: string;
6
+ disabled?: boolean;
7
+ }
8
+ export declare const Input: React.FC<InputProps>;
9
+ export default Input;
@@ -0,0 +1,49 @@
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
+ import { colors, icons } from '../themes/retro.js';
5
+ export const Input = ({ onSubmit, placeholder = 'Type a message...', prefix = '>', disabled = false, }) => {
6
+ const [value, setValue] = useState('');
7
+ const [cursorPosition, setCursorPosition] = useState(0);
8
+ useInput((input, key) => {
9
+ if (disabled)
10
+ return;
11
+ if (key.return) {
12
+ if (value.trim()) {
13
+ onSubmit(value);
14
+ setValue('');
15
+ setCursorPosition(0);
16
+ }
17
+ }
18
+ else if (key.backspace || key.delete) {
19
+ if (cursorPosition > 0) {
20
+ setValue(prev => prev.slice(0, cursorPosition - 1) + prev.slice(cursorPosition));
21
+ setCursorPosition(pos => pos - 1);
22
+ }
23
+ }
24
+ else if (key.leftArrow) {
25
+ setCursorPosition(pos => Math.max(0, pos - 1));
26
+ }
27
+ else if (key.rightArrow) {
28
+ setCursorPosition(pos => Math.min(value.length, pos + 1));
29
+ }
30
+ else if (key.ctrl && input === 'c') {
31
+ process.exit(0);
32
+ }
33
+ else if (key.ctrl && input === 'u') {
34
+ // Clear line
35
+ setValue('');
36
+ setCursorPosition(0);
37
+ }
38
+ else if (!key.ctrl && !key.meta && input) {
39
+ setValue(prev => prev.slice(0, cursorPosition) + input + prev.slice(cursorPosition));
40
+ setCursorPosition(pos => pos + input.length);
41
+ }
42
+ });
43
+ // Render input with cursor
44
+ const beforeCursor = value.slice(0, cursorPosition);
45
+ const atCursor = value[cursorPosition] || ' ';
46
+ const afterCursor = value.slice(cursorPosition + 1);
47
+ return (_jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: colors.primary, bold: true, children: [prefix, " "] }), value.length === 0 && !disabled ? (_jsx(Text, { dimColor: true, children: placeholder })) : (_jsxs(_Fragment, { children: [_jsx(Text, { children: beforeCursor }), _jsx(Text, { inverse: true, children: atCursor }), _jsx(Text, { children: afterCursor })] })), disabled && _jsxs(Text, { dimColor: true, children: [" ", icons.sparkle, " thinking..."] })] }));
48
+ };
49
+ export default Input;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface StatusBarProps {
3
+ mode: 'dev' | 'ml';
4
+ tokens: number;
5
+ startTime: Date;
6
+ isProcessing?: boolean;
7
+ }
8
+ export declare const StatusBar: React.FC<StatusBarProps>;
9
+ export default StatusBar;
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from 'react';
3
+ import { Box, Text } from 'ink';
4
+ import { colors, icons, box } from '../themes/retro.js';
5
+ export const StatusBar = ({ mode, tokens, startTime, isProcessing = false, }) => {
6
+ const [elapsed, setElapsed] = useState('0s');
7
+ const [spinnerFrame, setSpinnerFrame] = useState(0);
8
+ // Update elapsed time every second
9
+ useEffect(() => {
10
+ const interval = setInterval(() => {
11
+ const secs = Math.floor((Date.now() - startTime.getTime()) / 1000);
12
+ const mins = Math.floor(secs / 60);
13
+ const remainingSecs = secs % 60;
14
+ setElapsed(mins > 0 ? `${mins}m ${remainingSecs}s` : `${secs}s`);
15
+ }, 1000);
16
+ return () => clearInterval(interval);
17
+ }, [startTime]);
18
+ // Spinner animation
19
+ useEffect(() => {
20
+ if (!isProcessing)
21
+ return;
22
+ const interval = setInterval(() => {
23
+ setSpinnerFrame(f => (f + 1) % icons.spinner.length);
24
+ }, 100);
25
+ return () => clearInterval(interval);
26
+ }, [isProcessing]);
27
+ const formatTokens = (t) => {
28
+ if (t >= 1000000)
29
+ return `${(t / 1000000).toFixed(1)}M`;
30
+ if (t >= 1000)
31
+ return `${(t / 1000).toFixed(1)}k`;
32
+ return t.toString();
33
+ };
34
+ const modeIcon = mode === 'dev' ? icons.lightning : icons.brain;
35
+ const modeLabel = mode === 'dev' ? 'Development' : 'ML Research';
36
+ const termWidth = process.stdout.columns || 80;
37
+ const barWidth = Math.min(termWidth - 2, 78);
38
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: colors.dim, children: box.horizontal.repeat(barWidth) }), _jsxs(Box, { justifyContent: "space-between", width: barWidth, children: [_jsxs(Text, { children: [_jsxs(Text, { color: colors.secondary, children: [modeIcon, " ", modeLabel] }), _jsx(Text, { dimColor: true, children: " \u2502 " }), _jsx(Text, { dimColor: true, children: "/help for commands" })] }), _jsxs(Text, { children: [isProcessing && (_jsxs(Text, { color: colors.warning, children: [icons.spinner[spinnerFrame], " "] })), _jsxs(Text, { dimColor: true, children: [elapsed, " \u2502 "] }), _jsxs(Text, { color: colors.primary, children: ["\u2191 ", formatTokens(tokens), " tokens"] })] })] })] }));
39
+ };
40
+ export default StatusBar;
@@ -0,0 +1,6 @@
1
+ export { App } from './App.js';
2
+ export { Banner } from './Banner.js';
3
+ export { ChatMessage } from './ChatMessage.js';
4
+ export { Input } from './Input.js';
5
+ export { StatusBar } from './StatusBar.js';
6
+ export { RetroBox } from './Box.js';
@@ -0,0 +1,6 @@
1
+ export { App } from './App.js';
2
+ export { Banner } from './Banner.js';
3
+ export { ChatMessage } from './ChatMessage.js';
4
+ export { Input } from './Input.js';
5
+ export { StatusBar } from './StatusBar.js';
6
+ export { RetroBox } from './Box.js';
@@ -0,0 +1,10 @@
1
+ interface ClaudeResult {
2
+ response: string;
3
+ tokens: {
4
+ input: number;
5
+ output: number;
6
+ };
7
+ }
8
+ export declare function runClaude(prompt: string, mode: 'dev' | 'ml'): Promise<ClaudeResult>;
9
+ export declare function checkClaudeInstalled(): Promise<boolean>;
10
+ export {};
@@ -0,0 +1,113 @@
1
+ import { spawn } from 'child_process';
2
+ export async function runClaude(prompt, mode) {
3
+ return new Promise((resolve, reject) => {
4
+ const systemPrompt = getSystemPrompt(mode);
5
+ // Run claude with JSON output to capture tokens
6
+ const args = [
7
+ '--print',
8
+ '--output-format', 'json',
9
+ '--system-prompt', systemPrompt,
10
+ prompt
11
+ ];
12
+ const claude = spawn('claude', args, {
13
+ stdio: ['pipe', 'pipe', 'pipe'],
14
+ });
15
+ let stdout = '';
16
+ let stderr = '';
17
+ claude.stdout.on('data', (data) => {
18
+ stdout += data.toString();
19
+ });
20
+ claude.stderr.on('data', (data) => {
21
+ stderr += data.toString();
22
+ });
23
+ claude.on('close', (code) => {
24
+ if (code !== 0) {
25
+ reject(new Error(stderr || `Claude exited with code ${code}`));
26
+ return;
27
+ }
28
+ try {
29
+ // Try to parse as JSON
30
+ const result = parseClaudeOutput(stdout);
31
+ resolve(result);
32
+ }
33
+ catch (e) {
34
+ // If not JSON, return as plain text
35
+ resolve({
36
+ response: stdout.trim(),
37
+ tokens: { input: 0, output: 0 },
38
+ });
39
+ }
40
+ });
41
+ claude.on('error', (err) => {
42
+ reject(new Error(`Failed to start Claude: ${err.message}`));
43
+ });
44
+ });
45
+ }
46
+ function parseClaudeOutput(output) {
47
+ try {
48
+ const json = JSON.parse(output);
49
+ // Extract response text
50
+ let response = '';
51
+ if (json.result) {
52
+ response = json.result;
53
+ }
54
+ else if (json.content) {
55
+ if (Array.isArray(json.content)) {
56
+ response = json.content.map((c) => c.text || '').join('\n');
57
+ }
58
+ else {
59
+ response = json.content;
60
+ }
61
+ }
62
+ else if (json.text) {
63
+ response = json.text;
64
+ }
65
+ else {
66
+ response = output;
67
+ }
68
+ // Extract tokens
69
+ const tokens = {
70
+ input: json.usage?.input_tokens || json.inputTokens || json.stats?.input_tokens || 0,
71
+ output: json.usage?.output_tokens || json.outputTokens || json.stats?.output_tokens || 0,
72
+ };
73
+ return { response, tokens };
74
+ }
75
+ catch {
76
+ return {
77
+ response: output.trim(),
78
+ tokens: { input: 0, output: 0 },
79
+ };
80
+ }
81
+ }
82
+ function getSystemPrompt(mode) {
83
+ const today = new Date().toISOString().split('T')[0];
84
+ if (mode === 'ml') {
85
+ return `You are the Orchestrator agent in AGENT-K, a multi-agent system for ML research.
86
+ Today's date: ${today}
87
+
88
+ Your role is to:
89
+ 1. Analyze ML tasks and break them into subtasks
90
+ 2. Coordinate between Researcher, ML Engineer, Data Engineer, and Evaluator
91
+ 3. Ensure best practices in ML development
92
+ 4. Provide clear, actionable responses
93
+
94
+ Be concise and practical in your responses.`;
95
+ }
96
+ return `You are the Orchestrator agent in AGENT-K, a multi-agent system for software development.
97
+ Today's date: ${today}
98
+
99
+ Your role is to:
100
+ 1. Analyze development tasks and break them into subtasks
101
+ 2. Coordinate between Engineer, Tester, and Security agents
102
+ 3. Ensure code quality and security
103
+ 4. Provide clear, actionable responses
104
+
105
+ Be concise and practical in your responses.`;
106
+ }
107
+ export async function checkClaudeInstalled() {
108
+ return new Promise((resolve) => {
109
+ const claude = spawn('claude', ['--version'], { stdio: 'ignore' });
110
+ claude.on('close', (code) => resolve(code === 0));
111
+ claude.on('error', () => resolve(false));
112
+ });
113
+ }
@@ -0,0 +1,46 @@
1
+ export declare const colors: {
2
+ primary: string;
3
+ secondary: string;
4
+ accent: string;
5
+ warning: string;
6
+ error: string;
7
+ dim: string;
8
+ bg: string;
9
+ text: string;
10
+ };
11
+ export declare const box: {
12
+ topLeft: string;
13
+ topRight: string;
14
+ bottomLeft: string;
15
+ bottomRight: string;
16
+ horizontal: string;
17
+ vertical: string;
18
+ cross: string;
19
+ teeDown: string;
20
+ teeUp: string;
21
+ teeRight: string;
22
+ teeLeft: string;
23
+ };
24
+ export declare const boxDouble: {
25
+ topLeft: string;
26
+ topRight: string;
27
+ bottomLeft: string;
28
+ bottomRight: string;
29
+ horizontal: string;
30
+ vertical: string;
31
+ };
32
+ export declare const icons: {
33
+ star: string;
34
+ sparkle: string;
35
+ check: string;
36
+ cross: string;
37
+ arrow: string;
38
+ bullet: string;
39
+ circle: string;
40
+ spinner: string[];
41
+ lightning: string;
42
+ brain: string;
43
+ };
44
+ export declare const ascii: {
45
+ banner: string;
46
+ };
@@ -0,0 +1,52 @@
1
+ // AGENT-K Retro Theme
2
+ // Inspired by classic terminal aesthetics
3
+ export const colors = {
4
+ primary: '#00ff00', // Matrix green
5
+ secondary: '#00ffff', // Cyan
6
+ accent: '#ff00ff', // Magenta
7
+ warning: '#ffff00', // Yellow
8
+ error: '#ff0000', // Red
9
+ dim: '#666666', // Gray
10
+ bg: '#000000', // Black
11
+ text: '#ffffff', // White
12
+ };
13
+ export const box = {
14
+ topLeft: '╭',
15
+ topRight: '╮',
16
+ bottomLeft: '╰',
17
+ bottomRight: '╯',
18
+ horizontal: '─',
19
+ vertical: '│',
20
+ cross: '┼',
21
+ teeDown: '┬',
22
+ teeUp: '┴',
23
+ teeRight: '├',
24
+ teeLeft: '┤',
25
+ };
26
+ export const boxDouble = {
27
+ topLeft: '╔',
28
+ topRight: '╗',
29
+ bottomLeft: '╚',
30
+ bottomRight: '╝',
31
+ horizontal: '═',
32
+ vertical: '║',
33
+ };
34
+ export const icons = {
35
+ star: '✦',
36
+ sparkle: '✢',
37
+ check: '✓',
38
+ cross: '✗',
39
+ arrow: '→',
40
+ bullet: '●',
41
+ circle: '○',
42
+ spinner: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
43
+ lightning: '⚡',
44
+ brain: '🧠',
45
+ };
46
+ export const ascii = {
47
+ banner: `
48
+ ╔═══════════════════════════════════════════╗
49
+ ║ ✦ A G E N T - K ✦ ║
50
+ ║ Multi-Agent Claude Code Suite ║
51
+ ╚═══════════════════════════════════════════╝`,
52
+ };