@zhive/cli 0.5.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.
Files changed (189) hide show
  1. package/README.md +118 -0
  2. package/dist/agent/analysis.js +160 -0
  3. package/dist/agent/app.js +122 -0
  4. package/dist/agent/chat-prompt.js +65 -0
  5. package/dist/agent/commands/registry.js +12 -0
  6. package/dist/agent/components/AsciiTicker.js +81 -0
  7. package/dist/agent/components/CommandInput.js +65 -0
  8. package/dist/agent/components/HoneycombBoot.js +291 -0
  9. package/dist/agent/components/Spinner.js +37 -0
  10. package/dist/agent/config.js +75 -0
  11. package/dist/agent/edit-section.js +59 -0
  12. package/dist/agent/fetch-rules.js +21 -0
  13. package/dist/agent/helpers.js +22 -0
  14. package/dist/agent/hooks/useAgent.js +480 -0
  15. package/dist/agent/memory-prompt.js +47 -0
  16. package/dist/agent/model.js +92 -0
  17. package/dist/agent/objects.js +1 -0
  18. package/dist/agent/process-lifecycle.js +18 -0
  19. package/dist/agent/prompt.js +353 -0
  20. package/dist/agent/run-headless.js +189 -0
  21. package/dist/agent/skills/index.js +2 -0
  22. package/dist/agent/skills/skill-parser.js +149 -0
  23. package/dist/agent/skills/types.js +1 -0
  24. package/dist/agent/theme.js +41 -0
  25. package/dist/agent/tools/index.js +76 -0
  26. package/dist/agent/tools/market/client.js +41 -0
  27. package/dist/agent/tools/market/index.js +3 -0
  28. package/dist/agent/tools/market/tools.js +518 -0
  29. package/dist/agent/tools/mindshare/client.js +124 -0
  30. package/dist/agent/tools/mindshare/index.js +3 -0
  31. package/dist/agent/tools/mindshare/tools.js +563 -0
  32. package/dist/agent/tools/read-skill-tool.js +30 -0
  33. package/dist/agent/tools/ta/index.js +1 -0
  34. package/dist/agent/tools/ta/indicators.js +201 -0
  35. package/dist/agent/types.js +1 -0
  36. package/dist/agents.js +110 -0
  37. package/dist/ai-providers.js +66 -0
  38. package/dist/avatar.js +34 -0
  39. package/dist/backtest/default-backtest-data.js +200 -0
  40. package/dist/backtest/fetch.js +41 -0
  41. package/dist/backtest/import.js +106 -0
  42. package/dist/backtest/index.js +10 -0
  43. package/dist/backtest/results.js +113 -0
  44. package/dist/backtest/runner.js +134 -0
  45. package/dist/backtest/storage.js +11 -0
  46. package/dist/backtest/types.js +1 -0
  47. package/dist/commands/create/ai-generate.js +126 -0
  48. package/dist/commands/create/commands/index.js +10 -0
  49. package/dist/commands/create/generate.js +73 -0
  50. package/dist/commands/create/presets/data.js +225 -0
  51. package/dist/commands/create/presets/formatting.js +81 -0
  52. package/dist/commands/create/presets/index.js +3 -0
  53. package/dist/commands/create/presets/options.js +307 -0
  54. package/dist/commands/create/presets/types.js +1 -0
  55. package/dist/commands/create/presets.js +613 -0
  56. package/dist/commands/create/ui/CreateApp.js +172 -0
  57. package/dist/commands/create/ui/steps/ApiKeyStep.js +89 -0
  58. package/dist/commands/create/ui/steps/AvatarStep.js +16 -0
  59. package/dist/commands/create/ui/steps/DoneStep.js +14 -0
  60. package/dist/commands/create/ui/steps/IdentityStep.js +125 -0
  61. package/dist/commands/create/ui/steps/NameStep.js +148 -0
  62. package/dist/commands/create/ui/steps/ScaffoldStep.js +59 -0
  63. package/dist/commands/create/ui/steps/SoulStep.js +21 -0
  64. package/dist/commands/create/ui/steps/StrategyStep.js +20 -0
  65. package/dist/commands/create/ui/steps/StreamingGenerationStep.js +56 -0
  66. package/dist/commands/create/ui/validation.js +34 -0
  67. package/dist/commands/create/validate-api-key.js +27 -0
  68. package/dist/commands/install.js +50 -0
  69. package/dist/commands/list/commands/index.js +7 -0
  70. package/dist/commands/list/ui/ListApp.js +79 -0
  71. package/dist/commands/migrate-templates/commands/index.js +9 -0
  72. package/dist/commands/migrate-templates/migrate.js +87 -0
  73. package/dist/commands/migrate-templates/ui/MigrateApp.js +132 -0
  74. package/dist/commands/run/commands/index.js +17 -0
  75. package/dist/commands/run/run-headless.js +111 -0
  76. package/dist/commands/shared/theme.js +57 -0
  77. package/dist/commands/shared/welcome.js +304 -0
  78. package/dist/commands/start/commands/backtest.js +35 -0
  79. package/dist/commands/start/commands/index.js +62 -0
  80. package/dist/commands/start/commands/prediction.js +73 -0
  81. package/dist/commands/start/commands/skills.js +44 -0
  82. package/dist/commands/start/commands/skills.test.js +140 -0
  83. package/dist/commands/start/hooks/types.js +1 -0
  84. package/dist/commands/start/hooks/useAgent.js +177 -0
  85. package/dist/commands/start/hooks/useChat.js +266 -0
  86. package/dist/commands/start/hooks/usePollActivity.js +45 -0
  87. package/dist/commands/start/hooks/utils.js +152 -0
  88. package/dist/commands/start/services/backtest/default-backtest-data.js +200 -0
  89. package/dist/commands/start/services/backtest/fetch.js +42 -0
  90. package/dist/commands/start/services/backtest/import.js +109 -0
  91. package/dist/commands/start/services/backtest/index.js +10 -0
  92. package/dist/commands/start/services/backtest/results.js +113 -0
  93. package/dist/commands/start/services/backtest/runner.js +103 -0
  94. package/dist/commands/start/services/backtest/storage.js +11 -0
  95. package/dist/commands/start/services/backtest/types.js +1 -0
  96. package/dist/commands/start/services/command-registry.js +13 -0
  97. package/dist/commands/start/ui/AsciiTicker.js +81 -0
  98. package/dist/commands/start/ui/CommandInput.js +65 -0
  99. package/dist/commands/start/ui/HoneycombBoot.js +291 -0
  100. package/dist/commands/start/ui/PollText.js +23 -0
  101. package/dist/commands/start/ui/PredictionsPanel.js +88 -0
  102. package/dist/commands/start/ui/SelectAgentApp.js +93 -0
  103. package/dist/commands/start/ui/Spinner.js +29 -0
  104. package/dist/commands/start/ui/SpinnerContext.js +20 -0
  105. package/dist/commands/start/ui/app.js +36 -0
  106. package/dist/commands/start-all/AgentProcessManager.js +98 -0
  107. package/dist/commands/start-all/commands/index.js +24 -0
  108. package/dist/commands/start-all/ui/Dashboard.js +91 -0
  109. package/dist/components/AsciiTicker.js +81 -0
  110. package/dist/components/CharacterSummaryCard.js +33 -0
  111. package/dist/components/CodeBlock.js +11 -0
  112. package/dist/components/ColoredStats.js +18 -0
  113. package/dist/components/Header.js +10 -0
  114. package/dist/components/HoneycombLoader.js +190 -0
  115. package/dist/components/InputGuard.js +6 -0
  116. package/dist/components/MultiSelectPrompt.js +45 -0
  117. package/dist/components/SelectPrompt.js +20 -0
  118. package/dist/components/Spinner.js +16 -0
  119. package/dist/components/StepIndicator.js +31 -0
  120. package/dist/components/StreamingText.js +50 -0
  121. package/dist/components/TextPrompt.js +28 -0
  122. package/dist/components/stdout-spinner.js +48 -0
  123. package/dist/config.js +28 -0
  124. package/dist/create/CreateApp.js +153 -0
  125. package/dist/create/ai-generate.js +147 -0
  126. package/dist/create/generate.js +73 -0
  127. package/dist/create/steps/ApiKeyStep.js +97 -0
  128. package/dist/create/steps/AvatarStep.js +16 -0
  129. package/dist/create/steps/BioStep.js +14 -0
  130. package/dist/create/steps/DoneStep.js +14 -0
  131. package/dist/create/steps/IdentityStep.js +163 -0
  132. package/dist/create/steps/NameStep.js +71 -0
  133. package/dist/create/steps/ScaffoldStep.js +58 -0
  134. package/dist/create/steps/SoulStep.js +58 -0
  135. package/dist/create/steps/StrategyStep.js +58 -0
  136. package/dist/create/validate-api-key.js +47 -0
  137. package/dist/create/welcome.js +304 -0
  138. package/dist/index.js +60 -0
  139. package/dist/list/ListApp.js +79 -0
  140. package/dist/load-agent-env.js +30 -0
  141. package/dist/migrate-templates/MigrateApp.js +131 -0
  142. package/dist/migrate-templates/migrate.js +86 -0
  143. package/dist/presets.js +613 -0
  144. package/dist/shared/agent/agent-runtime.js +144 -0
  145. package/dist/shared/agent/analysis.js +171 -0
  146. package/dist/shared/agent/helpers.js +1 -0
  147. package/dist/shared/agent/prompts/chat-prompt.js +60 -0
  148. package/dist/shared/agent/prompts/megathread.js +202 -0
  149. package/dist/shared/agent/prompts/memory-prompt.js +47 -0
  150. package/dist/shared/agent/prompts/prompt.js +18 -0
  151. package/dist/shared/agent/skills/index.js +2 -0
  152. package/dist/shared/agent/skills/skill-parser.js +167 -0
  153. package/dist/shared/agent/skills/skill-parser.test.js +190 -0
  154. package/dist/shared/agent/skills/types.js +1 -0
  155. package/dist/shared/agent/tools/edit-section.js +60 -0
  156. package/dist/shared/agent/tools/execute-skill-tool.js +134 -0
  157. package/dist/shared/agent/tools/fetch-rules.js +22 -0
  158. package/dist/shared/agent/tools/formatting.js +48 -0
  159. package/dist/shared/agent/tools/index.js +87 -0
  160. package/dist/shared/agent/tools/market/client.js +41 -0
  161. package/dist/shared/agent/tools/market/index.js +3 -0
  162. package/dist/shared/agent/tools/market/tools.js +497 -0
  163. package/dist/shared/agent/tools/mindshare/client.js +124 -0
  164. package/dist/shared/agent/tools/mindshare/index.js +3 -0
  165. package/dist/shared/agent/tools/mindshare/tools.js +167 -0
  166. package/dist/shared/agent/tools/read-skill-tool.js +30 -0
  167. package/dist/shared/agent/tools/ta/index.js +1 -0
  168. package/dist/shared/agent/tools/ta/indicators.js +201 -0
  169. package/dist/shared/agent/types.js +1 -0
  170. package/dist/shared/agent/utils.js +43 -0
  171. package/dist/shared/config/agent.js +177 -0
  172. package/dist/shared/config/ai-providers.js +156 -0
  173. package/dist/shared/config/config.js +22 -0
  174. package/dist/shared/config/constant.js +8 -0
  175. package/dist/shared/config/env-loader.js +30 -0
  176. package/dist/shared/types.js +1 -0
  177. package/dist/start/AgentProcessManager.js +98 -0
  178. package/dist/start/Dashboard.js +92 -0
  179. package/dist/start/SelectAgentApp.js +81 -0
  180. package/dist/start/StartApp.js +189 -0
  181. package/dist/start/patch-headless.js +101 -0
  182. package/dist/start/patch-managed-mode.js +142 -0
  183. package/dist/start/start-command.js +24 -0
  184. package/dist/theme.js +54 -0
  185. package/package.json +68 -0
  186. package/templates/components/HoneycombBoot.tsx +343 -0
  187. package/templates/fetch-rules.ts +23 -0
  188. package/templates/skills/mindshare/SKILL.md +197 -0
  189. package/templates/skills/ta/SKILL.md +179 -0
@@ -0,0 +1,79 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from 'react';
3
+ import { Box, Text, useApp } from 'ink';
4
+ import { colors, symbols, border } from '../theme.js';
5
+ import { scanAgents, fetchBulkStats, sortByHoney } from '../agents.js';
6
+ const COL = {
7
+ name: 0,
8
+ honey: 8,
9
+ wax: 8,
10
+ winRate: 10,
11
+ confidence: 8,
12
+ provider: 0,
13
+ created: 14,
14
+ };
15
+ function cell(text, width) {
16
+ return ` ${text}`.padEnd(width);
17
+ }
18
+ function formatDate(date) {
19
+ const formatted = date.toLocaleDateString('en-US', {
20
+ year: 'numeric',
21
+ month: 'short',
22
+ day: 'numeric',
23
+ });
24
+ return formatted;
25
+ }
26
+ export function ListApp() {
27
+ const { exit } = useApp();
28
+ const [rows, setRows] = useState(null);
29
+ useEffect(() => {
30
+ const load = async () => {
31
+ const agents = await scanAgents();
32
+ if (agents.length === 0) {
33
+ setRows([]);
34
+ return;
35
+ }
36
+ const names = agents.map((a) => a.name);
37
+ const statsMap = await fetchBulkStats(names);
38
+ const agentRows = agents.map((info) => ({
39
+ info,
40
+ stats: statsMap.get(info.name) ?? null,
41
+ }));
42
+ const sortedRows = sortByHoney(agentRows);
43
+ setRows(sortedRows);
44
+ };
45
+ void load();
46
+ }, []);
47
+ useEffect(() => {
48
+ if (rows !== null) {
49
+ exit();
50
+ }
51
+ }, [rows]);
52
+ if (rows === null) {
53
+ return (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: colors.gray, children: "Scanning agents..." }) }));
54
+ }
55
+ if (rows.length === 0) {
56
+ return (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: colors.honey, children: [symbols.hive, " "] }), _jsx(Text, { color: colors.white, bold: true, children: "No agents found" })] }), _jsxs(Text, { color: colors.gray, children: ["Create one with: ", _jsx(Text, { color: colors.white, children: "npx @hive-org/cli@latest create" })] })] }));
57
+ }
58
+ const nameW = Math.max(COL.name, ...rows.map((r) => r.info.name.length)) + 2;
59
+ const providerW = Math.max(COL.provider, ...rows.map((r) => r.info.provider.length)) + 2;
60
+ const honeyW = COL.honey;
61
+ const waxW = COL.wax;
62
+ const winRateW = COL.winRate;
63
+ const confidenceW = COL.confidence;
64
+ const createdW = COL.created;
65
+ const sep = border.horizontal;
66
+ const totalWidth = nameW + 1 + honeyW + 1 + waxW + 1 + winRateW + 1 + confidenceW + 1 + providerW + 1 + createdW;
67
+ const topBorder = `${border.topLeft}${sep.repeat(totalWidth)}${border.topRight}`;
68
+ const midBorder = `${border.teeLeft}${sep.repeat(totalWidth)}${border.teeRight}`;
69
+ const botBorder = `${border.bottomLeft}${sep.repeat(totalWidth)}${border.bottomRight}`;
70
+ const v = border.vertical;
71
+ return (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: colors.honey, children: [symbols.hive, " "] }), _jsx(Text, { color: colors.white, bold: true, children: "Your Hive Agents" }), _jsxs(Text, { color: colors.grayDim, children: [" (", rows.length, ")"] })] }), _jsx(Box, { children: _jsx(Text, { color: colors.honey, children: topBorder }) }), _jsxs(Box, { children: [_jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.white, bold: true, children: cell('Name', nameW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.white, bold: true, children: cell('Honey', honeyW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.white, bold: true, children: cell('Wax', waxW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.white, bold: true, children: cell('Win Rate', winRateW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.white, bold: true, children: cell('Conf', confidenceW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.white, bold: true, children: cell('Provider', providerW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.white, bold: true, children: cell('Created', createdW) }), _jsx(Text, { color: colors.honey, children: v })] }), _jsx(Box, { children: _jsx(Text, { color: colors.honey, children: midBorder }) }), rows.map((row) => {
72
+ const s = row.stats;
73
+ const honeyText = s !== null ? String(Math.floor(s.honey)) : '-';
74
+ const waxText = s !== null ? String(Math.floor(s.wax)) : '-';
75
+ const winRateText = s !== null ? `${(s.win_rate * 100).toFixed(2)}%` : '-';
76
+ const confidenceText = s !== null ? s.confidence.toFixed(2) : '-';
77
+ return (_jsxs(Box, { children: [_jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.white, children: cell(row.info.name, nameW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.honey, children: cell(honeyText, honeyW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.wax, children: cell(waxText, waxW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.green, children: cell(winRateText, winRateW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.cyan, children: cell(confidenceText, confidenceW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.gray, children: cell(row.info.provider, providerW) }), _jsx(Text, { color: colors.honey, children: v }), _jsx(Text, { color: colors.grayDim, children: cell(formatDate(row.info.created), createdW) }), _jsx(Text, { color: colors.honey, children: v })] }, row.info.name));
78
+ }), _jsx(Box, { children: _jsx(Text, { color: colors.honey, children: botBorder }) })] }));
79
+ }
@@ -0,0 +1,30 @@
1
+ import { readFileSync } from 'fs';
2
+ import { AI_PROVIDER_ENV_VARS } from './ai-providers.js';
3
+ let _agentProviderKeys = new Set();
4
+ /**
5
+ * Provider env-var names declared in the agent's .env file.
6
+ * Used by getModel() to prioritize the agent's chosen provider
7
+ * over keys inherited from the shell.
8
+ */
9
+ export function getAgentProviderKeys() {
10
+ return _agentProviderKeys;
11
+ }
12
+ /**
13
+ * Load the agent's .env with provider-key priority.
14
+ *
15
+ * 1. Parse .env to discover which provider keys the agent declared.
16
+ * 2. Load .env with override so the agent's values win for the same key.
17
+ * 3. getModel() uses getAgentProviderKeys() to check those providers first,
18
+ * falling back to shell-inherited keys if the agent has none.
19
+ */
20
+ export async function loadAgentEnv() {
21
+ try {
22
+ const content = readFileSync('.env', 'utf-8');
23
+ _agentProviderKeys = new Set(AI_PROVIDER_ENV_VARS.filter((key) => new RegExp(`^${key}=`, 'm').test(content)));
24
+ }
25
+ catch {
26
+ _agentProviderKeys = new Set();
27
+ }
28
+ const { config } = await import('dotenv');
29
+ config({ override: true });
30
+ }
@@ -0,0 +1,131 @@
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState, useEffect, useCallback } from 'react';
3
+ import { Box, Text, useInput, useApp } from 'ink';
4
+ import { scanAgents } from '../agents.js';
5
+ import { colors, symbols, styled, border } from '../theme.js';
6
+ import { isOldStyleAgent, migrateAgent } from './migrate.js';
7
+ export function MigrateApp() {
8
+ const { exit } = useApp();
9
+ const [phase, setPhase] = useState('scanning');
10
+ const [agents, setAgents] = useState([]);
11
+ const [cursor, setCursor] = useState(0);
12
+ const [results, setResults] = useState([]);
13
+ const [currentStep, setCurrentStep] = useState('');
14
+ const [currentAgent, setCurrentAgent] = useState('');
15
+ // ─── Scan phase ────────────────────────────────────
16
+ useEffect(() => {
17
+ const scan = async () => {
18
+ const discovered = await scanAgents();
19
+ if (discovered.length === 0) {
20
+ setPhase('done');
21
+ return;
22
+ }
23
+ const selectableAgents = discovered.map((info) => {
24
+ const oldStyle = isOldStyleAgent(info.dir);
25
+ return {
26
+ info,
27
+ selected: oldStyle,
28
+ isOldStyle: oldStyle,
29
+ };
30
+ });
31
+ const hasOldStyle = selectableAgents.some((a) => a.isOldStyle);
32
+ if (!hasOldStyle) {
33
+ setResults(selectableAgents.map((a) => ({
34
+ name: a.info.name,
35
+ success: true,
36
+ error: 'Already migrated',
37
+ })));
38
+ setPhase('done');
39
+ return;
40
+ }
41
+ setAgents(selectableAgents);
42
+ setPhase('selecting');
43
+ };
44
+ scan().catch((err) => {
45
+ const message = err instanceof Error ? err.message : String(err);
46
+ setResults([{ name: 'scan', success: false, error: message }]);
47
+ setPhase('done');
48
+ });
49
+ }, []);
50
+ // ─── Keyboard input (selecting phase) ──────────────
51
+ useInput((input, key) => {
52
+ if (phase !== 'selecting')
53
+ return;
54
+ const oldStyleAgents = agents.filter((a) => a.isOldStyle);
55
+ if (key.upArrow) {
56
+ setCursor((prev) => Math.max(0, prev - 1));
57
+ }
58
+ else if (key.downArrow) {
59
+ setCursor((prev) => Math.min(oldStyleAgents.length - 1, prev + 1));
60
+ }
61
+ else if (input === ' ') {
62
+ // Toggle selection
63
+ const targetName = oldStyleAgents[cursor]?.info.name;
64
+ if (targetName) {
65
+ setAgents((prev) => prev.map((a) => a.info.name === targetName ? { ...a, selected: !a.selected } : a));
66
+ }
67
+ }
68
+ else if (key.return) {
69
+ const selected = agents.filter((a) => a.selected && a.isOldStyle);
70
+ if (selected.length > 0) {
71
+ setPhase('migrating');
72
+ runMigrations(selected);
73
+ }
74
+ }
75
+ else if (input === 'q' || key.escape) {
76
+ exit();
77
+ }
78
+ }, { isActive: phase === 'selecting' });
79
+ // ─── Migrate phase ─────────────────────────────────
80
+ const runMigrations = useCallback(async (selected) => {
81
+ const migrateResults = [];
82
+ for (const agent of selected) {
83
+ setCurrentAgent(agent.info.name);
84
+ setCurrentStep('Starting migration');
85
+ const result = await migrateAgent(agent.info.dir, agent.info.name, (step) => {
86
+ setCurrentStep(step);
87
+ });
88
+ migrateResults.push(result);
89
+ setResults([...migrateResults]);
90
+ }
91
+ setCurrentAgent('');
92
+ setCurrentStep('');
93
+ setPhase('done');
94
+ }, []);
95
+ // ─── Done phase — exit after a short delay ─────────
96
+ useEffect(() => {
97
+ if (phase === 'done') {
98
+ const timer = setTimeout(() => {
99
+ exit();
100
+ }, 1500);
101
+ return () => {
102
+ clearTimeout(timer);
103
+ };
104
+ }
105
+ }, [phase, exit]);
106
+ // ─── Render ────────────────────────────────────────
107
+ const termWidth = process.stdout.columns || 60;
108
+ if (phase === 'scanning') {
109
+ return (_jsx(Box, { flexDirection: "column", paddingLeft: 1, children: _jsxs(Text, { color: colors.honey, children: [symbols.hive, " Scanning agents..."] }) }));
110
+ }
111
+ if (phase === 'selecting') {
112
+ const oldStyleAgents = agents.filter((a) => a.isOldStyle);
113
+ const newStyleAgents = agents.filter((a) => !a.isOldStyle);
114
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsxs(Text, { color: colors.honey, bold: true, children: [symbols.hive, " Migrate agents to @hive-org/cli"] }), _jsx(Text, { color: colors.gray, children: border.horizontal.repeat(termWidth - 4) }), _jsxs(Text, { color: colors.gray, children: ["Use ", styled.white('↑↓'), " to navigate, ", styled.white('space'), " to toggle, ", styled.white('enter'), " to confirm"] }), _jsx(Text, { children: " " }), oldStyleAgents.map((agent, i) => {
115
+ const isCursor = i === cursor;
116
+ const prefix = agent.selected ? symbols.check : symbols.diamondOpen;
117
+ const prefixColor = agent.selected ? colors.green : colors.gray;
118
+ const nameColor = isCursor ? colors.white : colors.gray;
119
+ const cursorChar = isCursor ? symbols.arrow : ' ';
120
+ return (_jsxs(Box, { children: [_jsxs(Text, { color: colors.honey, children: [cursorChar, " "] }), _jsxs(Text, { color: prefixColor, children: [prefix, " "] }), _jsx(Text, { color: nameColor, bold: isCursor, children: agent.info.name }), _jsxs(Text, { color: colors.gray, children: [" (", agent.info.provider, ")"] })] }, agent.info.name));
121
+ }), newStyleAgents.length > 0 && (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsx(Text, { color: colors.gray, children: "Already migrated:" }), newStyleAgents.map((agent) => (_jsx(Box, { children: _jsxs(Text, { color: colors.gray, children: [' ', symbols.check, " ", agent.info.name] }) }, agent.info.name)))] })), _jsx(Text, { children: " " }), _jsx(Text, { color: colors.gray, children: styled.dim('q/esc to cancel') })] }));
122
+ }
123
+ if (phase === 'migrating') {
124
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsxs(Text, { color: colors.honey, bold: true, children: [symbols.hive, " Migrating agents..."] }), _jsx(Text, { color: colors.gray, children: border.horizontal.repeat(termWidth - 4) }), results.map((r) => (_jsx(Box, { children: _jsxs(Text, { color: r.success ? colors.green : colors.red, children: [r.success ? symbols.check : symbols.cross, " ", r.name] }) }, r.name))), currentAgent && (_jsx(Box, { children: _jsxs(Text, { color: colors.honey, children: [symbols.diamond, " ", currentAgent, ": ", currentStep] }) }))] }));
125
+ }
126
+ // phase === 'done'
127
+ const successCount = results.filter((r) => r.success && !r.error).length;
128
+ const alreadyNew = results.filter((r) => r.error === 'Already migrated').length;
129
+ const failCount = results.filter((r) => !r.success).length;
130
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsxs(Text, { color: colors.honey, bold: true, children: [symbols.hive, " Migration complete"] }), _jsx(Text, { color: colors.gray, children: border.horizontal.repeat(termWidth - 4) }), results.map((r) => (_jsxs(Box, { children: [r.success && !r.error && (_jsxs(Text, { color: colors.green, children: [symbols.check, " ", r.name, " \u2014 migrated"] })), r.error === 'Already migrated' && (_jsxs(Text, { color: colors.gray, children: [symbols.check, " ", r.name, " \u2014 already migrated"] })), !r.success && r.error !== 'Already migrated' && (_jsxs(Text, { color: colors.red, children: [symbols.cross, " ", r.name, " \u2014 ", r.error] }))] }, r.name))), agents.length === 0 && results.length === 0 && (_jsx(Text, { color: colors.gray, children: "No agents found in ~/.hive/agents/" })), _jsx(Text, { children: " " }), successCount > 0 && (_jsxs(Text, { color: colors.gray, children: ["Agents now run via @hive-org/cli. ", styled.white('npx @hive-org/cli@latest start'), " always uses the latest version."] }))] }));
131
+ }
@@ -0,0 +1,86 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ /** Files scaffolded by the old `hive create` that are now in @hive-org/cli */
4
+ const OLD_FILES = [
5
+ 'index.tsx',
6
+ 'analysis.ts',
7
+ 'prompt.ts',
8
+ 'chat-prompt.ts',
9
+ 'memory-prompt.ts',
10
+ 'edit-section.ts',
11
+ 'fetch-rules.ts',
12
+ 'helpers.ts',
13
+ 'theme.ts',
14
+ 'types.ts',
15
+ 'process-lifecycle.ts',
16
+ 'tsconfig.json',
17
+ ];
18
+ /** Directories scaffolded by the old `hive create` */
19
+ const OLD_DIRS = ['hooks', 'components', 'hive'];
20
+ export function isOldStyleAgent(agentDir) {
21
+ const indexPath = path.join(agentDir, 'index.tsx');
22
+ return fs.pathExistsSync(indexPath);
23
+ }
24
+ export async function migrateAgent(agentDir, name, onStep) {
25
+ try {
26
+ // 1. Verify it's a valid agent
27
+ const soulPath = path.join(agentDir, 'SOUL.md');
28
+ const soulExists = await fs.pathExists(soulPath);
29
+ if (!soulExists) {
30
+ return { name, success: false, error: 'No SOUL.md found — not a valid agent' };
31
+ }
32
+ // 2. Delete old scaffolded files
33
+ onStep('Removing old runtime files');
34
+ for (const file of OLD_FILES) {
35
+ const filePath = path.join(agentDir, file);
36
+ const exists = await fs.pathExists(filePath);
37
+ if (exists) {
38
+ await fs.remove(filePath);
39
+ }
40
+ }
41
+ // 3. Delete old directories
42
+ onStep('Removing old directories');
43
+ for (const dir of OLD_DIRS) {
44
+ const dirPath = path.join(agentDir, dir);
45
+ const exists = await fs.pathExists(dirPath);
46
+ if (exists) {
47
+ await fs.remove(dirPath);
48
+ }
49
+ }
50
+ // 4. Rewrite package.json
51
+ onStep('Rewriting package.json');
52
+ const pkgPath = path.join(agentDir, 'package.json');
53
+ const pkgExists = await fs.pathExists(pkgPath);
54
+ let pkgName = `hive-agent-${name}`;
55
+ if (pkgExists) {
56
+ const oldPkg = await fs.readJson(pkgPath);
57
+ pkgName = oldPkg.name ?? pkgName;
58
+ }
59
+ const newPkg = {
60
+ name: pkgName,
61
+ private: true,
62
+ type: 'module',
63
+ scripts: {
64
+ start: 'npx @hive-org/cli@latest start',
65
+ },
66
+ };
67
+ await fs.writeJson(pkgPath, newPkg, { spaces: 2 });
68
+ // 5. Remove old node_modules and lock files (no longer needed)
69
+ onStep('Cleaning up old dependencies');
70
+ const nodeModulesPath = path.join(agentDir, 'node_modules');
71
+ const nodeModulesExists = await fs.pathExists(nodeModulesPath);
72
+ if (nodeModulesExists) {
73
+ await fs.remove(nodeModulesPath);
74
+ }
75
+ const lockPath = path.join(agentDir, 'package-lock.json');
76
+ const lockExists = await fs.pathExists(lockPath);
77
+ if (lockExists) {
78
+ await fs.remove(lockPath);
79
+ }
80
+ return { name, success: true };
81
+ }
82
+ catch (err) {
83
+ const message = err instanceof Error ? err.message : String(err);
84
+ return { name, success: false, error: message.slice(0, 200) };
85
+ }
86
+ }