@hive-org/cli 0.0.6 → 0.0.7
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/agent/analysis.js +78 -0
- package/dist/agent/app.js +32 -0
- package/dist/agent/chat-prompt.js +63 -0
- package/dist/agent/components/AsciiTicker.js +81 -0
- package/dist/agent/components/HoneycombBoot.js +270 -0
- package/dist/agent/components/Spinner.js +37 -0
- package/dist/agent/config.js +52 -0
- package/dist/agent/edit-section.js +59 -0
- package/dist/agent/fetch-rules.js +21 -0
- package/dist/agent/helpers.js +22 -0
- package/dist/agent/hooks/useAgent.js +269 -0
- package/{templates/memory-prompt.ts → dist/agent/memory-prompt.js} +17 -32
- package/dist/agent/model.js +63 -0
- package/dist/agent/objects.js +1 -0
- package/dist/agent/process-lifecycle.js +56 -0
- package/{templates/prompt.ts → dist/agent/prompt.js} +18 -47
- package/dist/agent/theme.js +37 -0
- package/dist/agent/types.js +1 -0
- package/dist/agents.js +30 -21
- package/dist/ai-providers.js +0 -13
- package/dist/create/generate.js +10 -120
- package/dist/index.js +27 -4
- package/dist/migrate-templates/MigrateApp.js +131 -0
- package/dist/migrate-templates/migrate.js +86 -0
- package/dist/start/AgentProcessManager.js +131 -0
- package/dist/start/Dashboard.js +88 -0
- package/dist/start/patch-headless.js +101 -0
- package/dist/start/patch-managed-mode.js +142 -0
- package/dist/start/start-command.js +22 -0
- package/package.json +6 -5
- package/templates/analysis.ts +0 -103
- package/templates/chat-prompt.ts +0 -94
- package/templates/components/AsciiTicker.tsx +0 -113
- package/templates/components/HoneycombBoot.tsx +0 -348
- package/templates/components/Spinner.tsx +0 -64
- package/templates/edit-section.ts +0 -64
- package/templates/fetch-rules.ts +0 -23
- package/templates/helpers.ts +0 -22
- package/templates/hive/agent.ts +0 -2
- package/templates/hive/config.ts +0 -96
- package/templates/hive/memory.ts +0 -1
- package/templates/hive/objects.ts +0 -26
- package/templates/hooks/useAgent.ts +0 -337
- package/templates/index.tsx +0 -257
- package/templates/process-lifecycle.ts +0 -66
- package/templates/theme.ts +0 -40
- package/templates/types.ts +0 -23
package/templates/index.tsx
DELETED
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { render, Box, Text } from 'ink';
|
|
3
|
-
import TextInput from 'ink-text-input';
|
|
4
|
-
import * as dotenv from 'dotenv';
|
|
5
|
-
import { useAgent } from './hooks/useAgent';
|
|
6
|
-
import { setupProcessLifecycle } from './process-lifecycle';
|
|
7
|
-
import { colors, symbols, border } from './theme';
|
|
8
|
-
import { formatTime, convictionColor } from './helpers';
|
|
9
|
-
import { Spinner, PollText } from './components/Spinner';
|
|
10
|
-
import { AsciiTicker } from './components/AsciiTicker';
|
|
11
|
-
import { HoneycombBoot } from './components/HoneycombBoot';
|
|
12
|
-
|
|
13
|
-
dotenv.config({ override: true });
|
|
14
|
-
|
|
15
|
-
// ─── Main TUI App ────────────────────────────────────
|
|
16
|
-
|
|
17
|
-
function AgentApp(): React.ReactElement {
|
|
18
|
-
const {
|
|
19
|
-
phase,
|
|
20
|
-
connected,
|
|
21
|
-
agentName,
|
|
22
|
-
pollActivity,
|
|
23
|
-
chatActivity,
|
|
24
|
-
input,
|
|
25
|
-
chatStreaming,
|
|
26
|
-
chatBuffer,
|
|
27
|
-
predictionCount,
|
|
28
|
-
termWidth,
|
|
29
|
-
setInput,
|
|
30
|
-
handleChatSubmit,
|
|
31
|
-
handleBootComplete,
|
|
32
|
-
} = useAgent();
|
|
33
|
-
|
|
34
|
-
if (phase === 'booting') {
|
|
35
|
-
return <HoneycombBoot agentName={agentName} width={termWidth} onComplete={handleBootComplete} />;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const boxWidth = termWidth;
|
|
39
|
-
const visiblePollActivity = pollActivity.slice(-10);
|
|
40
|
-
const visibleChatActivity = chatActivity.slice(-3);
|
|
41
|
-
|
|
42
|
-
const statsText =
|
|
43
|
-
predictionCount > 0 ? ` ${border.horizontal.repeat(3)} ${predictionCount} predicted` : '';
|
|
44
|
-
const connectedDisplay = connected ? 'Connected to the Hive' : 'connecting...';
|
|
45
|
-
const nameDisplay = `${agentName} agent`;
|
|
46
|
-
const headerFill = Math.max(
|
|
47
|
-
0,
|
|
48
|
-
boxWidth - nameDisplay.length - connectedDisplay.length - 12 - statsText.length,
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<Box flexDirection="column" width={boxWidth}>
|
|
53
|
-
{/* ASCII Ticker */}
|
|
54
|
-
<AsciiTicker rows={2} step={predictionCount} />
|
|
55
|
-
|
|
56
|
-
{/* Header */}
|
|
57
|
-
<Box>
|
|
58
|
-
<Text color={colors.honey}>{`${border.topLeft}${border.horizontal} ${symbols.hive} `}</Text>
|
|
59
|
-
<Text color="white" bold>
|
|
60
|
-
{agentName} agent
|
|
61
|
-
</Text>
|
|
62
|
-
<Text color="gray"> {`${border.horizontal.repeat(3)} `}</Text>
|
|
63
|
-
<Text color={connected ? 'green' : 'yellow'}>
|
|
64
|
-
{connected ? 'Connected to the Hive' : 'connecting...'}
|
|
65
|
-
</Text>
|
|
66
|
-
{statsText && <Text color="gray"> {`${border.horizontal.repeat(3)} `}</Text>}
|
|
67
|
-
{statsText && <Text color={colors.honey}>{predictionCount} predicted</Text>}
|
|
68
|
-
<Text color="gray">
|
|
69
|
-
{' '}
|
|
70
|
-
{border.horizontal.repeat(Math.max(0, headerFill))}
|
|
71
|
-
{border.topRight}
|
|
72
|
-
</Text>
|
|
73
|
-
</Box>
|
|
74
|
-
|
|
75
|
-
{/* Polling Feed */}
|
|
76
|
-
<Box flexDirection="column" paddingLeft={1} paddingRight={1} minHeight={8} maxHeight={24}>
|
|
77
|
-
{!connected && <Spinner label="Initiating neural link..." />}
|
|
78
|
-
{visiblePollActivity.map((item, i) => {
|
|
79
|
-
const isNewest = i === visiblePollActivity.length - 1 && item.type !== 'analyzing';
|
|
80
|
-
return (
|
|
81
|
-
<Box key={i} flexDirection="column">
|
|
82
|
-
{item.type === 'online' && (
|
|
83
|
-
<Box>
|
|
84
|
-
<Text color="gray" dimColor>
|
|
85
|
-
{formatTime(item.timestamp)}{' '}
|
|
86
|
-
</Text>
|
|
87
|
-
<Text color={colors.honey}>{symbols.hive} </Text>
|
|
88
|
-
<PollText color="white" text={item.text} animate={isNewest} />
|
|
89
|
-
</Box>
|
|
90
|
-
)}
|
|
91
|
-
{item.type === 'signal' && (
|
|
92
|
-
<Box>
|
|
93
|
-
<Text color="gray" dimColor>
|
|
94
|
-
{formatTime(item.timestamp)}{' '}
|
|
95
|
-
</Text>
|
|
96
|
-
<Text color={colors.honey}>{symbols.hive} </Text>
|
|
97
|
-
<PollText color="cyan" text={item.text} animate={isNewest} />
|
|
98
|
-
</Box>
|
|
99
|
-
)}
|
|
100
|
-
{item.type === 'signal' && item.detail && (
|
|
101
|
-
<Box marginLeft={13}>
|
|
102
|
-
<PollText color="gray" text={`"${item.detail}"`} animate={isNewest} />
|
|
103
|
-
</Box>
|
|
104
|
-
)}
|
|
105
|
-
{item.type === 'analyzing' && (
|
|
106
|
-
<Box marginLeft={13}>
|
|
107
|
-
<Spinner label={item.text} />
|
|
108
|
-
</Box>
|
|
109
|
-
)}
|
|
110
|
-
{item.type === 'posted' && (
|
|
111
|
-
<Box>
|
|
112
|
-
<Text color="gray" dimColor>
|
|
113
|
-
{formatTime(item.timestamp)}{' '}
|
|
114
|
-
</Text>
|
|
115
|
-
<Text color={convictionColor(item.conviction ?? 0)}>
|
|
116
|
-
{symbols.diamond} Predicted{' '}
|
|
117
|
-
</Text>
|
|
118
|
-
<PollText color="white" text={item.text} animate={isNewest} />
|
|
119
|
-
</Box>
|
|
120
|
-
)}
|
|
121
|
-
{item.type === 'skipped' && (
|
|
122
|
-
<Box>
|
|
123
|
-
<Text color="gray" dimColor>
|
|
124
|
-
{formatTime(item.timestamp)}{' '}
|
|
125
|
-
</Text>
|
|
126
|
-
<PollText
|
|
127
|
-
color="yellow"
|
|
128
|
-
text={`${symbols.diamondOpen} ${item.text}`}
|
|
129
|
-
animate={isNewest}
|
|
130
|
-
/>
|
|
131
|
-
</Box>
|
|
132
|
-
)}
|
|
133
|
-
{item.type === 'error' && (
|
|
134
|
-
<Box>
|
|
135
|
-
<Text color="gray" dimColor>
|
|
136
|
-
{formatTime(item.timestamp)}{' '}
|
|
137
|
-
</Text>
|
|
138
|
-
<PollText
|
|
139
|
-
color="red"
|
|
140
|
-
text={`${symbols.cross} ${item.text}`}
|
|
141
|
-
animate={isNewest}
|
|
142
|
-
/>
|
|
143
|
-
</Box>
|
|
144
|
-
)}
|
|
145
|
-
{item.type === 'idle' && (
|
|
146
|
-
<Box>
|
|
147
|
-
<Text color="gray" dimColor>
|
|
148
|
-
{formatTime(item.timestamp)}{' '}
|
|
149
|
-
</Text>
|
|
150
|
-
<PollText
|
|
151
|
-
color="gray"
|
|
152
|
-
text={`${symbols.circle} ${item.text}`}
|
|
153
|
-
animate={isNewest}
|
|
154
|
-
/>
|
|
155
|
-
</Box>
|
|
156
|
-
)}
|
|
157
|
-
</Box>
|
|
158
|
-
);
|
|
159
|
-
})}
|
|
160
|
-
</Box>
|
|
161
|
-
|
|
162
|
-
{/* Chat section - visible after first message */}
|
|
163
|
-
{(chatActivity.length > 0 || chatStreaming) && (
|
|
164
|
-
<>
|
|
165
|
-
<Box>
|
|
166
|
-
<Text color="gray">
|
|
167
|
-
{border.teeLeft}
|
|
168
|
-
{`${border.horizontal.repeat(2)} chat with ${agentName} agent `}
|
|
169
|
-
{border.horizontal.repeat(Math.max(0, boxWidth - agentName.length - 22))}
|
|
170
|
-
{border.teeRight}
|
|
171
|
-
</Text>
|
|
172
|
-
</Box>
|
|
173
|
-
<Box flexDirection="column" paddingLeft={1} paddingRight={1} minHeight={2} maxHeight={8}>
|
|
174
|
-
{visibleChatActivity.map((item, i) => (
|
|
175
|
-
<Box key={i}>
|
|
176
|
-
{item.type === 'chat-user' && (
|
|
177
|
-
<Box>
|
|
178
|
-
<Text color="white" bold>
|
|
179
|
-
you:{' '}
|
|
180
|
-
</Text>
|
|
181
|
-
<Text color="white">{item.text}</Text>
|
|
182
|
-
</Box>
|
|
183
|
-
)}
|
|
184
|
-
{item.type === 'chat-agent' && (
|
|
185
|
-
<Box>
|
|
186
|
-
<Text color={colors.honey} bold>
|
|
187
|
-
{agentName} agent:{' '}
|
|
188
|
-
</Text>
|
|
189
|
-
<Text color="white" wrap="wrap">
|
|
190
|
-
{item.text}
|
|
191
|
-
</Text>
|
|
192
|
-
</Box>
|
|
193
|
-
)}
|
|
194
|
-
{item.type === 'chat-error' && (
|
|
195
|
-
<Box>
|
|
196
|
-
<Text color="red">
|
|
197
|
-
{symbols.cross} {item.text}
|
|
198
|
-
</Text>
|
|
199
|
-
</Box>
|
|
200
|
-
)}
|
|
201
|
-
</Box>
|
|
202
|
-
))}
|
|
203
|
-
{chatStreaming && chatBuffer && (
|
|
204
|
-
<Box>
|
|
205
|
-
<Text color={colors.honey} bold>
|
|
206
|
-
{agentName} agent:{' '}
|
|
207
|
-
</Text>
|
|
208
|
-
<Text color="white" wrap="wrap">
|
|
209
|
-
{chatBuffer}
|
|
210
|
-
</Text>
|
|
211
|
-
</Box>
|
|
212
|
-
)}
|
|
213
|
-
</Box>
|
|
214
|
-
</>
|
|
215
|
-
)}
|
|
216
|
-
|
|
217
|
-
{/* Input Bar */}
|
|
218
|
-
<Box>
|
|
219
|
-
<Text color="gray">
|
|
220
|
-
{border.teeLeft}
|
|
221
|
-
{border.horizontal.repeat(boxWidth - 2)}
|
|
222
|
-
{border.teeRight}
|
|
223
|
-
</Text>
|
|
224
|
-
</Box>
|
|
225
|
-
<Box paddingLeft={1}>
|
|
226
|
-
<Text color={colors.honey}>{symbols.arrow} </Text>
|
|
227
|
-
<TextInput
|
|
228
|
-
value={input}
|
|
229
|
-
onChange={setInput}
|
|
230
|
-
onSubmit={(val) => {
|
|
231
|
-
setInput('');
|
|
232
|
-
void handleChatSubmit(val);
|
|
233
|
-
}}
|
|
234
|
-
placeholder={chatStreaming ? 'thinking...' : `chat with ${agentName} agent...`}
|
|
235
|
-
/>
|
|
236
|
-
</Box>
|
|
237
|
-
<Box>
|
|
238
|
-
<Text color="gray">
|
|
239
|
-
{border.bottomLeft}
|
|
240
|
-
{border.horizontal.repeat(boxWidth - 2)}
|
|
241
|
-
{border.bottomRight}
|
|
242
|
-
</Text>
|
|
243
|
-
</Box>
|
|
244
|
-
</Box>
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// ─── Entrypoint ──────────────────────────────────────
|
|
249
|
-
|
|
250
|
-
setupProcessLifecycle();
|
|
251
|
-
|
|
252
|
-
const app = render(React.createElement(AgentApp));
|
|
253
|
-
|
|
254
|
-
process.stdout.on('resize', () => {
|
|
255
|
-
process.stdout.write('\x1b[2J\x1b[H');
|
|
256
|
-
app.clear();
|
|
257
|
-
});
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { symbols } from './theme';
|
|
3
|
-
|
|
4
|
-
type ShutdownFn = () => Promise<void>;
|
|
5
|
-
|
|
6
|
-
let _shutdownAgent: ShutdownFn | null = null;
|
|
7
|
-
let _shuttingDown = false;
|
|
8
|
-
|
|
9
|
-
export function registerShutdownAgent(fn: ShutdownFn): void {
|
|
10
|
-
_shutdownAgent = fn;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function clearShutdownAgent(): void {
|
|
14
|
-
_shutdownAgent = null;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const restoreScreen = (): void => {
|
|
18
|
-
process.stdout.write('\x1b[?1049l');
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const gracefulShutdown = async (): Promise<void> => {
|
|
22
|
-
if (_shuttingDown) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
_shuttingDown = true;
|
|
26
|
-
|
|
27
|
-
if (_shutdownAgent) {
|
|
28
|
-
try {
|
|
29
|
-
await _shutdownAgent();
|
|
30
|
-
} catch {
|
|
31
|
-
// Best-effort memory save on shutdown
|
|
32
|
-
}
|
|
33
|
-
_shutdownAgent = null;
|
|
34
|
-
}
|
|
35
|
-
restoreScreen();
|
|
36
|
-
process.exit(0);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export function setupProcessLifecycle(): void {
|
|
40
|
-
// Unhandled rejection handler
|
|
41
|
-
process.on('unhandledRejection', (reason) => {
|
|
42
|
-
const raw = reason instanceof Error ? reason.message : String(reason);
|
|
43
|
-
const message = raw.length > 200 ? raw.slice(0, 200) + '\u2026' : raw;
|
|
44
|
-
console.error(chalk.red(` ${symbols.cross} Unhandled: ${message}`));
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// Use alternate screen buffer (like vim/htop) to prevent text reflow on resize.
|
|
48
|
-
// The normal buffer reflows wrapped lines when the terminal width changes, which
|
|
49
|
-
// desyncs Ink's internal line counter and produces ghost copies of the UI.
|
|
50
|
-
// The alternate buffer is position-based — no reflow, no ghosts.
|
|
51
|
-
process.stdout.write('\x1b[?1049h');
|
|
52
|
-
|
|
53
|
-
process.on('exit', restoreScreen);
|
|
54
|
-
process.on('SIGINT', () => {
|
|
55
|
-
gracefulShutdown().catch(() => {
|
|
56
|
-
restoreScreen();
|
|
57
|
-
process.exit(1);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
process.on('SIGTERM', () => {
|
|
61
|
-
gracefulShutdown().catch(() => {
|
|
62
|
-
restoreScreen();
|
|
63
|
-
process.exit(1);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
}
|
package/templates/theme.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
export const colors = {
|
|
2
|
-
honey: '#F5A623',
|
|
3
|
-
honeyDark: '#D4891A',
|
|
4
|
-
white: '#FFFFFF',
|
|
5
|
-
gray: '#888888',
|
|
6
|
-
grayDim: '#555555',
|
|
7
|
-
green: '#4CAF50',
|
|
8
|
-
red: '#F44336',
|
|
9
|
-
cyan: '#00BCD4',
|
|
10
|
-
} as const;
|
|
11
|
-
|
|
12
|
-
export const symbols = {
|
|
13
|
-
hive: '\u2B21', // ⬡
|
|
14
|
-
diamond: '\u25C6', // ◆
|
|
15
|
-
diamondOpen: '\u25C7', // ◇
|
|
16
|
-
dot: '\u25CF', // ●
|
|
17
|
-
check: '\u2713', // ✓
|
|
18
|
-
cross: '\u2717', // ✗
|
|
19
|
-
arrow: '\u203A', // ›
|
|
20
|
-
circle: '\u25CB', // ○
|
|
21
|
-
} as const;
|
|
22
|
-
|
|
23
|
-
export const border = {
|
|
24
|
-
horizontal: '\u2500', // ─
|
|
25
|
-
vertical: '\u2502', // │
|
|
26
|
-
topLeft: '\u250C', // ┌
|
|
27
|
-
topRight: '\u2510', // ┐
|
|
28
|
-
bottomLeft: '\u2514', // └
|
|
29
|
-
bottomRight: '\u2518', // ┘
|
|
30
|
-
teeLeft: '\u251C', // ├
|
|
31
|
-
teeRight: '\u2524', // ┤
|
|
32
|
-
} as const;
|
|
33
|
-
|
|
34
|
-
export const animation = {
|
|
35
|
-
DATA_CHARS: '01\u25AA\u25AB\u2591\u2592',
|
|
36
|
-
HEX_CHARS: '\u2B21\u2B22',
|
|
37
|
-
TICK_MS: 120,
|
|
38
|
-
HEX_W: 8,
|
|
39
|
-
HEX_H: 4,
|
|
40
|
-
} as const;
|
package/templates/types.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export type PollActivityType =
|
|
2
|
-
| 'signal'
|
|
3
|
-
| 'analyzing'
|
|
4
|
-
| 'posted'
|
|
5
|
-
| 'skipped'
|
|
6
|
-
| 'error'
|
|
7
|
-
| 'idle'
|
|
8
|
-
| 'online';
|
|
9
|
-
export type ChatActivityType = 'chat-user' | 'chat-agent' | 'chat-error';
|
|
10
|
-
|
|
11
|
-
export interface PollActivityItem {
|
|
12
|
-
type: PollActivityType;
|
|
13
|
-
text: string;
|
|
14
|
-
detail?: string;
|
|
15
|
-
conviction?: number;
|
|
16
|
-
timestamp: Date;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface ChatActivityItem {
|
|
20
|
-
type: ChatActivityType;
|
|
21
|
-
text: string;
|
|
22
|
-
timestamp: Date;
|
|
23
|
-
}
|