Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement โ†’
Sign In

@hive-org/cli

Package Overview
Dependencies
Maintainers
2
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@hive-org/cli - npm Package Compare versions

Comparing version
0.1.9
to
0.2.0
+45
-22
dist/agent/config.js

@@ -16,2 +16,39 @@ import * as fs from 'fs/promises';

}
const VALID_SENTIMENTS = [
'very-bullish',
'bullish',
'neutral',
'bearish',
'very-bearish',
];
const VALID_TIMEFRAMES = ['1h', '4h', '24h'];
function parseSentiment(raw) {
if (raw !== null && VALID_SENTIMENTS.includes(raw)) {
return raw;
}
return 'neutral';
}
function parseSectors(raw) {
if (raw === null || raw.trim() === '') {
return [];
}
const sectors = raw
.split(',')
.map((s) => s.trim())
.filter((s) => s.length > 0);
return sectors;
}
function parseTimeframes(raw) {
if (raw === null || raw.trim() === '') {
return ['1h', '4h', '24h'];
}
const parsed = raw
.split(',')
.map((t) => t.trim())
.filter((t) => VALID_TIMEFRAMES.includes(t));
if (parsed.length === 0) {
return ['1h', '4h', '24h'];
}
return parsed;
}
export async function loadAgentConfig() {

@@ -30,25 +67,11 @@ const soulContent = await loadMarkdownFile('SOUL.md');

const bio = bioRaw ?? null;
const signalMethod = extractField(strategyContent, /^-\s+Method:\s+(.+)$/m);
const convictionStyle = extractField(strategyContent, /^-\s+Boldness:\s+(.+)$/m);
const directionalBias = extractField(strategyContent, /^-\s+Directional bias:\s+(.+)$/m);
const participation = extractField(strategyContent, /^-\s+Participation:\s+(.+)$/m);
if (signalMethod === null ||
convictionStyle === null ||
directionalBias === null ||
participation === null) {
const missing = [
signalMethod === null ? 'Method' : null,
convictionStyle === null ? 'Boldness' : null,
directionalBias === null ? 'Directional bias' : null,
participation === null ? 'Participation' : null,
].filter(Boolean);
throw new Error(`Could not parse prediction profile from STRATEGY.md. Missing fields: ${missing.join(', ')}`);
}
const predictionProfile = {
signal_method: signalMethod,
conviction_style: convictionStyle,
directional_bias: directionalBias,
participation,
const sentimentRaw = extractField(strategyContent, /^-\s+Bias:\s+(.+)$/m);
const sectorsRaw = extractField(strategyContent, /^-\s+Sectors:\s+(.+)$/m);
const timeframesRaw = extractField(strategyContent, /^-\s+Active timeframes:\s+(.+)$/m);
const agentProfile = {
sentiment: parseSentiment(sentimentRaw),
sectors: parseSectors(sectorsRaw),
timeframes: parseTimeframes(timeframesRaw),
};
return { name, bio, avatarUrl, soulContent, strategyContent, predictionProfile };
return { name, bio, avatarUrl, soulContent, strategyContent, agentProfile };
}

@@ -121,3 +121,3 @@ import { HiveAgent, loadMemory } from '@hive-org/sdk';

bio: config.bio ?? undefined,
predictionProfile: config.predictionProfile,
agentProfile: config.agentProfile,
pollIntervalMs: 30_000,

@@ -124,0 +124,0 @@ pollLimit: 5,

@@ -56,3 +56,3 @@ import { HiveAgent } from '@hive-org/sdk';

bio: config.bio ?? undefined,
predictionProfile: config.predictionProfile,
agentProfile: config.agentProfile,
pollIntervalMs: 30_000,

@@ -59,0 +59,0 @@ pollLimit: 5,

@@ -5,3 +5,3 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";

import { colors, border } from '../theme.js';
export function StreamingText({ stream, title, onComplete }) {
export function StreamingText({ stream, title, onComplete, onError }) {
const [text, setText] = useState('');

@@ -14,2 +14,3 @@ const bufferRef = useRef('');

}
bufferRef.current = '';
completedRef.current = false;

@@ -36,4 +37,7 @@ let cancelled = false;

};
consume().catch(() => {
/* stream error โ€” handled by caller */
consume().catch((err) => {
if (cancelled)
return;
const message = err instanceof Error ? err.message : String(err);
onError?.(message);
});

@@ -40,0 +44,0 @@ return () => {

@@ -110,3 +110,3 @@ import { streamText } from 'ai';

Generate a STRATEGY.md file. The STRATEGY.md defines HOW the agent makes predictions โ€” their method, conviction style, sector focus, and decision framework. The strategy should reflect the agent's personality and tone, and should address the game mechanics above (e.g. when to skip, how aggressive to be with timing, how to calibrate conviction magnitude).
Generate a STRATEGY.md file. The STRATEGY.md defines HOW the agent makes predictions โ€” their method, sector focus, and decision framework. The strategy should reflect the agent's personality and tone, and should address the game mechanics above (e.g. when to skip, how aggressive to be with timing, how to calibrate conviction magnitude).

@@ -122,10 +122,10 @@ CRITICAL: Output ONLY valid markdown matching this exact structure. No extra commentary.

- Primary indicators: (list key indicators)
## Conviction Style
- Boldness: (must be one of: conservative, moderate, bold, degen)
- Directional bias: (must be one of: neutral, bullish, bearish)
- Participation: (must be one of: selective, moderate, active)
## Sentiment
- Bias: ${sentiment}
## Sector Focus
- Primary: (main sector)
- Secondary: (secondary sector)
- Sectors: ${sectorsLine}
- Avoid: (sectors to avoid)
## Timeframe
- Active timeframes: ${timeframesLine}
(Explain why these timeframes suit the agent's style. Mention that the agent skips signals outside these timeframes.)
## Decision Framework

@@ -135,7 +135,2 @@ 1. (first step)

3. (third step)
## Timeframe Preference
- Active timeframes: ${timeframesLine}
(Explain why these timeframes suit the agent's style. Mention that the agent skips signals outside these timeframes.)
## Participation Criteria
(Must reference the agent's preferred timeframes โ€” the agent only participates in signals matching ${timeframesLine} and skips others.)

@@ -142,0 +137,0 @@ Here are reference examples of well-crafted STRATEGY.md files:

@@ -37,2 +37,42 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";

}
function ensureSectionLine(content, sectionHeader, linePrefix, value) {
const lines = content.split('\n');
const sectionIdx = lines.findIndex((l) => new RegExp(`^##\\s+${sectionHeader}`).test(l));
if (sectionIdx === -1) {
// Section missing โ€” append it at the end
return content + `\n\n## ${sectionHeader}\n\n${linePrefix} ${value}\n`;
}
// Find the next section header after this one
let nextSectionIdx = lines.length;
for (let i = sectionIdx + 1; i < lines.length; i++) {
if (/^##?\s/.test(lines[i])) {
nextSectionIdx = i;
break;
}
}
// Look for existing line with the prefix in this section
const prefixRegex = new RegExp(`^${linePrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s`);
const lineIdx = lines.findIndex((l, i) => i > sectionIdx && i < nextSectionIdx && prefixRegex.test(l));
if (lineIdx !== -1) {
// Replace the existing line
lines[lineIdx] = `${linePrefix} ${value}`;
}
else {
// Insert after the section header (skip blank lines)
let insertIdx = sectionIdx + 1;
while (insertIdx < nextSectionIdx && lines[insertIdx].trim() === '') {
insertIdx++;
}
lines.splice(insertIdx, 0, `${linePrefix} ${value}`);
}
return lines.join('\n');
}
function ensureStrategyFields(content, sectors, sentiment, timeframes) {
const sectorsLine = sectors.length > 0 ? sectors.join(', ') : 'all categories';
const timeframesLine = timeframes.length > 0 ? timeframes.join(', ') : '1h, 4h, 24h';
let patched = ensureSectionLine(content, 'Sentiment', '- Bias:', sentiment);
patched = ensureSectionLine(patched, 'Sector Focus', '- Sectors:', sectorsLine);
patched = ensureSectionLine(patched, 'Timeframe', '- Active timeframes:', timeframesLine);
return patched;
}
const STEP_ORDER = ['name', 'identity', 'avatar', 'api-key', 'soul', 'strategy', 'scaffold', 'done'];

@@ -101,5 +141,6 @@ const STEP_LABELS = {

const handleStrategy = useCallback((content) => {
setStrategyContent(content);
const patched = ensureStrategyFields(content, sectors, sentiment, timeframes);
setStrategyContent(patched);
setStep('scaffold');
}, []);
}, [sectors, sentiment, timeframes]);
const handleScaffoldComplete = useCallback((projectDir) => {

@@ -106,0 +147,0 @@ setResolvedProjectDir(projectDir);

@@ -13,2 +13,3 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";

const [draft, setDraft] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const [feedbackCount, setFeedbackCount] = useState(0);

@@ -18,8 +19,26 @@ const stream = useMemo(() => streamSoul(providerId, apiKey, agentName, bio, avatarUrl, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes), []);

const handleStreamComplete = useCallback((fullText) => {
setDraft(fullText);
const trimmed = fullText.trim();
if (trimmed.length === 0) {
setErrorMessage('LLM returned empty content. Try regenerating.');
setPhase('error');
return;
}
setDraft(trimmed);
setPhase('review');
}, []);
const handleStreamError = useCallback((error) => {
setErrorMessage(error);
setPhase('error');
}, []);
const handleAccept = useCallback(() => {
onComplete(draft);
}, [draft, onComplete]);
const handleRetry = useCallback(() => {
setFeedbackCount((prev) => prev + 1);
setPhase('streaming');
setDraft('');
setErrorMessage('');
const newStream = streamSoul(providerId, apiKey, agentName, bio, avatarUrl, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes);
setCurrentStream(newStream);
}, [providerId, apiKey, agentName, bio, avatarUrl, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes]);
const handleFeedback = useCallback((feedback) => {

@@ -29,6 +48,7 @@ setFeedbackCount((prev) => prev + 1);

setDraft('');
setErrorMessage('');
const newStream = streamSoul(providerId, apiKey, agentName, bio, avatarUrl, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes, feedback);
setCurrentStream(newStream);
}, [providerId, apiKey, agentName, bio, avatarUrl, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes]);
return (_jsxs(Box, { flexDirection: "column", children: [phase === 'streaming' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Spinner, { label: feedbackCount > 0 ? 'Regenerating SOUL.md...' : 'Generating SOUL.md...' }) }), _jsx(StreamingText, { stream: currentStream, title: "SOUL.md", onComplete: handleStreamComplete })] })), phase === 'review' && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: colors.green, children: [symbols.check, " "] }), _jsx(Text, { color: colors.white, children: "SOUL.md draft ready" })] }), _jsx(CodeBlock, { title: "SOUL.md", children: draft }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: colors.gray, children: ["Press ", _jsx(Text, { color: colors.honey, bold: true, children: "Enter" }), " to accept", ' ', symbols.dot, ' ', "Type feedback to regenerate"] }) }), _jsx(Box, { marginTop: 1, children: _jsx(TextPrompt, { label: "", placeholder: "Enter to accept, or type feedback...", onSubmit: (val) => {
return (_jsxs(Box, { flexDirection: "column", children: [phase === 'streaming' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Spinner, { label: feedbackCount > 0 ? 'Regenerating SOUL.md...' : 'Generating SOUL.md...' }) }), _jsx(StreamingText, { stream: currentStream, title: "SOUL.md", onComplete: handleStreamComplete, onError: handleStreamError })] })), phase === 'error' && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: colors.red, children: [symbols.cross, " "] }), _jsx(Text, { color: colors.white, children: "Failed to generate SOUL.md" })] }), _jsx(Box, { marginLeft: 2, marginBottom: 1, children: _jsx(Text, { color: colors.red, children: errorMessage }) }), _jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: colors.gray, children: ["Press ", _jsx(Text, { color: colors.honey, bold: true, children: "Enter" }), " to retry"] }) }), _jsx(Box, { marginTop: 1, children: _jsx(TextPrompt, { label: "", placeholder: "Enter to retry...", onSubmit: () => handleRetry() }) })] })), phase === 'review' && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: colors.green, children: [symbols.check, " "] }), _jsx(Text, { color: colors.white, children: "SOUL.md draft ready" })] }), _jsx(CodeBlock, { title: "SOUL.md", children: draft }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: colors.gray, children: ["Press ", _jsx(Text, { color: colors.honey, bold: true, children: "Enter" }), " to accept", ' ', symbols.dot, ' ', "Type feedback to regenerate"] }) }), _jsx(Box, { marginTop: 1, children: _jsx(TextPrompt, { label: "", placeholder: "Enter to accept, or type feedback...", onSubmit: (val) => {
if (!val) {

@@ -35,0 +55,0 @@ handleAccept();

@@ -13,2 +13,3 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";

const [draft, setDraft] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const [feedbackCount, setFeedbackCount] = useState(0);

@@ -18,8 +19,26 @@ const stream = useMemo(() => streamStrategy(providerId, apiKey, agentName, bio, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes), []);

const handleStreamComplete = useCallback((fullText) => {
setDraft(fullText);
const trimmed = fullText.trim();
if (trimmed.length === 0) {
setErrorMessage('LLM returned empty content. Try regenerating.');
setPhase('error');
return;
}
setDraft(trimmed);
setPhase('review');
}, []);
const handleStreamError = useCallback((error) => {
setErrorMessage(error);
setPhase('error');
}, []);
const handleAccept = useCallback(() => {
onComplete(draft);
}, [draft, onComplete]);
const handleRetry = useCallback(() => {
setFeedbackCount((prev) => prev + 1);
setPhase('streaming');
setDraft('');
setErrorMessage('');
const newStream = streamStrategy(providerId, apiKey, agentName, bio, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes);
setCurrentStream(newStream);
}, [providerId, apiKey, agentName, bio, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes]);
const handleFeedback = useCallback((feedback) => {

@@ -29,6 +48,7 @@ setFeedbackCount((prev) => prev + 1);

setDraft('');
setErrorMessage('');
const newStream = streamStrategy(providerId, apiKey, agentName, bio, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes, feedback);
setCurrentStream(newStream);
}, [providerId, apiKey, agentName, bio, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes]);
return (_jsxs(Box, { flexDirection: "column", children: [phase === 'streaming' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Spinner, { label: feedbackCount > 0 ? 'Regenerating STRATEGY.md...' : 'Generating STRATEGY.md...' }) }), _jsx(StreamingText, { stream: currentStream, title: "STRATEGY.md", onComplete: handleStreamComplete })] })), phase === 'review' && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: colors.green, children: [symbols.check, " "] }), _jsx(Text, { color: colors.white, children: "STRATEGY.md draft ready" })] }), _jsx(CodeBlock, { title: "STRATEGY.md", children: draft }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: colors.gray, children: ["Press ", _jsx(Text, { color: colors.honey, bold: true, children: "Enter" }), " to accept", ' ', symbols.dot, ' ', "Type feedback to regenerate"] }) }), _jsx(Box, { marginTop: 1, children: _jsx(TextPrompt, { label: "", placeholder: "Enter to accept, or type feedback...", onSubmit: (val) => {
return (_jsxs(Box, { flexDirection: "column", children: [phase === 'streaming' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Spinner, { label: feedbackCount > 0 ? 'Regenerating STRATEGY.md...' : 'Generating STRATEGY.md...' }) }), _jsx(StreamingText, { stream: currentStream, title: "STRATEGY.md", onComplete: handleStreamComplete, onError: handleStreamError })] })), phase === 'error' && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: colors.red, children: [symbols.cross, " "] }), _jsx(Text, { color: colors.white, children: "Failed to generate STRATEGY.md" })] }), _jsx(Box, { marginLeft: 2, marginBottom: 1, children: _jsx(Text, { color: colors.red, children: errorMessage }) }), _jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: colors.gray, children: ["Press ", _jsx(Text, { color: colors.honey, bold: true, children: "Enter" }), " to retry"] }) }), _jsx(Box, { marginTop: 1, children: _jsx(TextPrompt, { label: "", placeholder: "Enter to retry...", onSubmit: () => handleRetry() }) })] })), phase === 'review' && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: colors.green, children: [symbols.check, " "] }), _jsx(Text, { color: colors.white, children: "STRATEGY.md draft ready" })] }), _jsx(CodeBlock, { title: "STRATEGY.md", children: draft }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: colors.gray, children: ["Press ", _jsx(Text, { color: colors.honey, bold: true, children: "Enter" }), " to accept", ' ', symbols.dot, ' ', "Type feedback to regenerate"] }) }), _jsx(Box, { marginTop: 1, children: _jsx(TextPrompt, { label: "", placeholder: "Enter to accept, or type feedback...", onSubmit: (val) => {
if (!val) {

@@ -35,0 +55,0 @@ handleAccept();

@@ -153,11 +153,7 @@ export const SOUL_PRESETS = [

philosophy: "On-chain metrics and protocol fundamentals drive predictions. Numbers don't lie.",
predictionProfile: {
signal_method: 'onchain',
conviction_style: 'conservative',
directional_bias: 'neutral',
participation: 'selective',
},
signalMethod: 'onchain',
primaryIndicators: 'TVL changes, active addresses, protocol revenue, token velocity',
sectorPrimary: 'DeFi protocols with measurable on-chain activity',
sectorSecondary: 'L1/L2 chains with growing usage metrics',
sectors: ['defi', 'l1', 'l2'],
sentiment: 'neutral',
timeframes: ['4h', '24h'],
sectorAvoid: 'Memecoins and projects without on-chain fundamentals',

@@ -169,3 +165,2 @@ decisionSteps: [

],
participationCriteria: 'Only predict when on-chain data shows clear directional signals. Skip noise.',
},

@@ -175,11 +170,7 @@ {

philosophy: 'Pure technical analysis. Chart patterns, S/R levels, and indicators are the only truth.',
predictionProfile: {
signal_method: 'technical',
conviction_style: 'moderate',
directional_bias: 'neutral',
participation: 'active',
},
signalMethod: 'technical',
primaryIndicators: 'RSI, MACD, Bollinger Bands, volume profile, support/resistance levels',
sectorPrimary: 'Large-cap tokens with high liquidity and clean chart structures',
sectorSecondary: 'Mid-cap tokens at key technical levels',
sectors: ['l1', 'l2', 'defi'],
sentiment: 'neutral',
timeframes: ['1h', '4h', '24h'],
sectorAvoid: 'Low-liquidity tokens where TA is unreliable',

@@ -191,3 +182,2 @@ decisionSteps: [

],
participationCriteria: 'Predict on any signal where the chart shows clear technical setups.',
},

@@ -197,11 +187,7 @@ {

philosophy: 'Follows crypto narratives and CT sentiment. The story moves the price before the data does.',
predictionProfile: {
signal_method: 'sentiment',
conviction_style: 'bold',
directional_bias: 'bullish',
participation: 'active',
},
signalMethod: 'sentiment',
primaryIndicators: 'Social volume, CT sentiment, funding rates, narrative momentum',
sectorPrimary: 'Trending narratives (AI, RWA, memes) with growing mindshare',
sectorSecondary: 'Ecosystem plays riding broader narrative waves',
sectors: ['ai', 'meme', 'rwa', 'gaming'],
sentiment: 'bullish',
timeframes: ['1h', '4h'],
sectorAvoid: 'Dead narratives and tokens that lost CT attention',

@@ -213,3 +199,2 @@ decisionSteps: [

],
participationCriteria: 'Predict on most signals, especially those tied to active narratives.',
},

@@ -219,11 +204,7 @@ {

philosophy: "Crypto doesn't exist in a vacuum. Fed policy, DXY, bond yields, and global liquidity determine direction.",
predictionProfile: {
signal_method: 'macro',
conviction_style: 'conservative',
directional_bias: 'bearish',
participation: 'selective',
},
signalMethod: 'macro',
primaryIndicators: 'DXY, US 10Y yield, Fed funds rate, global M2 liquidity, BTC dominance',
sectorPrimary: 'BTC and ETH as macro proxies',
sectorSecondary: 'Large-cap alts that correlate strongly with macro conditions',
sectors: ['l1'],
sentiment: 'bearish',
timeframes: ['24h'],
sectorAvoid: 'Small-cap tokens decoupled from macro trends',

@@ -235,3 +216,2 @@ decisionSteps: [

],
participationCriteria: 'Only predict when macro conditions provide clear directional context.',
},

@@ -241,11 +221,7 @@ {

philosophy: 'Vibes over analysis. Max conviction, max frequency. Fortune favors the bold.',
predictionProfile: {
signal_method: 'sentiment',
conviction_style: 'degen',
directional_bias: 'bullish',
participation: 'active',
},
signalMethod: 'sentiment',
primaryIndicators: 'Vibes, CT hype, funding rates, "trust me bro"',
sectorPrimary: 'Whatever is pumping right now',
sectorSecondary: 'Memecoins, new launches, anything with momentum',
sectors: ['meme', 'ai', 'gaming'],
sentiment: 'very-bullish',
timeframes: ['1h'],
sectorAvoid: 'Nothing is off limits',

@@ -257,3 +233,2 @@ decisionSteps: [

],
participationCriteria: 'Predict on everything. No signal left behind.',
},

@@ -507,2 +482,62 @@ ];

},
{
label: '๐Ÿ•ต๏ธ Privacy',
value: 'privacy',
description: 'Privacy-focused chains and protocols โ€” XMR, ZEC, SCRT, etc.',
},
{
label: '๐Ÿ”„ DEX',
value: 'dex',
description: 'Decentralized exchanges โ€” UNI, SUSHI, CRV, JUP, etc.',
},
{
label: '๐Ÿ›๏ธ Lending',
value: 'lending',
description: 'Lending and borrowing protocols โ€” AAVE, COMP, MORPHO, etc.',
},
{
label: '๐Ÿ’ต Stablecoin',
value: 'stablecoin',
description: 'Stablecoin protocols and pegged assets โ€” MKR, FXS, LQTY, etc.',
},
{
label: '๐ŸŒ‰ Cross-chain',
value: 'cross-chain',
description: 'Bridges and interoperability โ€” ATOM, DOT, AXL, W, etc.',
},
{
label: '๐Ÿ’พ Storage',
value: 'storage',
description: 'Decentralized storage โ€” FIL, AR, STORJ, etc.',
},
{
label: '๐Ÿ’ง Liquid Staking',
value: 'liquid-staking',
description: 'Liquid staking derivatives โ€” LDO, RPL, SWISE, etc.',
},
{
label: 'โ™ป๏ธ Restaking',
value: 'restaking',
description: 'Restaking protocols โ€” EIGEN, ALT, etc.',
},
{
label: '๐Ÿ’ฌ Social',
value: 'social',
description: 'Social and identity protocols โ€” LENS, CYBER, ID, etc.',
},
{
label: '๐ŸŽฏ Prediction Markets',
value: 'prediction-markets',
description: 'Prediction and betting markets โ€” POLY, GNO, etc.',
},
{
label: '๐Ÿ–ผ๏ธ NFT',
value: 'nft',
description: 'NFT infrastructure and marketplaces โ€” BLUR, X2Y2, RARE, etc.',
},
{
label: '๐Ÿ“ก DePIN',
value: 'depin',
description: 'Decentralized physical infrastructure โ€” HNT, RNDR, DIMO, etc.',
},
];

@@ -567,17 +602,18 @@ function formatBulletList(items) {

- Method: ${preset.predictionProfile.signal_method}
- Method: ${preset.signalMethod}
- Primary indicators: ${preset.primaryIndicators}
## Conviction Style
## Sentiment
- Boldness: ${preset.predictionProfile.conviction_style}
- Directional bias: ${preset.predictionProfile.directional_bias}
- Participation: ${preset.predictionProfile.participation}
- Bias: ${preset.sentiment}
## Sector Focus
- Primary: ${preset.sectorPrimary}
- Secondary: ${preset.sectorSecondary}
- Sectors: ${preset.sectors.join(', ')}
- Avoid: ${preset.sectorAvoid}
## Timeframe
- Active timeframes: ${preset.timeframes.join(', ')}
## Decision Framework

@@ -588,7 +624,3 @@

3. ${preset.decisionSteps[2]}
## Participation Criteria
${preset.participationCriteria}
`;
}
{
"name": "@hive-org/cli",
"version": "0.1.9",
"version": "0.2.0",
"description": "CLI for bootstrapping Hive AI Agents",

@@ -32,3 +32,3 @@ "type": "module",

"@ai-sdk/xai": "^3.0.0",
"@hive-org/sdk": "^0.1.5",
"@hive-org/sdk": "^0.2.0",
"@openrouter/ai-sdk-provider": "^0.4.0",

@@ -35,0 +35,0 @@ "ai": "^6.0.71",