@zhive/cli 0.5.5 → 0.6.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/README.md +5 -5
- package/dist/CLAUDE.md +7 -0
- package/dist/backtest/CLAUDE.md +7 -0
- package/dist/cli.js +20 -0
- package/dist/commands/agent/commands/index.js +7 -0
- package/dist/commands/agent/commands/profile.js +40 -0
- package/dist/commands/agent/commands/profile.test.js +137 -0
- package/dist/commands/create/commands/index.js +10 -5
- package/dist/commands/list/commands/index.js +8 -3
- package/dist/commands/megathread/commands/create-comment.js +99 -0
- package/dist/commands/megathread/commands/create-comment.test.js +480 -0
- package/dist/commands/megathread/commands/index.js +9 -0
- package/dist/commands/megathread/commands/list.js +102 -0
- package/dist/commands/megathread/commands/list.test.js +206 -0
- package/dist/commands/migrate-templates/commands/index.js +9 -4
- package/dist/commands/run/commands/index.js +17 -12
- package/dist/commands/run/run-headless.js +2 -1
- package/dist/commands/start/commands/index.js +37 -32
- package/dist/commands/start/hooks/useAgent.js +2 -1
- package/dist/commands/start/services/backtest/runner.js +1 -1
- package/dist/commands/start-all/commands/index.js +22 -17
- package/dist/index.js +26 -57
- package/dist/{agent → services/agent}/analysis.js +5 -5
- package/dist/{load-agent-env.js → services/agent/env.js} +1 -1
- package/dist/{agent → services/agent/helpers}/model.js +2 -2
- package/dist/{agent → services/agent/prompts}/memory-prompt.js +20 -22
- package/dist/{agent → services/agent/prompts}/prompt.js +80 -54
- package/dist/{agent → services/agent}/tools/market/client.js +1 -1
- package/dist/{agent → services/agent}/tools/mindshare/client.js +1 -1
- package/dist/{agents.js → services/config/agent.js} +2 -2
- package/dist/{config.js → services/config/config.js} +1 -7
- package/dist/services/config/constant.js +8 -0
- package/dist/shared/agent/config.js +75 -0
- package/dist/shared/agent/env.js +30 -0
- package/dist/shared/agent/handler.js +129 -0
- package/dist/shared/agent/helpers/model.js +92 -0
- package/dist/shared/agent/runtime.js +15 -0
- package/dist/shared/ai-providers.js +66 -0
- package/dist/shared/config/agent.js +19 -0
- package/dist/shared/config/agent.test.js +115 -0
- package/package.json +4 -3
- package/dist/agent/app.js +0 -122
- package/dist/agent/commands/registry.js +0 -12
- package/dist/agent/components/AsciiTicker.js +0 -81
- package/dist/agent/components/CommandInput.js +0 -65
- package/dist/agent/components/HoneycombBoot.js +0 -291
- package/dist/agent/components/Spinner.js +0 -37
- package/dist/agent/hooks/useAgent.js +0 -480
- package/dist/agent/objects.js +0 -1
- package/dist/agent/process-lifecycle.js +0 -18
- package/dist/agent/run-headless.js +0 -189
- package/dist/agent/theme.js +0 -41
- package/dist/avatar.js +0 -34
- package/dist/backtest/default-backtest-data.js +0 -200
- package/dist/backtest/fetch.js +0 -41
- package/dist/backtest/import.js +0 -106
- package/dist/backtest/index.js +0 -10
- package/dist/backtest/results.js +0 -113
- package/dist/backtest/runner.js +0 -134
- package/dist/backtest/storage.js +0 -11
- package/dist/backtest/types.js +0 -1
- package/dist/commands/install.js +0 -50
- package/dist/commands/start/ui/PollText.js +0 -23
- package/dist/commands/start/ui/PredictionsPanel.js +0 -88
- package/dist/commands/start/ui/SpinnerContext.js +0 -20
- package/dist/components/InputGuard.js +0 -6
- package/dist/components/stdout-spinner.js +0 -48
- package/dist/create/CreateApp.js +0 -153
- package/dist/create/ai-generate.js +0 -147
- package/dist/create/generate.js +0 -73
- package/dist/create/steps/ApiKeyStep.js +0 -97
- package/dist/create/steps/AvatarStep.js +0 -16
- package/dist/create/steps/BioStep.js +0 -14
- package/dist/create/steps/DoneStep.js +0 -14
- package/dist/create/steps/IdentityStep.js +0 -163
- package/dist/create/steps/NameStep.js +0 -71
- package/dist/create/steps/ScaffoldStep.js +0 -58
- package/dist/create/steps/SoulStep.js +0 -58
- package/dist/create/steps/StrategyStep.js +0 -58
- package/dist/create/validate-api-key.js +0 -47
- package/dist/create/welcome.js +0 -304
- package/dist/list/ListApp.js +0 -79
- package/dist/migrate-templates/MigrateApp.js +0 -131
- package/dist/migrate-templates/migrate.js +0 -86
- package/dist/presets.js +0 -613
- package/dist/start/AgentProcessManager.js +0 -98
- package/dist/start/Dashboard.js +0 -92
- package/dist/start/SelectAgentApp.js +0 -81
- package/dist/start/StartApp.js +0 -189
- package/dist/start/patch-headless.js +0 -101
- package/dist/start/patch-managed-mode.js +0 -142
- package/dist/start/start-command.js +0 -24
- package/dist/theme.js +0 -54
- /package/dist/{agent → services/agent}/config.js +0 -0
- /package/dist/{agent → services/agent}/helpers.js +0 -0
- /package/dist/{agent → services/agent/prompts}/chat-prompt.js +0 -0
- /package/dist/{agent → services/agent}/skills/index.js +0 -0
- /package/dist/{agent → services/agent}/skills/skill-parser.js +0 -0
- /package/dist/{agent → services/agent}/skills/types.js +0 -0
- /package/dist/{agent → services/agent/tools}/edit-section.js +0 -0
- /package/dist/{agent → services/agent/tools}/fetch-rules.js +0 -0
- /package/dist/{agent → services/agent}/tools/index.js +0 -0
- /package/dist/{agent → services/agent}/tools/market/index.js +0 -0
- /package/dist/{agent → services/agent}/tools/market/tools.js +0 -0
- /package/dist/{agent → services/agent}/tools/mindshare/index.js +0 -0
- /package/dist/{agent → services/agent}/tools/mindshare/tools.js +0 -0
- /package/dist/{agent → services/agent}/tools/read-skill-tool.js +0 -0
- /package/dist/{agent → services/agent}/tools/ta/index.js +0 -0
- /package/dist/{agent → services/agent}/tools/ta/indicators.js +0 -0
- /package/dist/{agent → services/agent}/types.js +0 -0
- /package/dist/{ai-providers.js → services/ai-providers.js} +0 -0
package/dist/backtest/results.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Format a number with sign for display.
|
|
3
|
-
*/
|
|
4
|
-
export function formatConviction(value) {
|
|
5
|
-
const sign = value >= 0 ? '+' : '';
|
|
6
|
-
const formatted = `${sign}${value.toFixed(2)}%`;
|
|
7
|
-
return formatted;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Format a percentage for display.
|
|
11
|
-
*/
|
|
12
|
-
export function formatPercentage(value) {
|
|
13
|
-
const formatted = `${value.toFixed(1)}%`;
|
|
14
|
-
return formatted;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Get direction indicator.
|
|
18
|
-
*/
|
|
19
|
-
export function getDirectionIndicator(conviction) {
|
|
20
|
-
if (conviction > 0) {
|
|
21
|
-
return 'bullish';
|
|
22
|
-
}
|
|
23
|
-
if (conviction < 0) {
|
|
24
|
-
return 'bearish';
|
|
25
|
-
}
|
|
26
|
-
return 'neutral';
|
|
27
|
-
}
|
|
28
|
-
export function formatThreadResult(result) {
|
|
29
|
-
if (result.skipped) {
|
|
30
|
-
return {
|
|
31
|
-
index: result.thread_index + 1,
|
|
32
|
-
projectName: result.project_name,
|
|
33
|
-
predicted: 'SKIP',
|
|
34
|
-
actual: formatConviction(result.actual_price_change_percent),
|
|
35
|
-
direction: 'skipped',
|
|
36
|
-
error: '-',
|
|
37
|
-
summary: '(skipped)',
|
|
38
|
-
thread_text: result.thread_text,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
const directionLabel = result.direction_correct ? 'correct' : 'incorrect';
|
|
42
|
-
return {
|
|
43
|
-
index: result.thread_index + 1,
|
|
44
|
-
projectName: result.project_name,
|
|
45
|
-
predicted: formatConviction(result.predicted_conviction),
|
|
46
|
-
actual: formatConviction(result.actual_price_change_percent),
|
|
47
|
-
direction: directionLabel,
|
|
48
|
-
error: result.absolute_error !== null ? result.absolute_error.toFixed(2) : '-',
|
|
49
|
-
summary: result.predicted_summary.slice(0, 200) + (result.predicted_summary.length > 200 ? '...' : ''),
|
|
50
|
-
thread_text: result.thread_text.slice(0, 100) + (result.thread_text.length > 100 ? '...' : ''),
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
export function formatSummary(result) {
|
|
54
|
-
return {
|
|
55
|
-
agentName: result.agent_name,
|
|
56
|
-
backtestId: result.backtest_id,
|
|
57
|
-
totalThreads: result.total_threads,
|
|
58
|
-
threadsPredicted: result.threads_predicted,
|
|
59
|
-
threadsSkipped: result.threads_skipped,
|
|
60
|
-
directionAccuracy: formatPercentage(result.direction_accuracy),
|
|
61
|
-
meanAbsoluteError: result.mean_absolute_error.toFixed(2),
|
|
62
|
-
runAt: new Date(result.run_at).toLocaleString(),
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Get accuracy grade based on direction accuracy percentage.
|
|
67
|
-
*/
|
|
68
|
-
export function getAccuracyGrade(accuracy) {
|
|
69
|
-
if (accuracy >= 70) {
|
|
70
|
-
return { grade: 'A', color: 'green' };
|
|
71
|
-
}
|
|
72
|
-
if (accuracy >= 60) {
|
|
73
|
-
return { grade: 'B', color: 'green' };
|
|
74
|
-
}
|
|
75
|
-
if (accuracy >= 50) {
|
|
76
|
-
return { grade: 'C', color: 'honey' };
|
|
77
|
-
}
|
|
78
|
-
if (accuracy >= 40) {
|
|
79
|
-
return { grade: 'D', color: 'red' };
|
|
80
|
-
}
|
|
81
|
-
return { grade: 'F', color: 'red' };
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Build a text report of the backtest results.
|
|
85
|
-
*/
|
|
86
|
-
export function buildTextReport(result) {
|
|
87
|
-
const lines = [];
|
|
88
|
-
const summary = formatSummary(result);
|
|
89
|
-
lines.push(`Backtest Results: ${summary.backtestId}`);
|
|
90
|
-
lines.push(`Agent: ${summary.agentName}`);
|
|
91
|
-
lines.push(`Run at: ${summary.runAt}`);
|
|
92
|
-
lines.push('');
|
|
93
|
-
lines.push('--- Summary ---');
|
|
94
|
-
lines.push(`Total threads: ${summary.totalThreads}`);
|
|
95
|
-
lines.push(`Predictions made: ${summary.threadsPredicted}`);
|
|
96
|
-
lines.push(`Skipped: ${summary.threadsSkipped}`);
|
|
97
|
-
lines.push(`Direction accuracy: ${summary.directionAccuracy}`);
|
|
98
|
-
lines.push(`Mean absolute error: ${summary.meanAbsoluteError}`);
|
|
99
|
-
lines.push('');
|
|
100
|
-
lines.push('--- Per-Thread Results ---');
|
|
101
|
-
for (const threadResult of result.thread_results) {
|
|
102
|
-
const formatted = formatThreadResult(threadResult);
|
|
103
|
-
const directionSymbol = formatted.direction === 'correct'
|
|
104
|
-
? '[OK]'
|
|
105
|
-
: formatted.direction === 'skipped'
|
|
106
|
-
? '[--]'
|
|
107
|
-
: '[XX]';
|
|
108
|
-
lines.push(`#${formatted.index} ${formatted.projectName}: Predicted ${formatted.predicted}, Actual ${formatted.actual} ${directionSymbol}`);
|
|
109
|
-
lines.push(`\tThread: ${formatted.thread_text}`);
|
|
110
|
-
lines.push(`\tSummary: ${formatted.summary}`);
|
|
111
|
-
}
|
|
112
|
-
return lines.join('\n');
|
|
113
|
-
}
|
package/dist/backtest/runner.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { processSignalAndSummarize } from '../agent/analysis.js';
|
|
2
|
-
import { loadMemory } from '@hive-org/sdk';
|
|
3
|
-
import { getAllTools, initializeSkills, getSkillMetadataList, getReadSkillTool, } from '../agent/tools/index.js';
|
|
4
|
-
/**
|
|
5
|
-
* Run a backtest against an agent configuration.
|
|
6
|
-
*/
|
|
7
|
-
export async function runBacktest(backtest, config, callbacks) {
|
|
8
|
-
const { agentPath, soulContent, strategyContent, agentName } = config;
|
|
9
|
-
const threads = backtest.threads;
|
|
10
|
-
const results = [];
|
|
11
|
-
// Load agent tools and skills
|
|
12
|
-
const baseTools = getAllTools();
|
|
13
|
-
const skillRegistry = await initializeSkills(agentPath);
|
|
14
|
-
const tools = { ...baseTools };
|
|
15
|
-
if (skillRegistry.size > 0) {
|
|
16
|
-
tools['readSkill'] = getReadSkillTool(skillRegistry);
|
|
17
|
-
}
|
|
18
|
-
const availableSkills = getSkillMetadataList(skillRegistry) || undefined;
|
|
19
|
-
// Load memory once (static for backtest)
|
|
20
|
-
const memory = await loadMemory();
|
|
21
|
-
for (let i = 0; i < threads.length; i++) {
|
|
22
|
-
const thread = threads[i];
|
|
23
|
-
callbacks?.onThreadStart?.(i, threads.length, thread);
|
|
24
|
-
// Convert BacktestThread to ThreadDto format (without price_on_eval)
|
|
25
|
-
const threadDto = convertToThreadDto(thread, i);
|
|
26
|
-
// Run analysis
|
|
27
|
-
const analysisResult = await processSignalAndSummarize(threadDto, [], // No recent comments in backtest
|
|
28
|
-
memory, soulContent, strategyContent, tools, availableSkills);
|
|
29
|
-
// Calculate actual price change
|
|
30
|
-
const actualPriceChangePercent = calculatePriceChange(thread.price_on_fetch, thread.price_on_eval);
|
|
31
|
-
// Build result
|
|
32
|
-
const result = buildThreadResult(i, thread, analysisResult, actualPriceChangePercent);
|
|
33
|
-
results.push(result);
|
|
34
|
-
callbacks?.onThreadComplete?.(i, result);
|
|
35
|
-
}
|
|
36
|
-
// Calculate summary statistics
|
|
37
|
-
const runResult = buildRunResult(backtest.metadata.id, agentName, results);
|
|
38
|
-
return runResult;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Convert a BacktestThread to ThreadDto format for the agent.
|
|
42
|
-
* Strips price_on_eval since the agent shouldn't see the outcome.
|
|
43
|
-
*/
|
|
44
|
-
function convertToThreadDto(thread, index) {
|
|
45
|
-
const dto = {
|
|
46
|
-
id: `backtest-thread-${index}`,
|
|
47
|
-
pollen_id: `backtest-pollen-${index}`,
|
|
48
|
-
project_id: thread.project_id,
|
|
49
|
-
project_name: thread.project_name,
|
|
50
|
-
project_categories: thread.project_categories,
|
|
51
|
-
project_description: thread.project_description,
|
|
52
|
-
project_symbol: thread.project_symbol,
|
|
53
|
-
price_on_eval: thread.price_on_eval,
|
|
54
|
-
text: thread.text,
|
|
55
|
-
timestamp: thread.timestamp,
|
|
56
|
-
locked: false,
|
|
57
|
-
created_at: thread.timestamp,
|
|
58
|
-
updated_at: thread.timestamp,
|
|
59
|
-
price_on_fetch: thread.price_on_fetch,
|
|
60
|
-
// Intentionally omitting price_on_eval - agent should not see outcome
|
|
61
|
-
citations: thread.citations,
|
|
62
|
-
};
|
|
63
|
-
return dto;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Calculate percentage price change.
|
|
67
|
-
*/
|
|
68
|
-
function calculatePriceChange(priceOnFetch, priceOnEval) {
|
|
69
|
-
const change = ((priceOnEval - priceOnFetch) / priceOnFetch) * 100;
|
|
70
|
-
return change;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Build a thread result from analysis output.
|
|
74
|
-
*/
|
|
75
|
-
function buildThreadResult(index, thread, analysis, actualPriceChangePercent) {
|
|
76
|
-
if (analysis.skip) {
|
|
77
|
-
return {
|
|
78
|
-
thread_index: index,
|
|
79
|
-
project_id: thread.project_id,
|
|
80
|
-
project_name: thread.project_name,
|
|
81
|
-
thread_text: thread.text,
|
|
82
|
-
predicted_conviction: 0,
|
|
83
|
-
predicted_summary: '',
|
|
84
|
-
skipped: true,
|
|
85
|
-
actual_price_change_percent: actualPriceChangePercent,
|
|
86
|
-
direction_correct: null,
|
|
87
|
-
absolute_error: null,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
// Determine direction correctness
|
|
91
|
-
const predictedDirection = Math.sign(analysis.conviction);
|
|
92
|
-
const actualDirection = Math.sign(actualPriceChangePercent);
|
|
93
|
-
const directionCorrect = predictedDirection === actualDirection;
|
|
94
|
-
// Calculate absolute error
|
|
95
|
-
const absoluteError = Math.abs(analysis.conviction - actualPriceChangePercent);
|
|
96
|
-
return {
|
|
97
|
-
thread_index: index,
|
|
98
|
-
project_id: thread.project_id,
|
|
99
|
-
project_name: thread.project_name,
|
|
100
|
-
thread_text: thread.text,
|
|
101
|
-
predicted_conviction: analysis.conviction,
|
|
102
|
-
predicted_summary: analysis.summary,
|
|
103
|
-
skipped: false,
|
|
104
|
-
actual_price_change_percent: actualPriceChangePercent,
|
|
105
|
-
direction_correct: directionCorrect,
|
|
106
|
-
absolute_error: absoluteError,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Build the final run result with summary statistics.
|
|
111
|
-
*/
|
|
112
|
-
function buildRunResult(backtestId, agentName, results) {
|
|
113
|
-
const totalThreads = results.length;
|
|
114
|
-
const predictedResults = results.filter((r) => !r.skipped);
|
|
115
|
-
const threadsPredicted = predictedResults.length;
|
|
116
|
-
const threadsSkipped = totalThreads - threadsPredicted;
|
|
117
|
-
// Calculate direction accuracy
|
|
118
|
-
const correctDirections = predictedResults.filter((r) => r.direction_correct === true).length;
|
|
119
|
-
const directionAccuracy = threadsPredicted > 0 ? (correctDirections / threadsPredicted) * 100 : 0;
|
|
120
|
-
// Calculate mean absolute error
|
|
121
|
-
const totalError = predictedResults.reduce((sum, r) => sum + (r.absolute_error ?? 0), 0);
|
|
122
|
-
const meanAbsoluteError = threadsPredicted > 0 ? totalError / threadsPredicted : 0;
|
|
123
|
-
return {
|
|
124
|
-
backtest_id: backtestId,
|
|
125
|
-
agent_name: agentName,
|
|
126
|
-
run_at: new Date().toISOString(),
|
|
127
|
-
thread_results: results,
|
|
128
|
-
total_threads: totalThreads,
|
|
129
|
-
threads_predicted: threadsPredicted,
|
|
130
|
-
threads_skipped: threadsSkipped,
|
|
131
|
-
direction_accuracy: directionAccuracy,
|
|
132
|
-
mean_absolute_error: meanAbsoluteError,
|
|
133
|
-
};
|
|
134
|
-
}
|
package/dist/backtest/storage.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_BACKTEST_DATA } from './default-backtest-data.js';
|
|
2
|
-
/**
|
|
3
|
-
* ID for the bundled default backtest dataset.
|
|
4
|
-
*/
|
|
5
|
-
export const DEFAULT_BACKTEST_ID = 'default';
|
|
6
|
-
/**
|
|
7
|
-
* Load the bundled default backtest dataset.
|
|
8
|
-
*/
|
|
9
|
-
export function loadDefaultBacktest() {
|
|
10
|
-
return DEFAULT_BACKTEST_DATA;
|
|
11
|
-
}
|
package/dist/backtest/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/commands/install.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { exec } from 'child_process';
|
|
3
|
-
import { promisify } from 'util';
|
|
4
|
-
import fs from 'fs-extra';
|
|
5
|
-
import path from 'path';
|
|
6
|
-
import { fileURLToPath } from 'url';
|
|
7
|
-
const execAsync = promisify(exec);
|
|
8
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
export async function install(targetDir = process.cwd(), options = {}) {
|
|
10
|
-
const packageJsonPath = path.join(targetDir, 'package.json');
|
|
11
|
-
if (!fs.existsSync(packageJsonPath)) {
|
|
12
|
-
throw new Error('No package.json found. Please run this command in the root of your project.');
|
|
13
|
-
}
|
|
14
|
-
console.log(chalk.blue('Installing Hive bootstrap...'));
|
|
15
|
-
const dir = path.join(targetDir, 'hive');
|
|
16
|
-
await fs.ensureDir(dir);
|
|
17
|
-
const templatesDir = path.resolve(__dirname, '../../templates/hive');
|
|
18
|
-
if (!fs.existsSync(templatesDir)) {
|
|
19
|
-
throw new Error(`Templates directory not found at ${templatesDir}`);
|
|
20
|
-
}
|
|
21
|
-
await fs.copy(templatesDir, dir);
|
|
22
|
-
console.log(chalk.green('\u2713 Bootstrap code copied to hive/'));
|
|
23
|
-
// Hive dependencies: @hive-org/sdk (and dotenv if missing)
|
|
24
|
-
console.log(chalk.blue('Installing dependencies...'));
|
|
25
|
-
try {
|
|
26
|
-
const packageJson = await fs.readJson(packageJsonPath);
|
|
27
|
-
const deps = packageJson.dependencies ?? {};
|
|
28
|
-
const hasSdk = deps['@hive-org/sdk'];
|
|
29
|
-
const hasDotenv = deps['dotenv'];
|
|
30
|
-
const toInstall = [];
|
|
31
|
-
if (!hasSdk) {
|
|
32
|
-
toInstall.push('@hive-org/sdk@*');
|
|
33
|
-
}
|
|
34
|
-
if (!hasDotenv) {
|
|
35
|
-
toInstall.push('dotenv');
|
|
36
|
-
}
|
|
37
|
-
if (toInstall.length > 0) {
|
|
38
|
-
await execAsync(`pnpm add ${toInstall.join(' ')}`, { cwd: targetDir });
|
|
39
|
-
console.log(chalk.green('\u2713 Dependencies installed'));
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
console.log(chalk.gray('Dependencies already installed.'));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch (e) {
|
|
46
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
47
|
-
console.error(chalk.yellow("Warning: Failed to install dependencies automatically. Please run 'pnpm add @hive-org/sdk dotenv' manually."));
|
|
48
|
-
}
|
|
49
|
-
console.log(chalk.green('\nHive installed successfully!'));
|
|
50
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useEffect } from 'react';
|
|
3
|
-
import { Text } from 'ink';
|
|
4
|
-
export function TypewriterText({ text, color, speed = 25, }) {
|
|
5
|
-
const [visible, setVisible] = useState(0);
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
if (visible >= text.length)
|
|
8
|
-
return;
|
|
9
|
-
const timer = setTimeout(() => {
|
|
10
|
-
setVisible((prev) => Math.min(prev + 2, text.length));
|
|
11
|
-
}, speed);
|
|
12
|
-
return () => {
|
|
13
|
-
clearTimeout(timer);
|
|
14
|
-
};
|
|
15
|
-
}, [visible, text, speed]);
|
|
16
|
-
return _jsx(Text, { color: color, children: text.slice(0, visible) });
|
|
17
|
-
}
|
|
18
|
-
export function PollText({ text, color, animate, }) {
|
|
19
|
-
if (animate) {
|
|
20
|
-
return _jsx(TypewriterText, { text: text, color: color });
|
|
21
|
-
}
|
|
22
|
-
return _jsx(Text, { color: color, children: text });
|
|
23
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useEffect } from 'react';
|
|
3
|
-
import { Box, Text, useInput } from 'ink';
|
|
4
|
-
import { border, colors, symbols } from '../../shared/theme.js';
|
|
5
|
-
function formatCountdown(ms) {
|
|
6
|
-
if (ms < 0)
|
|
7
|
-
return 'expired';
|
|
8
|
-
const totalMinutes = Math.floor(ms / 60_000);
|
|
9
|
-
if (totalMinutes < 1)
|
|
10
|
-
return '<1m';
|
|
11
|
-
const hours = Math.floor(totalMinutes / 60);
|
|
12
|
-
const minutes = totalMinutes % 60;
|
|
13
|
-
if (hours >= 1)
|
|
14
|
-
return `${hours}h ${minutes}m`;
|
|
15
|
-
return `${minutes}m`;
|
|
16
|
-
}
|
|
17
|
-
function isPredictionResolved(prediction, now) {
|
|
18
|
-
const resolvedAt = new Date(prediction.resolved_at);
|
|
19
|
-
return resolvedAt <= now;
|
|
20
|
-
}
|
|
21
|
-
function formatPredictionRow(prediction, now) {
|
|
22
|
-
const resolved = isPredictionResolved(prediction, now);
|
|
23
|
-
const sign = prediction.conviction >= 0 ? '+' : '';
|
|
24
|
-
const convictionStr = `${sign}${prediction.conviction.toFixed(2)}%`;
|
|
25
|
-
const project = `c/${prediction.project_id}`;
|
|
26
|
-
if (!resolved) {
|
|
27
|
-
const resolvedAt = new Date(prediction.resolved_at);
|
|
28
|
-
const remainingMs = resolvedAt.getTime() - now.getTime();
|
|
29
|
-
const countdown = formatCountdown(remainingMs);
|
|
30
|
-
return `${symbols.diamondOpen} ${project} ${convictionStr} pending ${countdown}`;
|
|
31
|
-
}
|
|
32
|
-
if (prediction.honey > 0) {
|
|
33
|
-
return `${symbols.check} ${project} ${convictionStr} +${prediction.honey.toFixed(2)} honey`;
|
|
34
|
-
}
|
|
35
|
-
if (prediction.wax > 0) {
|
|
36
|
-
return `${symbols.cross} ${project} ${convictionStr} ${prediction.wax.toFixed(2)} wax`;
|
|
37
|
-
}
|
|
38
|
-
return `${symbols.diamond} ${project} ${convictionStr} resolved`;
|
|
39
|
-
}
|
|
40
|
-
function getRowColor(prediction, now) {
|
|
41
|
-
const resolved = isPredictionResolved(prediction, now);
|
|
42
|
-
if (!resolved)
|
|
43
|
-
return colors.white;
|
|
44
|
-
if (prediction.honey > 0)
|
|
45
|
-
return colors.green;
|
|
46
|
-
if (prediction.wax > 0)
|
|
47
|
-
return colors.wax;
|
|
48
|
-
return colors.gray;
|
|
49
|
-
}
|
|
50
|
-
export function PredictionsPanel({ predictions, loading, hasMore, onExit, onLoadMore, termWidth, }) {
|
|
51
|
-
const [scrollOffset, setScrollOffset] = useState(0);
|
|
52
|
-
// Reserve lines: header(1) + padding(1) + footer separator(1) + footer text(1) + bottom border(1)
|
|
53
|
-
const chromeLines = 5;
|
|
54
|
-
const visibleRows = Math.max(1, (process.stdout.rows || 20) - 12 - chromeLines);
|
|
55
|
-
useInput((input, key) => {
|
|
56
|
-
if (key.escape) {
|
|
57
|
-
onExit();
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (key.upArrow) {
|
|
61
|
-
setScrollOffset((prev) => Math.max(0, prev - 1));
|
|
62
|
-
}
|
|
63
|
-
if (key.downArrow) {
|
|
64
|
-
const maxOffset = Math.max(0, predictions.length - visibleRows);
|
|
65
|
-
setScrollOffset((prev) => Math.min(maxOffset, prev + 1));
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
// Infinite scroll: trigger load when near bottom
|
|
69
|
-
useEffect(() => {
|
|
70
|
-
const threshold = 3;
|
|
71
|
-
const nearBottom = scrollOffset + visibleRows >= predictions.length - threshold;
|
|
72
|
-
if (nearBottom && hasMore && !loading) {
|
|
73
|
-
void onLoadMore();
|
|
74
|
-
}
|
|
75
|
-
}, [scrollOffset, predictions.length, hasMore, loading, onLoadMore, visibleRows]);
|
|
76
|
-
const boxWidth = termWidth;
|
|
77
|
-
const innerWidth = boxWidth - 4;
|
|
78
|
-
const now = new Date();
|
|
79
|
-
const visiblePredictions = predictions.slice(scrollOffset, scrollOffset + visibleRows);
|
|
80
|
-
const countLabel = `${predictions.length} loaded`;
|
|
81
|
-
const titleText = ` ${symbols.hive} Predictions `;
|
|
82
|
-
const titleFill = Math.max(0, boxWidth - titleText.length - countLabel.length - 6);
|
|
83
|
-
return (_jsxs(Box, { flexDirection: "column", width: boxWidth, children: [_jsxs(Box, { children: [_jsxs(Text, { color: colors.honey, children: [border.topLeft, border.horizontal] }), _jsx(Text, { color: colors.honey, bold: true, children: titleText }), _jsxs(Text, { color: colors.gray, children: [border.horizontal.repeat(2), " ", countLabel, " ", border.horizontal.repeat(titleFill), border.topRight] })] }), _jsxs(Box, { flexDirection: "column", paddingLeft: 2, paddingRight: 2, minHeight: visibleRows, children: [predictions.length === 0 && !loading && (_jsx(Box, { children: _jsx(Text, { color: colors.gray, children: "No predictions yet." }) })), visiblePredictions.map((prediction) => {
|
|
84
|
-
const row = formatPredictionRow(prediction, now);
|
|
85
|
-
const rowColor = getRowColor(prediction, now);
|
|
86
|
-
return (_jsx(Box, { children: _jsx(Text, { color: rowColor, wrap: "truncate", children: row.length > innerWidth ? row.slice(0, innerWidth) : row }) }, prediction.id));
|
|
87
|
-
}), loading && (_jsx(Box, { children: _jsx(Text, { color: colors.honey, children: "Loading..." }) }))] }), _jsx(Box, { children: _jsxs(Text, { color: colors.gray, children: [border.teeLeft, border.horizontal.repeat(boxWidth - 2), border.teeRight] }) }), _jsx(Box, { paddingLeft: 2, children: _jsxs(Text, { color: colors.gray, children: ['\u2191\u2193', " scroll ", symbols.circle, " esc exit"] }) }), _jsx(Box, { children: _jsxs(Text, { color: colors.gray, children: [border.bottomLeft, border.horizontal.repeat(boxWidth - 2), border.bottomRight] }) })] }));
|
|
88
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useContext, useEffect, useState } from 'react';
|
|
3
|
-
export const SPINNER_FRAMES = ['\u25D0', '\u25D3', '\u25D1', '\u25D2'];
|
|
4
|
-
const SPINNER_INTERVAL_MS = 200;
|
|
5
|
-
const SpinnerContext = createContext(0);
|
|
6
|
-
export function SpinnerProvider({ children }) {
|
|
7
|
-
const [frame, setFrame] = useState(0);
|
|
8
|
-
useEffect(() => {
|
|
9
|
-
const timer = setInterval(() => {
|
|
10
|
-
setFrame((prev) => (prev + 1) % SPINNER_FRAMES.length);
|
|
11
|
-
}, SPINNER_INTERVAL_MS);
|
|
12
|
-
return () => {
|
|
13
|
-
clearInterval(timer);
|
|
14
|
-
};
|
|
15
|
-
}, []);
|
|
16
|
-
return _jsx(SpinnerContext.Provider, { value: frame, children: children });
|
|
17
|
-
}
|
|
18
|
-
export function useSpinnerFrame() {
|
|
19
|
-
return useContext(SpinnerContext);
|
|
20
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
const FRAMES = ['\u25D0', '\u25D3', '\u25D1', '\u25D2']; // ◐ ◓ ◑ ◒
|
|
3
|
-
const INTERVAL_MS = 200;
|
|
4
|
-
const HONEY_ANSI = '\x1b[38;2;245;166;35m';
|
|
5
|
-
const RESET_ANSI = '\x1b[0m';
|
|
6
|
-
let _frame = 0;
|
|
7
|
-
let _timer = null;
|
|
8
|
-
const _entries = new Map();
|
|
9
|
-
let _nextId = 0;
|
|
10
|
-
function rawWrite(data) {
|
|
11
|
-
try {
|
|
12
|
-
fs.writeSync(process.stdout.fd, data);
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
// Ignore write errors (non-TTY, closed fd, etc.)
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function tick() {
|
|
19
|
-
_frame = (_frame + 1) % FRAMES.length;
|
|
20
|
-
const char = `${HONEY_ANSI}${FRAMES[_frame]}${RESET_ANSI}`;
|
|
21
|
-
for (const getPosition of _entries.values()) {
|
|
22
|
-
const pos = getPosition();
|
|
23
|
-
if (!pos || pos.linesFromBottom <= 0)
|
|
24
|
-
continue;
|
|
25
|
-
rawWrite('\x1b7'); // Save cursor (DEC)
|
|
26
|
-
rawWrite(`\x1b[${pos.linesFromBottom}A`); // Move up N lines
|
|
27
|
-
rawWrite(`\x1b[${pos.col + 1}G`); // Move to column (1-indexed)
|
|
28
|
-
rawWrite(char);
|
|
29
|
-
rawWrite('\x1b8'); // Restore cursor (DEC)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
export function register(getPosition) {
|
|
33
|
-
const id = _nextId++;
|
|
34
|
-
_entries.set(id, getPosition);
|
|
35
|
-
if (!_timer) {
|
|
36
|
-
_timer = setInterval(tick, INTERVAL_MS);
|
|
37
|
-
}
|
|
38
|
-
return id;
|
|
39
|
-
}
|
|
40
|
-
export function unregister(id) {
|
|
41
|
-
_entries.delete(id);
|
|
42
|
-
if (_entries.size === 0 && _timer) {
|
|
43
|
-
clearInterval(_timer);
|
|
44
|
-
_timer = null;
|
|
45
|
-
_frame = 0;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
export { FRAMES };
|
package/dist/create/CreateApp.js
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useCallback } from 'react';
|
|
3
|
-
import { Box, Text, useApp } from 'ink';
|
|
4
|
-
import { Header } from '../components/Header.js';
|
|
5
|
-
import { AsciiTicker } from '../components/AsciiTicker.js';
|
|
6
|
-
import { StepIndicator } from '../components/StepIndicator.js';
|
|
7
|
-
import { ApiKeyStep } from './steps/ApiKeyStep.js';
|
|
8
|
-
import { NameStep } from './steps/NameStep.js';
|
|
9
|
-
import { IdentityStep } from './steps/IdentityStep.js';
|
|
10
|
-
import { AvatarStep } from './steps/AvatarStep.js';
|
|
11
|
-
import { SoulStep } from './steps/SoulStep.js';
|
|
12
|
-
import { StrategyStep } from './steps/StrategyStep.js';
|
|
13
|
-
import { ScaffoldStep } from './steps/ScaffoldStep.js';
|
|
14
|
-
import { DoneStep } from './steps/DoneStep.js';
|
|
15
|
-
import { colors, symbols } from '../theme.js';
|
|
16
|
-
import { getProvider } from '../ai-providers.js';
|
|
17
|
-
function ensureAvatarUrl(content, avatarUrl) {
|
|
18
|
-
const lines = content.split('\n');
|
|
19
|
-
const avatarIdx = lines.findIndex((l) => /^## Avatar/.test(l));
|
|
20
|
-
if (avatarIdx === -1) {
|
|
21
|
-
return content;
|
|
22
|
-
}
|
|
23
|
-
// Find the next section header after ## Avatar
|
|
24
|
-
let nextSectionIdx = lines.length;
|
|
25
|
-
for (let i = avatarIdx + 1; i < lines.length; i++) {
|
|
26
|
-
if (/^##?\s/.test(lines[i])) {
|
|
27
|
-
nextSectionIdx = i;
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
// Replace the content between ## Avatar and next section with the raw URL
|
|
32
|
-
const before = lines.slice(0, avatarIdx + 1);
|
|
33
|
-
const after = lines.slice(nextSectionIdx);
|
|
34
|
-
const result = [...before, '', avatarUrl, '', ...after];
|
|
35
|
-
return result.join('\n');
|
|
36
|
-
}
|
|
37
|
-
function ensureSectionLine(content, sectionHeader, linePrefix, value) {
|
|
38
|
-
const lines = content.split('\n');
|
|
39
|
-
const sectionIdx = lines.findIndex((l) => new RegExp(`^##\\s+${sectionHeader}`).test(l));
|
|
40
|
-
if (sectionIdx === -1) {
|
|
41
|
-
// Section missing — append it at the end
|
|
42
|
-
return content + `\n\n## ${sectionHeader}\n\n${linePrefix} ${value}\n`;
|
|
43
|
-
}
|
|
44
|
-
// Find the next section header after this one
|
|
45
|
-
let nextSectionIdx = lines.length;
|
|
46
|
-
for (let i = sectionIdx + 1; i < lines.length; i++) {
|
|
47
|
-
if (/^##?\s/.test(lines[i])) {
|
|
48
|
-
nextSectionIdx = i;
|
|
49
|
-
break;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// Look for existing line with the prefix in this section
|
|
53
|
-
const prefixRegex = new RegExp(`^${linePrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s`);
|
|
54
|
-
const lineIdx = lines.findIndex((l, i) => i > sectionIdx && i < nextSectionIdx && prefixRegex.test(l));
|
|
55
|
-
if (lineIdx !== -1) {
|
|
56
|
-
// Replace the existing line
|
|
57
|
-
lines[lineIdx] = `${linePrefix} ${value}`;
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
// Insert after the section header (skip blank lines)
|
|
61
|
-
let insertIdx = sectionIdx + 1;
|
|
62
|
-
while (insertIdx < nextSectionIdx && lines[insertIdx].trim() === '') {
|
|
63
|
-
insertIdx++;
|
|
64
|
-
}
|
|
65
|
-
lines.splice(insertIdx, 0, `${linePrefix} ${value}`);
|
|
66
|
-
}
|
|
67
|
-
return lines.join('\n');
|
|
68
|
-
}
|
|
69
|
-
function ensureStrategyFields(content, sectors, sentiment, timeframes) {
|
|
70
|
-
const sectorsLine = sectors.length > 0 ? sectors.join(', ') : 'all categories';
|
|
71
|
-
const timeframesLine = timeframes.length > 0 ? timeframes.join(', ') : '1h, 4h, 24h';
|
|
72
|
-
let patched = ensureSectionLine(content, 'Sentiment', '- Bias:', sentiment);
|
|
73
|
-
patched = ensureSectionLine(patched, 'Sector Focus', '- Sectors:', sectorsLine);
|
|
74
|
-
patched = ensureSectionLine(patched, 'Timeframe', '- Active timeframes:', timeframesLine);
|
|
75
|
-
return patched;
|
|
76
|
-
}
|
|
77
|
-
const STEP_ORDER = ['name', 'identity', 'avatar', 'api-key', 'soul', 'strategy', 'scaffold', 'done'];
|
|
78
|
-
const STEP_LABELS = {
|
|
79
|
-
'api-key': 'API Key',
|
|
80
|
-
'name': 'Name',
|
|
81
|
-
'identity': 'Identity',
|
|
82
|
-
'avatar': 'Avatar',
|
|
83
|
-
'soul': 'Soul',
|
|
84
|
-
'strategy': 'Strategy',
|
|
85
|
-
'scaffold': 'Scaffold',
|
|
86
|
-
'done': 'Done',
|
|
87
|
-
};
|
|
88
|
-
const STEP_DEFS = STEP_ORDER.map((s) => ({ key: s, label: STEP_LABELS[s] }));
|
|
89
|
-
export function CreateApp({ initialName }) {
|
|
90
|
-
const { exit } = useApp();
|
|
91
|
-
const [step, setStep] = useState(initialName ? 'identity' : 'name');
|
|
92
|
-
const [providerId, setProviderId] = useState(null);
|
|
93
|
-
const [apiKey, setApiKey] = useState('');
|
|
94
|
-
const [agentName, setAgentName] = useState(initialName ?? '');
|
|
95
|
-
const [bio, setBio] = useState('');
|
|
96
|
-
const [personality, setPersonality] = useState('');
|
|
97
|
-
const [tone, setTone] = useState('');
|
|
98
|
-
const [voiceStyle, setVoiceStyle] = useState('');
|
|
99
|
-
const [tradingStyle, setTradingStyle] = useState('');
|
|
100
|
-
const [sectors, setSectors] = useState([]);
|
|
101
|
-
const [sentiment, setSentiment] = useState('');
|
|
102
|
-
const [timeframes, setTimeframes] = useState([]);
|
|
103
|
-
const [avatarUrl, setAvatarUrl] = useState('');
|
|
104
|
-
const [soulContent, setSoulContent] = useState('');
|
|
105
|
-
const [strategyContent, setStrategyContent] = useState('');
|
|
106
|
-
const [resolvedProjectDir, setResolvedProjectDir] = useState('');
|
|
107
|
-
const [error, setError] = useState('');
|
|
108
|
-
const stepIndex = STEP_ORDER.indexOf(step);
|
|
109
|
-
const provider = providerId ? getProvider(providerId) : null;
|
|
110
|
-
const handleApiKey = useCallback((result) => {
|
|
111
|
-
setProviderId(result.providerId);
|
|
112
|
-
setApiKey(result.apiKey);
|
|
113
|
-
setStep('soul');
|
|
114
|
-
}, []);
|
|
115
|
-
const handleName = useCallback((name) => {
|
|
116
|
-
setAgentName(name);
|
|
117
|
-
setStep('identity');
|
|
118
|
-
}, []);
|
|
119
|
-
const handleIdentity = useCallback((result) => {
|
|
120
|
-
setPersonality(result.personality);
|
|
121
|
-
setTone(result.tone);
|
|
122
|
-
setVoiceStyle(result.voiceStyle);
|
|
123
|
-
setTradingStyle(result.tradingStyle);
|
|
124
|
-
setSectors(result.sectors);
|
|
125
|
-
setSentiment(result.sentiment);
|
|
126
|
-
setTimeframes(result.timeframes);
|
|
127
|
-
setBio(result.bio);
|
|
128
|
-
setStep('avatar');
|
|
129
|
-
}, []);
|
|
130
|
-
const handleAvatar = useCallback((value) => {
|
|
131
|
-
setAvatarUrl(value);
|
|
132
|
-
setStep('api-key');
|
|
133
|
-
}, []);
|
|
134
|
-
const handleSoul = useCallback((content) => {
|
|
135
|
-
const patched = ensureAvatarUrl(content, avatarUrl);
|
|
136
|
-
setSoulContent(patched);
|
|
137
|
-
setStep('strategy');
|
|
138
|
-
}, [avatarUrl]);
|
|
139
|
-
const handleStrategy = useCallback((content) => {
|
|
140
|
-
const patched = ensureStrategyFields(content, sectors, sentiment, timeframes);
|
|
141
|
-
setStrategyContent(patched);
|
|
142
|
-
setStep('scaffold');
|
|
143
|
-
}, [sectors, sentiment, timeframes]);
|
|
144
|
-
const handleScaffoldComplete = useCallback((projectDir) => {
|
|
145
|
-
setResolvedProjectDir(projectDir);
|
|
146
|
-
setStep('done');
|
|
147
|
-
}, []);
|
|
148
|
-
const handleScaffoldError = useCallback((message) => {
|
|
149
|
-
setError(message);
|
|
150
|
-
exit();
|
|
151
|
-
}, [exit]);
|
|
152
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, {}), _jsx(StepIndicator, { steps: STEP_DEFS, currentIndex: stepIndex }), step !== 'done' && (_jsx(Box, { marginBottom: 1, children: _jsx(AsciiTicker, { step: stepIndex + 1 }) })), step === 'api-key' && (_jsx(ApiKeyStep, { onComplete: handleApiKey })), step === 'name' && (_jsx(NameStep, { onComplete: handleName })), step === 'identity' && (_jsx(IdentityStep, { agentName: agentName, onComplete: handleIdentity })), step === 'avatar' && (_jsx(AvatarStep, { agentName: agentName, onComplete: handleAvatar })), step === 'soul' && providerId && (_jsx(SoulStep, { providerId: providerId, apiKey: apiKey, agentName: agentName, bio: bio, avatarUrl: avatarUrl, personality: personality, tone: tone, voiceStyle: voiceStyle, tradingStyle: tradingStyle, sectors: sectors, sentiment: sentiment, timeframes: timeframes, onComplete: handleSoul })), step === 'strategy' && providerId && (_jsx(StrategyStep, { providerId: providerId, apiKey: apiKey, agentName: agentName, bio: bio, personality: personality, tone: tone, voiceStyle: voiceStyle, tradingStyle: tradingStyle, sectors: sectors, sentiment: sentiment, timeframes: timeframes, onComplete: handleStrategy })), step === 'scaffold' && provider && (_jsx(ScaffoldStep, { projectName: agentName, provider: provider, apiKey: apiKey, soulContent: soulContent, strategyContent: strategyContent, onComplete: handleScaffoldComplete, onError: handleScaffoldError })), step === 'done' && (_jsx(DoneStep, { projectDir: resolvedProjectDir })), error !== '' && (_jsx(Box, { marginTop: 1, marginLeft: 2, children: _jsxs(Text, { color: colors.red, children: [symbols.cross, " ", error] }) }))] }));
|
|
153
|
-
}
|