@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,172 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useCallback } from 'react';
3
+ import { Box, Text, useApp } from 'ink';
4
+ import { Header } from '../../../components/Header.js';
5
+ import { AsciiTicker } from '../../../components/AsciiTicker.js';
6
+ import { StepIndicator } from '../../../components/StepIndicator.js';
7
+ import { ApiKeyStep } from './steps/ApiKeyStep.js';
8
+ import { NameStep } from './steps/NameStep.js';
9
+ import { IdentityStep } from './steps/IdentityStep.js';
10
+ import { AvatarStep } from './steps/AvatarStep.js';
11
+ import { SoulStep } from './steps/SoulStep.js';
12
+ import { StrategyStep } from './steps/StrategyStep.js';
13
+ import { ScaffoldStep } from './steps/ScaffoldStep.js';
14
+ import { DoneStep } from './steps/DoneStep.js';
15
+ import { colors, symbols } from '../../shared/theme.js';
16
+ import { getProvider } from '../../../shared/config/ai-providers.js';
17
+ function ensureAvatarUrl(content, avatarUrl) {
18
+ const lines = content.split('\n');
19
+ const avatarIdx = lines.findIndex((l) => /^## Avatar/.test(l));
20
+ if (avatarIdx === -1) {
21
+ return content;
22
+ }
23
+ // Find the next section header after ## Avatar
24
+ let nextSectionIdx = lines.length;
25
+ for (let i = avatarIdx + 1; i < lines.length; i++) {
26
+ if (/^##?\s/.test(lines[i])) {
27
+ nextSectionIdx = i;
28
+ break;
29
+ }
30
+ }
31
+ // Replace the content between ## Avatar and next section with the raw URL
32
+ const before = lines.slice(0, avatarIdx + 1);
33
+ const after = lines.slice(nextSectionIdx);
34
+ const result = [...before, '', avatarUrl, '', ...after];
35
+ return result.join('\n');
36
+ }
37
+ function ensureSectionLine(content, sectionHeader, linePrefix, value) {
38
+ const lines = content.split('\n');
39
+ const sectionIdx = lines.findIndex((l) => new RegExp(`^##\\s+${sectionHeader}`).test(l));
40
+ if (sectionIdx === -1) {
41
+ // Section missing — append it at the end
42
+ return content + `\n\n## ${sectionHeader}\n\n${linePrefix} ${value}\n`;
43
+ }
44
+ // Find the next section header after this one
45
+ let nextSectionIdx = lines.length;
46
+ for (let i = sectionIdx + 1; i < lines.length; i++) {
47
+ if (/^##?\s/.test(lines[i])) {
48
+ nextSectionIdx = i;
49
+ break;
50
+ }
51
+ }
52
+ // Look for existing line with the prefix in this section
53
+ const escapedPrefix = linePrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
54
+ const prefixRegex = new RegExp(`^${escapedPrefix}\\s`);
55
+ const lineIdx = lines.findIndex((l, i) => i > sectionIdx && i < nextSectionIdx && prefixRegex.test(l));
56
+ if (lineIdx !== -1) {
57
+ // Replace the existing line
58
+ lines[lineIdx] = `${linePrefix} ${value}`;
59
+ }
60
+ else {
61
+ // Insert after the section header (skip blank lines)
62
+ let insertIdx = sectionIdx + 1;
63
+ while (insertIdx < nextSectionIdx && lines[insertIdx].trim() === '') {
64
+ insertIdx++;
65
+ }
66
+ lines.splice(insertIdx, 0, `${linePrefix} ${value}`);
67
+ }
68
+ // Remove duplicate/malformed lines with the same prefix (e.g. "- Active timeframes" without value)
69
+ const loosePrefix = linePrefix.replace(/:$/, '');
70
+ const looseRegex = new RegExp(`^${loosePrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(\\s|$)`);
71
+ const canonicalLine = `${linePrefix} ${value}`;
72
+ for (let i = nextSectionIdx - 1; i > sectionIdx; i--) {
73
+ if (looseRegex.test(lines[i]) && lines[i] !== canonicalLine) {
74
+ lines.splice(i, 1);
75
+ }
76
+ }
77
+ return lines.join('\n');
78
+ }
79
+ function ensureStrategyFields(content, sectors, sentiment, timeframes) {
80
+ const sectorsLine = sectors.length > 0 ? sectors.join(', ') : 'all categories';
81
+ const timeframesLine = timeframes.length > 0 ? timeframes.join(', ') : '1h, 4h, 24h';
82
+ let patched = ensureSectionLine(content, 'Sentiment', '- Bias:', sentiment);
83
+ patched = ensureSectionLine(patched, 'Sector Focus', '- Sectors:', sectorsLine);
84
+ patched = ensureSectionLine(patched, 'Timeframe', '- Active timeframes:', timeframesLine);
85
+ return patched;
86
+ }
87
+ const STEP_ORDER = [
88
+ 'name',
89
+ 'identity',
90
+ 'avatar',
91
+ 'api-key',
92
+ 'soul',
93
+ 'strategy',
94
+ 'scaffold',
95
+ 'done',
96
+ ];
97
+ const STEP_LABELS = {
98
+ 'api-key': 'API Key',
99
+ name: 'Name',
100
+ identity: 'Identity',
101
+ avatar: 'Avatar',
102
+ soul: 'Soul',
103
+ strategy: 'Strategy',
104
+ scaffold: 'Scaffold',
105
+ done: 'Done',
106
+ };
107
+ const STEP_DEFS = STEP_ORDER.map((s) => ({ key: s, label: STEP_LABELS[s] }));
108
+ export function CreateApp({ initialName }) {
109
+ const { exit } = useApp();
110
+ const [step, setStep] = useState(initialName ? 'identity' : 'name');
111
+ const [providerId, setProviderId] = useState(null);
112
+ const [apiKey, setApiKey] = useState('');
113
+ const [agentName, setAgentName] = useState(initialName ?? '');
114
+ const [bio, setBio] = useState('');
115
+ const [personality, setPersonality] = useState('');
116
+ const [tone, setTone] = useState('');
117
+ const [voiceStyle, setVoiceStyle] = useState('');
118
+ const [tradingStyle, setTradingStyle] = useState('');
119
+ const [sectors, setSectors] = useState([]);
120
+ const [sentiment, setSentiment] = useState('');
121
+ const [timeframes, setTimeframes] = useState([]);
122
+ const [avatarUrl, setAvatarUrl] = useState('');
123
+ const [soulContent, setSoulContent] = useState('');
124
+ const [strategyContent, setStrategyContent] = useState('');
125
+ const [resolvedProjectDir, setResolvedProjectDir] = useState('');
126
+ const [error, setError] = useState('');
127
+ const stepIndex = STEP_ORDER.indexOf(step);
128
+ const provider = providerId ? getProvider(providerId) : null;
129
+ const handleApiKey = useCallback((result) => {
130
+ setProviderId(result.providerId);
131
+ setApiKey(result.apiKey);
132
+ setStep('soul');
133
+ }, []);
134
+ const handleName = useCallback((name) => {
135
+ setAgentName(name);
136
+ setStep('identity');
137
+ }, []);
138
+ const handleIdentity = useCallback((result) => {
139
+ setPersonality(result.personality);
140
+ setTone(result.tone);
141
+ setVoiceStyle(result.voiceStyle);
142
+ setTradingStyle(result.tradingStyle);
143
+ setSectors(result.sectors);
144
+ setSentiment(result.sentiment);
145
+ setTimeframes(result.timeframes);
146
+ setBio(result.bio);
147
+ setStep('avatar');
148
+ }, []);
149
+ const handleAvatar = useCallback((value) => {
150
+ setAvatarUrl(value);
151
+ setStep('api-key');
152
+ }, []);
153
+ const handleSoul = useCallback((content) => {
154
+ const patched = ensureAvatarUrl(content, avatarUrl);
155
+ setSoulContent(patched);
156
+ setStep('strategy');
157
+ }, [avatarUrl]);
158
+ const handleStrategy = useCallback((content) => {
159
+ const patched = ensureStrategyFields(content, sectors, sentiment, timeframes);
160
+ setStrategyContent(patched);
161
+ setStep('scaffold');
162
+ }, [sectors, sentiment, timeframes]);
163
+ const handleScaffoldComplete = useCallback((projectDir) => {
164
+ setResolvedProjectDir(projectDir);
165
+ setStep('done');
166
+ }, []);
167
+ const handleScaffoldError = useCallback((message) => {
168
+ setError(message);
169
+ exit();
170
+ }, [exit]);
171
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, {}), _jsx(StepIndicator, { steps: STEP_DEFS, currentIndex: stepIndex }), step !== 'done' && (_jsx(Box, { marginBottom: 1, children: _jsx(AsciiTicker, { step: stepIndex + 1 }) })), step === 'api-key' && _jsx(ApiKeyStep, { onComplete: handleApiKey }), step === 'name' && _jsx(NameStep, { onComplete: handleName }), step === 'identity' && _jsx(IdentityStep, { agentName: agentName, onComplete: handleIdentity }), step === 'avatar' && _jsx(AvatarStep, { agentName: agentName, onComplete: handleAvatar }), step === 'soul' && providerId && (_jsx(SoulStep, { providerId: providerId, apiKey: apiKey, agentName: agentName, bio: bio, avatarUrl: avatarUrl, personality: personality, tone: tone, voiceStyle: voiceStyle, tradingStyle: tradingStyle, sectors: sectors, sentiment: sentiment, timeframes: timeframes, onComplete: handleSoul })), step === 'strategy' && providerId && (_jsx(StrategyStep, { providerId: providerId, apiKey: apiKey, agentName: agentName, bio: bio, personality: personality, tone: tone, voiceStyle: voiceStyle, tradingStyle: tradingStyle, sectors: sectors, sentiment: sentiment, timeframes: timeframes, onComplete: handleStrategy })), step === 'scaffold' && provider && (_jsx(ScaffoldStep, { projectName: agentName, provider: provider, apiKey: apiKey, soulContent: soulContent, strategyContent: strategyContent, onComplete: handleScaffoldComplete, onError: handleScaffoldError })), step === 'done' && _jsx(DoneStep, { projectDir: resolvedProjectDir }), error !== '' && (_jsx(Box, { marginTop: 1, marginLeft: 2, children: _jsxs(Text, { color: colors.red, children: [symbols.cross, " ", error] }) }))] }));
172
+ }
@@ -0,0 +1,89 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from 'react';
3
+ import { Box, Text } from 'ink';
4
+ import { SelectPrompt } from '../../../../components/SelectPrompt.js';
5
+ import { TextPrompt } from '../../../../components/TextPrompt.js';
6
+ import { Spinner } from '../../../../components/Spinner.js';
7
+ import { colors, symbols } from '../../../shared/theme.js';
8
+ import { AI_PROVIDERS } from '../../../../shared/config/ai-providers.js';
9
+ import { validateApiKey } from '../../validate-api-key.js';
10
+ import { readConfig, writeConfig } from '../../../../shared/config/config.js';
11
+ import { apiKey as validateApiKeyFormat } from '../validation.js';
12
+ function maskKey(key) {
13
+ if (key.length <= 8) {
14
+ return '****';
15
+ }
16
+ const visible = key.slice(0, 4) + '...' + key.slice(-4);
17
+ return visible;
18
+ }
19
+ export function ApiKeyStep({ onComplete }) {
20
+ const [phase, setPhase] = useState('check-saved');
21
+ const [savedConfig, setSavedConfig] = useState(null);
22
+ const [providerId, setProviderId] = useState(null);
23
+ const [error, setError] = useState('');
24
+ useEffect(() => {
25
+ const loadConfig = async () => {
26
+ const config = await readConfig();
27
+ if (config) {
28
+ setSavedConfig(config);
29
+ setPhase('use-saved');
30
+ }
31
+ else {
32
+ setPhase('select-provider');
33
+ }
34
+ };
35
+ void loadConfig();
36
+ }, []);
37
+ const providerItems = AI_PROVIDERS.map((p) => ({
38
+ label: p.label,
39
+ value: p.id,
40
+ description: p.envVar,
41
+ }));
42
+ const handleProviderSelect = (item) => {
43
+ setProviderId(item.value);
44
+ setPhase('enter-key');
45
+ };
46
+ const handleKeySubmit = async (key, selectedProviderId) => {
47
+ setPhase('validating');
48
+ setError('');
49
+ const result = await validateApiKey(selectedProviderId, key);
50
+ if (result === true) {
51
+ await writeConfig({ providerId: selectedProviderId, apiKey: key });
52
+ onComplete({ providerId: selectedProviderId, apiKey: key });
53
+ }
54
+ else {
55
+ setError(result);
56
+ setPhase('error');
57
+ }
58
+ };
59
+ const handleUseSaved = async (item) => {
60
+ if (item.value === 'yes' && savedConfig) {
61
+ setPhase('validating');
62
+ const result = await validateApiKey(savedConfig.providerId, savedConfig.apiKey);
63
+ if (result === true) {
64
+ onComplete({ providerId: savedConfig.providerId, apiKey: savedConfig.apiKey });
65
+ }
66
+ else {
67
+ setError(`Saved key is no longer valid: ${result}`);
68
+ setPhase('select-provider');
69
+ }
70
+ }
71
+ else {
72
+ setPhase('select-provider');
73
+ }
74
+ };
75
+ const selectedProvider = providerId ? AI_PROVIDERS.find((p) => p.id === providerId) : null;
76
+ const savedProvider = savedConfig
77
+ ? AI_PROVIDERS.find((p) => p.id === savedConfig.providerId)
78
+ : null;
79
+ return (_jsxs(Box, { flexDirection: "column", children: [phase === 'check-saved' && _jsx(Spinner, { label: "Checking for saved API key..." }), phase === 'use-saved' && savedConfig && savedProvider && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, marginLeft: 2, children: _jsxs(Text, { color: colors.gray, children: [symbols.diamond, " Saved key: ", _jsx(Text, { color: colors.honey, children: savedProvider.label }), ' ', _jsxs(Text, { color: colors.grayDim, children: ["(", maskKey(savedConfig.apiKey), ")"] })] }) }), _jsx(SelectPrompt, { label: "Use saved API key?", items: [
80
+ { label: 'Yes, use saved key', value: 'yes' },
81
+ { label: 'No, enter a new key', value: 'no' },
82
+ ], onSelect: (item) => {
83
+ void handleUseSaved(item);
84
+ } })] })), phase === 'select-provider' && (_jsxs(Box, { flexDirection: "column", children: [error !== '' && (_jsx(Box, { marginBottom: 1, marginLeft: 2, children: _jsxs(Text, { color: colors.red, children: [symbols.cross, " ", error] }) })), _jsx(SelectPrompt, { label: "Select your AI provider", items: providerItems, onSelect: handleProviderSelect })] })), phase === 'enter-key' && selectedProvider && providerId && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: colors.gray, children: [symbols.diamond, " Provider: ", _jsx(Text, { color: colors.honey, children: selectedProvider.label })] }) }), _jsx(TextPrompt, { label: `Enter your ${selectedProvider.envVar}`, placeholder: "sk-...", onSubmit: (key) => {
85
+ void handleKeySubmit(key, providerId);
86
+ }, validate: validateApiKeyFormat })] })), phase === 'validating' && _jsx(Spinner, { label: "Validating API key..." }), phase === 'error' && providerId && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: colors.red, children: [symbols.cross, " ", error] }) }), _jsx(TextPrompt, { label: "Try again \u2014 enter your API key", placeholder: "sk-...", onSubmit: (key) => {
87
+ void handleKeySubmit(key, providerId);
88
+ }, validate: validateApiKeyFormat })] }))] }));
89
+ }
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { TextPrompt } from '../../../../components/TextPrompt.js';
4
+ import { colors, symbols } from '../../../shared/theme.js';
5
+ export function AvatarStep({ agentName, onComplete }) {
6
+ const defaultUrl = `https://api.dicebear.com/9.x/bottts-neutral/svg?seed=${encodeURIComponent(agentName)}`;
7
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, marginLeft: 2, children: _jsxs(Text, { color: colors.gray, children: [symbols.diamond, " Default: ", _jsx(Text, { color: colors.honey, children: defaultUrl })] }) }), _jsx(TextPrompt, { label: "Avatar image URL (press Enter for default)", placeholder: defaultUrl, onSubmit: (val) => onComplete(val || defaultUrl), validate: (val) => {
8
+ if (!val) {
9
+ return true;
10
+ }
11
+ if (!val.startsWith('http://') && !val.startsWith('https://')) {
12
+ return 'Must start with http:// or https://';
13
+ }
14
+ return true;
15
+ } })] }));
16
+ }
@@ -0,0 +1,14 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect } from 'react';
3
+ import { Box, Text, useApp } from 'ink';
4
+ import { colors, symbols, border } from '../../../shared/theme.js';
5
+ export function DoneStep({ projectDir }) {
6
+ const { exit } = useApp();
7
+ useEffect(() => {
8
+ exit();
9
+ }, []);
10
+ const termWidth = process.stdout.columns || 60;
11
+ const boxWidth = Math.min(termWidth - 4, 60);
12
+ const line = border.horizontal.repeat(boxWidth - 2);
13
+ return (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsx(Box, { children: _jsxs(Text, { color: colors.honey, children: [border.topLeft, line, border.topRight] }) }), _jsxs(Box, { children: [_jsx(Text, { color: colors.honey, children: border.vertical }), _jsx(Text, { children: " " }), _jsxs(Text, { color: colors.honey, bold: true, children: [symbols.hive, " Agent created successfully!"] }), _jsx(Text, { children: ' '.repeat(Math.max(0, boxWidth - 32)) }), _jsx(Text, { color: colors.honey, children: border.vertical })] }), _jsx(Box, { children: _jsxs(Text, { color: colors.honey, children: [border.bottomLeft, line, border.bottomRight] }) }), _jsxs(Box, { flexDirection: "column", marginTop: 1, marginLeft: 1, children: [_jsx(Text, { color: colors.white, bold: true, children: "Next steps:" }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsxs(Text, { color: colors.gray, children: [' ', "1. ", _jsx(Text, { color: colors.white, children: "npx @zhive/cli@latest start" })] }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: colors.grayDim, children: [' ', "Fine-tune SOUL.md and STRATEGY.md by chatting with your agent during"] }), _jsx(Text, { color: colors.grayDim, children: " a run, or edit them directly at:" }), _jsxs(Text, { color: colors.grayDim, children: [' ', _jsx(Text, { color: colors.white, children: projectDir })] })] })] })] }));
14
+ }
@@ -0,0 +1,125 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useCallback } from 'react';
3
+ import { Box, Text } from 'ink';
4
+ import { SelectPrompt } from '../../../../components/SelectPrompt.js';
5
+ import { MultiSelectPrompt, } from '../../../../components/MultiSelectPrompt.js';
6
+ import { TextPrompt } from '../../../../components/TextPrompt.js';
7
+ import { CharacterSummaryCard } from '../../../../components/CharacterSummaryCard.js';
8
+ import { PERSONALITY_OPTIONS, VOICE_OPTIONS, TRADING_STYLE_OPTIONS, PROJECT_CATEGORY_OPTIONS, SENTIMENT_OPTIONS, TIMEFRAME_OPTIONS, BIO_EXAMPLES, } from '../../presets/index.js';
9
+ import { colors, symbols } from '../../../shared/theme.js';
10
+ import { required, compose, maxLength } from '../validation.js';
11
+ function buildSelectItems(options, addCustom = false) {
12
+ const items = options.map((opt) => ({
13
+ label: opt.label,
14
+ value: opt.value,
15
+ description: opt.description,
16
+ }));
17
+ if (addCustom) {
18
+ items.push({ label: 'Custom...', value: '__custom__' });
19
+ }
20
+ return items;
21
+ }
22
+ const personalityItems = buildSelectItems(PERSONALITY_OPTIONS, true);
23
+ const voiceItems = buildSelectItems(VOICE_OPTIONS, true);
24
+ const tradingStyleItems = buildSelectItems(TRADING_STYLE_OPTIONS, true);
25
+ const categoryItems = buildSelectItems(PROJECT_CATEGORY_OPTIONS);
26
+ const sentimentItems = buildSelectItems(SENTIMENT_OPTIONS);
27
+ const timeframeItems = buildSelectItems(TIMEFRAME_OPTIONS);
28
+ export function IdentityStep({ agentName, onComplete }) {
29
+ const [subStep, setSubStep] = useState('personality');
30
+ const [personalityLabel, setPersonalityLabel] = useState('');
31
+ const [personality, setPersonality] = useState('');
32
+ const [tone, setTone] = useState('');
33
+ const [voiceStyle, setVoiceStyle] = useState('');
34
+ const [voiceLabel, setVoiceLabel] = useState('');
35
+ const [tradingStyle, setTradingStyle] = useState('');
36
+ const [tradingStyleLabel, setTradingStyleLabel] = useState('');
37
+ const [sectors, setSectors] = useState([]);
38
+ const [sectorsLabel, setSectorsLabel] = useState('');
39
+ const [sentiment, setSentiment] = useState('');
40
+ const [sentimentLabel, setSentimentLabel] = useState('');
41
+ const [timeframes, setTimeframes] = useState([]);
42
+ const [timeframesLabel, setTimeframesLabel] = useState('');
43
+ const handlePersonalitySelect = useCallback((item) => {
44
+ if (item.value === '__custom__') {
45
+ setSubStep('personality-custom');
46
+ return;
47
+ }
48
+ const description = item.description ?? '';
49
+ const personalityValue = `${item.label} — ${description}`;
50
+ setPersonality(personalityValue);
51
+ setPersonalityLabel(item.label);
52
+ setSubStep('voice');
53
+ }, []);
54
+ const handlePersonalityCustom = useCallback((value) => {
55
+ setPersonality(value);
56
+ setPersonalityLabel(value);
57
+ setSubStep('voice');
58
+ }, []);
59
+ const handleVoiceSelect = useCallback((item) => {
60
+ if (item.value === '__custom__') {
61
+ setSubStep('voice-custom');
62
+ return;
63
+ }
64
+ const voiceOption = VOICE_OPTIONS.find((v) => v.value === item.value);
65
+ setTone(voiceOption.tone);
66
+ setVoiceStyle(voiceOption.voiceStyle);
67
+ setVoiceLabel(item.label);
68
+ setSubStep('trading');
69
+ }, []);
70
+ const handleVoiceCustom = useCallback((value) => {
71
+ setTone(value);
72
+ setVoiceStyle(value);
73
+ setVoiceLabel(value);
74
+ setSubStep('trading');
75
+ }, []);
76
+ const handleTradingStyleSelect = useCallback((item) => {
77
+ if (item.value === '__custom__') {
78
+ setSubStep('trading-custom');
79
+ return;
80
+ }
81
+ setTradingStyle(item.value);
82
+ setTradingStyleLabel(item.label);
83
+ setSubStep('sectors');
84
+ }, []);
85
+ const handleTradingStyleCustom = useCallback((value) => {
86
+ setTradingStyle(value);
87
+ setTradingStyleLabel(value);
88
+ setSubStep('sectors');
89
+ }, []);
90
+ const handleSectors = useCallback((selected) => {
91
+ const values = selected.map((s) => s.value);
92
+ const labels = selected.map((s) => s.label);
93
+ setSectors(values);
94
+ const displayLabel = values.length === categoryItems.length ? 'All' : labels.join(', ');
95
+ setSectorsLabel(displayLabel);
96
+ setSubStep('sentiment');
97
+ }, []);
98
+ const handleSentimentSelect = useCallback((item) => {
99
+ setSentiment(item.value);
100
+ setSentimentLabel(item.label);
101
+ setSubStep('timeframe');
102
+ }, []);
103
+ const handleTimeframes = useCallback((selected) => {
104
+ const values = selected.map((s) => s.value);
105
+ const labels = selected.map((s) => s.label);
106
+ setTimeframes(values);
107
+ const displayLabel = values.length === timeframeItems.length ? 'All' : labels.join(', ');
108
+ setTimeframesLabel(displayLabel);
109
+ setSubStep('bio');
110
+ }, []);
111
+ const handleBio = useCallback((value) => {
112
+ const result = {
113
+ personality,
114
+ tone,
115
+ voiceStyle,
116
+ tradingStyle,
117
+ sectors,
118
+ sentiment,
119
+ timeframes,
120
+ bio: value,
121
+ };
122
+ onComplete(result);
123
+ }, [personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes, onComplete]);
124
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(CharacterSummaryCard, { name: agentName, personality: personalityLabel || undefined, voice: voiceLabel || undefined, tradingStyle: tradingStyleLabel || undefined, sectors: sectorsLabel || undefined, sentiment: sentimentLabel || undefined, timeframe: timeframesLabel || undefined }), subStep === 'personality' && (_jsx(SelectPrompt, { label: "Choose a personality", items: personalityItems, onSelect: handlePersonalitySelect })), subStep === 'personality-custom' && (_jsx(TextPrompt, { label: "Describe your agent's personality", placeholder: "e.g. stoic realist with a dry wit", onSubmit: handlePersonalityCustom, validate: required('Personality') })), subStep === 'voice' && (_jsx(SelectPrompt, { label: "Choose a voice", items: voiceItems, onSelect: handleVoiceSelect })), subStep === 'voice-custom' && (_jsx(TextPrompt, { label: "Describe your agent's voice", placeholder: "e.g. writes like a bloomberg terminal on acid", onSubmit: handleVoiceCustom, validate: required('Voice') })), subStep === 'trading' && (_jsx(SelectPrompt, { label: "How does your agent evaluate signals?", items: tradingStyleItems, onSelect: handleTradingStyleSelect })), subStep === 'trading-custom' && (_jsx(TextPrompt, { label: "Describe your agent's trading style", placeholder: "e.g. combines on-chain data with sentiment analysis", onSubmit: handleTradingStyleCustom, validate: required('Trading style') })), subStep === 'sectors' && (_jsx(MultiSelectPrompt, { label: "Which categories should your agent trade?", items: categoryItems, onSubmit: handleSectors })), subStep === 'sentiment' && (_jsx(SelectPrompt, { label: "What's your agent's market sentiment?", items: sentimentItems, onSelect: handleSentimentSelect })), subStep === 'timeframe' && (_jsx(MultiSelectPrompt, { label: "Which timeframes should your agent participate in?", items: timeframeItems, onSubmit: handleTimeframes })), subStep === 'bio' && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: [_jsxs(Text, { color: colors.grayDim, italic: true, children: [symbols.arrow, " Examples:"] }), BIO_EXAMPLES.map((example, i) => (_jsx(Box, { marginLeft: 2, marginTop: i > 0 ? 1 : 0, children: _jsxs(Text, { color: colors.grayDim, italic: true, children: [symbols.diamond, " ", `"${example}"`] }) }, i)))] }), _jsx(TextPrompt, { label: "Write your agent's bio", placeholder: `short bio for your ${personalityLabel} agent`, onSubmit: handleBio, maxLength: 1000, validate: compose(required('Bio'), maxLength(1000)) })] }))] }));
125
+ }
@@ -0,0 +1,148 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useCallback, useMemo } from 'react';
3
+ import { Box, Text } from 'ink';
4
+ import axios from 'axios';
5
+ import { TextPrompt } from '../../../../components/TextPrompt.js';
6
+ import { Spinner } from '../../../../components/Spinner.js';
7
+ import { colors, symbols } from '../../../shared/theme.js';
8
+ import { HIVE_API_URL } from '../../../../shared/config/constant.js';
9
+ import { agentName as validateAgentName } from '../validation.js';
10
+ const ADJECTIVES = [
11
+ 'royal',
12
+ 'golden',
13
+ 'buzzy',
14
+ 'honey',
15
+ 'sweet',
16
+ 'stung',
17
+ 'waxed',
18
+ 'bold',
19
+ 'swift',
20
+ 'wild',
21
+ 'keen',
22
+ 'warm',
23
+ 'hazy',
24
+ 'calm',
25
+ 'busy',
26
+ 'amber',
27
+ 'pollen',
28
+ 'nectar',
29
+ 'floral',
30
+ 'sunny',
31
+ 'misty',
32
+ 'fuzzy',
33
+ 'striped',
34
+ 'waggle',
35
+ 'silent',
36
+ 'fierce',
37
+ 'humble',
38
+ 'lunar',
39
+ 'solar',
40
+ 'bloomed',
41
+ 'bullish',
42
+ 'bearish',
43
+ 'staked',
44
+ 'minted',
45
+ 'forked',
46
+ 'based',
47
+ 'degen',
48
+ 'pumped',
49
+ 'longed',
50
+ 'shorted',
51
+ 'bridged',
52
+ 'pegged',
53
+ 'hodl',
54
+ 'mega',
55
+ 'alpha',
56
+ 'sigma',
57
+ 'hyper',
58
+ 'ultra',
59
+ 'rapid',
60
+ 'atomic',
61
+ ];
62
+ const NOUNS = [
63
+ 'bee',
64
+ 'drone',
65
+ 'queen',
66
+ 'swarm',
67
+ 'hive',
68
+ 'comb',
69
+ 'larva',
70
+ 'pupa',
71
+ 'sting',
72
+ 'apiary',
73
+ 'keeper',
74
+ 'mead',
75
+ 'pollen',
76
+ 'nectar',
77
+ 'propolis',
78
+ 'colony',
79
+ 'brood',
80
+ 'waggle',
81
+ 'cell',
82
+ 'wax',
83
+ 'bloom',
84
+ 'blossom',
85
+ 'hornet',
86
+ 'bumble',
87
+ 'worker',
88
+ 'forager',
89
+ 'scout',
90
+ 'smoker',
91
+ 'whale',
92
+ 'bull',
93
+ 'bear',
94
+ 'shard',
95
+ 'block',
96
+ 'node',
97
+ 'vault',
98
+ 'ledger',
99
+ 'oracle',
100
+ 'miner',
101
+ 'staker',
102
+ 'bridge',
103
+ 'token',
104
+ 'chain',
105
+ 'wick',
106
+ 'candle',
107
+ 'pump',
108
+ 'moon',
109
+ 'floor',
110
+ 'whale',
111
+ ];
112
+ function generateRandomName() {
113
+ const adjective = ADJECTIVES[Math.floor(Math.random() * ADJECTIVES.length)];
114
+ const noun = NOUNS[Math.floor(Math.random() * NOUNS.length)];
115
+ const number = Math.floor(Math.random() * 900) + 100;
116
+ const name = `${adjective}-${noun}-${number}`;
117
+ return name;
118
+ }
119
+ export function NameStep({ onComplete }) {
120
+ const [checking, setChecking] = useState(false);
121
+ const [error, setError] = useState('');
122
+ const placeholder = useMemo(() => generateRandomName(), []);
123
+ const handleSubmit = useCallback(async (name) => {
124
+ setChecking(true);
125
+ setError('');
126
+ try {
127
+ const apiUrl = HIVE_API_URL;
128
+ const response = await axios.get(`${apiUrl}/agent/check-name`, {
129
+ params: { name },
130
+ timeout: 3000,
131
+ });
132
+ if (!response.data.available) {
133
+ setError(`Name "${name}" is already taken`);
134
+ setChecking(false);
135
+ return;
136
+ }
137
+ }
138
+ catch {
139
+ // best-effort: silently proceed if backend is unavailable
140
+ }
141
+ setChecking(false);
142
+ onComplete(name);
143
+ }, [onComplete]);
144
+ if (checking) {
145
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(Spinner, { label: "Checking name availability..." }) }));
146
+ }
147
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(TextPrompt, { label: "Enter your agent name", placeholder: placeholder, onSubmit: handleSubmit, validate: validateAgentName }), error !== '' && (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: colors.red, children: [symbols.cross, " ", error] }) }))] }));
148
+ }
@@ -0,0 +1,59 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect } from 'react';
3
+ import { Box, Text } from 'ink';
4
+ import { HoneycombLoader } from '../../../../components/HoneycombLoader.js';
5
+ import { colors, symbols } from '../../../shared/theme.js';
6
+ import { scaffoldProject } from '../../generate.js';
7
+ import { extractErrorMessage } from '../../../../shared/agent/utils.js';
8
+ export function ScaffoldStep({ projectName, provider, apiKey, soulContent, strategyContent, onComplete, onError, }) {
9
+ const [steps, setSteps] = useState([]);
10
+ const [currentLabel, setCurrentLabel] = useState('Starting...');
11
+ useEffect(() => {
12
+ let cancelled = false;
13
+ const run = async () => {
14
+ await scaffoldProject(projectName, provider, apiKey, soulContent, strategyContent, {
15
+ onStep: (label) => {
16
+ if (cancelled)
17
+ return;
18
+ setSteps((prev) => {
19
+ if (prev.length > 0) {
20
+ const updated = [...prev];
21
+ updated[updated.length - 1] = { ...updated[updated.length - 1], done: true };
22
+ return [...updated, { label, done: false }];
23
+ }
24
+ return [{ label, done: false }];
25
+ });
26
+ setCurrentLabel(label);
27
+ },
28
+ onDone: (projectDir) => {
29
+ if (cancelled)
30
+ return;
31
+ setSteps((prev) => {
32
+ if (prev.length > 0) {
33
+ const updated = [...prev];
34
+ updated[updated.length - 1] = { ...updated[updated.length - 1], done: true };
35
+ return updated;
36
+ }
37
+ return prev;
38
+ });
39
+ onComplete(projectDir);
40
+ },
41
+ onError: (message) => {
42
+ if (cancelled)
43
+ return;
44
+ onError(message);
45
+ },
46
+ });
47
+ };
48
+ run().catch((err) => {
49
+ if (cancelled)
50
+ return;
51
+ const message = extractErrorMessage(err);
52
+ onError(message);
53
+ });
54
+ return () => {
55
+ cancelled = true;
56
+ };
57
+ }, [projectName, provider, apiKey, soulContent, strategyContent, onComplete, onError]);
58
+ return (_jsxs(Box, { flexDirection: "column", children: [steps.map((step, i) => (_jsx(Box, { marginLeft: 2, children: step.done ? (_jsxs(Text, { color: colors.green, children: [symbols.check, " ", step.label] })) : (_jsx(HoneycombLoader, { label: step.label })) }, i))), steps.length === 0 && (_jsx(Box, { marginLeft: 2, children: _jsx(HoneycombLoader, { label: currentLabel }) }))] }));
59
+ }
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useCallback } from 'react';
3
+ import { streamSoul } from '../../ai-generate.js';
4
+ import { StreamingGenerationStep } from './StreamingGenerationStep.js';
5
+ export function SoulStep({ providerId, apiKey, agentName, bio, avatarUrl, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes, onComplete, }) {
6
+ const createStream = useCallback((feedback) => streamSoul(providerId, apiKey, agentName, bio, avatarUrl, personality, tone, voiceStyle, tradingStyle, sectors, sentiment, timeframes, feedback), [
7
+ providerId,
8
+ apiKey,
9
+ agentName,
10
+ bio,
11
+ avatarUrl,
12
+ personality,
13
+ tone,
14
+ voiceStyle,
15
+ tradingStyle,
16
+ sectors,
17
+ sentiment,
18
+ timeframes,
19
+ ]);
20
+ return (_jsx(StreamingGenerationStep, { title: "SOUL.md", createStream: createStream, onComplete: onComplete }));
21
+ }