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.
- package/LICENSE +21 -0
- package/README.md +116 -0
- package/dist/bin/aman.d.ts +2 -0
- package/dist/bin/aman.js +165 -0
- package/dist/cli/global-install.d.ts +7 -0
- package/dist/cli/global-install.js +36 -0
- package/dist/cli/help-text.d.ts +1 -0
- package/dist/cli/help-text.js +62 -0
- package/dist/cli/version.d.ts +1 -0
- package/dist/cli/version.js +6 -0
- package/dist/commands/backup.d.ts +11 -0
- package/dist/commands/backup.js +262 -0
- package/dist/commands/browse.d.ts +11 -0
- package/dist/commands/browse.js +641 -0
- package/dist/commands/cache.d.ts +1 -0
- package/dist/commands/cache.js +38 -0
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.js +146 -0
- package/dist/commands/dashboard.d.ts +1 -0
- package/dist/commands/dashboard.js +1004 -0
- package/dist/commands/doctor.d.ts +4 -0
- package/dist/commands/doctor.js +54 -0
- package/dist/commands/export.d.ts +1 -0
- package/dist/commands/export.js +137 -0
- package/dist/commands/help.d.ts +1 -0
- package/dist/commands/help.js +47 -0
- package/dist/commands/import-wizard.d.ts +7 -0
- package/dist/commands/import-wizard.js +374 -0
- package/dist/commands/import.d.ts +9 -0
- package/dist/commands/import.js +351 -0
- package/dist/commands/info.d.ts +1 -0
- package/dist/commands/info.js +174 -0
- package/dist/commands/init.d.ts +20 -0
- package/dist/commands/init.js +146 -0
- package/dist/commands/install.d.ts +10 -0
- package/dist/commands/install.js +342 -0
- package/dist/commands/pack.d.ts +23 -0
- package/dist/commands/pack.js +331 -0
- package/dist/commands/registry.d.ts +6 -0
- package/dist/commands/registry.js +218 -0
- package/dist/commands/remove.d.ts +1 -0
- package/dist/commands/remove.js +76 -0
- package/dist/commands/search.d.ts +7 -0
- package/dist/commands/search.js +295 -0
- package/dist/commands/stack.d.ts +18 -0
- package/dist/commands/stack.js +327 -0
- package/dist/commands/sync.d.ts +9 -0
- package/dist/commands/sync.js +428 -0
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.js +97 -0
- package/dist/config/features.d.ts +2 -0
- package/dist/config/features.js +2 -0
- package/dist/config/index.d.ts +13 -0
- package/dist/config/index.js +80 -0
- package/dist/config/paths.d.ts +23 -0
- package/dist/config/paths.js +45 -0
- package/dist/import/adapters.d.ts +14 -0
- package/dist/import/adapters.js +580 -0
- package/dist/import/discovery.service.d.ts +8 -0
- package/dist/import/discovery.service.js +26 -0
- package/dist/import/import.service.d.ts +7 -0
- package/dist/import/import.service.js +259 -0
- package/dist/import/types.d.ts +71 -0
- package/dist/import/types.js +1 -0
- package/dist/import/utils.d.ts +36 -0
- package/dist/import/utils.js +428 -0
- package/dist/marketplace/cache.d.ts +18 -0
- package/dist/marketplace/cache.js +141 -0
- package/dist/marketplace/github-search.d.ts +17 -0
- package/dist/marketplace/github-search.js +268 -0
- package/dist/marketplace/install-from-candidate.d.ts +6 -0
- package/dist/marketplace/install-from-candidate.js +14 -0
- package/dist/marketplace/install.d.ts +15 -0
- package/dist/marketplace/install.js +54 -0
- package/dist/marketplace/metadata-validator.d.ts +8 -0
- package/dist/marketplace/metadata-validator.js +79 -0
- package/dist/marketplace/types.d.ts +34 -0
- package/dist/marketplace/types.js +1 -0
- package/dist/providers/local.provider.d.ts +9 -0
- package/dist/providers/local.provider.js +51 -0
- package/dist/providers/provider.interface.d.ts +7 -0
- package/dist/providers/provider.interface.js +1 -0
- package/dist/providers/registry.provider.d.ts +2 -0
- package/dist/providers/registry.provider.js +42 -0
- package/dist/providers/skills-sh.provider.d.ts +11 -0
- package/dist/providers/skills-sh.provider.js +56 -0
- package/dist/registry/adapter.interface.d.ts +16 -0
- package/dist/registry/adapter.interface.js +1 -0
- package/dist/registry/errors.d.ts +5 -0
- package/dist/registry/errors.js +8 -0
- package/dist/registry/filesystem-registry.adapter.d.ts +25 -0
- package/dist/registry/filesystem-registry.adapter.js +288 -0
- package/dist/registry/github-registry.adapter.d.ts +11 -0
- package/dist/registry/github-registry.adapter.js +32 -0
- package/dist/registry/index.d.ts +8 -0
- package/dist/registry/index.js +8 -0
- package/dist/registry/local-registry.adapter.d.ts +6 -0
- package/dist/registry/local-registry.adapter.js +9 -0
- package/dist/registry/registry.service.d.ts +44 -0
- package/dist/registry/registry.service.js +163 -0
- package/dist/registry/slug-utils.d.ts +12 -0
- package/dist/registry/slug-utils.js +51 -0
- package/dist/registry/types.d.ts +160 -0
- package/dist/registry/types.js +1 -0
- package/dist/services/asset.service.d.ts +12 -0
- package/dist/services/asset.service.js +142 -0
- package/dist/services/backup.service.d.ts +8 -0
- package/dist/services/backup.service.js +169 -0
- package/dist/services/classification.service.d.ts +31 -0
- package/dist/services/classification.service.js +271 -0
- package/dist/services/config.service.d.ts +9 -0
- package/dist/services/config.service.js +20 -0
- package/dist/services/doctor.service.d.ts +5 -0
- package/dist/services/doctor.service.js +186 -0
- package/dist/services/environment.service.d.ts +42 -0
- package/dist/services/environment.service.js +227 -0
- package/dist/services/github.service.d.ts +7 -0
- package/dist/services/github.service.js +42 -0
- package/dist/services/lock.service.d.ts +12 -0
- package/dist/services/lock.service.js +71 -0
- package/dist/services/marketplace.service.d.ts +40 -0
- package/dist/services/marketplace.service.js +225 -0
- package/dist/services/pack.service.d.ts +9 -0
- package/dist/services/pack.service.js +193 -0
- package/dist/services/stack.service.d.ts +9 -0
- package/dist/services/stack.service.js +94 -0
- package/dist/storage/asset-layout.d.ts +46 -0
- package/dist/storage/asset-layout.js +277 -0
- package/dist/storage/filesystem.d.ts +12 -0
- package/dist/storage/filesystem.js +113 -0
- package/dist/storage/scan-by-type.d.ts +2 -0
- package/dist/storage/scan-by-type.js +8 -0
- package/dist/storage/scanner.d.ts +11 -0
- package/dist/storage/scanner.js +188 -0
- package/dist/types/asset-metadata.d.ts +84 -0
- package/dist/types/asset-metadata.js +104 -0
- package/dist/types/index.d.ts +212 -0
- package/dist/types/index.js +1 -0
- package/dist/ui/animations/ErrorIndicator.d.ts +5 -0
- package/dist/ui/animations/ErrorIndicator.js +6 -0
- package/dist/ui/animations/GithubIndicator.d.ts +6 -0
- package/dist/ui/animations/GithubIndicator.js +9 -0
- package/dist/ui/animations/ProgressBar.d.ts +5 -0
- package/dist/ui/animations/ProgressBar.js +15 -0
- package/dist/ui/animations/Spinner.d.ts +5 -0
- package/dist/ui/animations/Spinner.js +21 -0
- package/dist/ui/animations/SuccessIndicator.d.ts +5 -0
- package/dist/ui/animations/SuccessIndicator.js +6 -0
- package/dist/ui/animations/SyncActivity.d.ts +5 -0
- package/dist/ui/animations/SyncActivity.js +21 -0
- package/dist/ui/animations/TransitionScreen.d.ts +7 -0
- package/dist/ui/animations/TransitionScreen.js +25 -0
- package/dist/ui/animations/useAnimationMode.d.ts +1 -0
- package/dist/ui/animations/useAnimationMode.js +16 -0
- package/dist/ui/assetDisplay.d.ts +19 -0
- package/dist/ui/assetDisplay.js +59 -0
- package/dist/ui/components/Confirm.d.ts +8 -0
- package/dist/ui/components/Confirm.js +14 -0
- package/dist/ui/components/CustomSelect.d.ts +19 -0
- package/dist/ui/components/CustomSelect.js +13 -0
- package/dist/ui/components/Header.d.ts +6 -0
- package/dist/ui/components/Header.js +9 -0
- package/dist/ui/components/HealthReport.d.ts +7 -0
- package/dist/ui/components/HealthReport.js +13 -0
- package/dist/ui/components/MarketplaceInstallConfirm.d.ts +19 -0
- package/dist/ui/components/MarketplaceInstallConfirm.js +23 -0
- package/dist/ui/components/Narrator.d.ts +9 -0
- package/dist/ui/components/Narrator.js +26 -0
- package/dist/ui/components/ScopePrompt.d.ts +8 -0
- package/dist/ui/components/ScopePrompt.js +23 -0
- package/dist/ui/components/TooSmallScreen.d.ts +8 -0
- package/dist/ui/components/TooSmallScreen.js +6 -0
- package/dist/ui/date.d.ts +2 -0
- package/dist/ui/date.js +33 -0
- package/dist/ui/layout.d.ts +23 -0
- package/dist/ui/layout.js +44 -0
- package/dist/ui/list-item.d.ts +12 -0
- package/dist/ui/list-item.js +1 -0
- package/dist/ui/marketplaceDisplay.d.ts +10 -0
- package/dist/ui/marketplaceDisplay.js +36 -0
- package/dist/ui/theme.d.ts +42 -0
- package/dist/ui/theme.js +47 -0
- package/dist/utils/asset-list-fields.d.ts +11 -0
- package/dist/utils/asset-list-fields.js +28 -0
- package/dist/utils/error-message.d.ts +2 -0
- package/dist/utils/error-message.js +6 -0
- package/dist/utils/integrity.d.ts +9 -0
- package/dist/utils/integrity.js +23 -0
- package/dist/utils/lock-migrate.d.ts +25 -0
- package/dist/utils/lock-migrate.js +93 -0
- package/dist/utils/mcp-local.d.ts +15 -0
- package/dist/utils/mcp-local.js +129 -0
- package/dist/utils/slug.d.ts +6 -0
- package/dist/utils/slug.js +13 -0
- package/dist/utils/stack-normalize.d.ts +3 -0
- package/dist/utils/stack-normalize.js +43 -0
- package/package.json +77 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { 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 { Header } from '../ui/components/Header.js';
|
|
8
|
+
import { theme } from '../ui/theme.js';
|
|
9
|
+
const storageItems = [
|
|
10
|
+
{ label: 'GitHub (recommended)', value: 'github' },
|
|
11
|
+
{ label: 'Local only', value: 'local' },
|
|
12
|
+
];
|
|
13
|
+
const githubModeItems = [
|
|
14
|
+
{ label: 'Create a new private repo', value: 'create' },
|
|
15
|
+
{ label: 'Use an existing repo', value: 'existing' },
|
|
16
|
+
];
|
|
17
|
+
export const InitFlow = ({ startWithGithub, repository, githubMode = 'create', exitOnDone = true, onDone, }) => {
|
|
18
|
+
const { exit } = useApp();
|
|
19
|
+
const [screen, setScreen] = useState(startWithGithub ? 'githubMode' : 'storage');
|
|
20
|
+
const [selectedGithubMode, setSelectedGithubMode] = useState(githubMode);
|
|
21
|
+
const [repoValue, setRepoValue] = useState(repository || '');
|
|
22
|
+
const [repoError, setRepoError] = useState();
|
|
23
|
+
const finish = (result) => {
|
|
24
|
+
onDone(result);
|
|
25
|
+
if (exitOnDone) {
|
|
26
|
+
exit();
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
useInput((input, key) => {
|
|
30
|
+
if (input === 'q') {
|
|
31
|
+
finish({ action: 'exit' });
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (key.escape) {
|
|
35
|
+
if (screen === 'repo') {
|
|
36
|
+
setScreen('githubMode');
|
|
37
|
+
}
|
|
38
|
+
else if (screen === 'githubMode') {
|
|
39
|
+
if (startWithGithub) {
|
|
40
|
+
finish({ action: 'exit' });
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
setScreen('storage');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else if (screen === 'storage') {
|
|
47
|
+
finish({ action: 'exit' });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (repository && screen === 'githubMode') {
|
|
53
|
+
finish({ action: 'github', repository, mode: githubMode });
|
|
54
|
+
}
|
|
55
|
+
}, [githubMode, repository, screen]);
|
|
56
|
+
if (screen === 'storage') {
|
|
57
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { compact: true }), _jsx(Text, { children: "Where should aman store your environment?" }), _jsx(Text, { color: theme.dim, children: "GitHub syncs and backs up your environment." }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: storageItems, onSelect: (item) => {
|
|
58
|
+
if (item.value === 'github')
|
|
59
|
+
setScreen('githubMode');
|
|
60
|
+
if (item.value === 'local')
|
|
61
|
+
finish({ action: 'local' });
|
|
62
|
+
} }) })] }));
|
|
63
|
+
}
|
|
64
|
+
if (screen === 'githubMode') {
|
|
65
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { compact: true }), _jsx(Text, { children: "How should aman connect to GitHub?" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: githubModeItems, onSelect: (item) => {
|
|
66
|
+
setSelectedGithubMode(item.value);
|
|
67
|
+
setScreen('repo');
|
|
68
|
+
} }) })] }));
|
|
69
|
+
}
|
|
70
|
+
if (screen === 'repo') {
|
|
71
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { compact: true }), _jsx(Text, { children: selectedGithubMode === 'existing' ? 'Which GitHub repo should aman use?' : 'Name your aman GitHub repo.' }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: theme.primary, children: '> ' }), _jsx(TextInput, { value: repoValue, onChange: (value) => {
|
|
72
|
+
setRepoValue(value);
|
|
73
|
+
setRepoError(undefined);
|
|
74
|
+
}, placeholder: selectedGithubMode === 'existing' ? 'github-user/repo' : 'aman-environment', onSubmit: (value) => {
|
|
75
|
+
const trimmed = value.trim();
|
|
76
|
+
if (!trimmed) {
|
|
77
|
+
setRepoError('Enter a repository name to continue.');
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
finish({ action: 'github', repository: trimmed, mode: selectedGithubMode });
|
|
81
|
+
} })] }), repoError && (_jsx(Text, { color: theme.error, children: repoError }))] }));
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
};
|
|
85
|
+
async function renderInitFlow(options = {}) {
|
|
86
|
+
let result = { action: 'exit' };
|
|
87
|
+
const { waitUntilExit } = render(_jsx(InitFlow, { ...options, onDone: (nextResult) => { result = nextResult; } }));
|
|
88
|
+
await waitUntilExit();
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
async function completeLocalInit(storagePath) {
|
|
92
|
+
console.log(' ◌ Setting up local environment...');
|
|
93
|
+
const environmentPath = await environmentService.initLocal({ storagePath });
|
|
94
|
+
console.log(` ✓ Environment ready: ${environmentPath}`);
|
|
95
|
+
console.log('');
|
|
96
|
+
console.log(' Next: aman browse');
|
|
97
|
+
}
|
|
98
|
+
async function completeGithubInit(repository, mode) {
|
|
99
|
+
if (!environmentService.isGithubCliAvailable()) {
|
|
100
|
+
console.log(' ◌ Installing GitHub CLI...');
|
|
101
|
+
environmentService.installGithubCli();
|
|
102
|
+
console.log(' ✓ GitHub CLI ready.');
|
|
103
|
+
}
|
|
104
|
+
console.log(` ◌ Setting up GitHub environment: ${repository}`);
|
|
105
|
+
const environmentPath = await environmentService.initGithub({ repository, mode });
|
|
106
|
+
console.log(` ✓ Environment ready: ${environmentPath}`);
|
|
107
|
+
console.log('');
|
|
108
|
+
console.log(' Next: aman browse');
|
|
109
|
+
}
|
|
110
|
+
async function completeInitResult(result, options) {
|
|
111
|
+
if (result.action === 'exit') {
|
|
112
|
+
console.log(' Setup paused. Run aman init when ready.');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (result.action === 'local') {
|
|
116
|
+
await completeLocalInit(options.path);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
await completeGithubInit(result.repository, result.mode);
|
|
120
|
+
}
|
|
121
|
+
export async function initCommand(args, options) {
|
|
122
|
+
const wantsGithub = Boolean(options.github);
|
|
123
|
+
const wantsLocal = Boolean(options.local);
|
|
124
|
+
if (wantsGithub && wantsLocal) {
|
|
125
|
+
console.log(' Choose either --github or --local, not both.');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (wantsLocal) {
|
|
129
|
+
await completeLocalInit(options.path || args[0]);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (!process.stdin.isTTY && !wantsGithub && !wantsLocal) {
|
|
133
|
+
console.log(' Non-interactive mode detected. Initializing local storage by default...');
|
|
134
|
+
await completeLocalInit(options.path || args[0]);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (wantsGithub) {
|
|
138
|
+
const repository = options.repo || options.repository || args[0];
|
|
139
|
+
const mode = options.existing ? 'existing' : 'create';
|
|
140
|
+
const result = await renderInitFlow({ startWithGithub: true, repository, githubMode: mode });
|
|
141
|
+
await completeInitResult(result, options);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const result = await renderInitFlow();
|
|
145
|
+
await completeInitResult(result, options);
|
|
146
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const InstallWizardApp: ({ onBack }: {
|
|
2
|
+
onBack?: () => void;
|
|
3
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export declare function installCommand(args: string[], options: {
|
|
5
|
+
project?: boolean;
|
|
6
|
+
p?: boolean;
|
|
7
|
+
global?: boolean;
|
|
8
|
+
g?: boolean;
|
|
9
|
+
type?: string;
|
|
10
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { render, Box, Text, useApp, useInput } from 'ink';
|
|
4
|
+
import TextInput from 'ink-text-input';
|
|
5
|
+
import { CustomSelectInput } from '../ui/components/CustomSelect.js';
|
|
6
|
+
import { assetService } from '../services/asset.service.js';
|
|
7
|
+
import { marketplaceService } from '../services/marketplace.service.js';
|
|
8
|
+
import { registryService, isRegistryInstallReference } from '../registry/registry.service.js';
|
|
9
|
+
import { ScopePrompt } from '../ui/components/ScopePrompt.js';
|
|
10
|
+
import { Narrator } from '../ui/components/Narrator.js';
|
|
11
|
+
import { Header } from '../ui/components/Header.js';
|
|
12
|
+
import { theme } from '../ui/theme.js';
|
|
13
|
+
import { shortDescription, titleize } from '../ui/marketplaceDisplay.js';
|
|
14
|
+
import { ASSET_TAB_ORDER, ASSET_TYPE_PLURAL } from '../ui/assetDisplay.js';
|
|
15
|
+
import { TransitionScreen } from '../ui/animations/TransitionScreen.js';
|
|
16
|
+
import { MarketplaceInstallConfirm } from '../ui/components/MarketplaceInstallConfirm.js';
|
|
17
|
+
import { installFromCandidate } from '../marketplace/install-from-candidate.js';
|
|
18
|
+
import { MARKETPLACE_ENABLED } from '../config/features.js';
|
|
19
|
+
import { environmentService } from '../services/environment.service.js';
|
|
20
|
+
function scopeLabel(scope) {
|
|
21
|
+
return scope === 'project' ? 'project' : 'global';
|
|
22
|
+
}
|
|
23
|
+
function assertInstallEnvironment(scope) {
|
|
24
|
+
if (!environmentService.isEnvironmentInitialized(scope)) {
|
|
25
|
+
console.error('\n Aman Intelligence is not initialized yet.');
|
|
26
|
+
console.error(` Run the following command to get started:\n`);
|
|
27
|
+
console.error(` aman init --local\n`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function assetLookupFailureMessage(name) {
|
|
32
|
+
return MARKETPLACE_ENABLED
|
|
33
|
+
? `Could not find "${name}" in marketplace or bundled assets`
|
|
34
|
+
: `Could not find "${name}" in registry or local assets`;
|
|
35
|
+
}
|
|
36
|
+
async function runHeadlessInstall(name, scope, assetType) {
|
|
37
|
+
const candidate = await marketplaceService.findInstallCandidate(name);
|
|
38
|
+
if (candidate) {
|
|
39
|
+
const result = await installFromCandidate(candidate, scope);
|
|
40
|
+
console.log(`Installed ${ASSET_TYPE_PLURAL[candidate.type].slice(0, -1)} ${titleize(candidate.name)} → ${result.path}`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const types = assetType ? [assetType] : ASSET_TAB_ORDER;
|
|
44
|
+
for (const type of types) {
|
|
45
|
+
try {
|
|
46
|
+
await assetService.install(name, type, scope, undefined, 'local');
|
|
47
|
+
console.log(`Installed ${type} ${name} → ${scopeLabel(scope)}`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// try next type
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
console.error(`Could not find or install "${name}".`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
const InstallApp = ({ name, initialScope, initialType }) => {
|
|
58
|
+
const { exit } = useApp();
|
|
59
|
+
const [scope, setScope] = useState(initialScope);
|
|
60
|
+
const [assetType, setAssetType] = useState(initialType);
|
|
61
|
+
const [candidate, setCandidate] = useState(null);
|
|
62
|
+
const [registryRef, setRegistryRef] = useState(null);
|
|
63
|
+
const [lookupDone, setLookupDone] = useState(false);
|
|
64
|
+
const [confirmDone, setConfirmDone] = useState(false);
|
|
65
|
+
const [state, setState] = useState('searching');
|
|
66
|
+
const [message, setMessage] = useState(`Looking up ${name}...`);
|
|
67
|
+
useInput((input) => {
|
|
68
|
+
if (input === 'q')
|
|
69
|
+
exit();
|
|
70
|
+
});
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
let active = true;
|
|
73
|
+
async function lookup() {
|
|
74
|
+
try {
|
|
75
|
+
const parsedRegistry = registryService.parseInstallReference(name);
|
|
76
|
+
if (parsedRegistry) {
|
|
77
|
+
if (!active)
|
|
78
|
+
return;
|
|
79
|
+
setRegistryRef(parsedRegistry);
|
|
80
|
+
setLookupDone(true);
|
|
81
|
+
setMessage(`Registry: ${parsedRegistry.slug}@${parsedRegistry.version}`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const types = assetType ? [assetType] : ASSET_TAB_ORDER;
|
|
85
|
+
let match = null;
|
|
86
|
+
for (const type of types) {
|
|
87
|
+
const results = await marketplaceService.search(name, type);
|
|
88
|
+
const found = results.find((item) => item.name.toLowerCase() === name.toLowerCase().replace(/\s+/g, '-'));
|
|
89
|
+
if (found) {
|
|
90
|
+
match = await marketplaceService.findInstallCandidate(found.name);
|
|
91
|
+
if (match)
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (!match) {
|
|
96
|
+
match = await marketplaceService.findInstallCandidate(name);
|
|
97
|
+
}
|
|
98
|
+
if (!active)
|
|
99
|
+
return;
|
|
100
|
+
if (!match) {
|
|
101
|
+
setState('error');
|
|
102
|
+
setMessage(assetLookupFailureMessage(name));
|
|
103
|
+
setLookupDone(true);
|
|
104
|
+
setTimeout(() => exit(), 1800);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
setCandidate(match);
|
|
108
|
+
setAssetType(match.type);
|
|
109
|
+
setLookupDone(true);
|
|
110
|
+
setMessage(`Found ${ASSET_TYPE_PLURAL[match.type].slice(0, -1)}: ${titleize(match.name)}`);
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
if (!active)
|
|
114
|
+
return;
|
|
115
|
+
setState('error');
|
|
116
|
+
setMessage(`Error: ${err.message}`);
|
|
117
|
+
setLookupDone(true);
|
|
118
|
+
setTimeout(() => exit(), 1800);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
lookup();
|
|
122
|
+
return () => {
|
|
123
|
+
active = false;
|
|
124
|
+
};
|
|
125
|
+
}, [exit, name, assetType]);
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
if (!scope || !lookupDone || !registryRef)
|
|
128
|
+
return;
|
|
129
|
+
async function doRegistryInstall() {
|
|
130
|
+
try {
|
|
131
|
+
setState('installing');
|
|
132
|
+
setMessage(`Installing ${registryRef.slug}@${registryRef.version}...`);
|
|
133
|
+
const result = await registryService.installFromRegistry(registryRef.slug, registryRef.version, scope);
|
|
134
|
+
for (const warning of result.warnings) {
|
|
135
|
+
console.warn(warning);
|
|
136
|
+
}
|
|
137
|
+
setState('success');
|
|
138
|
+
setMessage(`Installed ${result.localName} (${registryRef.slug}@${registryRef.version}) → ${scopeLabel(scope)}`);
|
|
139
|
+
setTimeout(() => exit(), 800);
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
setState('error');
|
|
143
|
+
setMessage(`Error: ${err.message}`);
|
|
144
|
+
setTimeout(() => exit(), 1600);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
doRegistryInstall();
|
|
148
|
+
}, [registryRef, exit, lookupDone, scope]);
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
if (!scope || !lookupDone || !candidate || registryRef || !confirmDone)
|
|
151
|
+
return;
|
|
152
|
+
const selectedScope = scope;
|
|
153
|
+
async function doInstall() {
|
|
154
|
+
try {
|
|
155
|
+
setState('installing');
|
|
156
|
+
setMessage(`Installing ${titleize(candidate.name)}...`);
|
|
157
|
+
const result = await installFromCandidate(candidate, selectedScope);
|
|
158
|
+
setState('success');
|
|
159
|
+
setMessage(`Installed ${ASSET_TYPE_PLURAL[candidate.type].slice(0, -1)} ${titleize(candidate.name)} → ${result.path}`);
|
|
160
|
+
setTimeout(() => exit(), 800);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
setState('error');
|
|
164
|
+
setMessage(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
165
|
+
setTimeout(() => exit(), 1600);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
doInstall();
|
|
169
|
+
}, [candidate, exit, lookupDone, scope, name, confirmDone]);
|
|
170
|
+
if (!lookupDone) {
|
|
171
|
+
return (_jsx(Box, { paddingX: 1, flexDirection: "column", children: _jsx(Narrator, { state: "searching", message: message }) }));
|
|
172
|
+
}
|
|
173
|
+
if (!scope &&
|
|
174
|
+
state !== 'error' &&
|
|
175
|
+
candidate?.marketplaceAsset &&
|
|
176
|
+
lookupDone &&
|
|
177
|
+
!confirmDone) {
|
|
178
|
+
const gh = candidate.marketplaceAsset;
|
|
179
|
+
return (_jsx(Box, { flexDirection: "column", paddingX: 1, children: _jsx(MarketplaceInstallConfirm, { details: {
|
|
180
|
+
name: gh.localName,
|
|
181
|
+
type: gh.type,
|
|
182
|
+
slug: gh.slug,
|
|
183
|
+
author: gh.author,
|
|
184
|
+
version: gh.version,
|
|
185
|
+
source: gh.source,
|
|
186
|
+
checksum: gh.checksum,
|
|
187
|
+
verified: gh.verified,
|
|
188
|
+
}, onConfirm: (s) => {
|
|
189
|
+
setConfirmDone(true);
|
|
190
|
+
setScope(s);
|
|
191
|
+
}, onCancel: () => exit() }) }));
|
|
192
|
+
}
|
|
193
|
+
if (!scope && state !== 'error' && (candidate || registryRef)) {
|
|
194
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, children: registryRef
|
|
195
|
+
? `${registryRef.slug}@${registryRef.version}`
|
|
196
|
+
: `${titleize(candidate.name)} (${candidate.type})` }), candidate?.description && (_jsx(Text, { color: theme.dim, children: shortDescription(candidate.description) })), _jsx(Box, { marginTop: 1, children: _jsx(ScopePrompt, { onSelect: (s) => {
|
|
197
|
+
setConfirmDone(true);
|
|
198
|
+
setScope(s);
|
|
199
|
+
} }) })] }));
|
|
200
|
+
}
|
|
201
|
+
return (_jsx(Box, { paddingX: 1, flexDirection: "column", children: _jsx(Narrator, { state: state, message: message }) }));
|
|
202
|
+
};
|
|
203
|
+
export const InstallWizardApp = ({ onBack }) => {
|
|
204
|
+
const { exit } = useApp();
|
|
205
|
+
const handleExit = () => {
|
|
206
|
+
if (onBack)
|
|
207
|
+
onBack();
|
|
208
|
+
else
|
|
209
|
+
exit();
|
|
210
|
+
};
|
|
211
|
+
const [step, setStep] = useState('type');
|
|
212
|
+
const [assetType, setAssetType] = useState(ASSET_TAB_ORDER[0]);
|
|
213
|
+
const [source, setSource] = useState(MARKETPLACE_ENABLED ? 'marketplace' : 'local');
|
|
214
|
+
const [name, setName] = useState('');
|
|
215
|
+
const [scope, setScope] = useState();
|
|
216
|
+
const [state, setState] = useState('idle');
|
|
217
|
+
const [message, setMessage] = useState('');
|
|
218
|
+
useInput((input, key) => {
|
|
219
|
+
if (key.escape || input === 'q')
|
|
220
|
+
handleExit();
|
|
221
|
+
});
|
|
222
|
+
useEffect(() => {
|
|
223
|
+
if (step !== 'installing' || !scope || !name.trim())
|
|
224
|
+
return;
|
|
225
|
+
async function run() {
|
|
226
|
+
setState('installing');
|
|
227
|
+
setMessage(`Installing ${titleize(name)}...`);
|
|
228
|
+
try {
|
|
229
|
+
if (source === 'marketplace') {
|
|
230
|
+
const candidate = await marketplaceService.findInstallCandidate(name);
|
|
231
|
+
if (!candidate)
|
|
232
|
+
throw new Error(`"${name}" not found in marketplace`);
|
|
233
|
+
await installFromCandidate(candidate, scope);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
await assetService.install(name, assetType, scope, undefined, source);
|
|
237
|
+
}
|
|
238
|
+
setState('success');
|
|
239
|
+
setMessage(`Installed ${ASSET_TYPE_PLURAL[assetType].slice(0, -1)} ${titleize(name)} → ${scopeLabel(scope)}`);
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
setState('error');
|
|
243
|
+
setMessage(err.message);
|
|
244
|
+
}
|
|
245
|
+
setStep('done');
|
|
246
|
+
setTimeout(() => handleExit(), 1200);
|
|
247
|
+
}
|
|
248
|
+
run();
|
|
249
|
+
}, [step, scope, name, assetType, source]);
|
|
250
|
+
if (step === 'type') {
|
|
251
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Install Asset" }), _jsx(Text, { color: theme.dim, children: "Type" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: ASSET_TAB_ORDER.map((t) => ({
|
|
252
|
+
label: `${t === assetType ? '❯ ' : ' '}${ASSET_TYPE_PLURAL[t].slice(0, -1)}`,
|
|
253
|
+
value: t,
|
|
254
|
+
})), onSelect: (item) => {
|
|
255
|
+
setAssetType(item.value);
|
|
256
|
+
setStep('source');
|
|
257
|
+
} }) })] }));
|
|
258
|
+
}
|
|
259
|
+
if (step === 'source') {
|
|
260
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, color: theme.accent, children: "Install Asset" }), _jsx(Text, { color: theme.dim, children: "Source" }), _jsx(Box, { marginTop: 1, children: _jsx(CustomSelectInput, { items: MARKETPLACE_ENABLED
|
|
261
|
+
? [
|
|
262
|
+
{ label: '❯ Marketplace', value: 'marketplace' },
|
|
263
|
+
{ label: ' Local / Registry', value: 'local' },
|
|
264
|
+
{ label: ' GitHub', value: 'github' },
|
|
265
|
+
]
|
|
266
|
+
: [
|
|
267
|
+
{ label: '❯ Registry / Local', value: 'local' },
|
|
268
|
+
{ label: ' GitHub', value: 'github' },
|
|
269
|
+
], onSelect: (item) => {
|
|
270
|
+
setSource(item.value);
|
|
271
|
+
setStep('name');
|
|
272
|
+
} }) })] }));
|
|
273
|
+
}
|
|
274
|
+
if (step === 'name') {
|
|
275
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { compact: true }), _jsxs(Text, { bold: true, color: theme.accent, children: ["Install ", ASSET_TYPE_PLURAL[assetType].slice(0, -1)] }), _jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(Text, { color: theme.primary, children: "\u276F " }), _jsx(TextInput, { value: name, onChange: setName, onSubmit: () => setStep('scope'), placeholder: "Asset name..." })] }), _jsx(Text, { color: theme.dim, children: "press enter to continue" })] }));
|
|
276
|
+
}
|
|
277
|
+
if (step === 'scope') {
|
|
278
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { compact: true }), _jsx(Text, { bold: true, children: titleize(name) }), _jsxs(Text, { color: theme.dim, children: [ASSET_TYPE_PLURAL[assetType].slice(0, -1), " \u00B7 ", source] }), _jsx(Box, { marginTop: 1, children: _jsx(ScopePrompt, { onSelect: (s) => {
|
|
279
|
+
setScope(s);
|
|
280
|
+
setStep('installing');
|
|
281
|
+
} }) })] }));
|
|
282
|
+
}
|
|
283
|
+
return (_jsx(Box, { paddingX: 1, children: _jsx(Narrator, { state: state, message: message }) }));
|
|
284
|
+
};
|
|
285
|
+
export async function installCommand(args, options) {
|
|
286
|
+
const name = args.join(' ').trim();
|
|
287
|
+
if (isRegistryInstallReference(name)) {
|
|
288
|
+
const registryRef = registryService.parseInstallReference(name);
|
|
289
|
+
let scope = options.project || options.p
|
|
290
|
+
? 'project'
|
|
291
|
+
: options.global || options.g
|
|
292
|
+
? 'global'
|
|
293
|
+
: undefined;
|
|
294
|
+
if (!scope) {
|
|
295
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
296
|
+
console.error('Registry install requires --global or --project when not interactive.');
|
|
297
|
+
process.exit(1);
|
|
298
|
+
}
|
|
299
|
+
const { waitUntilExit } = render(_jsx(TransitionScreen, { message: `Preparing registry install for ${name}...`, children: _jsx(InstallApp, { name: name, initialScope: undefined }) }));
|
|
300
|
+
await waitUntilExit();
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
assertInstallEnvironment(scope);
|
|
304
|
+
const result = await registryService.installFromRegistry(registryRef.slug, registryRef.version, scope);
|
|
305
|
+
for (const warning of result.warnings) {
|
|
306
|
+
console.warn(warning);
|
|
307
|
+
}
|
|
308
|
+
console.log(`Installed ${result.localName} (${registryRef.slug}@${registryRef.version}) → ${scope}`);
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
let initialScope = options.project || options.p
|
|
312
|
+
? 'project'
|
|
313
|
+
: options.global || options.g
|
|
314
|
+
? 'global'
|
|
315
|
+
: undefined;
|
|
316
|
+
const typeFlag = options.type;
|
|
317
|
+
const initialType = typeFlag && ASSET_TAB_ORDER.includes(typeFlag) ? typeFlag : undefined;
|
|
318
|
+
if (!name) {
|
|
319
|
+
if (!process.stdin.isTTY) {
|
|
320
|
+
console.log(' Usage: aman install <name> [--global|--project] [--type skill|prompt|mcp]');
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const { waitUntilExit } = render(_jsx(InstallWizardApp, {}));
|
|
324
|
+
await waitUntilExit();
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
328
|
+
if (!initialScope) {
|
|
329
|
+
console.error('Install requires --global or --project when not interactive.\n' +
|
|
330
|
+
'Example: aman install my-skill --global');
|
|
331
|
+
process.exit(1);
|
|
332
|
+
}
|
|
333
|
+
assertInstallEnvironment(initialScope);
|
|
334
|
+
await runHeadlessInstall(name, initialScope, initialType);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (initialScope) {
|
|
338
|
+
assertInstallEnvironment(initialScope);
|
|
339
|
+
}
|
|
340
|
+
const { waitUntilExit } = render(_jsx(TransitionScreen, { message: `Preparing installation for ${name}...`, children: _jsx(InstallApp, { name: name, initialScope: initialScope, initialType: initialType }) }));
|
|
341
|
+
await waitUntilExit();
|
|
342
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Scope } from '../types/index.js';
|
|
3
|
+
interface PackCreateAppProps {
|
|
4
|
+
name: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const PackCreateApp: React.FC<PackCreateAppProps & {
|
|
7
|
+
onBack?: () => void;
|
|
8
|
+
}>;
|
|
9
|
+
interface PackInspectAppProps {
|
|
10
|
+
packPath: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const PackInspectApp: React.FC<PackInspectAppProps & {
|
|
13
|
+
onBack?: () => void;
|
|
14
|
+
}>;
|
|
15
|
+
interface PackInstallAppProps {
|
|
16
|
+
packPath: string;
|
|
17
|
+
initialScope?: Scope;
|
|
18
|
+
}
|
|
19
|
+
export declare const PackInstallApp: React.FC<PackInstallAppProps & {
|
|
20
|
+
onBack?: () => void;
|
|
21
|
+
}>;
|
|
22
|
+
export declare function packCommand(args: string[], options: any): Promise<void>;
|
|
23
|
+
export {};
|