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,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { theme } from '../theme.js';
4
+ import { Spinner } from '../animations/Spinner.js';
5
+ import { SuccessIndicator } from '../animations/SuccessIndicator.js';
6
+ import { ErrorIndicator } from '../animations/ErrorIndicator.js';
7
+ import { SyncActivity } from '../animations/SyncActivity.js';
8
+ export const Narrator = ({ state, message, compact = false }) => {
9
+ const text = message || '';
10
+ return (_jsx(Box, { marginRight: compact ? 1 : 0, children: (() => {
11
+ switch (state) {
12
+ case 'syncing':
13
+ return _jsx(SyncActivity, { label: text });
14
+ case 'success':
15
+ return _jsx(SuccessIndicator, { message: text });
16
+ case 'error':
17
+ return _jsx(ErrorIndicator, { message: text });
18
+ case 'searching':
19
+ case 'installing':
20
+ case 'updating':
21
+ return _jsx(Spinner, { label: text });
22
+ default:
23
+ return (_jsxs(Text, { color: theme.dim, children: [_jsx(Text, { bold: true, children: "\u00B7" }), text ? ` ${text}` : ''] }));
24
+ }
25
+ })() }));
26
+ };
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { Scope } from '../../types/index.js';
3
+ interface ScopePromptProps {
4
+ label?: string;
5
+ onSelect: (scope: Scope) => void;
6
+ }
7
+ export declare const ScopePrompt: React.FC<ScopePromptProps>;
8
+ export {};
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { CustomSelectInput } from './CustomSelect.js';
4
+ import { theme } from '../theme.js';
5
+ import { exists } from '../../storage/filesystem.js';
6
+ import path from 'path';
7
+ const scopeItems = [
8
+ { label: 'Project', value: 'project' },
9
+ { label: 'Global', value: 'global' },
10
+ ];
11
+ const scopeItemsGlobalFirst = [
12
+ { label: 'Global', value: 'global' },
13
+ { label: 'Project', value: 'project' },
14
+ ];
15
+ function isInsideProject() {
16
+ // Check if .aman/ or package.json exists in cwd
17
+ return exists(path.resolve(process.cwd(), '.aman')) || exists(path.resolve(process.cwd(), 'package.json'));
18
+ }
19
+ export const ScopePrompt = ({ label = 'Install location', onSelect }) => {
20
+ const inProject = isInsideProject();
21
+ const items = inProject ? scopeItems : scopeItemsGlobalFirst;
22
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: theme.dim, children: label }), _jsx(Box, { marginTop: 0, children: _jsx(CustomSelectInput, { items: items, onSelect: (item) => onSelect(item.value) }) })] }));
23
+ };
@@ -0,0 +1,8 @@
1
+ interface TooSmallScreenProps {
2
+ columns: number;
3
+ rows: number;
4
+ minColumns: number;
5
+ minRows: number;
6
+ }
7
+ export declare const TooSmallScreen: ({ columns, rows, minColumns, minRows, }: TooSmallScreenProps) => import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { theme } from '../theme.js';
4
+ export const TooSmallScreen = ({ columns, rows, minColumns, minRows, }) => {
5
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { bold: true, color: theme.error, children: "Terminal too small" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { children: ["Current: ", columns, "\u00D7", rows] }), _jsxs(Text, { children: ["Required: ", minColumns, "\u00D7", minRows] })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.primary, children: "Please enlarge the terminal." }) })] }));
6
+ };
@@ -0,0 +1,2 @@
1
+ export declare function getRelativeBackupDate(backupName: string): string;
2
+ export declare function getBackupLabel(backupName: string): string;
@@ -0,0 +1,33 @@
1
+ export function getRelativeBackupDate(backupName) {
2
+ if (!backupName || backupName === 'none' || backupName === 'never')
3
+ return 'Never';
4
+ const match = backupName.match(/^(\d{4})-(\d{2})-(\d{2})/);
5
+ if (!match)
6
+ return 'Never';
7
+ const year = parseInt(match[1], 10);
8
+ const month = parseInt(match[2], 10) - 1; // 0-indexed month
9
+ const day = parseInt(match[3], 10);
10
+ const dateObj = new Date(year, month, day);
11
+ if (isNaN(dateObj.getTime()))
12
+ return 'Never';
13
+ const now = new Date();
14
+ const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
15
+ const backup = new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate());
16
+ const diffTime = today.getTime() - backup.getTime();
17
+ const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
18
+ if (diffDays === 0)
19
+ return 'Today';
20
+ if (diffDays === 1)
21
+ return 'Yesterday';
22
+ if (diffDays > 1)
23
+ return `${diffDays} days ago`;
24
+ return 'Today';
25
+ }
26
+ export function getBackupLabel(backupName) {
27
+ const relative = getRelativeBackupDate(backupName);
28
+ if (relative === 'Never')
29
+ return backupName;
30
+ const labelIndex = backupName.indexOf('Z-');
31
+ const labelText = labelIndex !== -1 ? backupName.substring(labelIndex + 2) : backupName;
32
+ return `${relative} (${labelText})`;
33
+ }
@@ -0,0 +1,23 @@
1
+ export interface StdoutDimensions {
2
+ columns: number;
3
+ rows: number;
4
+ }
5
+ export declare function useStdoutDimensions(): StdoutDimensions;
6
+ export interface ResponsiveLayout {
7
+ columns: number;
8
+ rows: number;
9
+ physicalColumns: number;
10
+ physicalRows: number;
11
+ isTooSmall: boolean;
12
+ isCompact: boolean;
13
+ canShowDescriptions: boolean;
14
+ canShowFooter: boolean;
15
+ canShowDetailsPanel: boolean;
16
+ }
17
+ /** Below this width: browse/search use plain output only. */
18
+ export declare const PLAIN_OUTPUT_MAX_COLUMNS = 60;
19
+ export declare const MIN_COLUMNS = 70;
20
+ export declare const MIN_ROWS = 20;
21
+ export declare const COMPACT_MAX_COLUMNS = 90;
22
+ export declare const COMPACT_MAX_ROWS = 28;
23
+ export declare function useResponsiveLayout(): ResponsiveLayout;
@@ -0,0 +1,44 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { useStdout } from 'ink';
3
+ export function useStdoutDimensions() {
4
+ const { stdout } = useStdout();
5
+ const [dimensions, setDimensions] = useState({
6
+ columns: stdout.columns || 80,
7
+ rows: stdout.rows || 24,
8
+ });
9
+ useEffect(() => {
10
+ const handler = () => {
11
+ setDimensions({
12
+ columns: stdout.columns || 80,
13
+ rows: stdout.rows || 24,
14
+ });
15
+ };
16
+ stdout.on('resize', handler);
17
+ return () => {
18
+ stdout.off('resize', handler);
19
+ };
20
+ }, [stdout]);
21
+ return dimensions;
22
+ }
23
+ /** Below this width: browse/search use plain output only. */
24
+ export const PLAIN_OUTPUT_MAX_COLUMNS = 60;
25
+ export const MIN_COLUMNS = 70;
26
+ export const MIN_ROWS = 20;
27
+ export const COMPACT_MAX_COLUMNS = 90;
28
+ export const COMPACT_MAX_ROWS = 28;
29
+ export function useResponsiveLayout() {
30
+ const { columns, rows } = useStdoutDimensions();
31
+ const isTooSmall = columns < MIN_COLUMNS || rows < MIN_ROWS;
32
+ const isCompact = columns < COMPACT_MAX_COLUMNS || rows < COMPACT_MAX_ROWS;
33
+ return {
34
+ columns,
35
+ rows: Math.max(1, rows - 1),
36
+ physicalColumns: columns,
37
+ physicalRows: rows,
38
+ isTooSmall,
39
+ isCompact,
40
+ canShowDescriptions: !isCompact,
41
+ canShowFooter: true, // Always show footer for now, adjust if needed
42
+ canShowDetailsPanel: !isCompact && columns > 120, // Optional future use
43
+ };
44
+ }
@@ -0,0 +1,12 @@
1
+ import { MarketplaceAsset } from '../marketplace/types.js';
2
+ export interface ListItem {
3
+ label: string;
4
+ value: string;
5
+ description?: string;
6
+ badge?: string;
7
+ metadata?: string[];
8
+ status?: string;
9
+ marketplaceAsset?: MarketplaceAsset;
10
+ rawAsset?: any;
11
+ scope?: 'global' | 'project';
12
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import { ProviderResult } from '../types/index.js';
2
+ import { InstallCandidate } from '../services/marketplace.service.js';
3
+ type MarketplaceLike = ProviderResult | InstallCandidate;
4
+ export declare function titleize(value: string): string;
5
+ export declare function sourceLabel(item: MarketplaceLike): string;
6
+ export declare function statusLabel(item: MarketplaceLike): string | undefined;
7
+ export declare function metadataParts(item: MarketplaceLike): string[];
8
+ export declare function verifiedBadge(verified?: boolean): string;
9
+ export declare function shortDescription(description?: string, maxLength?: number): string | undefined;
10
+ export {};
@@ -0,0 +1,36 @@
1
+ export function titleize(value) {
2
+ return value
3
+ .split(/[-_\s]+/g)
4
+ .filter(Boolean)
5
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
6
+ .join(' ');
7
+ }
8
+ export function sourceLabel(item) {
9
+ const sources = item.sources?.length ? item.sources : [item.source];
10
+ return sources.join(' + ');
11
+ }
12
+ export function statusLabel(item) {
13
+ return item.installed ? 'installed' : undefined;
14
+ }
15
+ export function metadataParts(item) {
16
+ const parts = [];
17
+ if (item.version) {
18
+ parts.push(`v${item.version}`);
19
+ }
20
+ if (item.updated) {
21
+ parts.push(`Updated ${item.updated}`);
22
+ }
23
+ parts.push(`Source: ${sourceLabel(item)}`);
24
+ return parts;
25
+ }
26
+ export function verifiedBadge(verified) {
27
+ return verified ? ' ✓ Aman' : '';
28
+ }
29
+ export function shortDescription(description, maxLength = 120) {
30
+ if (!description)
31
+ return undefined;
32
+ const normalized = description.replace(/\s+/g, ' ').trim();
33
+ if (normalized.length <= maxLength)
34
+ return normalized;
35
+ return `${normalized.slice(0, maxLength - 3).trimEnd()}...`;
36
+ }
@@ -0,0 +1,42 @@
1
+ export declare const darkPalette: {
2
+ primary: string;
3
+ accent: string;
4
+ highlight: string;
5
+ cyan: string;
6
+ secondary: string;
7
+ success: string;
8
+ error: string;
9
+ warning: string;
10
+ dim: string;
11
+ border: string;
12
+ borderMuted: string;
13
+ text: string;
14
+ };
15
+ export declare const lightPalette: {
16
+ primary: string;
17
+ accent: string;
18
+ highlight: string;
19
+ cyan: string;
20
+ secondary: string;
21
+ success: string;
22
+ error: string;
23
+ warning: string;
24
+ dim: string;
25
+ border: string;
26
+ borderMuted: string;
27
+ text: string;
28
+ };
29
+ export declare const theme: {
30
+ readonly primary: string;
31
+ readonly accent: string;
32
+ readonly highlight: string;
33
+ readonly cyan: string;
34
+ readonly secondary: string;
35
+ readonly success: string;
36
+ readonly error: string;
37
+ readonly warning: string;
38
+ readonly dim: string;
39
+ readonly border: string;
40
+ readonly borderMuted: string;
41
+ readonly text: string;
42
+ };
@@ -0,0 +1,47 @@
1
+ import { config } from '../config/index.js';
2
+ export const darkPalette = {
3
+ primary: '#FF9D23', // Signature Aman Amber
4
+ accent: '#A78BFA', // Violet supporting accent
5
+ highlight: '#FF9D23', // Highlight (Primary Amber)
6
+ cyan: '#22D3EE',
7
+ secondary: '#CBD5E1', // Slate 300
8
+ success: '#34D399', // Emerald 400
9
+ error: '#F87171', // Red 400
10
+ warning: '#FBBF24', // Amber 400
11
+ dim: '#94A3B8', // Slate 400
12
+ border: '#475569', // Slate 600
13
+ borderMuted: '#334155', // Slate 700
14
+ text: '#F8FAFC', // Slate 50
15
+ };
16
+ export const lightPalette = {
17
+ primary: '#D97706', // High-contrast Dark Amber
18
+ accent: '#7C3AED', // High-contrast Violet
19
+ highlight: '#D97706', // Highlight
20
+ cyan: '#0891B2', // Cyan 600
21
+ secondary: '#475569', // Slate 600
22
+ success: '#059669', // Emerald 600
23
+ error: '#DC2626', // Red 600
24
+ warning: '#D97706', // Amber 600
25
+ dim: '#64748B', // Slate 500
26
+ border: '#CBD5E1', // Slate 300
27
+ borderMuted: '#E2E8F0', // Slate 200
28
+ text: '#0F172A', // Slate 900
29
+ };
30
+ function getActivePalette() {
31
+ const activeTheme = config.getTheme();
32
+ return activeTheme === 'light' ? lightPalette : darkPalette;
33
+ }
34
+ export const theme = {
35
+ get primary() { return getActivePalette().primary; },
36
+ get accent() { return getActivePalette().accent; },
37
+ get highlight() { return getActivePalette().highlight; },
38
+ get cyan() { return getActivePalette().cyan; },
39
+ get secondary() { return getActivePalette().secondary; },
40
+ get success() { return getActivePalette().success; },
41
+ get error() { return getActivePalette().error; },
42
+ get warning() { return getActivePalette().warning; },
43
+ get dim() { return getActivePalette().dim; },
44
+ get border() { return getActivePalette().border; },
45
+ get borderMuted() { return getActivePalette().borderMuted; },
46
+ get text() { return getActivePalette().text; },
47
+ };
@@ -0,0 +1,11 @@
1
+ import { AssetListItem } from '../types/index.js';
2
+ /** Optional listing fields shared across asset kinds (for union-safe access). */
3
+ export declare function assetListDescription(item: AssetListItem): string | undefined;
4
+ export declare function assetListTags(item: AssetListItem): string[] | undefined;
5
+ export declare function assetListCategory(item: AssetListItem): string | undefined;
6
+ export declare function assetListInstalls(item: AssetListItem): number | undefined;
7
+ export declare function assetListRating(item: AssetListItem): number | undefined;
8
+ export declare function assetListUpdated(item: AssetListItem): string | undefined;
9
+ export declare function assetListVersion(item: AssetListItem): string | undefined;
10
+ export declare function assetListOrganization(item: AssetListItem): string | undefined;
11
+ export declare function assetListOriginalName(item: AssetListItem): string | undefined;
@@ -0,0 +1,28 @@
1
+ /** Optional listing fields shared across asset kinds (for union-safe access). */
2
+ export function assetListDescription(item) {
3
+ return 'description' in item ? item.description : undefined;
4
+ }
5
+ export function assetListTags(item) {
6
+ return 'tags' in item ? item.tags : undefined;
7
+ }
8
+ export function assetListCategory(item) {
9
+ return 'category' in item ? item.category : undefined;
10
+ }
11
+ export function assetListInstalls(item) {
12
+ return 'installs' in item ? item.installs : undefined;
13
+ }
14
+ export function assetListRating(item) {
15
+ return 'rating' in item ? item.rating : undefined;
16
+ }
17
+ export function assetListUpdated(item) {
18
+ return 'updated' in item ? item.updated : undefined;
19
+ }
20
+ export function assetListVersion(item) {
21
+ return 'version' in item ? item.version : undefined;
22
+ }
23
+ export function assetListOrganization(item) {
24
+ return 'organization' in item ? item.organization : undefined;
25
+ }
26
+ export function assetListOriginalName(item) {
27
+ return 'originalName' in item ? item.originalName : undefined;
28
+ }
@@ -0,0 +1,2 @@
1
+ /** Extract a user-visible message from an unknown thrown value. */
2
+ export declare function getErrorMessage(err: unknown): string;
@@ -0,0 +1,6 @@
1
+ /** Extract a user-visible message from an unknown thrown value. */
2
+ export function getErrorMessage(err) {
3
+ if (err instanceof Error)
4
+ return err.message;
5
+ return String(err);
6
+ }
@@ -0,0 +1,9 @@
1
+ import { AssetType } from '../types/index.js';
2
+ export declare const INTEGRITY_ALGORITHM: "sha256";
3
+ export declare function formatChecksum(digest: Buffer): string;
4
+ export declare function hashFileContent(filePath: string): Promise<string>;
5
+ /**
6
+ * Computes canonical content checksum per AMAN-ASSET-SPEC-V1.
7
+ * `assetPath` MUST be the asset directory (not a flat file).
8
+ */
9
+ export declare function computeAssetChecksum(type: AssetType, assetDirectory: string): Promise<string>;
@@ -0,0 +1,23 @@
1
+ import { createHash } from 'crypto';
2
+ import { promises as fs } from 'fs';
3
+ import { exists } from '../storage/filesystem.js';
4
+ import { contentFilePath, CONTENT_FILES } from '../storage/asset-layout.js';
5
+ export const INTEGRITY_ALGORITHM = 'sha256';
6
+ export function formatChecksum(digest) {
7
+ return `sha256:${digest.toString('hex')}`;
8
+ }
9
+ export async function hashFileContent(filePath) {
10
+ const content = await fs.readFile(filePath);
11
+ return formatChecksum(createHash('sha256').update(content).digest());
12
+ }
13
+ /**
14
+ * Computes canonical content checksum per AMAN-ASSET-SPEC-V1.
15
+ * `assetPath` MUST be the asset directory (not a flat file).
16
+ */
17
+ export async function computeAssetChecksum(type, assetDirectory) {
18
+ const contentPath = contentFilePath(assetDirectory, type);
19
+ if (!exists(contentPath)) {
20
+ throw new Error(`Missing ${CONTENT_FILES[type]} for checksum: ${assetDirectory}`);
21
+ }
22
+ return hashFileContent(contentPath);
23
+ }
@@ -0,0 +1,25 @@
1
+ import { AssetType, LockEntry, Lockfile, LockSource, Scope } from '../types/index.js';
2
+ interface LegacyLockEntry {
3
+ name: string;
4
+ type: AssetType;
5
+ source: string;
6
+ installedAt: string;
7
+ version?: string;
8
+ originalName?: string;
9
+ }
10
+ interface LegacyLockfile {
11
+ version?: number;
12
+ schemaVersion?: number;
13
+ skills?: LegacyLockEntry[];
14
+ prompts?: LegacyLockEntry[];
15
+ mcps?: LegacyLockEntry[];
16
+ assets?: LockEntry[];
17
+ scope?: Scope;
18
+ generatedAt?: string;
19
+ }
20
+ export declare function parseLockSource(source: string): LockSource;
21
+ /** Normalize legacy or partial lockfiles to AMAN-LOCKFILE-SPEC-V1 shape. */
22
+ export declare function normalizeLockfile(raw: LegacyLockfile | null | undefined, scope: Scope): Lockfile;
23
+ export declare function emptyLockfile(scope: Scope): Lockfile;
24
+ export declare function isLegacyLockfile(raw: LegacyLockfile): boolean;
25
+ export {};
@@ -0,0 +1,93 @@
1
+ import { randomUUID } from 'crypto';
2
+ import { defaultSlugForName } from './slug.js';
3
+ import { INTEGRITY_ALGORITHM } from './integrity.js';
4
+ function inferSourceKind(source) {
5
+ if (source.startsWith('registry:'))
6
+ return 'registry';
7
+ if (source.startsWith('github:') || source.includes('/'))
8
+ return 'github';
9
+ if (source.startsWith('pack:'))
10
+ return 'pack';
11
+ if (source.startsWith('import:'))
12
+ return 'import';
13
+ if (source === 'bundled' || source === 'local')
14
+ return 'local';
15
+ return 'manual';
16
+ }
17
+ export function parseLockSource(source) {
18
+ const kind = inferSourceKind(source);
19
+ if (kind === 'registry' || kind === 'pack' || kind === 'import' || kind === 'github') {
20
+ return { kind, ref: source };
21
+ }
22
+ if (kind === 'local') {
23
+ return { kind, ref: `local:${source}` };
24
+ }
25
+ return { kind: 'manual', ref: `manual:${source}` };
26
+ }
27
+ function migrateLegacyEntry(entry, scope) {
28
+ return {
29
+ id: randomUUID(),
30
+ slug: defaultSlugForName(entry.originalName ?? entry.name),
31
+ type: entry.type,
32
+ localName: entry.name,
33
+ version: entry.version ?? '1.0.0',
34
+ integrity: {
35
+ algorithm: INTEGRITY_ALGORITHM,
36
+ checksum: 'sha256:0000000000000000000000000000000000000000000000000000000000000000',
37
+ },
38
+ source: parseLockSource(entry.source),
39
+ scope,
40
+ installedAt: entry.installedAt,
41
+ dependencies: [],
42
+ requiresLocalConfig: entry.type === 'mcp',
43
+ };
44
+ }
45
+ /** Normalize legacy or partial lockfiles to AMAN-LOCKFILE-SPEC-V1 shape. */
46
+ export function normalizeLockfile(raw, scope) {
47
+ if (!raw) {
48
+ return emptyLockfile(scope);
49
+ }
50
+ if (Array.isArray(raw.assets)) {
51
+ return {
52
+ schemaVersion: 1,
53
+ generatedAt: raw.generatedAt ?? new Date().toISOString(),
54
+ scope: raw.scope ?? scope,
55
+ assets: raw.assets.filter(isValidLockEntry).map((entry) => ({
56
+ ...entry,
57
+ scope: entry.scope ?? scope,
58
+ dependencies: entry.dependencies ?? [],
59
+ requiresLocalConfig: entry.requiresLocalConfig ?? entry.type === 'mcp',
60
+ })),
61
+ };
62
+ }
63
+ const legacyEntries = [
64
+ ...(raw.skills ?? []),
65
+ ...(raw.prompts ?? []),
66
+ ...(raw.mcps ?? []),
67
+ ];
68
+ return {
69
+ schemaVersion: 1,
70
+ generatedAt: raw.generatedAt ?? new Date().toISOString(),
71
+ scope: raw.scope ?? scope,
72
+ assets: legacyEntries.map((entry) => migrateLegacyEntry(entry, raw.scope ?? scope)),
73
+ };
74
+ }
75
+ export function emptyLockfile(scope) {
76
+ return {
77
+ schemaVersion: 1,
78
+ generatedAt: new Date().toISOString(),
79
+ scope,
80
+ assets: [],
81
+ };
82
+ }
83
+ export function isLegacyLockfile(raw) {
84
+ return !Array.isArray(raw.assets) && !!(raw.skills?.length || raw.prompts?.length || raw.mcps?.length || raw.version === 1);
85
+ }
86
+ function isValidLockEntry(entry) {
87
+ if (!entry || typeof entry !== 'object')
88
+ return false;
89
+ const e = entry;
90
+ return (typeof e.localName === 'string' &&
91
+ (e.type === 'skill' || e.type === 'prompt' || e.type === 'mcp') &&
92
+ typeof e.version === 'string');
93
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Extract env var keys from mcp.json that need local values.
3
+ */
4
+ export declare function extractMcpEnvKeys(mcpData: Record<string, unknown>): string[];
5
+ export declare function buildMcpLocalTemplate(envKeys: string[]): Record<string, string>;
6
+ /** Create mcp.local.json when missing; never overwrite existing file. */
7
+ export declare function scaffoldMcpLocalConfig(assetDir: string): Promise<{
8
+ created: boolean;
9
+ keys: string[];
10
+ }>;
11
+ export declare function mcpRequiresLocalConfig(mcpData: Record<string, unknown>): boolean;
12
+ export declare function ensureMcpLocalGitignore(scopeRoot: string): Promise<boolean>;
13
+ export declare function readGitignoreContent(scopeRoot: string): Promise<string>;
14
+ export declare function gitignoreIncludesMcpLocalAsync(scopeRoot: string): Promise<boolean>;
15
+ export declare function countEmptyMcpLocalValues(assetDir: string): Promise<number>;