aman-intelligence 0.1.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 (197) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +116 -0
  3. package/dist/bin/aman.d.ts +2 -0
  4. package/dist/bin/aman.js +165 -0
  5. package/dist/cli/global-install.d.ts +7 -0
  6. package/dist/cli/global-install.js +36 -0
  7. package/dist/cli/help-text.d.ts +1 -0
  8. package/dist/cli/help-text.js +62 -0
  9. package/dist/cli/version.d.ts +1 -0
  10. package/dist/cli/version.js +6 -0
  11. package/dist/commands/backup.d.ts +11 -0
  12. package/dist/commands/backup.js +262 -0
  13. package/dist/commands/browse.d.ts +11 -0
  14. package/dist/commands/browse.js +641 -0
  15. package/dist/commands/cache.d.ts +1 -0
  16. package/dist/commands/cache.js +38 -0
  17. package/dist/commands/config.d.ts +4 -0
  18. package/dist/commands/config.js +146 -0
  19. package/dist/commands/dashboard.d.ts +1 -0
  20. package/dist/commands/dashboard.js +1004 -0
  21. package/dist/commands/doctor.d.ts +4 -0
  22. package/dist/commands/doctor.js +54 -0
  23. package/dist/commands/export.d.ts +1 -0
  24. package/dist/commands/export.js +137 -0
  25. package/dist/commands/help.d.ts +1 -0
  26. package/dist/commands/help.js +47 -0
  27. package/dist/commands/import-wizard.d.ts +7 -0
  28. package/dist/commands/import-wizard.js +374 -0
  29. package/dist/commands/import.d.ts +9 -0
  30. package/dist/commands/import.js +351 -0
  31. package/dist/commands/info.d.ts +1 -0
  32. package/dist/commands/info.js +174 -0
  33. package/dist/commands/init.d.ts +20 -0
  34. package/dist/commands/init.js +146 -0
  35. package/dist/commands/install.d.ts +10 -0
  36. package/dist/commands/install.js +342 -0
  37. package/dist/commands/pack.d.ts +23 -0
  38. package/dist/commands/pack.js +331 -0
  39. package/dist/commands/registry.d.ts +6 -0
  40. package/dist/commands/registry.js +218 -0
  41. package/dist/commands/remove.d.ts +1 -0
  42. package/dist/commands/remove.js +76 -0
  43. package/dist/commands/search.d.ts +7 -0
  44. package/dist/commands/search.js +295 -0
  45. package/dist/commands/stack.d.ts +18 -0
  46. package/dist/commands/stack.js +327 -0
  47. package/dist/commands/sync.d.ts +9 -0
  48. package/dist/commands/sync.js +428 -0
  49. package/dist/commands/update.d.ts +1 -0
  50. package/dist/commands/update.js +97 -0
  51. package/dist/config/features.d.ts +2 -0
  52. package/dist/config/features.js +2 -0
  53. package/dist/config/index.d.ts +13 -0
  54. package/dist/config/index.js +80 -0
  55. package/dist/config/paths.d.ts +23 -0
  56. package/dist/config/paths.js +45 -0
  57. package/dist/import/adapters.d.ts +14 -0
  58. package/dist/import/adapters.js +580 -0
  59. package/dist/import/discovery.service.d.ts +8 -0
  60. package/dist/import/discovery.service.js +26 -0
  61. package/dist/import/import.service.d.ts +7 -0
  62. package/dist/import/import.service.js +259 -0
  63. package/dist/import/types.d.ts +71 -0
  64. package/dist/import/types.js +1 -0
  65. package/dist/import/utils.d.ts +36 -0
  66. package/dist/import/utils.js +428 -0
  67. package/dist/marketplace/cache.d.ts +18 -0
  68. package/dist/marketplace/cache.js +141 -0
  69. package/dist/marketplace/github-search.d.ts +17 -0
  70. package/dist/marketplace/github-search.js +268 -0
  71. package/dist/marketplace/install-from-candidate.d.ts +6 -0
  72. package/dist/marketplace/install-from-candidate.js +14 -0
  73. package/dist/marketplace/install.d.ts +15 -0
  74. package/dist/marketplace/install.js +54 -0
  75. package/dist/marketplace/metadata-validator.d.ts +8 -0
  76. package/dist/marketplace/metadata-validator.js +79 -0
  77. package/dist/marketplace/types.d.ts +34 -0
  78. package/dist/marketplace/types.js +1 -0
  79. package/dist/providers/local.provider.d.ts +9 -0
  80. package/dist/providers/local.provider.js +51 -0
  81. package/dist/providers/provider.interface.d.ts +7 -0
  82. package/dist/providers/provider.interface.js +1 -0
  83. package/dist/providers/registry.provider.d.ts +2 -0
  84. package/dist/providers/registry.provider.js +42 -0
  85. package/dist/providers/skills-sh.provider.d.ts +11 -0
  86. package/dist/providers/skills-sh.provider.js +56 -0
  87. package/dist/registry/adapter.interface.d.ts +16 -0
  88. package/dist/registry/adapter.interface.js +1 -0
  89. package/dist/registry/errors.d.ts +5 -0
  90. package/dist/registry/errors.js +8 -0
  91. package/dist/registry/filesystem-registry.adapter.d.ts +25 -0
  92. package/dist/registry/filesystem-registry.adapter.js +288 -0
  93. package/dist/registry/github-registry.adapter.d.ts +11 -0
  94. package/dist/registry/github-registry.adapter.js +32 -0
  95. package/dist/registry/index.d.ts +8 -0
  96. package/dist/registry/index.js +8 -0
  97. package/dist/registry/local-registry.adapter.d.ts +6 -0
  98. package/dist/registry/local-registry.adapter.js +9 -0
  99. package/dist/registry/registry.service.d.ts +44 -0
  100. package/dist/registry/registry.service.js +163 -0
  101. package/dist/registry/slug-utils.d.ts +12 -0
  102. package/dist/registry/slug-utils.js +51 -0
  103. package/dist/registry/types.d.ts +160 -0
  104. package/dist/registry/types.js +1 -0
  105. package/dist/services/asset.service.d.ts +12 -0
  106. package/dist/services/asset.service.js +142 -0
  107. package/dist/services/backup.service.d.ts +8 -0
  108. package/dist/services/backup.service.js +169 -0
  109. package/dist/services/classification.service.d.ts +31 -0
  110. package/dist/services/classification.service.js +271 -0
  111. package/dist/services/config.service.d.ts +9 -0
  112. package/dist/services/config.service.js +20 -0
  113. package/dist/services/doctor.service.d.ts +5 -0
  114. package/dist/services/doctor.service.js +186 -0
  115. package/dist/services/environment.service.d.ts +42 -0
  116. package/dist/services/environment.service.js +227 -0
  117. package/dist/services/github.service.d.ts +7 -0
  118. package/dist/services/github.service.js +42 -0
  119. package/dist/services/lock.service.d.ts +12 -0
  120. package/dist/services/lock.service.js +71 -0
  121. package/dist/services/marketplace.service.d.ts +40 -0
  122. package/dist/services/marketplace.service.js +225 -0
  123. package/dist/services/pack.service.d.ts +9 -0
  124. package/dist/services/pack.service.js +193 -0
  125. package/dist/services/stack.service.d.ts +9 -0
  126. package/dist/services/stack.service.js +94 -0
  127. package/dist/storage/asset-layout.d.ts +46 -0
  128. package/dist/storage/asset-layout.js +277 -0
  129. package/dist/storage/filesystem.d.ts +12 -0
  130. package/dist/storage/filesystem.js +113 -0
  131. package/dist/storage/scan-by-type.d.ts +2 -0
  132. package/dist/storage/scan-by-type.js +8 -0
  133. package/dist/storage/scanner.d.ts +11 -0
  134. package/dist/storage/scanner.js +188 -0
  135. package/dist/types/asset-metadata.d.ts +84 -0
  136. package/dist/types/asset-metadata.js +104 -0
  137. package/dist/types/index.d.ts +212 -0
  138. package/dist/types/index.js +1 -0
  139. package/dist/ui/animations/ErrorIndicator.d.ts +5 -0
  140. package/dist/ui/animations/ErrorIndicator.js +6 -0
  141. package/dist/ui/animations/GithubIndicator.d.ts +6 -0
  142. package/dist/ui/animations/GithubIndicator.js +9 -0
  143. package/dist/ui/animations/ProgressBar.d.ts +5 -0
  144. package/dist/ui/animations/ProgressBar.js +15 -0
  145. package/dist/ui/animations/Spinner.d.ts +5 -0
  146. package/dist/ui/animations/Spinner.js +21 -0
  147. package/dist/ui/animations/SuccessIndicator.d.ts +5 -0
  148. package/dist/ui/animations/SuccessIndicator.js +6 -0
  149. package/dist/ui/animations/SyncActivity.d.ts +5 -0
  150. package/dist/ui/animations/SyncActivity.js +21 -0
  151. package/dist/ui/animations/TransitionScreen.d.ts +7 -0
  152. package/dist/ui/animations/TransitionScreen.js +25 -0
  153. package/dist/ui/animations/useAnimationMode.d.ts +1 -0
  154. package/dist/ui/animations/useAnimationMode.js +16 -0
  155. package/dist/ui/assetDisplay.d.ts +19 -0
  156. package/dist/ui/assetDisplay.js +59 -0
  157. package/dist/ui/components/Confirm.d.ts +8 -0
  158. package/dist/ui/components/Confirm.js +14 -0
  159. package/dist/ui/components/CustomSelect.d.ts +19 -0
  160. package/dist/ui/components/CustomSelect.js +13 -0
  161. package/dist/ui/components/Header.d.ts +6 -0
  162. package/dist/ui/components/Header.js +9 -0
  163. package/dist/ui/components/HealthReport.d.ts +7 -0
  164. package/dist/ui/components/HealthReport.js +13 -0
  165. package/dist/ui/components/MarketplaceInstallConfirm.d.ts +19 -0
  166. package/dist/ui/components/MarketplaceInstallConfirm.js +23 -0
  167. package/dist/ui/components/Narrator.d.ts +9 -0
  168. package/dist/ui/components/Narrator.js +26 -0
  169. package/dist/ui/components/ScopePrompt.d.ts +8 -0
  170. package/dist/ui/components/ScopePrompt.js +23 -0
  171. package/dist/ui/components/TooSmallScreen.d.ts +8 -0
  172. package/dist/ui/components/TooSmallScreen.js +6 -0
  173. package/dist/ui/date.d.ts +2 -0
  174. package/dist/ui/date.js +33 -0
  175. package/dist/ui/layout.d.ts +23 -0
  176. package/dist/ui/layout.js +44 -0
  177. package/dist/ui/list-item.d.ts +12 -0
  178. package/dist/ui/list-item.js +1 -0
  179. package/dist/ui/marketplaceDisplay.d.ts +10 -0
  180. package/dist/ui/marketplaceDisplay.js +36 -0
  181. package/dist/ui/theme.d.ts +42 -0
  182. package/dist/ui/theme.js +47 -0
  183. package/dist/utils/asset-list-fields.d.ts +11 -0
  184. package/dist/utils/asset-list-fields.js +28 -0
  185. package/dist/utils/error-message.d.ts +2 -0
  186. package/dist/utils/error-message.js +6 -0
  187. package/dist/utils/integrity.d.ts +9 -0
  188. package/dist/utils/integrity.js +23 -0
  189. package/dist/utils/lock-migrate.d.ts +25 -0
  190. package/dist/utils/lock-migrate.js +93 -0
  191. package/dist/utils/mcp-local.d.ts +15 -0
  192. package/dist/utils/mcp-local.js +129 -0
  193. package/dist/utils/slug.d.ts +6 -0
  194. package/dist/utils/slug.js +13 -0
  195. package/dist/utils/stack-normalize.d.ts +3 -0
  196. package/dist/utils/stack-normalize.js +43 -0
  197. package/package.json +77 -0
@@ -0,0 +1,1004 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useEffect, useState } from 'react';
3
+ import { render, Box, Text, useApp, useInput } from 'ink';
4
+ import { CustomSelectInput } from '../ui/components/CustomSelect.js';
5
+ import TextInput from 'ink-text-input';
6
+ import { environmentService } from '../services/environment.service.js';
7
+ import { backupService } from '../services/backup.service.js';
8
+ import { stackService } from '../services/stack.service.js';
9
+ import { lockService } from '../services/lock.service.js';
10
+ import { scanAll } from '../storage/scanner.js';
11
+ import { exists } from '../storage/filesystem.js';
12
+ import { theme } from '../ui/theme.js';
13
+ import { useResponsiveLayout, MIN_COLUMNS, MIN_ROWS } from '../ui/layout.js';
14
+ import { TooSmallScreen } from '../ui/components/TooSmallScreen.js';
15
+ import { GithubIndicator } from '../ui/animations/GithubIndicator.js';
16
+ import { Header } from '../ui/components/Header.js';
17
+ import { Narrator } from '../ui/components/Narrator.js';
18
+ import { getBackupLabel } from '../ui/date.js';
19
+ import { BrowseApp } from './browse.js';
20
+ import { SearchApp } from './search.js';
21
+ import { PackCreateApp, PackInspectApp, PackInstallApp } from './pack.js';
22
+ import { StackCreateApp, StackActivateApp } from './stack.js';
23
+ import { BackupApp } from './backup.js';
24
+ import { SyncApp } from './sync.js';
25
+ import { ConfigApp } from './config.js';
26
+ import { DoctorApp } from './doctor.js';
27
+ import { ImportApp } from './import.js';
28
+ import { ImportWizardApp } from './import-wizard.js';
29
+ import { InitFlow } from './init.js';
30
+ import { InstallWizardApp } from './install.js';
31
+ import { execFileSync } from 'child_process';
32
+ import { MARKETPLACE_ENABLED } from '../config/features.js';
33
+ import path from 'path';
34
+ const InputScreen = ({ title, placeholder, onSubmit, onBack, }) => {
35
+ const [val, setVal] = useState('');
36
+ const { rows } = useResponsiveLayout();
37
+ useInput((input, key) => {
38
+ if (key.escape)
39
+ onBack();
40
+ });
41
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: title }), _jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(Text, { color: theme.primary, children: "\u276F " }), _jsx(TextInput, { value: val, onChange: setVal, onSubmit: onSubmit, placeholder: placeholder })] })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to submit \u00B7 esc go back" }) })] }));
42
+ };
43
+ const StableScreenWrapper = ({ children }) => {
44
+ const { rows } = useResponsiveLayout();
45
+ return (_jsx(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: _jsx(Box, { flexDirection: "column", children: children }) }));
46
+ };
47
+ const DashboardApp = () => {
48
+ const { rows, columns, isTooSmall, isCompact, canShowDescriptions, physicalColumns, physicalRows } = useResponsiveLayout();
49
+ const { exit } = useApp();
50
+ const [loading, setLoading] = useState(true);
51
+ const [initRequired, setInitRequired] = useState(false);
52
+ const [stats, setStats] = useState({ skills: 0, prompts: 0, mcps: 0, packs: 0, stacks: 0 });
53
+ const [storageInfo, setStorageInfo] = useState({ path: '', repo: '', type: 'local' });
54
+ const [lastSync, setLastSync] = useState('never');
55
+ const [lastBackup, setLastBackup] = useState('none');
56
+ // SPTA navigation states
57
+ const [screen, setScreen] = useState('menu');
58
+ const [menuCursor, setMenuCursor] = useState(0);
59
+ const [inputVal, setInputVal] = useState('');
60
+ const [secondInputVal, setSecondInputVal] = useState('');
61
+ const [selectItems, setSelectItems] = useState([]);
62
+ const [infoMessage, setInfoMessage] = useState('');
63
+ const [infoState, setInfoState] = useState('idle');
64
+ // Quick setup states
65
+ const [setupState, setSetupState] = useState('idle');
66
+ const [setupMessage, setSetupMessage] = useState('');
67
+ const isConnected = storageInfo.type === 'github' && !!storageInfo.repo;
68
+ const currentMenuItems = React.useMemo(() => {
69
+ const items = [
70
+ { label: 'Browse Assets', value: 'browse', section: 'Discover', description: 'Browse registry and installed skills, prompts, and MCPs' },
71
+ { label: 'Import Assets', value: 'import_menu', section: 'Discover', description: 'Import skills, prompts, and MCPs from AI tools, editors, GitHub, or folders' },
72
+ { label: 'Search Assets', value: 'search', section: 'Discover', description: 'Universal search across all asset types' },
73
+ { label: 'Install Asset', value: 'install', section: 'Discover', description: 'Install a skill, prompt, or MCP (equal asset types)' },
74
+ { label: 'My Assets', value: 'my-assets', section: 'Manage', description: 'View and manage installed skills, prompts, and MCPs' },
75
+ { label: 'Packs', value: 'packs_menu', section: 'Manage', description: 'Bundle skills, prompts, and MCPs into workflow packs' },
76
+ { label: 'Stacks', value: 'stacks_menu', section: 'Manage', description: 'Create workflow environments with mixed asset types' },
77
+ ];
78
+ if (!isConnected) {
79
+ items.push({ label: 'Connect GitHub', value: 'connect_github', section: 'Environment', description: 'Link your environment to a GitHub repository' }, { label: 'Change Local Folder', value: 'change_local_folder_input', section: 'Environment', description: 'Change the directory path where local assets are stored' });
80
+ }
81
+ else {
82
+ items.push({ label: 'Sync Environment', value: 'sync_menu', section: 'Environment', description: 'Push, pull, or manage your GitHub environment settings' }, { label: 'Change Local Folder', value: 'change_local_folder_input', section: 'Environment', description: 'Change the directory path where local assets are stored' });
83
+ }
84
+ items.push({ label: 'Backup & Restore', value: 'backup_menu', section: 'Environment', description: 'Save and restore snapshots of your workspace' }, { label: 'Settings', value: 'settings', section: 'System', description: 'Configure CLI options and environment variables' }, { label: 'Doctor', value: 'doctor', section: 'System', description: 'Run system diagnostics and verify dependencies' }, { label: 'Exit', value: 'exit', section: 'System', description: 'Quit the Asset Hub' });
85
+ return items;
86
+ }, [isConnected]);
87
+ async function connectGithub(repository, mode) {
88
+ if (!environmentService.isGithubCliAvailable()) {
89
+ setScreen('gh_cli_required');
90
+ return;
91
+ }
92
+ setScreen('github_setup_loading');
93
+ setSetupState('installing');
94
+ setSetupMessage(`Setting up GitHub repository: ${repository}...`);
95
+ try {
96
+ await environmentService.initGithub({ repository, mode });
97
+ setSetupState('success');
98
+ setSetupMessage('GitHub connected successfully!');
99
+ setInitRequired(false);
100
+ setTimeout(() => {
101
+ setScreen('menu');
102
+ loadData();
103
+ }, 1500);
104
+ }
105
+ catch (err) {
106
+ setSetupState('error');
107
+ setSetupMessage(`Failed: ${err.message}`);
108
+ setTimeout(() => {
109
+ setScreen('menu');
110
+ }, 2500);
111
+ }
112
+ }
113
+ async function changeLocalFolder(targetPath) {
114
+ setScreen('github_setup_loading');
115
+ setSetupState('installing');
116
+ setSetupMessage(`Configuring local folder: ${targetPath}...`);
117
+ try {
118
+ await environmentService.initLocal({ storagePath: targetPath });
119
+ setSetupState('success');
120
+ setSetupMessage(`Environment directory changed successfully!`);
121
+ setInitRequired(false);
122
+ setTimeout(() => {
123
+ setScreen('menu');
124
+ loadData();
125
+ }, 1500);
126
+ }
127
+ catch (err) {
128
+ setSetupState('error');
129
+ setSetupMessage(`Failed: ${err.message}`);
130
+ setTimeout(() => {
131
+ setScreen('menu');
132
+ }, 2500);
133
+ }
134
+ }
135
+ async function logoutGithub() {
136
+ setScreen('github_setup_loading');
137
+ setSetupState('installing');
138
+ setSetupMessage('Disconnecting from GitHub...');
139
+ try {
140
+ await environmentService.initLocal({});
141
+ setSetupState('success');
142
+ setSetupMessage('Logged out of GitHub! Storage switched to local.');
143
+ setTimeout(() => {
144
+ setScreen('menu');
145
+ loadData();
146
+ }, 1500);
147
+ }
148
+ catch (err) {
149
+ setSetupState('error');
150
+ setSetupMessage(`Failed to log out: ${err.message}`);
151
+ setTimeout(() => {
152
+ setScreen('menu');
153
+ }, 2500);
154
+ }
155
+ }
156
+ async function configureLocal() {
157
+ setScreen('github_setup_loading');
158
+ setSetupState('installing');
159
+ setSetupMessage('Configuring local folder...');
160
+ try {
161
+ await environmentService.initLocal({});
162
+ setSetupState('success');
163
+ setSetupMessage('Local environment initialized successfully!');
164
+ setInitRequired(false);
165
+ setTimeout(() => {
166
+ setScreen('menu');
167
+ loadData();
168
+ }, 1500);
169
+ }
170
+ catch (err) {
171
+ setSetupState('error');
172
+ setSetupMessage(`Failed: ${err.message}`);
173
+ setTimeout(() => {
174
+ setScreen('menu');
175
+ }, 2500);
176
+ }
177
+ }
178
+ useInput((input, key) => {
179
+ if (initRequired) {
180
+ if (key.escape || input === 'q') {
181
+ exit();
182
+ }
183
+ return;
184
+ }
185
+ if (screen !== 'menu') {
186
+ if (key.escape || input === 'q') {
187
+ if (screen === 'packs_menu' ||
188
+ screen === 'stacks_menu' ||
189
+ screen === 'backup_menu' ||
190
+ screen === 'sync_menu' ||
191
+ screen === 'import_menu' ||
192
+ screen === 'connect_github' ||
193
+ screen === 'gh_cli_required' ||
194
+ screen === 'change_local_folder_input') {
195
+ setScreen('menu');
196
+ return;
197
+ }
198
+ if (screen === 'import_repo_input') {
199
+ setScreen('import_menu');
200
+ return;
201
+ }
202
+ if (screen === 'change_repo_input') {
203
+ setScreen('sync_menu');
204
+ return;
205
+ }
206
+ if (screen === 'change_repo_mode') {
207
+ setScreen('change_repo_input');
208
+ return;
209
+ }
210
+ if (screen === 'stacks_create_scope') {
211
+ setScreen('stacks_create_name');
212
+ return;
213
+ }
214
+ if (screen === 'stacks_activate_select' || screen === 'stacks_remove_select') {
215
+ setScreen('stacks_menu');
216
+ return;
217
+ }
218
+ if (screen === 'backup_restore_select' || screen === 'backup_delete_select') {
219
+ setScreen('backup_menu');
220
+ return;
221
+ }
222
+ }
223
+ return;
224
+ }
225
+ // Key handlers for Dashboard menu
226
+ if (key.upArrow) {
227
+ setMenuCursor((prev) => (prev > 0 ? prev - 1 : currentMenuItems.length - 1));
228
+ }
229
+ else if (key.downArrow) {
230
+ setMenuCursor((prev) => (prev < currentMenuItems.length - 1 ? prev + 1 : 0));
231
+ }
232
+ else if (key.leftArrow) {
233
+ const leftCount = currentMenuItems.filter((i) => i.section === 'Discover').length +
234
+ currentMenuItems.filter((i) => i.section === 'Manage').length;
235
+ setMenuCursor((prev) => (prev >= leftCount ? prev - leftCount : prev));
236
+ }
237
+ else if (key.rightArrow) {
238
+ const leftCount = currentMenuItems.filter((i) => i.section === 'Discover').length +
239
+ currentMenuItems.filter((i) => i.section === 'Manage').length;
240
+ setMenuCursor((prev) => (prev < leftCount ? prev + leftCount : prev));
241
+ }
242
+ else if (key.return) {
243
+ const activeItem = currentMenuItems[menuCursor];
244
+ handleMainMenuSelect(activeItem);
245
+ }
246
+ else if (input === 'q') {
247
+ exit();
248
+ }
249
+ });
250
+ async function loadData() {
251
+ const environmentPath = environmentService.getActiveEnvironmentDir();
252
+ const isReady = exists(path.join(environmentPath, 'aman.json'));
253
+ if (!isReady) {
254
+ setInitRequired(true);
255
+ setLoading(false);
256
+ return;
257
+ }
258
+ const data = await scanAll(environmentPath, 'installed');
259
+ const storage = environmentService.getStorage();
260
+ const localStacks = await stackService.list('global');
261
+ const projectStacks = await stackService.list('project');
262
+ const packRefs = new Set();
263
+ for (const scope of ['global', 'project']) {
264
+ try {
265
+ const lock = await lockService.read(scope);
266
+ for (const entry of lock.assets) {
267
+ if (entry.source.kind === 'pack')
268
+ packRefs.add(entry.source.ref);
269
+ }
270
+ }
271
+ catch {
272
+ // ignore
273
+ }
274
+ }
275
+ setStats({
276
+ skills: data.skills.length,
277
+ prompts: data.prompts.length,
278
+ mcps: data.mcps.length,
279
+ packs: packRefs.size,
280
+ stacks: localStacks.length + projectStacks.length,
281
+ });
282
+ setStorageInfo({
283
+ path: environmentPath,
284
+ type: storage.type,
285
+ repo: storage.repository || '',
286
+ });
287
+ // Scan Last Sync (Git relative commit date)
288
+ let lastSyncVal = 'never';
289
+ if (storage.type === 'github' && storage.repository) {
290
+ try {
291
+ const res = execFileSync('git', ['-C', environmentPath, 'log', '-1', '--format=%cr'], { stdio: 'pipe' });
292
+ lastSyncVal = res.toString().trim() || 'never';
293
+ }
294
+ catch {
295
+ lastSyncVal = 'never';
296
+ }
297
+ }
298
+ setLastSync(lastSyncVal);
299
+ // Scan Last Backup (Alphabetically latest directory name)
300
+ let lastBackupVal = 'none';
301
+ try {
302
+ const backups = await backupService.list();
303
+ if (backups && backups.length > 0) {
304
+ lastBackupVal = backups.sort().pop() || 'none';
305
+ }
306
+ }
307
+ catch {
308
+ lastBackupVal = 'none';
309
+ }
310
+ setLastBackup(lastBackupVal);
311
+ setLoading(false);
312
+ }
313
+ useEffect(() => {
314
+ loadData();
315
+ }, [screen]);
316
+ if (isTooSmall) {
317
+ return _jsx(TooSmallScreen, { columns: physicalColumns, rows: physicalRows, minColumns: MIN_COLUMNS, minRows: MIN_ROWS });
318
+ }
319
+ if (loading) {
320
+ return (_jsx(Box, { paddingX: 1, height: rows, justifyContent: "center", alignItems: "center", children: _jsx(Narrator, { state: "searching", message: "Loading Environment..." }) }));
321
+ }
322
+ if (screen === 'github_setup_loading') {
323
+ return (_jsx(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Narrator, { state: setupState, message: setupMessage })] }) }));
324
+ }
325
+ if (screen === 'connect_github') {
326
+ return (_jsx(InitFlow, { startWithGithub: true, exitOnDone: false, onDone: async (result) => {
327
+ if (result.action === 'github') {
328
+ await connectGithub(result.repository, result.mode);
329
+ }
330
+ else {
331
+ setScreen('menu');
332
+ }
333
+ } }));
334
+ }
335
+ if (screen === 'gh_cli_required') {
336
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.error, children: "GitHub CLI is required." }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Please install it via https://cli.github.com or using your package manager:" }) }), _jsxs(Box, { flexDirection: "column", marginTop: 1, marginLeft: 2, children: [_jsx(Text, { color: theme.secondary, children: "\u2022 Windows: winget install GitHub.cli" }), _jsx(Text, { color: theme.secondary, children: "\u2022 macOS: brew install gh" }), _jsx(Text, { color: theme.secondary, children: "\u2022 Linux: sudo apt install gh" })] }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: [
337
+ { label: 'Continue With Local Storage', value: 'local' },
338
+ { label: 'Back', value: 'back' },
339
+ ], onSelect: async (item) => {
340
+ if (item.value === 'local') {
341
+ await configureLocal();
342
+ }
343
+ else {
344
+ setScreen('menu');
345
+ }
346
+ } }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select" }) })] }));
347
+ }
348
+ if (initRequired) {
349
+ const quickSetupItems = [
350
+ { label: 'Connect GitHub', value: 'connect_github' },
351
+ { label: 'Configure Local Folder', value: 'local_setup' },
352
+ { label: 'Exit CLI', value: 'exit' },
353
+ ];
354
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: theme.accent, children: "Aman Intelligence" }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { bold: true, children: "Quick Setup" }) }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: quickSetupItems, onSelect: async (item) => {
355
+ if (item.value === 'connect_github') {
356
+ setScreen('connect_github');
357
+ }
358
+ else if (item.value === 'local_setup') {
359
+ await configureLocal();
360
+ }
361
+ else if (item.value === 'exit') {
362
+ exit();
363
+ }
364
+ } }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc exit" }) })] }));
365
+ }
366
+ // Handle menus
367
+ const handleMainMenuSelect = (item) => {
368
+ setInfoState('idle');
369
+ setInfoMessage('');
370
+ if (item.value === 'exit') {
371
+ exit();
372
+ return;
373
+ }
374
+ setScreen(item.value);
375
+ };
376
+ const handlePacksMenuSelect = (item) => {
377
+ if (item.value === 'back') {
378
+ setScreen('menu');
379
+ return;
380
+ }
381
+ setScreen(item.value);
382
+ };
383
+ const handleStacksMenuSelect = async (item) => {
384
+ if (item.value === 'back') {
385
+ setScreen('menu');
386
+ return;
387
+ }
388
+ if (item.value === 'stacks_activate_select') {
389
+ const globalStacks = await stackService.list('global');
390
+ const projectStacks = await stackService.list('project');
391
+ const combined = [
392
+ ...globalStacks.map((s) => ({
393
+ label: `[global] ${s.name} (${s.skills.length}s ${s.prompts.length}p ${s.mcps.length}m)`,
394
+ value: `global:${s.name}`,
395
+ })),
396
+ ...projectStacks.map((s) => ({
397
+ label: `[project] ${s.name} (${s.skills.length}s ${s.prompts.length}p ${s.mcps.length}m)`,
398
+ value: `project:${s.name}`,
399
+ })),
400
+ ];
401
+ if (combined.length === 0) {
402
+ setInfoState('error');
403
+ setInfoMessage('No stacks found to activate.');
404
+ return;
405
+ }
406
+ setSelectItems(combined);
407
+ }
408
+ if (item.value === 'stacks_remove_select') {
409
+ const globalStacks = await stackService.list('global');
410
+ const projectStacks = await stackService.list('project');
411
+ const combined = [
412
+ ...globalStacks.map((s) => ({ label: `[global] ${s.name}`, value: `global:${s.name}` })),
413
+ ...projectStacks.map((s) => ({ label: `[project] ${s.name}`, value: `project:${s.name}` })),
414
+ ];
415
+ if (combined.length === 0) {
416
+ setInfoState('error');
417
+ setInfoMessage('No stacks found to remove.');
418
+ return;
419
+ }
420
+ setSelectItems(combined);
421
+ }
422
+ setScreen(item.value);
423
+ };
424
+ const handleBackupMenuSelect = async (item) => {
425
+ if (item.value === 'back') {
426
+ setScreen('menu');
427
+ return;
428
+ }
429
+ if (item.value === 'backup_restore_select' || item.value === 'backup_delete_select') {
430
+ try {
431
+ const backups = await backupService.list();
432
+ if (backups.length === 0) {
433
+ setInfoState('error');
434
+ setInfoMessage('No backups found.');
435
+ return;
436
+ }
437
+ setSelectItems(backups.map((b) => ({ label: getBackupLabel(b), value: b })));
438
+ }
439
+ catch (err) {
440
+ setInfoState('error');
441
+ setInfoMessage(`Error reading backups: ${err.message}`);
442
+ return;
443
+ }
444
+ }
445
+ setScreen(item.value);
446
+ };
447
+ const handleSyncMenuSelect = async (item) => {
448
+ if (item.value === 'back') {
449
+ setScreen('menu');
450
+ return;
451
+ }
452
+ if (item.value === 'disconnect_github') {
453
+ await logoutGithub();
454
+ return;
455
+ }
456
+ setScreen(item.value);
457
+ };
458
+ // ── Screens Routing ──────────────────────────────────────────────────
459
+ // Submenu Screens
460
+ if (screen === 'packs_menu') {
461
+ const packsItems = [
462
+ { label: 'Create a Pack', value: 'packs_create_input' },
463
+ { label: 'Install a Pack (.amanpack)', value: 'packs_install_input' },
464
+ { label: 'Inspect a Pack', value: 'packs_inspect_input' },
465
+ { label: '← Back to Main Menu', value: 'back' },
466
+ ];
467
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Packs Management" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: packsItems, onSelect: handlePacksMenuSelect }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
468
+ }
469
+ if (screen === 'stacks_menu') {
470
+ const stacksItems = [
471
+ { label: 'Create a Stack', value: 'stacks_create_name' },
472
+ { label: 'Activate a Stack', value: 'stacks_activate_select' },
473
+ { label: 'List Stacks', value: 'stacks_list' },
474
+ { label: 'Remove a Stack', value: 'stacks_remove_select' },
475
+ { label: '← Back to Main Menu', value: 'back' },
476
+ ];
477
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Stacks Management" }), infoMessage && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: infoState === 'success' ? theme.success : theme.error, children: infoMessage }) })), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: stacksItems, onSelect: handleStacksMenuSelect }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
478
+ }
479
+ if (screen === 'backup_menu') {
480
+ const backupItems = [
481
+ { label: 'Save a Backup', value: 'backup_create_label' },
482
+ { label: 'Restore a Backup', value: 'backup_restore_select' },
483
+ { label: 'List Backups', value: 'backup_list' },
484
+ { label: 'Delete a Backup', value: 'backup_delete_select' },
485
+ { label: '← Back to Main Menu', value: 'back' },
486
+ ];
487
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Backup & Restore" }), infoMessage && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: infoState === 'success' ? theme.success : theme.error, children: infoMessage }) })), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: backupItems, onSelect: handleBackupMenuSelect }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
488
+ }
489
+ if (screen === 'sync_menu') {
490
+ const syncItems = [
491
+ { label: 'Push to GitHub', value: 'sync_push_app' },
492
+ { label: 'Pull from GitHub', value: 'sync_pull_app' },
493
+ { label: 'Change GitHub Repository', value: 'change_repo_input' },
494
+ { label: 'Disconnect GitHub (Switch to Local)', value: 'disconnect_github' },
495
+ { label: '← Back to Main Menu', value: 'back' },
496
+ ];
497
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Sync (GitHub Integration)" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: syncItems, onSelect: handleSyncMenuSelect }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
498
+ }
499
+ // Active Applications integration
500
+ if (screen === 'browse') {
501
+ return (_jsx(BrowseApp, { initialView: MARKETPLACE_ENABLED ? 'marketplace' : 'local', onBack: () => setScreen('menu') }));
502
+ }
503
+ if (screen === 'my-assets') {
504
+ return _jsx(BrowseApp, { initialView: "installed", onBack: () => setScreen('menu') });
505
+ }
506
+ if (screen === 'search') {
507
+ return _jsx(SearchApp, { onBack: () => setScreen('menu') });
508
+ }
509
+ if (screen === 'install') {
510
+ return _jsx(StableScreenWrapper, { children: _jsx(InstallWizardApp, { onBack: () => setScreen('menu') }) });
511
+ }
512
+ if (screen === 'settings') {
513
+ return _jsx(StableScreenWrapper, { children: _jsx(ConfigApp, { onBack: () => setScreen('menu') }) });
514
+ }
515
+ if (screen === 'doctor') {
516
+ return _jsx(StableScreenWrapper, { children: _jsx(DoctorApp, { onBack: () => setScreen('menu') }) });
517
+ }
518
+ // Packs workflows
519
+ if (screen === 'packs_create_input') {
520
+ return (_jsx(InputScreen, { title: "Create a New Pack", placeholder: "Enter pack name...", onSubmit: (val) => {
521
+ setInputVal(val);
522
+ setScreen('packs_create_app');
523
+ }, onBack: () => setScreen('packs_menu') }));
524
+ }
525
+ if (screen === 'packs_create_app') {
526
+ return _jsx(StableScreenWrapper, { children: _jsx(PackCreateApp, { name: inputVal, onBack: () => setScreen('packs_menu') }) });
527
+ }
528
+ if (screen === 'packs_install_input') {
529
+ return (_jsx(InputScreen, { title: "Install a Pack (.amanpack)", placeholder: "Enter path to .amanpack file...", onSubmit: (val) => {
530
+ setInputVal(val);
531
+ setScreen('packs_install_app');
532
+ }, onBack: () => setScreen('packs_menu') }));
533
+ }
534
+ if (screen === 'packs_install_app') {
535
+ return _jsx(StableScreenWrapper, { children: _jsx(PackInstallApp, { packPath: inputVal, onBack: () => setScreen('packs_menu') }) });
536
+ }
537
+ if (screen === 'packs_inspect_input') {
538
+ return (_jsx(InputScreen, { title: "Inspect a Pack", placeholder: "Enter path to .amanpack file...", onSubmit: (val) => {
539
+ setInputVal(val);
540
+ setScreen('packs_inspect_app');
541
+ }, onBack: () => setScreen('packs_menu') }));
542
+ }
543
+ if (screen === 'packs_inspect_app') {
544
+ return _jsx(StableScreenWrapper, { children: _jsx(PackInspectApp, { packPath: inputVal, onBack: () => setScreen('packs_menu') }) });
545
+ }
546
+ // Stacks workflows
547
+ if (screen === 'stacks_create_name') {
548
+ return (_jsx(InputScreen, { title: "Create a New Stack", placeholder: "Enter stack name...", onSubmit: (val) => {
549
+ setInputVal(val);
550
+ setScreen('stacks_create_scope');
551
+ }, onBack: () => setScreen('stacks_menu') }));
552
+ }
553
+ if (screen === 'stacks_create_scope') {
554
+ const scopes = [
555
+ { label: 'Global Scope', value: 'global' },
556
+ { label: 'Project Scope', value: 'project' },
557
+ ];
558
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Select Stack Scope" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: scopes, onSelect: (item) => {
559
+ setSecondInputVal(item.value);
560
+ setScreen('stacks_create_app');
561
+ } }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
562
+ }
563
+ if (screen === 'stacks_create_app') {
564
+ return _jsx(StableScreenWrapper, { children: _jsx(StackCreateApp, { name: inputVal, scope: secondInputVal, onBack: () => setScreen('stacks_menu') }) });
565
+ }
566
+ if (screen === 'stacks_activate_select') {
567
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Activate Stack" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: selectItems, onSelect: (item) => {
568
+ const [scope, name] = item.value.split(':');
569
+ setInputVal(name);
570
+ setSecondInputVal(scope);
571
+ setScreen('stacks_activate_app');
572
+ } }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "Select a stack to activate its assets in your project. \u00B7 esc go back" }) })] }));
573
+ }
574
+ if (screen === 'stacks_activate_app') {
575
+ return _jsx(StableScreenWrapper, { children: _jsx(StackActivateApp, { name: inputVal, scope: secondInputVal, onBack: () => setScreen('stacks_menu') }) });
576
+ }
577
+ if (screen === 'stacks_list') {
578
+ const StacksListScreen = () => {
579
+ const { rows } = useResponsiveLayout();
580
+ const [stacksList, setStacksList] = useState([]);
581
+ const [loading, setLoading] = useState(true);
582
+ const [currentView, setCurrentView] = useState('list');
583
+ const [selectedStack, setSelectedStack] = useState(null);
584
+ const [activeAssetType, setActiveAssetType] = useState('skill');
585
+ const [installedAssets, setInstalledAssets] = useState({ skills: [], prompts: [], mcps: [] });
586
+ const [actionMessage, setActionMessage] = useState(null);
587
+ const loadStacks = async () => {
588
+ setLoading(true);
589
+ const [globals, projects] = await Promise.all([
590
+ stackService.list('global'),
591
+ stackService.list('project'),
592
+ ]);
593
+ setStacksList([
594
+ ...globals.map((s) => ({ ...s, scope: 'global' })),
595
+ ...projects.map((s) => ({ ...s, scope: 'project' })),
596
+ ]);
597
+ setLoading(false);
598
+ };
599
+ const loadInstalled = async () => {
600
+ const globalDir = environmentService.getActiveEnvironmentDir();
601
+ const projectDir = environmentService.getProjectEnvironmentDir();
602
+ const globalData = await scanAll(globalDir, 'global');
603
+ let projectData = { skills: [], prompts: [], mcps: [] };
604
+ if (exists(projectDir)) {
605
+ const scanned = await scanAll(projectDir, 'project');
606
+ projectData = {
607
+ skills: scanned.skills,
608
+ prompts: scanned.prompts,
609
+ mcps: scanned.mcps
610
+ };
611
+ }
612
+ const uniqSkills = Array.from(new Set([...globalData.skills, ...projectData.skills].map((s) => s.name)));
613
+ const uniqPrompts = Array.from(new Set([...globalData.prompts, ...projectData.prompts].map((p) => p.name)));
614
+ const uniqMcps = Array.from(new Set([...globalData.mcps, ...projectData.mcps].map((m) => m.name)));
615
+ setInstalledAssets({
616
+ skills: uniqSkills,
617
+ prompts: uniqPrompts,
618
+ mcps: uniqMcps,
619
+ });
620
+ };
621
+ useEffect(() => {
622
+ loadStacks();
623
+ loadInstalled();
624
+ }, []);
625
+ useInput((input, key) => {
626
+ if (key.escape) {
627
+ if (currentView === 'list') {
628
+ setScreen('stacks_menu');
629
+ }
630
+ else if (currentView === 'detail') {
631
+ setCurrentView('list');
632
+ }
633
+ else if (currentView === 'add_type' || currentView === 'remove_type') {
634
+ setCurrentView('detail');
635
+ }
636
+ else if (currentView === 'add_select') {
637
+ setCurrentView('add_type');
638
+ }
639
+ else if (currentView === 'remove_select') {
640
+ setCurrentView('remove_type');
641
+ }
642
+ }
643
+ });
644
+ const renderList = (items, max = 3) => {
645
+ if (items.length === 0)
646
+ return _jsx(Text, { color: theme.dim, children: " (None)" });
647
+ const visible = items.slice(0, max);
648
+ const diff = items.length - max;
649
+ return (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [visible.map((item) => (_jsxs(Text, { color: theme.text, children: ["\u2022 ", item] }, item))), diff > 0 && _jsxs(Text, { color: theme.dim, children: ["\u2022 ... and ", diff, " more"] })] }));
650
+ };
651
+ if (currentView === 'list') {
652
+ const stackItems = [
653
+ ...stacksList.map((s) => ({
654
+ label: `[${s.scope}] ${s.name} (${s.skills.length} skills, ${s.prompts.length} prompts, ${s.mcps.length} mcps)`,
655
+ value: `${s.scope}:${s.name}`,
656
+ })),
657
+ { label: '← Back to Stacks Menu', value: 'back' },
658
+ ];
659
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Installed Stacks" }), _jsx(Box, { marginTop: 1, children: loading ? (_jsx(Text, { color: theme.dim, children: "Loading stacks..." })) : stacksList.length === 0 ? (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: theme.dim, children: "No stacks found." }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: [{ label: '← Back to Stacks Menu', value: 'back' }], onSelect: () => setScreen('stacks_menu') }) })] })) : (_jsx(CustomSelectInput, { items: stackItems, onSelect: (item) => {
660
+ if (item.value === 'back') {
661
+ setScreen('stacks_menu');
662
+ }
663
+ else {
664
+ const found = stacksList.find((s) => `${s.scope}:${s.name}` === item.value);
665
+ if (found) {
666
+ setSelectedStack(found);
667
+ setCurrentView('detail');
668
+ }
669
+ }
670
+ } })) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to inspect/edit \u00B7 esc go back" }) })] }));
671
+ }
672
+ if (currentView === 'detail' && selectedStack) {
673
+ const detailItems = [
674
+ { label: 'Add Asset', value: 'add' },
675
+ { label: 'Remove Asset', value: 'remove' },
676
+ { label: '← Back to Stacks List', value: 'back' },
677
+ ];
678
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsxs(Box, { flexDirection: "row", justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: theme.accent, children: selectedStack.name }), _jsxs(Text, { color: theme.dim, children: ["Scope: ", selectedStack.scope] })] }), _jsxs(Text, { color: theme.dim, children: [selectedStack.skills.length, " Skills \u2022 ", selectedStack.prompts.length, " Prompts \u2022 ", selectedStack.mcps.length, " MCPs"] }), _jsx(Text, { color: theme.borderMuted, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, color: theme.primary, children: "Skills" }), renderList(selectedStack.skills)] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, color: theme.primary, children: "Prompts" }), renderList(selectedStack.prompts)] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, color: theme.primary, children: "MCPs" }), renderList(selectedStack.mcps)] }), actionMessage && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.success, children: actionMessage }) })), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: detailItems, onSelect: (item) => {
679
+ if (item.value === 'back') {
680
+ setCurrentView('list');
681
+ }
682
+ else if (item.value === 'add') {
683
+ setCurrentView('add_type');
684
+ }
685
+ else if (item.value === 'remove') {
686
+ setCurrentView('remove_type');
687
+ }
688
+ } }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
689
+ }
690
+ if (currentView === 'add_type' && selectedStack) {
691
+ const addTypes = [
692
+ { label: 'Skills', value: 'skill' },
693
+ { label: 'Prompts', value: 'prompt' },
694
+ { label: 'MCPs', value: 'mcp' },
695
+ { label: '← Back', value: 'back' },
696
+ ];
697
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsxs(Text, { bold: true, color: theme.accent, children: ["Add Asset to ", selectedStack.name] }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: addTypes, onSelect: (item) => {
698
+ if (item.value === 'back') {
699
+ setCurrentView('detail');
700
+ }
701
+ else {
702
+ setActiveAssetType(item.value);
703
+ setCurrentView('add_select');
704
+ }
705
+ } }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
706
+ }
707
+ if (currentView === 'remove_type' && selectedStack) {
708
+ const removeTypes = [
709
+ { label: `Skills (${selectedStack.skills.length})`, value: 'skill' },
710
+ { label: `Prompts (${selectedStack.prompts.length})`, value: 'prompt' },
711
+ { label: `MCPs (${selectedStack.mcps.length})`, value: 'mcp' },
712
+ { label: '← Back', value: 'back' },
713
+ ];
714
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsxs(Text, { bold: true, color: theme.accent, children: ["Remove Asset from ", selectedStack.name] }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: removeTypes, onSelect: (item) => {
715
+ if (item.value === 'back') {
716
+ setCurrentView('detail');
717
+ }
718
+ else {
719
+ setActiveAssetType(item.value);
720
+ setCurrentView('remove_select');
721
+ }
722
+ } }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
723
+ }
724
+ if (currentView === 'add_select' && selectedStack) {
725
+ let available = [];
726
+ if (activeAssetType === 'skill') {
727
+ available = installedAssets.skills.filter((name) => !selectedStack.skills.includes(name));
728
+ }
729
+ else if (activeAssetType === 'prompt') {
730
+ available = installedAssets.prompts.filter((name) => !selectedStack.prompts.includes(name));
731
+ }
732
+ else if (activeAssetType === 'mcp') {
733
+ available = installedAssets.mcps.filter((name) => !selectedStack.mcps.includes(name));
734
+ }
735
+ const items = [
736
+ ...available.map((name) => ({ label: name, value: name })),
737
+ { label: '← Back', value: 'back' },
738
+ ];
739
+ const handleAdd = async (item) => {
740
+ if (item.value === 'back') {
741
+ setCurrentView('add_type');
742
+ return;
743
+ }
744
+ const assetName = item.value;
745
+ let updatedSkills = [...selectedStack.skills];
746
+ let updatedPrompts = [...selectedStack.prompts];
747
+ let updatedMcps = [...selectedStack.mcps];
748
+ if (activeAssetType === 'skill') {
749
+ updatedSkills.push(assetName);
750
+ }
751
+ else if (activeAssetType === 'prompt') {
752
+ updatedPrompts.push(assetName);
753
+ }
754
+ else if (activeAssetType === 'mcp') {
755
+ updatedMcps.push(assetName);
756
+ }
757
+ try {
758
+ await stackService.update(selectedStack.scope, selectedStack.name, {
759
+ skills: updatedSkills,
760
+ prompts: updatedPrompts,
761
+ mcps: updatedMcps,
762
+ });
763
+ const updatedStack = {
764
+ ...selectedStack,
765
+ skills: updatedSkills,
766
+ prompts: updatedPrompts,
767
+ mcps: updatedMcps,
768
+ };
769
+ setSelectedStack(updatedStack);
770
+ setStacksList((prev) => prev.map((s) => (s.name === selectedStack.name && s.scope === selectedStack.scope ? updatedStack : s)));
771
+ setActionMessage(`Added ${activeAssetType} "${assetName}" successfully.`);
772
+ setTimeout(() => setActionMessage(null), 2000);
773
+ }
774
+ catch (err) {
775
+ setActionMessage(`Error adding asset: ${err.message}`);
776
+ setTimeout(() => setActionMessage(null), 3000);
777
+ }
778
+ setCurrentView('detail');
779
+ };
780
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsxs(Text, { bold: true, color: theme.accent, children: ["Select ", activeAssetType, " to Add"] }), _jsx(Box, { marginTop: 1, children: available.length === 0 ? (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: theme.dim, children: ["No installed ", activeAssetType, "s available to add."] }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: [{ label: '← Back', value: 'back' }], onSelect: () => setCurrentView('add_type') }) })] })) : (_jsx(CustomSelectInput, { items: items, onSelect: handleAdd })) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
781
+ }
782
+ if (currentView === 'remove_select' && selectedStack) {
783
+ let currentAssets = [];
784
+ if (activeAssetType === 'skill') {
785
+ currentAssets = selectedStack.skills;
786
+ }
787
+ else if (activeAssetType === 'prompt') {
788
+ currentAssets = selectedStack.prompts;
789
+ }
790
+ else if (activeAssetType === 'mcp') {
791
+ currentAssets = selectedStack.mcps;
792
+ }
793
+ const items = [
794
+ ...currentAssets.map((name) => ({ label: name, value: name })),
795
+ { label: '← Back', value: 'back' },
796
+ ];
797
+ const handleRemove = async (item) => {
798
+ if (item.value === 'back') {
799
+ setCurrentView('remove_type');
800
+ return;
801
+ }
802
+ const assetName = item.value;
803
+ let updatedSkills = selectedStack.skills.filter((s) => s !== assetName);
804
+ let updatedPrompts = selectedStack.prompts.filter((p) => p !== assetName);
805
+ let updatedMcps = selectedStack.mcps.filter((m) => m !== assetName);
806
+ try {
807
+ await stackService.update(selectedStack.scope, selectedStack.name, {
808
+ skills: updatedSkills,
809
+ prompts: updatedPrompts,
810
+ mcps: updatedMcps,
811
+ });
812
+ const updatedStack = {
813
+ ...selectedStack,
814
+ skills: updatedSkills,
815
+ prompts: updatedPrompts,
816
+ mcps: updatedMcps,
817
+ };
818
+ setSelectedStack(updatedStack);
819
+ setStacksList((prev) => prev.map((s) => (s.name === selectedStack.name && s.scope === selectedStack.scope ? updatedStack : s)));
820
+ setActionMessage(`Removed ${activeAssetType} "${assetName}" successfully.`);
821
+ setTimeout(() => setActionMessage(null), 2000);
822
+ }
823
+ catch (err) {
824
+ setActionMessage(`Error removing asset: ${err.message}`);
825
+ setTimeout(() => setActionMessage(null), 3000);
826
+ }
827
+ setCurrentView('detail');
828
+ };
829
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsxs(Text, { bold: true, color: theme.accent, children: ["Select ", activeAssetType, " to Remove"] }), _jsx(Box, { marginTop: 1, children: currentAssets.length === 0 ? (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: theme.dim, children: ["No ", activeAssetType, "s in this stack."] }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: [{ label: '← Back', value: 'back' }], onSelect: () => setCurrentView('remove_type') }) })] })) : (_jsx(CustomSelectInput, { items: items, onSelect: handleRemove })) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
830
+ }
831
+ return null;
832
+ };
833
+ return _jsx(StacksListScreen, {});
834
+ }
835
+ if (screen === 'stacks_remove_select') {
836
+ const StacksRemoveScreen = () => {
837
+ const { rows } = useResponsiveLayout();
838
+ const handleRemove = async (item) => {
839
+ const [scope, name] = item.value.split(':');
840
+ try {
841
+ await stackService.remove(scope, name);
842
+ setInfoState('success');
843
+ setInfoMessage(`Stack "${name}" removed successfully.`);
844
+ }
845
+ catch (err) {
846
+ setInfoState('error');
847
+ setInfoMessage(`Error removing stack: ${err.message}`);
848
+ }
849
+ setScreen('stacks_menu');
850
+ };
851
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Remove Stack" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: selectItems, onSelect: handleRemove }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
852
+ };
853
+ return _jsx(StacksRemoveScreen, {});
854
+ }
855
+ // Backup & Restore workflows
856
+ if (screen === 'backup_create_label') {
857
+ return (_jsx(InputScreen, { title: "Save a Backup", placeholder: "Enter backup label (optional)...", onSubmit: (val) => {
858
+ setInputVal(val);
859
+ setScreen('backup_create_app');
860
+ }, onBack: () => setScreen('backup_menu') }));
861
+ }
862
+ if (screen === 'backup_create_app') {
863
+ return _jsx(StableScreenWrapper, { children: _jsx(BackupApp, { subcmd: "create", idOrName: inputVal || undefined, bypassConfirm: true, onBack: () => setScreen('backup_menu') }) });
864
+ }
865
+ if (screen === 'backup_restore_select') {
866
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Restore Backup" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: selectItems, onSelect: (item) => {
867
+ setInputVal(item.value);
868
+ setScreen('backup_restore_app');
869
+ } }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "WARNING: Restore will completely replace your active environments. \u00B7 esc go back" }) })] }));
870
+ }
871
+ if (screen === 'backup_restore_app') {
872
+ return _jsx(StableScreenWrapper, { children: _jsx(BackupApp, { subcmd: "restore", idOrName: inputVal, bypassConfirm: true, onBack: () => setScreen('backup_menu') }) });
873
+ }
874
+ if (screen === 'backup_list') {
875
+ return _jsx(StableScreenWrapper, { children: _jsx(BackupApp, { subcmd: "list", onBack: () => setScreen('backup_menu') }) });
876
+ }
877
+ if (screen === 'backup_delete_select') {
878
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Delete Backup" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: selectItems, onSelect: (item) => {
879
+ setInputVal(item.value);
880
+ setScreen('backup_delete_app');
881
+ } }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
882
+ }
883
+ if (screen === 'backup_delete_app') {
884
+ return _jsx(StableScreenWrapper, { children: _jsx(BackupApp, { subcmd: "delete", idOrName: inputVal, bypassConfirm: true, onBack: () => setScreen('backup_menu') }) });
885
+ }
886
+ // Sync workflows
887
+ if (screen === 'sync_push_app') {
888
+ return _jsx(StableScreenWrapper, { children: _jsx(SyncApp, { action: "push", onBack: () => setScreen('sync_menu') }) });
889
+ }
890
+ if (screen === 'sync_pull_app') {
891
+ return _jsx(StableScreenWrapper, { children: _jsx(SyncApp, { action: "pull", onBack: () => setScreen('sync_menu') }) });
892
+ }
893
+ // Import workflows
894
+ if (screen === 'import_menu') {
895
+ const importMenuItems = [
896
+ { label: 'Import from AI Tool or Editor', value: 'import_wizard' },
897
+ { label: 'Import from GitHub or Custom Path', value: 'import_repo_input' },
898
+ { label: '← Back to Main Menu', value: 'back' },
899
+ ];
900
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Import Assets" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: importMenuItems, onSelect: (item) => {
901
+ if (item.value === 'back') {
902
+ setScreen('menu');
903
+ }
904
+ else {
905
+ setScreen(item.value);
906
+ }
907
+ } }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
908
+ }
909
+ if (screen === 'import_wizard') {
910
+ return _jsx(ImportWizardApp, { onBack: () => setScreen('import_menu') });
911
+ }
912
+ if (screen === 'import_repo_input') {
913
+ return (_jsx(InputScreen, { title: "Import Repository or Local Folder", placeholder: "Enter repo path (e.g. user/repo or ./path)...", onSubmit: (val) => {
914
+ setInputVal(val);
915
+ setScreen('import_app');
916
+ }, onBack: () => setScreen('import_menu') }));
917
+ }
918
+ if (screen === 'import_app') {
919
+ return _jsx(StableScreenWrapper, { children: _jsx(ImportApp, { source: inputVal, onBack: () => setScreen('import_menu') }) });
920
+ }
921
+ if (screen === 'change_local_folder_input') {
922
+ return (_jsx(InputScreen, { title: "Change Local Folder Path", placeholder: "Enter path (e.g. ~/.aman-custom)...", onSubmit: (val) => {
923
+ void changeLocalFolder(val);
924
+ }, onBack: () => setScreen('menu') }));
925
+ }
926
+ if (screen === 'change_repo_input') {
927
+ return (_jsx(InputScreen, { title: "Change GitHub Repository", placeholder: "Enter repository (e.g. username/repo)...", onSubmit: (val) => {
928
+ setInputVal(val);
929
+ setScreen('change_repo_mode');
930
+ }, onBack: () => setScreen('sync_menu') }));
931
+ }
932
+ if (screen === 'change_repo_mode') {
933
+ const modes = [
934
+ { label: 'Connect to an Existing Repository', value: 'existing' },
935
+ { label: 'Create a New Private Repository', value: 'create' },
936
+ ];
937
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Select Repository Mode" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: modes, onSelect: async (item) => {
938
+ await connectGithub(inputVal, item.value);
939
+ } }) })] }), _jsx(Box, { children: _jsx(Text, { color: theme.dim, children: "press enter to select \u00B7 esc go back" }) })] }));
940
+ }
941
+ // Default Dashboard Home Screen
942
+ const storageStr = storageInfo.type === 'github' ? 'GitHub' : 'Local';
943
+ const repoStr = storageInfo.repo || 'none';
944
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: rows, justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.accent, children: "Aman Intelligence" }), _jsx(Text, { color: theme.dim, children: "Assets" }), _jsxs(Text, { children: ["MCPs: ", _jsx(Text, { bold: true, children: stats.mcps }), " \u00B7 Prompts: ", _jsx(Text, { bold: true, children: stats.prompts }), " \u00B7 Skills:", ' ', _jsx(Text, { bold: true, children: stats.skills }), " \u00B7 Packs: ", _jsx(Text, { bold: true, children: stats.packs }), " \u00B7 Stacks:", ' ', _jsx(Text, { bold: true, children: stats.stacks })] }), _jsxs(Box, { flexDirection: "row", marginTop: 1, children: [_jsx(Text, { children: "Storage: " }), _jsx(GithubIndicator, { isConnected: isConnected, repository: storageInfo.repo })] }), storageInfo.repo && _jsxs(Text, { color: theme.dim, children: ["Repo: ", storageInfo.repo] }), _jsxs(Text, { color: theme.dim, children: ["Last sync: ", lastSync, " \u00B7 Last backup: ", lastBackup] }), !isCompact && _jsx(Text, { color: theme.borderMuted, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" })] }), _jsxs(Box, { flexDirection: "row", justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, marginRight: 2, children: [_jsx(Text, { bold: true, color: theme.accent, children: "DISCOVER" }), _jsx(Box, { flexDirection: "column", marginLeft: 2, children: currentMenuItems.filter((i) => i.section === 'Discover').map((item) => {
945
+ const globalIdx = currentMenuItems.findIndex((m) => m.value === item.value);
946
+ const isCurrent = globalIdx === menuCursor;
947
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: isCurrent ? theme.primary : theme.dim, children: isCurrent ? ' › ' : ' ' }), _jsx(Text, { bold: isCurrent, color: isCurrent ? theme.text : theme.secondary, children: item.label })] }, item.value));
948
+ }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, color: theme.accent, children: "MANAGE" }), _jsx(Box, { flexDirection: "column", marginLeft: 2, children: currentMenuItems.filter((i) => i.section === 'Manage').map((item, idx) => {
949
+ const globalIdx = currentMenuItems.findIndex((m) => m.value === item.value);
950
+ const isCurrent = globalIdx === menuCursor;
951
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: isCurrent ? theme.primary : theme.dim, children: isCurrent ? ' › ' : ' ' }), _jsx(Text, { bold: isCurrent, color: isCurrent ? theme.text : theme.secondary, children: item.label })] }, item.value));
952
+ }) })] })] }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Text, { bold: true, color: theme.accent, children: "ENVIRONMENT" }), _jsx(Box, { flexDirection: "column", marginLeft: 2, children: currentMenuItems.filter((i) => i.section === 'Environment').map((item) => {
953
+ const globalIdx = currentMenuItems.findIndex((m) => m.value === item.value);
954
+ const isCurrent = globalIdx === menuCursor;
955
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: isCurrent ? theme.primary : theme.dim, children: isCurrent ? ' › ' : ' ' }), _jsx(Text, { bold: isCurrent, color: isCurrent ? theme.text : theme.secondary, children: item.label })] }, item.value));
956
+ }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, color: theme.accent, children: "SYSTEM" }), _jsx(Box, { flexDirection: "column", marginLeft: 2, children: currentMenuItems.filter((i) => i.section === 'System').map((item) => {
957
+ const globalIdx = currentMenuItems.findIndex((m) => m.value === item.value);
958
+ const isCurrent = globalIdx === menuCursor;
959
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: isCurrent ? theme.primary : theme.dim, children: isCurrent ? ' › ' : ' ' }), _jsx(Text, { bold: isCurrent, color: isCurrent ? theme.text : theme.secondary, children: item.label })] }, item.value));
960
+ }) })] })] })] })] }), _jsxs(Box, { flexDirection: "column", children: [canShowDescriptions && (_jsx(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, borderStyle: "round", borderColor: theme.borderMuted, height: isCompact ? 0 : 5, justifyContent: "center", children: _jsx(Text, { color: theme.text, children: currentMenuItems[menuCursor]?.description || '' }) })), _jsx(Box, { marginTop: isCompact ? 1 : 0, children: isCompact ? _jsx(Text, { color: theme.dim, children: "\u2191\u2193 Navigate \u00B7 Enter Select \u00B7 Esc Back" }) : _jsx(Text, { color: theme.dim, children: "\u2191\u2193\u2190\u2192 Navigate \u00B7 Enter Select \u00B7 Esc Back \u00B7 Q Quit" }) })] })] }));
961
+ };
962
+ export async function dashboardCommand() {
963
+ const environmentPath = environmentService.getActiveEnvironmentDir();
964
+ const isReady = exists(path.join(environmentPath, 'aman.json'));
965
+ if (!process.stdin.isTTY) {
966
+ if (!isReady) {
967
+ console.log(`\n \x1b[31;1mAman Intelligence is not initialized yet.\x1b[0m`);
968
+ console.log(` Run the following command to get started:\n`);
969
+ console.log(` \x1b[38;2;255;157;35maman init\x1b[0m\n`);
970
+ return;
971
+ }
972
+ const data = await scanAll(environmentPath, 'installed');
973
+ const storage = environmentService.getStorage();
974
+ const localStacks = await stackService.list('global');
975
+ const projectStacks = await stackService.list('project');
976
+ const storageStr = storage.type === 'github' ? `github: ${storage.repository}` : 'local';
977
+ console.log(`\n \x1b[38;2;255;157;35mAman Intelligence — Asset Hub\x1b[0m`);
978
+ console.log(` Path: ${environmentPath}`);
979
+ console.log(` Storage: ${storageStr}`);
980
+ console.log(` Assets:`);
981
+ const packRefs = new Set();
982
+ for (const scope of ['global', 'project']) {
983
+ try {
984
+ const lock = await lockService.read(scope);
985
+ for (const entry of lock.assets) {
986
+ if (entry.source.kind === 'pack')
987
+ packRefs.add(entry.source.ref);
988
+ }
989
+ }
990
+ catch {
991
+ // ignore
992
+ }
993
+ }
994
+ console.log(` MCPs: ${data.mcps.length}`);
995
+ console.log(` Prompts: ${data.prompts.length}`);
996
+ console.log(` Skills: ${data.skills.length}`);
997
+ console.log(` Packs: ${packRefs.size}`);
998
+ console.log(` Stacks: ${localStacks.length + projectStacks.length}\n`);
999
+ console.log(' To open the interactive Asset Hub, run "aman" inside a TTY terminal.\n');
1000
+ return;
1001
+ }
1002
+ const { waitUntilExit } = render(_jsx(DashboardApp, {}));
1003
+ await waitUntilExit();
1004
+ }