@hive-org/cli
Advanced tools
@@ -25,3 +25,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; | ||
| const accentColor = isMega ? colors.controversial : colors.cyan; | ||
| return (_jsxs(Box, { flexDirection: "column", children: [item.type === 'online' && (_jsxs(Box, { children: [_jsxs(Text, { color: colors.gray, dimColor: true, children: [formatTime(item.timestamp), ' '] }), _jsxs(Text, { color: colors.honey, children: [symbols.hive, " "] }), _jsx(PollText, { color: colors.white, text: item.text, animate: isNewest })] })), (item.type === 'signal' || item.type === 'megathread') && (_jsxs(_Fragment, { children: [_jsxs(Box, { children: [_jsxs(Text, { color: colors.gray, dimColor: true, children: [formatTime(item.timestamp), ' '] }), _jsxs(Text, { color: isMega ? colors.controversial : colors.honey, children: [symbols.hive, " "] }), _jsx(PollText, { color: accentColor, text: item.text, animate: isNewest }), item.status === 'analyzing' && (_jsx(Text, { children: " " })), item.status === 'analyzing' && (_jsx(Spinner, { label: "analyzing..." })), item.status === 'skipped' && (_jsxs(Text, { color: colors.honey, children: [" ", symbols.diamondOpen, " skipped"] })), item.status === 'skipped' && item.tokenUsage && (_jsxs(Text, { color: colors.gray, dimColor: true, children: [' ', symbols.circle, " ", item.tokenUsage.inputTokens.toLocaleString(), " in", item.tokenUsage.cacheReadTokens > 0 && ` (${item.tokenUsage.cacheReadTokens.toLocaleString()} cached)`, item.tokenUsage.cacheReadTokens === 0 && item.tokenUsage.cacheWriteTokens > 0 && ` (${item.tokenUsage.cacheWriteTokens.toLocaleString()} cache write)`, ' \u00b7 ', item.tokenUsage.outputTokens.toLocaleString(), " out", item.tokenUsage.toolCalls > 0 && ` \u00b7 tools: ${item.tokenUsage.toolNames.join(', ')}`] }))] }), item.status === 'analyzing' && item.detail && (_jsx(Box, { marginLeft: 13, children: _jsx(PollText, { color: colors.gray, text: `"${item.detail}"`, animate: false }) })), item.status === 'posted' && item.result && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginLeft: 13, children: [_jsxs(Text, { color: isMega ? colors.controversial : convictionColor(item.conviction ?? 0), children: [symbols.diamond, ' '] }), _jsx(PollText, { color: colors.white, text: item.result, animate: isNewest })] }), item.url && (_jsx(Box, { marginLeft: 15, children: _jsx(Text, { color: colors.gray, dimColor: true, children: item.url }) })), item.tokenUsage && (_jsx(Box, { marginLeft: 15, children: _jsxs(Text, { color: colors.gray, dimColor: true, children: ["tokens: ", item.tokenUsage.inputTokens.toLocaleString(), " in", item.tokenUsage.cacheReadTokens > 0 && ` (${item.tokenUsage.cacheReadTokens.toLocaleString()} cached)`, item.tokenUsage.cacheReadTokens === 0 && item.tokenUsage.cacheWriteTokens > 0 && ` (${item.tokenUsage.cacheWriteTokens.toLocaleString()} cache write)`, ' \u00b7 ', item.tokenUsage.outputTokens.toLocaleString(), " out", item.tokenUsage.toolCalls > 0 && ` \u00b7 tools: ${item.tokenUsage.toolNames.join(', ')}`] }) }))] })), item.status === 'error' && item.result && (_jsx(Box, { marginLeft: 13, children: _jsx(PollText, { color: colors.red, text: `${symbols.cross} ${item.result}`, animate: isNewest }) }))] })), item.type === 'idle' && (_jsxs(Box, { children: [_jsxs(Text, { color: colors.gray, dimColor: true, children: [formatTime(item.timestamp), ' '] }), _jsx(PollText, { color: colors.gray, text: `${symbols.circle} ${item.text}`, animate: isNewest })] })), item.type === 'error' && (_jsxs(Box, { children: [_jsxs(Text, { color: colors.gray, dimColor: true, children: [formatTime(item.timestamp), ' '] }), _jsx(PollText, { color: colors.red, text: `${symbols.cross} ${item.text}`, animate: isNewest })] }))] }, i)); | ||
| return (_jsxs(Box, { flexDirection: "column", children: [item.type === 'online' && (_jsxs(Box, { children: [_jsxs(Text, { color: colors.gray, dimColor: true, children: [formatTime(item.timestamp), ' '] }), _jsxs(Text, { color: colors.honey, children: [symbols.hive, " "] }), _jsx(PollText, { color: colors.white, text: item.text, animate: isNewest })] })), (item.type === 'signal' || item.type === 'megathread') && (_jsxs(_Fragment, { children: [_jsxs(Box, { children: [_jsxs(Text, { color: colors.gray, dimColor: true, children: [formatTime(item.timestamp), ' '] }), _jsxs(Text, { color: isMega ? colors.controversial : colors.honey, children: [symbols.hive, " "] }), _jsx(PollText, { color: accentColor, text: item.text, animate: isNewest }), item.status === 'analyzing' && (_jsx(Text, { children: " " })), item.status === 'analyzing' && (_jsx(Spinner, { label: "analyzing..." })), item.status === 'skipped' && (_jsxs(Text, { color: colors.honey, children: [" ", symbols.diamondOpen, " skipped"] })), item.status === 'skipped' && item.tokenUsage && (_jsxs(Text, { color: colors.gray, dimColor: true, children: [' ', symbols.circle, " ", item.tokenUsage.inputTokens.toLocaleString(), " in", item.tokenUsage.cacheReadTokens > 0 && ` (${item.tokenUsage.cacheReadTokens.toLocaleString()} cached)`, item.tokenUsage.cacheReadTokens === 0 && item.tokenUsage.cacheWriteTokens > 0 && ` (${item.tokenUsage.cacheWriteTokens.toLocaleString()} cache write)`, ' \u00b7 ', item.tokenUsage.outputTokens.toLocaleString(), " out", item.tokenUsage.toolCalls > 0 && ` \u00b7 tools: ${item.tokenUsage.toolNames.join(', ')}`] }))] }), item.status === 'analyzing' && item.detail && (_jsx(Box, { marginLeft: 13, children: _jsx(PollText, { color: colors.gray, text: `"${item.detail}"`, animate: false }) })), item.status === 'posted' && item.result && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginLeft: 13, children: [_jsxs(Text, { color: isMega ? colors.controversial : convictionColor(item.conviction ?? 0), children: [symbols.diamond, ' '] }), _jsx(PollText, { color: colors.white, text: item.result, animate: isNewest })] }), item.url && (_jsx(Box, { marginLeft: 15, children: _jsx(Text, { color: colors.gray, dimColor: true, children: item.url }) })), item.tokenUsage && (_jsxs(Box, { flexDirection: "column", marginLeft: 15, children: [_jsxs(Text, { color: colors.gray, dimColor: true, children: ["tokens: ", item.tokenUsage.inputTokens.toLocaleString(), " in", item.tokenUsage.cacheReadTokens > 0 && ` (${item.tokenUsage.cacheReadTokens.toLocaleString()} cached)`, item.tokenUsage.cacheReadTokens === 0 && item.tokenUsage.cacheWriteTokens > 0 && ` (${item.tokenUsage.cacheWriteTokens.toLocaleString()} cache write)`, ' \u00b7 ', item.tokenUsage.outputTokens.toLocaleString(), " out", item.tokenUsage.toolCalls > 0 && ` \u00b7 tools: ${item.tokenUsage.toolNames.join(', ')}`] }), item.tokenUsage.toolResults.map((tr, j) => { | ||
| const preview = tr.result.length > 200 ? tr.result.slice(0, 200) + '\u2026' : tr.result; | ||
| return (_jsxs(Text, { color: colors.gray, dimColor: true, children: [tr.toolName, ": ", preview] }, j)); | ||
| })] }))] })), item.status === 'error' && item.result && (_jsx(Box, { marginLeft: 13, children: _jsx(PollText, { color: colors.red, text: `${symbols.cross} ${item.result}`, animate: isNewest }) }))] })), item.type === 'idle' && (_jsxs(Box, { children: [_jsxs(Text, { color: colors.gray, dimColor: true, children: [formatTime(item.timestamp), ' '] }), _jsx(PollText, { color: colors.gray, text: `${symbols.circle} ${item.text}`, animate: isNewest })] })), item.type === 'error' && (_jsxs(Box, { children: [_jsxs(Text, { color: colors.gray, dimColor: true, children: [formatTime(item.timestamp), ' '] }), _jsx(PollText, { color: colors.red, text: `${symbols.cross} ${item.text}`, animate: isNewest })] }))] }, i)); | ||
| })] }), (chatActivity.length > 0 || chatStreaming) && (_jsxs(_Fragment, { children: [_jsx(Box, { children: _jsxs(Text, { color: colors.gray, children: [border.teeLeft, `${border.horizontal.repeat(2)} chat with ${agentName} agent `, border.horizontal.repeat(Math.max(0, boxWidth - agentName.length - 22)), border.teeRight] }) }), _jsxs(Box, { flexDirection: "column", paddingLeft: 1, paddingRight: 1, minHeight: 2, maxHeight: 8, children: [visibleChatActivity.map((item, i) => (_jsxs(Box, { children: [item.type === 'chat-user' && (_jsxs(Box, { children: [_jsxs(Text, { color: colors.white, bold: true, children: ["you:", ' '] }), _jsx(Text, { color: colors.white, children: item.text })] })), item.type === 'chat-agent' && (_jsxs(Box, { children: [_jsxs(Text, { color: colors.honey, bold: true, children: [agentName, " agent:", ' '] }), _jsx(Text, { color: colors.white, wrap: "wrap", children: item.text })] })), item.type === 'chat-error' && (_jsx(Box, { children: _jsxs(Text, { color: colors.red, children: [symbols.cross, " ", item.text] }) }))] }, i))), chatStreaming && chatBuffer && (_jsxs(Box, { children: [_jsxs(Text, { color: colors.honey, bold: true, children: [agentName, " agent:", ' '] }), _jsx(Text, { color: colors.white, wrap: "wrap", children: chatBuffer })] }))] })] })), _jsx(Box, { children: _jsxs(Text, { color: colors.gray, children: [isInteractive ? border.teeLeft : border.bottomLeft, border.horizontal.repeat(boxWidth - 2), isInteractive ? border.teeRight : border.bottomRight] }) }), isInteractive && (_jsxs(_Fragment, { children: [_jsx(Box, { paddingLeft: 1, children: _jsx(CommandInput, { value: input, onChange: setInput, onSubmit: (val) => { | ||
@@ -28,0 +31,0 @@ setInput(''); |
+41
-7
@@ -105,10 +105,27 @@ function humanDuration(ms) { | ||
| } | ||
| const now = Date.now(); | ||
| const roundStartMs = Math.floor(now / durationMs) * durationMs; | ||
| const timeRemainingMs = Math.max(0, roundStartMs + durationMs - now); | ||
| const timeRemaining = humanDuration(timeRemainingMs); | ||
| const lateInRound = timeRemainingMs < durationMs * 0.25; | ||
| const currentDate = new Date().toISOString().split('T')[0]; | ||
| const userPrompt = `## Context | ||
| - Project: c/${projectId} | ||
| - Conviction window: ${timeframe} | ||
| - Current date: ${currentDate} | ||
| - Round duration: ${timeframe} | ||
| - Time remaining: ~${timeRemaining} | ||
| ## The game | ||
| This is a price prediction game. You're predicting the % price change for c/${projectId} over this ${timeframe} round. | ||
| What matters: | ||
| - **Current price** — check with tools. This is the most important input to your prediction. | ||
| - **Time remaining** (~${timeRemaining}) — the runway left for price movement. Less time = smaller realistic moves. Scale your conviction accordingly.${lateInRound ? ' Round is almost over — keep your conviction small.' : ''} | ||
| - **Catalysts & momentum** — news, sentiment shifts, or technical setups that could move price in the remaining window. | ||
| ## Your task | ||
| This is a **megathread round** for c/${projectId}. You must form your own price conviction over the next ${timeframe}. | ||
| This is a **megathread round** for c/${projectId}. Form your price conviction for the remaining ~${timeRemaining} of this ${timeframe} round. | ||
@@ -124,7 +141,7 @@ **If you have tools available**, use them to research: | ||
| Form a thesis based on what you find or what you know. Your conviction should reflect your ${timeframe} outlook. | ||
| Form a thesis based on what you find or what you know. Your conviction should reflect what's realistic in the ~${timeRemaining} remaining. | ||
| ## How scoring works | ||
| You are predicting the % price change for c/${projectId} over the next ${timeframe}. | ||
| You are predicting the % price change for c/${projectId} over this ${timeframe} round (~${timeRemaining} remaining). | ||
| - Correct direction + close to actual = max honey (up to +100) | ||
@@ -138,3 +155,3 @@ - Correct direction but far off = less honey | ||
| Give your take in character and a conviction number. | ||
| Conviction: predicted % price change for c/${projectId} over the next ${timeframe}, up to one decimal. Positive = up, negative = down. 0 = neutral.`; | ||
| Conviction: predicted % price change for c/${projectId} for the remainder of this ${timeframe} round (~${timeRemaining} left), up to one decimal. Positive = up, negative = down. 0 = neutral.`; | ||
| return { system, prompt: userPrompt }; | ||
@@ -267,8 +284,25 @@ } | ||
| } | ||
| const currentDate = new Date().toISOString().split('T')[0]; | ||
| const EVAL_WINDOW_MS = 3 * 60 * 60 * 1000; | ||
| const signalTimeMs = new Date(timestamp).getTime(); | ||
| const timeRemainingMs = Math.max(0, signalTimeMs + EVAL_WINDOW_MS - Date.now()); | ||
| const timeRemaining = humanDuration(timeRemainingMs); | ||
| const lateWindow = timeRemainingMs < 45 * 60 * 1000; | ||
| const userPrompt = `## Context | ||
| - Project: c/${projectId} | ||
| - Current date: ${currentDate} | ||
| - Signal time: ${timestamp} | ||
| - Price at signal: $${priceOnFetch} | ||
| - Snapshot price: $${priceOnFetch} (captured at signal time) | ||
| - Time left: ~${timeRemaining} | ||
| ${citationsSection} | ||
| ## The game | ||
| This is a price prediction game. Your conviction = predicted % change from the snapshot price ($${priceOnFetch}), evaluated 3 hours after signal time. | ||
| What matters: | ||
| - **Snapshot price** ($${priceOnFetch}) — your baseline. Scoring measures % change from here. | ||
| - **Current price** — how much has already moved since the signal. Check with tools. | ||
| - **Time left** (~${timeRemaining}) — less time = less room for further movement from current price.${lateWindow ? ' Almost no time left — anchor your prediction to where the price is NOW relative to the snapshot.' : ''} | ||
| ## How scoring works | ||
@@ -292,4 +326,4 @@ | ||
| Give your take in character and a conviction number. | ||
| Conviction: predicted % price change from the snapshot price ($${priceOnFetch}) over the 3 hours following signal time (${timestamp}), up to one decimal. Positive = up, negative = down. 0 = neutral.`; | ||
| Conviction: predicted % price change from $${priceOnFetch} by evaluation time (~${timeRemaining} left), up to one decimal. Positive = up, negative = down. 0 = neutral.`; | ||
| return { system, prompt: userPrompt }; | ||
| } |
@@ -5,3 +5,3 @@ import { HiveAgent } from '@hive-org/sdk'; | ||
| import { HIVE_FRONTEND_URL } from '../config.js'; | ||
| import { processSignalAndSummarize, processMegathreadRound } from './analysis.js'; | ||
| import { processSignalAndSummarize, processMegathreadRound, } from './analysis.js'; | ||
| import { initializeSkills, getAllTools, getReadSkillTool, getSkillMetadataList, } from './tools/index.js'; | ||
@@ -22,2 +22,8 @@ function formatTokens(n) { | ||
| } | ||
| function logToolResults(results) { | ||
| for (const tr of results) { | ||
| const preview = tr.result.length > 200 ? tr.result.slice(0, 200) + '\u2026' : tr.result; | ||
| console.log(` ${tr.toolName}: ${preview}`); | ||
| } | ||
| } | ||
| function timestamp() { | ||
@@ -71,2 +77,3 @@ const now = new Date(); | ||
| console.log(` tools: ${toolNames} (${result.usage.toolCalls} calls)`); | ||
| logToolResults(result.usage.toolResults); | ||
| } | ||
@@ -112,2 +119,3 @@ else { | ||
| console.log(` tools: ${toolNames} (${result.usage.toolCalls} calls)`); | ||
| logToolResults(result.usage.toolResults); | ||
| } | ||
@@ -114,0 +122,0 @@ else { |
| import { tool } from 'ai'; | ||
| import { z } from 'zod'; | ||
| import { getMarketClient } from './client.js'; | ||
| import { computeSMA, computeEMA, computeRSI, computeMACD, computeBollingerBands } from '../ta/indicators.js'; | ||
| import { computeSMA, computeEMA, computeRSI, computeMACD, computeBollingerBands, } from '../ta/indicators.js'; | ||
| export const getPriceTool = tool({ | ||
| description: 'Get cryptocurrency price at a specific timestamp. Returns the price for the specified project at the given time.', | ||
| inputSchema: z.object({ | ||
| projectId: z.string().describe('Project ID to get price for (e.g., "bitcoin", "ethereum"). Use lowercase.'), | ||
| projectId: z | ||
| .string() | ||
| .describe('Project ID to get price for (e.g., "bitcoin", "ethereum"). Use lowercase.'), | ||
| timestamp: z | ||
| .string() | ||
| .describe('Timestamp in ISO 8601 format (e.g., "2024-01-15T12:00:00Z")'), | ||
| .describe('Timestamp in ISO 8601 format. Use the current date from context (e.g., if today is 2026-02-28, use "2026-02-28T12:00:00Z").'), | ||
| }), | ||
@@ -42,6 +44,6 @@ execute: async ({ projectId, timestamp }) => { | ||
| .string() | ||
| .describe('Start date in ISO 8601 format (e.g., "2024-01-01T00:00:00Z")'), | ||
| .describe('Start date in ISO 8601 format. Use recent dates relative to the current date from context (e.g., 30 days ago).'), | ||
| to: z | ||
| .string() | ||
| .describe('End date in ISO 8601 format (e.g., "2024-01-31T23:59:59Z")'), | ||
| .describe('End date in ISO 8601 format. Use the current date from context as the end date.'), | ||
| interval: z | ||
@@ -68,7 +70,3 @@ .enum(['daily', 'hourly']) | ||
| const displayData = ohlcData.length > maxPoints | ||
| ? [ | ||
| ...ohlcData.slice(0, 10), | ||
| null, | ||
| ...ohlcData.slice(-10), | ||
| ] | ||
| ? [...ohlcData.slice(0, 10), null, ...ohlcData.slice(-10)] | ||
| : ohlcData; | ||
@@ -114,6 +112,6 @@ for (const point of displayData) { | ||
| .string() | ||
| .describe('Start date in ISO 8601 format (e.g., "2024-01-01T00:00:00Z")'), | ||
| .describe('Start date in ISO 8601 format. Use recent dates relative to the current date from context (e.g., 30 days ago).'), | ||
| to: z | ||
| .string() | ||
| .describe('End date in ISO 8601 format (e.g., "2024-01-31T23:59:59Z")'), | ||
| .describe('End date in ISO 8601 format. Use the current date from context as the end date.'), | ||
| interval: z | ||
@@ -180,6 +178,6 @@ .enum(['daily', 'hourly']) | ||
| .string() | ||
| .describe('Start date in ISO 8601 format (e.g., "2024-01-01T00:00:00Z")'), | ||
| .describe('Start date in ISO 8601 format. Use recent dates relative to the current date from context (e.g., 30 days ago).'), | ||
| to: z | ||
| .string() | ||
| .describe('End date in ISO 8601 format (e.g., "2024-01-31T23:59:59Z")'), | ||
| .describe('End date in ISO 8601 format. Use the current date from context as the end date.'), | ||
| interval: z | ||
@@ -238,15 +236,9 @@ .enum(['daily', 'hourly']) | ||
| id: z.string().describe('Coin ID (e.g., "bitcoin", "ethereum"). Use lowercase.'), | ||
| period: z | ||
| .number() | ||
| .int() | ||
| .min(2) | ||
| .max(50) | ||
| .optional() | ||
| .describe('RSI period. Defaults to 14.'), | ||
| period: z.number().int().min(2).max(50).optional().describe('RSI period. Defaults to 14.'), | ||
| from: z | ||
| .string() | ||
| .describe('Start date in ISO 8601 format (e.g., "2024-01-01T00:00:00Z")'), | ||
| .describe('Start date in ISO 8601 format. Use recent dates relative to the current date from context (e.g., 30 days ago).'), | ||
| to: z | ||
| .string() | ||
| .describe('End date in ISO 8601 format (e.g., "2024-01-31T23:59:59Z")'), | ||
| .describe('End date in ISO 8601 format. Use the current date from context as the end date.'), | ||
| interval: z | ||
@@ -349,6 +341,6 @@ .enum(['daily', 'hourly']) | ||
| .string() | ||
| .describe('Start date in ISO 8601 format (e.g., "2024-01-01T00:00:00Z")'), | ||
| .describe('Start date in ISO 8601 format. Use recent dates relative to the current date from context (e.g., 30 days ago).'), | ||
| to: z | ||
| .string() | ||
| .describe('End date in ISO 8601 format (e.g., "2024-01-31T23:59:59Z")'), | ||
| .describe('End date in ISO 8601 format. Use the current date from context as the end date.'), | ||
| interval: z | ||
@@ -444,6 +436,6 @@ .enum(['daily', 'hourly']) | ||
| .string() | ||
| .describe('Start date in ISO 8601 format (e.g., "2024-01-01T00:00:00Z")'), | ||
| .describe('Start date in ISO 8601 format. Use recent dates relative to the current date from context (e.g., 30 days ago).'), | ||
| to: z | ||
| .string() | ||
| .describe('End date in ISO 8601 format (e.g., "2024-01-31T23:59:59Z")'), | ||
| .describe('End date in ISO 8601 format. Use the current date from context as the end date.'), | ||
| interval: z | ||
@@ -475,5 +467,3 @@ .enum(['daily', 'hourly']) | ||
| const maxPoints = 20; | ||
| const displayData = bbData.length > maxPoints | ||
| ? [...bbData.slice(0, 5), null, ...bbData.slice(-10)] | ||
| : bbData; | ||
| const displayData = bbData.length > maxPoints ? [...bbData.slice(0, 5), null, ...bbData.slice(-10)] : bbData; | ||
| for (const point of displayData) { | ||
@@ -480,0 +470,0 @@ if (point === null) { |
@@ -19,2 +19,10 @@ import { tool } from 'ai'; | ||
| .describe('Number of results to return (max 100). Defaults to 20.'); | ||
| function formatMindshare(ms) { | ||
| const value = ms?.value != null ? `${(ms.value * 100).toFixed(4)}%` : 'N/A'; | ||
| const rawDelta = ms?.delta ?? 0; | ||
| const deltaSign = rawDelta >= 0 ? '+' : ''; | ||
| const delta = `${deltaSign}${(rawDelta * 100).toFixed(2)}%`; | ||
| const rank = ms?.rank != null ? `#${ms.rank}` : 'N/A'; | ||
| return { value, delta, rank }; | ||
| } | ||
| export const getProjectLeaderboardTool = tool({ | ||
@@ -41,6 +49,4 @@ description: 'Get the top trending projects by mindshare. Returns a ranked list of projects sorted by mindshare value or delta change. Use this to identify what projects are gaining attention.', | ||
| for (const item of data) { | ||
| const delta = item.mindshare_delta ?? 0; | ||
| const deltaSign = delta >= 0 ? '+' : ''; | ||
| const deltaFormatted = `${deltaSign}${(delta * 100).toFixed(2)}%`; | ||
| lines.push(`#${item.rank} | ${item.name} | ${(item.mindshare_value * 100).toFixed(4)}% | ${deltaFormatted}`); | ||
| const ms = formatMindshare(item.mindshare); | ||
| lines.push(`${ms.rank} | ${item.name} | ${ms.value} | ${ms.delta}`); | ||
| } | ||
@@ -66,11 +72,9 @@ const output = lines.join('\n'); | ||
| const data = await client.getProjectMindshare(projectId, timeframe); | ||
| const delta = data.mindshare_delta ?? 0; | ||
| const deltaSign = delta >= 0 ? '+' : ''; | ||
| const deltaFormatted = `${deltaSign}${(delta * 100).toFixed(2)}%`; | ||
| const ms = formatMindshare(data.mindshare); | ||
| const lines = [ | ||
| `Mindshare for ${data.name} (${timeframe ?? '24h'}):`, | ||
| `Mindshare for ${data.name ?? projectId} (${timeframe ?? '24h'}):`, | ||
| '', | ||
| `- Rank: #${data.rank}`, | ||
| `- Mindshare Value: ${(data.mindshare_value * 100).toFixed(4)}%`, | ||
| `- Delta Change: ${deltaFormatted}`, | ||
| `- Rank: ${ms.rank}`, | ||
| `- Mindshare Value: ${ms.value}`, | ||
| `- Delta Change: ${ms.delta}`, | ||
| ]; | ||
@@ -108,5 +112,3 @@ if (data.symbol) { | ||
| const maxDisplay = 20; | ||
| const displayPoints = points.length > maxDisplay | ||
| ? [...points.slice(0, 5), null, ...points.slice(-10)] | ||
| : points; | ||
| const displayPoints = points.length > maxDisplay ? [...points.slice(0, 5), null, ...points.slice(-10)] : points; | ||
| for (const point of displayPoints) { | ||
@@ -161,6 +163,4 @@ if (point === null) { | ||
| for (const item of data) { | ||
| const delta = item.mindshare_delta ?? 0; | ||
| const deltaSign = delta >= 0 ? '+' : ''; | ||
| const deltaFormatted = `${deltaSign}${(delta * 100).toFixed(2)}%`; | ||
| lines.push(`#${item.rank} | ${item.name} | ${(item.mindshare_value * 100).toFixed(4)}% | ${deltaFormatted}`); | ||
| const ms = formatMindshare(item.mindshare); | ||
| lines.push(`${ms.rank} | ${item.name} | ${ms.value} | ${ms.delta}`); | ||
| } | ||
@@ -197,6 +197,4 @@ const output = lines.join('\n'); | ||
| for (const item of data) { | ||
| const delta = item.mindshare_delta ?? 0; | ||
| const deltaSign = delta >= 0 ? '+' : ''; | ||
| const deltaFormatted = `${deltaSign}${(delta * 100).toFixed(2)}%`; | ||
| lines.push(`#${item.rank} | ${item.name} | ${(item.mindshare_value * 100).toFixed(4)}% | ${deltaFormatted}`); | ||
| const ms = formatMindshare(item.mindshare); | ||
| lines.push(`${ms.rank} | ${item.id} | ${ms.value} | ${ms.delta}`); | ||
| } | ||
@@ -222,10 +220,8 @@ const output = lines.join('\n'); | ||
| const data = await client.getSectorMindshare(sectorId, timeframe); | ||
| const delta = data.mindshare_delta ?? 0; | ||
| const deltaSign = delta >= 0 ? '+' : ''; | ||
| const deltaFormatted = `${deltaSign}${(delta * 100).toFixed(2)}%`; | ||
| const ms = formatMindshare(data.mindshare); | ||
| const lines = [ | ||
| `Mindshare for Sector "${data.name}" (${timeframe ?? '24h'}):`, | ||
| `Mindshare for Sector "${sectorId}" (${timeframe ?? '24h'}):`, | ||
| '', | ||
| `- Mindshare Value: ${(data.mindshare_value * 100).toFixed(4)}%`, | ||
| `- Delta Change: ${deltaFormatted}`, | ||
| `- Mindshare Value: ${ms.value}`, | ||
| `- Delta Change: ${ms.delta}`, | ||
| ]; | ||
@@ -259,5 +255,3 @@ const output = lines.join('\n'); | ||
| const maxDisplay = 20; | ||
| const displayPoints = data.length > maxDisplay | ||
| ? [...data.slice(0, 5), null, ...data.slice(-10)] | ||
| : data; | ||
| const displayPoints = data.length > maxDisplay ? [...data.slice(0, 5), null, ...data.slice(-10)] : data; | ||
| for (const point of displayPoints) { | ||
@@ -308,7 +302,5 @@ if (point === null) { | ||
| for (const item of data) { | ||
| const delta = item.mindshare_delta ?? 0; | ||
| const deltaSign = delta >= 0 ? '+' : ''; | ||
| const deltaFormatted = `${deltaSign}${(delta * 100).toFixed(2)}%`; | ||
| const displayName = item.display_name || item.username; | ||
| lines.push(`#${item.rank} | @${item.username} (${displayName}) | ${(item.mindshare_value * 100).toFixed(4)}% | ${deltaFormatted}`); | ||
| const ms = formatMindshare(item.mindshare); | ||
| const displayName = item.name || item.username; | ||
| lines.push(`${ms.rank} | @${item.username} (${displayName}) | ${ms.value} | ${ms.delta}`); | ||
| } | ||
@@ -347,7 +339,5 @@ const output = lines.join('\n'); | ||
| for (const item of data) { | ||
| const delta = item.mindshare_delta ?? 0; | ||
| const deltaSign = delta >= 0 ? '+' : ''; | ||
| const deltaFormatted = `${deltaSign}${(delta * 100).toFixed(2)}%`; | ||
| const displayName = item.display_name || item.username; | ||
| lines.push(`#${item.rank} | @${item.username} (${displayName}) | ${(item.mindshare_value * 100).toFixed(4)}% | ${deltaFormatted}`); | ||
| const ms = formatMindshare(item.mindshare); | ||
| const displayName = item.name || item.username; | ||
| lines.push(`${ms.rank} | @${item.username} (${displayName}) | ${ms.value} | ${ms.delta}`); | ||
| } | ||
@@ -368,3 +358,6 @@ const output = lines.join('\n'); | ||
| timeframe: timeframeSchema, | ||
| withTimeseries: z.boolean().optional().describe('Include historical timeseries data. Defaults to false.'), | ||
| withTimeseries: z | ||
| .boolean() | ||
| .optional() | ||
| .describe('Include historical timeseries data. Defaults to false.'), | ||
| }), | ||
@@ -375,12 +368,10 @@ execute: async ({ userId, timeframe, withTimeseries }) => { | ||
| const data = await client.getUserMindshare(userId, timeframe, withTimeseries); | ||
| const delta = data.mindshare_delta ?? 0; | ||
| const deltaSign = delta >= 0 ? '+' : ''; | ||
| const deltaFormatted = `${deltaSign}${(delta * 100).toFixed(2)}%`; | ||
| const displayName = data.display_name || data.username; | ||
| const ms = formatMindshare(data.mindshare); | ||
| const displayName = data.name || data.username; | ||
| const lines = [ | ||
| `Mindshare for @${data.username} (${displayName}) (${timeframe ?? '24h'}):`, | ||
| `Mindshare for @${data.username ?? userId} (${displayName}) (${timeframe ?? '24h'}):`, | ||
| '', | ||
| `- Rank: #${data.rank}`, | ||
| `- Mindshare Value: ${(data.mindshare_value * 100).toFixed(4)}%`, | ||
| `- Delta Change: ${deltaFormatted}`, | ||
| `- Rank: ${ms.rank}`, | ||
| `- Mindshare Value: ${ms.value}`, | ||
| `- Delta Change: ${ms.delta}`, | ||
| ]; | ||
@@ -414,5 +405,3 @@ const output = lines.join('\n'); | ||
| const maxDisplay = 20; | ||
| const displayPoints = data.length > maxDisplay | ||
| ? [...data.slice(0, 5), null, ...data.slice(-10)] | ||
| : data; | ||
| const displayPoints = data.length > maxDisplay ? [...data.slice(0, 5), null, ...data.slice(-10)] : data; | ||
| for (const point of displayPoints) { | ||
@@ -445,6 +434,12 @@ if (point === null) { | ||
| projectId: z.string().optional().describe('Optional project ID to filter signals.'), | ||
| minThreshold: z.number().optional().describe('Minimum delta threshold percentage (e.g., 10 for 10% spike).'), | ||
| minThreshold: z | ||
| .number() | ||
| .optional() | ||
| .describe('Minimum delta threshold percentage (e.g., 10 for 10% spike).'), | ||
| limit: limitSchema, | ||
| page: z.number().int().min(1).optional().describe('Page number for pagination. Defaults to 1.'), | ||
| includeTrendingTopics: z.boolean().optional().describe('Include trending topics for each signal. Defaults to false.'), | ||
| includeTrendingTopics: z | ||
| .boolean() | ||
| .optional() | ||
| .describe('Include trending topics for each signal. Defaults to false.'), | ||
| }), | ||
@@ -481,6 +476,12 @@ execute: async ({ projectId, minThreshold, limit, page, includeTrendingTopics }) => { | ||
| projectId: z.string().optional().describe('Optional project ID to filter signals.'), | ||
| minThreshold: z.number().optional().describe('Minimum threshold in standard deviations above MA.'), | ||
| minThreshold: z | ||
| .number() | ||
| .optional() | ||
| .describe('Minimum threshold in standard deviations above MA.'), | ||
| limit: limitSchema, | ||
| page: z.number().int().min(1).optional().describe('Page number for pagination. Defaults to 1.'), | ||
| includeTrendingTopics: z.boolean().optional().describe('Include trending topics for each signal. Defaults to false.'), | ||
| includeTrendingTopics: z | ||
| .boolean() | ||
| .optional() | ||
| .describe('Include trending topics for each signal. Defaults to false.'), | ||
| }), | ||
@@ -518,5 +519,14 @@ execute: async ({ projectId, minThreshold, limit, page, includeTrendingTopics }) => { | ||
| limit: limitSchema, | ||
| cursor: z.string().optional().describe('Cursor for pagination (signal ID from previous response).'), | ||
| mode: z.enum(['asc', 'desc']).optional().describe('Sort order: desc (newest first) or asc (oldest first). Defaults to desc.'), | ||
| includeSignalSummary: z.boolean().optional().describe('Include signal summaries. Defaults to false.'), | ||
| cursor: z | ||
| .string() | ||
| .optional() | ||
| .describe('Cursor for pagination (signal ID from previous response).'), | ||
| mode: z | ||
| .enum(['asc', 'desc']) | ||
| .optional() | ||
| .describe('Sort order: desc (newest first) or asc (oldest first). Defaults to desc.'), | ||
| includeSignalSummary: z | ||
| .boolean() | ||
| .optional() | ||
| .describe('Include signal summaries. Defaults to false.'), | ||
| }), | ||
@@ -523,0 +533,0 @@ execute: async ({ projectId, limit, cursor, mode, includeSignalSummary }) => { |
+1
-1
| { | ||
| "name": "@hive-org/cli", | ||
| "version": "0.1.7", | ||
| "version": "0.1.8", | ||
| "description": "CLI for bootstrapping Hive AI Agents", | ||
@@ -5,0 +5,0 @@ "type": "module", |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
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
409844
0.6%8374
0.47%