@hive-org/cli
Advanced tools
+45
-22
@@ -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(); |
+88
-56
@@ -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} | ||
| `; | ||
| } |
+2
-2
| { | ||
| "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", |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
419444
1.28%8618
1.66%+ Added
- Removed
Updated