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,331 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState, useRef } from 'react';
3
+ import { render, Box, Text, useApp, useInput } from 'ink';
4
+ import { packService } from '../services/pack.service.js';
5
+ import { Narrator } from '../ui/components/Narrator.js';
6
+ import { ScopePrompt } from '../ui/components/ScopePrompt.js';
7
+ import { Header } from '../ui/components/Header.js';
8
+ import { theme } from '../ui/theme.js';
9
+ import { titleize } from '../ui/marketplaceDisplay.js';
10
+ import { ASSET_TYPE_PLURAL, ASSET_TAB_ORDER, assetCompositeKey, parseAssetCompositeKey } from '../ui/assetDisplay.js';
11
+ import { scanAll } from '../storage/scanner.js';
12
+ import { environmentService } from '../services/environment.service.js';
13
+ import path from 'path';
14
+ import { exists } from '../storage/filesystem.js';
15
+ import { ProgressBar } from '../ui/animations/ProgressBar.js';
16
+ import { TransitionScreen } from '../ui/animations/TransitionScreen.js';
17
+ const PAGE_SIZE = 8;
18
+ export const PackCreateApp = ({ name, onBack }) => {
19
+ const { exit } = useApp();
20
+ const handleExit = () => {
21
+ if (onBack)
22
+ onBack();
23
+ else
24
+ exit();
25
+ };
26
+ const [category, setCategory] = useState(ASSET_TAB_ORDER[0]);
27
+ const [allItems, setAllItems] = useState([]);
28
+ const [cursor, setCursor] = useState(0);
29
+ const [selected, setSelected] = useState(new Set());
30
+ const [mode, setMode] = useState('select');
31
+ const [state, setState] = useState('idle');
32
+ const [message, setMessage] = useState('');
33
+ const [loading, setLoading] = useState(true);
34
+ useEffect(() => {
35
+ async function load() {
36
+ const globalDir = environmentService.getActiveEnvironmentDir();
37
+ const projectDir = environmentService.getProjectEnvironmentDir();
38
+ const globalData = await scanAll(globalDir, 'global');
39
+ let projectData = { skills: [], prompts: [], mcps: [] };
40
+ if (exists(projectDir)) {
41
+ projectData = await scanAll(projectDir, 'project');
42
+ }
43
+ function mergeAssets(items, type) {
44
+ const merged = new Map();
45
+ const seen = new Set();
46
+ for (const item of items) {
47
+ const baseName = (item.originalName || item.name)
48
+ .replace(/[-_\s]+\d+$/, '')
49
+ .toLowerCase()
50
+ .replace(/[-_\s]+/g, ' ')
51
+ .trim();
52
+ if (seen.has(baseName))
53
+ continue;
54
+ seen.add(baseName);
55
+ merged.set(item.name, { name: item.name, label: titleize(baseName), type });
56
+ }
57
+ return Array.from(merged.values());
58
+ }
59
+ setAllItems([
60
+ ...mergeAssets([...globalData.skills, ...projectData.skills], 'skill'),
61
+ ...mergeAssets([...globalData.prompts, ...projectData.prompts], 'prompt'),
62
+ ...mergeAssets([...globalData.mcps, ...projectData.mcps], 'mcp'),
63
+ ]);
64
+ setLoading(false);
65
+ }
66
+ load();
67
+ }, []);
68
+ const items = useMemo(() => allItems.filter((i) => i.type === category), [allItems, category]);
69
+ const visibleItems = useMemo(() => {
70
+ if (items.length === 0)
71
+ return [];
72
+ const half = Math.floor(PAGE_SIZE / 2);
73
+ const start = Math.max(0, Math.min(cursor - half, Math.max(0, items.length - PAGE_SIZE)));
74
+ return items.slice(start, start + PAGE_SIZE).map((item, idx) => ({
75
+ item,
76
+ index: start + idx,
77
+ }));
78
+ }, [cursor, items]);
79
+ useInput((input, key) => {
80
+ if (input === 'q' || key.escape) {
81
+ handleExit();
82
+ return;
83
+ }
84
+ if (mode !== 'select')
85
+ return;
86
+ if (key.leftArrow || key.rightArrow) {
87
+ setCategory((prev) => {
88
+ const idx = ASSET_TAB_ORDER.indexOf(prev);
89
+ const next = key.leftArrow
90
+ ? (idx - 1 + ASSET_TAB_ORDER.length) % ASSET_TAB_ORDER.length
91
+ : (idx + 1) % ASSET_TAB_ORDER.length;
92
+ return ASSET_TAB_ORDER[next];
93
+ });
94
+ setCursor(0);
95
+ return;
96
+ }
97
+ if (key.upArrow) {
98
+ setCursor((p) => Math.max(0, p - 1));
99
+ return;
100
+ }
101
+ if (key.downArrow) {
102
+ setCursor((p) => Math.min(items.length - 1, p + 1));
103
+ return;
104
+ }
105
+ if (input === ' ') {
106
+ const item = items[cursor];
107
+ if (!item)
108
+ return;
109
+ const composite = assetCompositeKey(item.type, item.name);
110
+ setSelected((prev) => {
111
+ const next = new Set(prev);
112
+ if (next.has(composite))
113
+ next.delete(composite);
114
+ else
115
+ next.add(composite);
116
+ return next;
117
+ });
118
+ return;
119
+ }
120
+ if (key.return && selected.size > 0) {
121
+ createPack();
122
+ }
123
+ });
124
+ async function createPack() {
125
+ setMode('creating');
126
+ setState('installing');
127
+ setMessage(`Creating ${name}.amanpack...`);
128
+ try {
129
+ const selectedByType = (type) => Array.from(selected)
130
+ .map((key) => parseAssetCompositeKey(key))
131
+ .filter((p) => p !== null && p.type === type)
132
+ .map((p) => p.localName);
133
+ const packDef = {
134
+ name,
135
+ version: '1.0.0',
136
+ description: `Workflow pack: ${name}`,
137
+ skills: selectedByType('skill'),
138
+ prompts: selectedByType('prompt'),
139
+ mcps: selectedByType('mcp'),
140
+ stacks: [],
141
+ createdAt: new Date().toISOString(),
142
+ };
143
+ const outPath = path.resolve(process.cwd(), `${name}.amanpack`);
144
+ await packService.create(name, packDef, outPath);
145
+ setState('success');
146
+ setMessage(`Created ${name}.amanpack (${packDef.skills.length} skills, ${packDef.prompts.length} prompts, ${packDef.mcps.length} MCPs)`);
147
+ }
148
+ catch (err) {
149
+ setState('error');
150
+ setMessage(`Error: ${err.message}`);
151
+ }
152
+ setMode('done');
153
+ setTimeout(() => handleExit(), 1000);
154
+ }
155
+ if (loading) {
156
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { compact: true }), _jsx(Narrator, { state: "searching", message: "Loading assets..." })] }));
157
+ }
158
+ if (mode === 'creating' || mode === 'done') {
159
+ return (_jsx(Box, { flexDirection: "column", paddingX: 1, children: _jsx(Narrator, { state: state, message: message }) }));
160
+ }
161
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { compact: true }), _jsxs(Text, { children: ["Select assets for ", _jsx(Text, { bold: true, children: name })] }), _jsx(Box, { marginY: 1, children: ASSET_TAB_ORDER.map((t) => (_jsx(Box, { marginRight: 2, children: _jsxs(Text, { color: category === t ? theme.primary : theme.dim, bold: category === t, children: [category === t ? '❯ ' : ' ', ASSET_TYPE_PLURAL[t]] }) }, t))) }), visibleItems.map(({ item, index }) => {
162
+ const isCurrent = index === cursor;
163
+ const isSelected = selected.has(assetCompositeKey(item.type, item.name));
164
+ return (_jsxs(Text, { children: [_jsx(Text, { color: isCurrent ? theme.primary : theme.dim, children: isCurrent ? ' › ' : ' ' }), _jsx(Text, { color: isSelected ? theme.primary : theme.secondary, children: isSelected ? '◆ ' : '○ ' }), _jsx(Text, { color: isCurrent ? theme.text : theme.secondary, bold: isCurrent, children: item.label })] }, item.name));
165
+ }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.dim, children: ["\u2190\u2192 category space select enter create q quit", selected.size > 0 ? ` · ${selected.size} selected` : ''] }) })] }));
166
+ };
167
+ export const PackInspectApp = ({ packPath, onBack }) => {
168
+ const { exit } = useApp();
169
+ const handleExit = () => {
170
+ if (onBack)
171
+ onBack();
172
+ else
173
+ exit();
174
+ };
175
+ const [manifest, setManifest] = useState(null);
176
+ const [error, setError] = useState(null);
177
+ const started = useRef(false);
178
+ useEffect(() => {
179
+ if (started.current)
180
+ return;
181
+ started.current = true;
182
+ async function inspect() {
183
+ try {
184
+ const m = await packService.inspect(packPath);
185
+ setManifest(m);
186
+ }
187
+ catch (err) {
188
+ setError(err.message);
189
+ }
190
+ setTimeout(() => handleExit(), 300);
191
+ }
192
+ inspect();
193
+ }, [packPath]);
194
+ useInput((input, key) => {
195
+ if (key.escape || input === 'q') {
196
+ handleExit();
197
+ }
198
+ });
199
+ if (error) {
200
+ return (_jsx(Box, { paddingX: 1, children: _jsx(Narrator, { state: "error", message: error }) }));
201
+ }
202
+ if (!manifest) {
203
+ return (_jsx(Box, { paddingX: 1, children: _jsx(Narrator, { state: "searching", message: "Inspecting..." }) }));
204
+ }
205
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, children: titleize(manifest.name) }), manifest.version && _jsxs(Text, { color: theme.dim, children: ["v", manifest.version] }), manifest.description && _jsx(Text, { color: theme.secondary, children: manifest.description }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: theme.dim, children: ["Skills: ", manifest.skills.length] }), _jsxs(Text, { color: theme.dim, children: ["Prompts: ", manifest.prompts.length] }), _jsxs(Text, { color: theme.dim, children: ["MCPs: ", manifest.mcps.length] }), _jsxs(Text, { color: theme.dim, children: ["Stacks: ", manifest.stacks.length] })] }), manifest.skills.length > 0 && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, color: theme.primary, children: "Skills" }), manifest.skills.map((s) => (_jsxs(Text, { color: theme.dim, children: [' ', "\u2713 ", titleize(s)] }, s)))] })), manifest.prompts.length > 0 && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, color: theme.primary, children: "Prompts" }), manifest.prompts.map((p) => (_jsxs(Text, { color: theme.dim, children: [' ', "\u2713 ", titleize(p)] }, p)))] })), manifest.mcps.length > 0 && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, color: theme.primary, children: "MCPs" }), manifest.mcps.map((m) => (_jsxs(Text, { color: theme.dim, children: [' ', "\u2713 ", titleize(m)] }, m)))] }))] }));
206
+ };
207
+ export const PackInstallApp = ({ packPath, initialScope, onBack }) => {
208
+ const { exit } = useApp();
209
+ const handleExit = () => {
210
+ if (onBack)
211
+ onBack();
212
+ else
213
+ exit();
214
+ };
215
+ const [scope, setScope] = useState(initialScope);
216
+ const [state, setState] = useState('idle');
217
+ const [message, setMessage] = useState('');
218
+ const [progress, setProgress] = useState(0);
219
+ const started = useRef(false);
220
+ useEffect(() => {
221
+ if (!scope)
222
+ return;
223
+ if (started.current)
224
+ return;
225
+ started.current = true;
226
+ async function install() {
227
+ setState('installing');
228
+ setMessage(`Installing pack...`);
229
+ try {
230
+ await packService.install(packPath, scope, (p) => setProgress(p));
231
+ setState('success');
232
+ setMessage(`Installed pack → ${scope === 'project' ? 'project' : 'global'}`);
233
+ }
234
+ catch (err) {
235
+ setState('error');
236
+ setMessage(`Error: ${err.message}`);
237
+ }
238
+ setTimeout(() => handleExit(), 1000);
239
+ }
240
+ install();
241
+ }, [packPath, scope]);
242
+ useInput((input, key) => {
243
+ if (key.escape || input === 'q') {
244
+ handleExit();
245
+ }
246
+ });
247
+ if (!scope) {
248
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { compact: true }), _jsx(ScopePrompt, { onSelect: (s) => setScope(s) })] }));
249
+ }
250
+ return (_jsxs(Box, { paddingX: 1, flexDirection: "column", children: [_jsx(Narrator, { state: state, message: message }), state === 'installing' && (_jsx(Box, { marginTop: 1, children: _jsx(ProgressBar, { progress: progress }) }))] }));
251
+ };
252
+ // ── Entry point ─────────────────────────────────────────────────────
253
+ export async function packCommand(args, options) {
254
+ const subcmd = args[0];
255
+ if (subcmd === 'create') {
256
+ const name = args[1];
257
+ if (!name) {
258
+ console.log(' Usage: aman pack create <name>');
259
+ return;
260
+ }
261
+ if (!process.stdin.isTTY) {
262
+ console.log(' ERROR: Selective pack creation requires an interactive TTY terminal.');
263
+ process.exit(1);
264
+ }
265
+ const { waitUntilExit } = render(_jsx(PackCreateApp, { name: name }));
266
+ await waitUntilExit();
267
+ }
268
+ else if (subcmd === 'inspect') {
269
+ const packPath = args[1];
270
+ if (!packPath) {
271
+ console.log(' Usage: aman pack inspect <file.amanpack>');
272
+ return;
273
+ }
274
+ if (!process.stdin.isTTY) {
275
+ console.log(' ◌ Inspecting...');
276
+ try {
277
+ const manifest = await packService.inspect(packPath);
278
+ console.log(` ${titleize(manifest.name)}`);
279
+ console.log(` v${manifest.version || '1.0.0'}`);
280
+ console.log(` ${manifest.description || ''}\n`);
281
+ console.log(` Skills: ${manifest.skills.length}`);
282
+ console.log(` Prompts: ${manifest.prompts.length}`);
283
+ console.log(` MCPs: ${manifest.mcps.length}`);
284
+ console.log(` Stacks: ${manifest.stacks.length}\n`);
285
+ console.log(' Contents:');
286
+ manifest.skills.forEach((s) => console.log(` ${titleize(s)}`));
287
+ }
288
+ catch (err) {
289
+ console.log(` ✗ Inspect error: ${err.message}`);
290
+ process.exit(1);
291
+ }
292
+ return;
293
+ }
294
+ const { waitUntilExit } = render(_jsx(PackInspectApp, { packPath: packPath }));
295
+ await waitUntilExit();
296
+ }
297
+ else if (subcmd === 'install') {
298
+ const packPath = args[1];
299
+ if (!packPath) {
300
+ console.log(' Usage: aman pack install <file.amanpack>');
301
+ return;
302
+ }
303
+ let scope = options.project || options.p
304
+ ? 'project'
305
+ : options.global || options.g
306
+ ? 'global'
307
+ : undefined;
308
+ if (!process.stdin.isTTY && !scope) {
309
+ console.error('Pack install requires --global or --project when not interactive.\n' +
310
+ 'Example: aman pack install ./bundle.amanpack --global');
311
+ process.exit(1);
312
+ }
313
+ if (!process.stdin.isTTY) {
314
+ console.log(` ◌ Installing pack ${packPath} → ${scope}...`);
315
+ try {
316
+ await packService.install(packPath, scope);
317
+ console.log(` ✓ Installed pack → ${scope}`);
318
+ }
319
+ catch (err) {
320
+ console.log(` ✗ Install error: ${err.message}`);
321
+ process.exit(1);
322
+ }
323
+ return;
324
+ }
325
+ const { waitUntilExit } = render(_jsx(TransitionScreen, { message: `Preparing pack installation for ${path.basename(packPath)}...`, children: _jsx(PackInstallApp, { packPath: packPath, initialScope: scope }) }));
326
+ await waitUntilExit();
327
+ }
328
+ else {
329
+ console.log(' Usage: aman pack <create|inspect|install> [args]');
330
+ }
331
+ }
@@ -0,0 +1,6 @@
1
+ import { AssetType } from '../types/index.js';
2
+ export declare function registryCommand(args: string[], options: {
3
+ github?: boolean;
4
+ }): Promise<void>;
5
+ /** Publish from an installed global asset path (convenience for bootstrapping). */
6
+ export declare function publishInstalledAsset(localName: string, type: AssetType, slug: string, version: string): Promise<void>;
@@ -0,0 +1,218 @@
1
+ import path from 'path';
2
+ import { registryService } from '../registry/registry.service.js';
3
+ import { RegistryError } from '../registry/errors.js';
4
+ import { parseRegistryReference } from '../registry/slug-utils.js';
5
+ import { assetDir, isCanonicalAssetDir } from '../storage/asset-layout.js';
6
+ import { exists } from '../storage/filesystem.js';
7
+ import { environmentService } from '../services/environment.service.js';
8
+ import { localNameFromSlug } from '../utils/slug.js';
9
+ function printRegistryError(err) {
10
+ if (err instanceof RegistryError) {
11
+ console.error(`Registry error [${err.code}]: ${err.message}`);
12
+ return;
13
+ }
14
+ console.error(err);
15
+ }
16
+ export async function registryCommand(args, options) {
17
+ const sub = args[0];
18
+ const rest = args.slice(1);
19
+ if (options.github) {
20
+ registryService.setBackend('github');
21
+ }
22
+ switch (sub) {
23
+ case 'publish':
24
+ await publishSubcommand(rest);
25
+ break;
26
+ case 'deprecate':
27
+ await deprecateSubcommand(rest);
28
+ break;
29
+ case 'list':
30
+ await listSubcommand(rest);
31
+ break;
32
+ case 'search':
33
+ await searchSubcommand(rest.join(' '));
34
+ break;
35
+ case 'resolve':
36
+ await resolveSubcommand(rest);
37
+ break;
38
+ default:
39
+ console.log(`Usage: aman registry <command>
40
+
41
+ Commands:
42
+ publish Publish a canonical asset directory to the registry
43
+ deprecate Mark a published version deprecated
44
+ list List published versions for a slug
45
+ search Search the registry index
46
+ resolve Resolve slug@version metadata
47
+
48
+ Examples:
49
+ aman registry publish ./skills/caveman --slug @aman/caveman --version 1.0.0 --type skill
50
+ aman registry deprecate @aman/caveman@1.0.0 --reason "Superseded" --successor @aman/caveman@1.0.1
51
+ aman registry list @aman/caveman
52
+ aman registry search react
53
+ aman install @aman/caveman@1.0.0 --global
54
+ `);
55
+ }
56
+ }
57
+ async function publishSubcommand(args) {
58
+ const contentArg = args[0];
59
+ if (!contentArg) {
60
+ console.error('Usage: aman registry publish <content-dir> --slug @scope/name --version X.Y.Z --type skill|prompt|mcp');
61
+ process.exit(1);
62
+ }
63
+ let slug = '';
64
+ let version = '';
65
+ let type = 'skill';
66
+ for (let i = 1; i < args.length; i++) {
67
+ if (args[i] === '--slug' && args[i + 1])
68
+ slug = args[++i];
69
+ else if (args[i] === '--version' && args[i + 1])
70
+ version = args[++i];
71
+ else if (args[i] === '--type' && args[i + 1])
72
+ type = args[++i];
73
+ }
74
+ if (!slug || !version) {
75
+ console.error('Required: --slug @scope/name --version X.Y.Z');
76
+ process.exit(1);
77
+ }
78
+ const contentDirectory = path.resolve(contentArg);
79
+ if (!exists(contentDirectory) || !isCanonicalAssetDir(type, contentDirectory)) {
80
+ console.error(`Not a canonical ${type} directory: ${contentDirectory}`);
81
+ process.exit(1);
82
+ }
83
+ const name = localNameFromSlug(slug);
84
+ const id = registryService.newPublishId();
85
+ try {
86
+ const result = await registryService.publish({
87
+ slug,
88
+ version,
89
+ type,
90
+ contentDirectory,
91
+ metadata: {
92
+ id,
93
+ slug,
94
+ type,
95
+ name,
96
+ description: '',
97
+ version,
98
+ author: 'local',
99
+ tags: [],
100
+ visibility: 'public',
101
+ dependencies: [],
102
+ },
103
+ });
104
+ console.log(`Published ${result.record.slug}@${result.record.version}`);
105
+ console.log(` id: ${result.record.id}`);
106
+ console.log(` checksum: ${result.record.integrity.checksum}`);
107
+ }
108
+ catch (err) {
109
+ printRegistryError(err);
110
+ process.exit(1);
111
+ }
112
+ }
113
+ async function deprecateSubcommand(args) {
114
+ const ref = parseRegistryReference(args[0] ?? '');
115
+ if (!ref) {
116
+ console.error('Usage: aman registry deprecate @scope/name@X.Y.Z --reason "..." [--successor @scope/name@X.Y.Z]');
117
+ process.exit(1);
118
+ }
119
+ let reason = '';
120
+ let successor;
121
+ for (let i = 1; i < args.length; i++) {
122
+ if (args[i] === '--reason' && args[i + 1])
123
+ reason = args[++i];
124
+ else if (args[i] === '--successor' && args[i + 1])
125
+ successor = args[++i];
126
+ }
127
+ if (!reason) {
128
+ console.error('Required: --reason');
129
+ process.exit(1);
130
+ }
131
+ try {
132
+ const result = await registryService.deprecate({
133
+ slug: ref.slug,
134
+ version: ref.version,
135
+ reason,
136
+ successor,
137
+ });
138
+ console.log(`Deprecated ${ref.slug}@${ref.version}`);
139
+ console.log(` reason: ${result.record.deprecated?.reason}`);
140
+ }
141
+ catch (err) {
142
+ printRegistryError(err);
143
+ process.exit(1);
144
+ }
145
+ }
146
+ async function listSubcommand(args) {
147
+ const slug = args[0];
148
+ if (!slug?.startsWith('@')) {
149
+ console.error('Usage: aman registry list @scope/name');
150
+ process.exit(1);
151
+ }
152
+ try {
153
+ const result = await registryService.list({ slug });
154
+ console.log(`${result.slug} (${result.id})`);
155
+ for (const v of result.versions) {
156
+ const dep = v.deprecated ? ' [deprecated]' : '';
157
+ console.log(` ${v.version}${dep} ${v.integrity.checksum}`);
158
+ }
159
+ }
160
+ catch (err) {
161
+ printRegistryError(err);
162
+ process.exit(1);
163
+ }
164
+ }
165
+ async function searchSubcommand(query) {
166
+ const result = await registryService.search({ query });
167
+ for (const hit of result.hits) {
168
+ const dep = hit.record.deprecated ? ' [deprecated]' : '';
169
+ const verified = hit.record.trust.verified ? ' verified' : '';
170
+ console.log(`${hit.slug}@${hit.latestVersion}${dep}${verified} downloads:${hit.record.trust.downloads}`);
171
+ }
172
+ if (result.hits.length === 0) {
173
+ console.log('No matches.');
174
+ }
175
+ }
176
+ async function resolveSubcommand(args) {
177
+ const ref = parseRegistryReference(args[0] ?? '');
178
+ if (!ref) {
179
+ console.error('Usage: aman registry resolve @scope/name@X.Y.Z');
180
+ process.exit(1);
181
+ }
182
+ try {
183
+ const resolved = await registryService.resolve(ref);
184
+ console.log(JSON.stringify(resolved.record, null, 2));
185
+ }
186
+ catch (err) {
187
+ printRegistryError(err);
188
+ process.exit(1);
189
+ }
190
+ }
191
+ /** Publish from an installed global asset path (convenience for bootstrapping). */
192
+ export async function publishInstalledAsset(localName, type, slug, version) {
193
+ const root = environmentService.getActiveEnvironmentDir();
194
+ const typeRoot = type === 'skill'
195
+ ? path.join(root, 'skills')
196
+ : type === 'prompt'
197
+ ? path.join(root, 'prompts')
198
+ : path.join(root, 'mcps');
199
+ const contentDirectory = assetDir(type, typeRoot, localName);
200
+ await registryService.publish({
201
+ slug,
202
+ version,
203
+ type,
204
+ contentDirectory,
205
+ metadata: {
206
+ id: registryService.newPublishId(),
207
+ slug,
208
+ type,
209
+ name: localName,
210
+ description: '',
211
+ version,
212
+ author: 'local',
213
+ tags: [],
214
+ visibility: 'public',
215
+ dependencies: [],
216
+ },
217
+ });
218
+ }
@@ -0,0 +1 @@
1
+ export declare function removeCommand(args: string[], options: any): Promise<void>;
@@ -0,0 +1,76 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { render, Box, useApp } from 'ink';
4
+ import { assetService } from '../services/asset.service.js';
5
+ import { Confirm } from '../ui/components/Confirm.js';
6
+ import { Narrator } from '../ui/components/Narrator.js';
7
+ import { titleize } from '../ui/marketplaceDisplay.js';
8
+ import { ASSET_TAB_ORDER } from '../ui/assetDisplay.js';
9
+ const RemoveApp = ({ name, scope, skipConfirm }) => {
10
+ const { exit } = useApp();
11
+ const [confirmed, setConfirmed] = useState(skipConfirm);
12
+ const [state, setState] = useState('idle');
13
+ const [message, setMessage] = useState('');
14
+ useEffect(() => {
15
+ if (!confirmed)
16
+ return;
17
+ async function doRemove() {
18
+ setState('installing');
19
+ setMessage(`Removing ${titleize(name)}...`);
20
+ const types = ['skill', 'prompt', 'mcp'];
21
+ let removed = false;
22
+ for (const t of types) {
23
+ try {
24
+ const result = await assetService.remove(name, t, scope);
25
+ if (result)
26
+ removed = true;
27
+ }
28
+ catch {
29
+ // ignore
30
+ }
31
+ }
32
+ if (removed) {
33
+ setState('success');
34
+ setMessage(`Removed ${titleize(name)} from ${scope === 'project' ? 'project' : 'global'}`);
35
+ }
36
+ else {
37
+ setState('error');
38
+ setMessage(`Could not find ${titleize(name)} in ${scope === 'project' ? 'project' : 'global'}`);
39
+ }
40
+ setTimeout(() => exit(), 800);
41
+ }
42
+ doRemove();
43
+ }, [confirmed, exit, name, scope]);
44
+ if (!confirmed) {
45
+ return (_jsx(Box, { paddingX: 1, children: _jsx(Confirm, { message: `Remove ${titleize(name)}?`, onConfirm: () => setConfirmed(true), onCancel: () => {
46
+ console.log(' Cancelled.');
47
+ exit();
48
+ } }) }));
49
+ }
50
+ return (_jsx(Box, { paddingX: 1, children: _jsx(Narrator, { state: state, message: message }) }));
51
+ };
52
+ export async function removeCommand(args, options) {
53
+ const name = args.join(' ');
54
+ if (!name) {
55
+ console.log(' Usage: aman remove <name>');
56
+ return;
57
+ }
58
+ const scope = options.project || options.p ? 'project' : 'global';
59
+ let skipConfirm = Boolean(options.yes || options.y);
60
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
61
+ let removed = false;
62
+ for (const type of ASSET_TAB_ORDER) {
63
+ if (await assetService.remove(name, type, scope)) {
64
+ removed = true;
65
+ }
66
+ }
67
+ if (removed) {
68
+ console.log(`Removed ${titleize(name)} from ${scope === 'project' ? 'project' : 'global'}`);
69
+ return;
70
+ }
71
+ console.error(`Could not find ${titleize(name)} in ${scope === 'project' ? 'project' : 'global'}`);
72
+ process.exit(1);
73
+ }
74
+ const { waitUntilExit } = render(_jsx(RemoveApp, { name: name, scope: scope, skipConfirm: skipConfirm }));
75
+ await waitUntilExit();
76
+ }
@@ -0,0 +1,7 @@
1
+ export declare const SearchApp: ({ onBack, initialQuery }: {
2
+ onBack?: () => void;
3
+ initialQuery?: string;
4
+ }) => import("react/jsx-runtime").JSX.Element;
5
+ export declare function searchCommand(args: string[], options?: {
6
+ noTty?: boolean;
7
+ }): Promise<void>;