@within-7/minto 0.3.6 → 0.3.10
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/{cli.js → cli.cjs} +25 -23
- package/dist/commands/agents/AgentsCommand.js +459 -655
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/types.js +1 -0
- package/dist/commands/agents/types.js.map +2 -2
- package/dist/commands/agents/utils/fileOperations.js +96 -36
- package/dist/commands/agents/utils/fileOperations.js.map +3 -3
- package/dist/commands/agents/utils/index.js +3 -1
- package/dist/commands/agents/utils/index.js.map +2 -2
- package/dist/commands/context.js +54 -23
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/export.js +673 -93
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/language.js +110 -0
- package/dist/commands/language.js.map +7 -0
- package/dist/commands/mcp-interactive.js +419 -217
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +415 -66
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/new.js +56 -0
- package/dist/commands/new.js.map +7 -0
- package/dist/commands/permissions.js +75 -49
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin.js +882 -185
- package/dist/commands/plugin.js.map +3 -3
- package/dist/commands/resume.js +251 -16
- package/dist/commands/resume.js.map +2 -2
- package/dist/commands/sandbox.js +168 -70
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/sessions.js +224 -0
- package/dist/commands/sessions.js.map +7 -0
- package/dist/commands/setup.js +596 -109
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +292 -0
- package/dist/commands/stats.js.map +7 -0
- package/dist/commands/status.js +75 -7
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/undo.js +154 -180
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands.js +6 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/Config.js +9 -8
- package/dist/components/Config.js.map +2 -2
- package/dist/components/HeaderBar.js +2 -1
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/Help.js +166 -32
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +46 -44
- package/dist/components/HotkeyHelpPanel.js.map +2 -2
- package/dist/components/InfoPanel/InfoPanel.js +123 -0
- package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
- package/dist/components/InfoPanel/index.js +5 -0
- package/dist/components/InfoPanel/index.js.map +7 -0
- package/dist/components/InfoPanel/types.js +1 -0
- package/dist/components/InfoPanel/types.js.map +7 -0
- package/dist/components/Logo.js +5 -2
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/MCPServerApprovalDialog.js +6 -5
- package/dist/components/MCPServerApprovalDialog.js.map +2 -2
- package/dist/components/MCPServerMultiselectDialog.js +5 -4
- package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
- package/dist/components/MessageSelector.js +4 -3
- package/dist/components/MessageSelector.js.map +2 -2
- package/dist/components/ModelConfig.js +13 -12
- package/dist/components/ModelConfig.js.map +2 -2
- package/dist/components/ModelListManager.js +4 -3
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/BrandTextInput.js +43 -0
- package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +419 -501
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/ModelSelector/WizardContainer.js +45 -0
- package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
- package/dist/components/ModelSelector/index.js +1 -3
- package/dist/components/ModelSelector/index.js.map +2 -2
- package/dist/components/PromptInput.js +77 -44
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/SensitiveFileWarning.js +12 -8
- package/dist/components/SensitiveFileWarning.js.map +2 -2
- package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
- package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
- package/dist/components/SimpleSelector/index.js +5 -0
- package/dist/components/SimpleSelector/index.js.map +7 -0
- package/dist/components/SimpleSelector/types.js +1 -0
- package/dist/components/SimpleSelector/types.js.map +7 -0
- package/dist/components/StatusOverlayContent.js +21 -0
- package/dist/components/StatusOverlayContent.js.map +7 -0
- package/dist/components/TabbedListView/ScrollableList.js +117 -0
- package/dist/components/TabbedListView/ScrollableList.js.map +7 -0
- package/dist/components/TabbedListView/SearchInput.js +23 -0
- package/dist/components/TabbedListView/SearchInput.js.map +7 -0
- package/dist/components/TabbedListView/TabBar.js +20 -0
- package/dist/components/TabbedListView/TabBar.js.map +7 -0
- package/dist/components/TabbedListView/TabbedListView.js +246 -0
- package/dist/components/TabbedListView/TabbedListView.js.map +7 -0
- package/dist/components/TabbedListView/index.js +11 -0
- package/dist/components/TabbedListView/index.js.map +7 -0
- package/dist/components/TabbedListView/types.js +1 -0
- package/dist/components/TabbedListView/types.js.map +7 -0
- package/dist/components/TodoChangeBlock.js +6 -5
- package/dist/components/TodoChangeBlock.js.map +3 -3
- package/dist/components/TodoPanel.js +6 -3
- package/dist/components/TodoPanel.js.map +3 -3
- package/dist/components/TrustDialog.js +6 -5
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js +2 -1
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js.map +2 -2
- package/dist/constants/macros.js +1 -1
- package/dist/constants/macros.js.map +1 -1
- package/dist/constants/product.js +2 -2
- package/dist/constants/product.js.map +1 -1
- package/dist/constants/prompts.js +17 -0
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/toolInputExamples.js +5 -1
- package/dist/constants/toolInputExamples.js.map +2 -2
- package/dist/core/backupHook.js +29 -0
- package/dist/core/backupHook.js.map +7 -0
- package/dist/core/config/defaults.js +8 -2
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +14 -2
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +0 -16
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/tokenStatsManager.js +5 -0
- package/dist/core/tokenStatsManager.js.map +2 -2
- package/dist/cost-tracker.js +0 -16
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +56 -0
- package/dist/entrypoints/bootstrap.js.map +7 -0
- package/dist/entrypoints/cli.js +164 -23
- package/dist/entrypoints/cli.js.map +3 -3
- package/dist/history.js +75 -15
- package/dist/history.js.map +2 -2
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/index.js.map +2 -2
- package/dist/i18n/locales/en.js +582 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +582 -1
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +2 -2
- package/dist/messages.js +11 -0
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +9 -0
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +45 -7
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/customCommands.js +44 -16
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/plugins/lspServers.js +1 -1
- package/dist/services/plugins/lspServers.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +2 -1
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +10 -3
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +16 -8
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/systemReminder.js +17 -6
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +7 -0
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +7 -0
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +179 -1
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TodoWriteTool/prompt.js +21 -0
- package/dist/tools/TodoWriteTool/prompt.js.map +2 -2
- package/dist/tools/URLFetcherTool/prompt.js +14 -9
- package/dist/tools/URLFetcherTool/prompt.js.map +2 -2
- package/dist/tools/WebSearchTool/prompt.js +12 -6
- package/dist/tools/WebSearchTool/prompt.js.map +2 -2
- package/dist/types/PermissionMode.js +30 -1
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/plugin.js +2 -4
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +103 -0
- package/dist/utils/agentHookExecutor.js.map +7 -0
- package/dist/utils/agentLoader.js +272 -32
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentMemory.js +134 -0
- package/dist/utils/agentMemory.js.map +7 -0
- package/dist/utils/claudeCodeSync.js +439 -0
- package/dist/utils/claudeCodeSync.js.map +7 -0
- package/dist/utils/config.js +52 -24
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configPaths.js +199 -0
- package/dist/utils/configPaths.js.map +7 -0
- package/dist/utils/execFileNoThrow.js +2 -1
- package/dist/utils/execFileNoThrow.js.map +2 -2
- package/dist/utils/historyManager.js +234 -0
- package/dist/utils/historyManager.js.map +7 -0
- package/dist/utils/marketplaceManager.js +80 -43
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/messages.js +13 -8
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/migration/index.js +37 -0
- package/dist/utils/migration/index.js.map +7 -0
- package/dist/utils/migration/migrateHistory.js +273 -0
- package/dist/utils/migration/migrateHistory.js.map +7 -0
- package/dist/utils/migration/migrateTodos.js +323 -0
- package/dist/utils/migration/migrateTodos.js.map +7 -0
- package/dist/utils/pasteCache.js +309 -0
- package/dist/utils/pasteCache.js.map +7 -0
- package/dist/utils/pluginInstaller.js +34 -24
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +54 -28
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/repoFetcher.js +110 -0
- package/dist/utils/repoFetcher.js.map +7 -0
- package/dist/utils/sessionIndex.js +192 -0
- package/dist/utils/sessionIndex.js.map +7 -0
- package/dist/utils/sessionTracker.js +170 -0
- package/dist/utils/sessionTracker.js.map +7 -0
- package/dist/utils/skillLoader.js +103 -5
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/stats.js +417 -0
- package/dist/utils/stats.js.map +7 -0
- package/dist/utils/stringSubstitution.js +106 -0
- package/dist/utils/stringSubstitution.js.map +7 -0
- package/dist/utils/teamConfig.js +156 -14
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/terminal.js +1 -1
- package/dist/utils/terminal.js.map +2 -2
- package/dist/utils/todoStorage.js +51 -19
- package/dist/utils/todoStorage.js.map +2 -2
- package/dist/utils/tooling/safeRender.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +71 -28
- package/scripts/{postinstall.js → postinstall.cjs} +1 -1
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
readFileSync,
|
|
4
|
+
writeFileSync,
|
|
5
|
+
mkdirSync,
|
|
6
|
+
rmSync,
|
|
7
|
+
cpSync,
|
|
8
|
+
readdirSync,
|
|
9
|
+
statSync
|
|
10
|
+
} from "fs";
|
|
11
|
+
import { join, basename } from "path";
|
|
12
|
+
import { homedir } from "os";
|
|
13
|
+
import {
|
|
14
|
+
isMarketplaceRegistered,
|
|
15
|
+
registerMarketplaceFromDirectory
|
|
16
|
+
} from "./marketplaceManager.js";
|
|
17
|
+
const CC_HOME = join(homedir(), ".claude");
|
|
18
|
+
const CC_REGISTRY_PATH = join(CC_HOME, "plugins", "installed_plugins.json");
|
|
19
|
+
const CC_SETTINGS_PATH = join(CC_HOME, "settings.json");
|
|
20
|
+
const CC_MARKETPLACES_PATH = join(CC_HOME, "plugins", "known_marketplaces.json");
|
|
21
|
+
const MINTO_HOME = join(homedir(), ".minto");
|
|
22
|
+
const MINTO_SYNC_STATE_PATH = join(MINTO_HOME, "cc-sync-state.json");
|
|
23
|
+
const MINTO_PLUGINS_DIR = join(MINTO_HOME, "plugins");
|
|
24
|
+
function loadJSON(path) {
|
|
25
|
+
if (!existsSync(path)) return null;
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function loadCCRegistry() {
|
|
33
|
+
return loadJSON(CC_REGISTRY_PATH);
|
|
34
|
+
}
|
|
35
|
+
function loadCCSettings() {
|
|
36
|
+
return loadJSON(CC_SETTINGS_PATH) ?? {};
|
|
37
|
+
}
|
|
38
|
+
function loadCCKnownMarketplaces() {
|
|
39
|
+
return loadJSON(CC_MARKETPLACES_PATH);
|
|
40
|
+
}
|
|
41
|
+
function convertCCSourceToMintoSource(ccSource) {
|
|
42
|
+
switch (ccSource.source) {
|
|
43
|
+
case "github":
|
|
44
|
+
if (!ccSource.repo) return null;
|
|
45
|
+
return { type: "github", repo: ccSource.repo, ref: ccSource.ref };
|
|
46
|
+
case "url":
|
|
47
|
+
if (!ccSource.url) return null;
|
|
48
|
+
return { type: "url", url: ccSource.url, ref: ccSource.ref };
|
|
49
|
+
case "local":
|
|
50
|
+
return null;
|
|
51
|
+
default:
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function resolveMarketplaceSource(marketplace, knownMarketplaces) {
|
|
56
|
+
if (!knownMarketplaces) return null;
|
|
57
|
+
const mp = knownMarketplaces[marketplace];
|
|
58
|
+
if (!mp) return null;
|
|
59
|
+
return convertCCSourceToMintoSource(mp.source);
|
|
60
|
+
}
|
|
61
|
+
function syncMarketplaces(knownMarketplaces, dryRun, onProgress) {
|
|
62
|
+
const result = {
|
|
63
|
+
registered: [],
|
|
64
|
+
skipped: [],
|
|
65
|
+
failed: []
|
|
66
|
+
};
|
|
67
|
+
if (!knownMarketplaces) return result;
|
|
68
|
+
for (const [name, mp] of Object.entries(knownMarketplaces)) {
|
|
69
|
+
try {
|
|
70
|
+
if (isMarketplaceRegistered(name)) {
|
|
71
|
+
result.skipped.push(name);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const mintoSource = convertCCSourceToMintoSource(mp.source);
|
|
75
|
+
if (!mintoSource) {
|
|
76
|
+
result.skipped.push(name);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (!mp.installLocation || !existsSync(mp.installLocation)) {
|
|
80
|
+
result.failed.push({
|
|
81
|
+
name,
|
|
82
|
+
error: `Install location not found: ${mp.installLocation || "(empty)"}`
|
|
83
|
+
});
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (dryRun) {
|
|
87
|
+
result.registered.push(name);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
onProgress?.(`Registering marketplace ${name}...`);
|
|
91
|
+
const registered = registerMarketplaceFromDirectory(
|
|
92
|
+
name,
|
|
93
|
+
mintoSource,
|
|
94
|
+
mp.installLocation
|
|
95
|
+
);
|
|
96
|
+
if (registered) {
|
|
97
|
+
result.registered.push(name);
|
|
98
|
+
} else {
|
|
99
|
+
result.skipped.push(name);
|
|
100
|
+
}
|
|
101
|
+
} catch (err) {
|
|
102
|
+
result.failed.push({
|
|
103
|
+
name,
|
|
104
|
+
error: err instanceof Error ? err.message : String(err)
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
function loadSyncState() {
|
|
111
|
+
return loadJSON(MINTO_SYNC_STATE_PATH);
|
|
112
|
+
}
|
|
113
|
+
function saveSyncState(state) {
|
|
114
|
+
if (!existsSync(MINTO_HOME)) {
|
|
115
|
+
mkdirSync(MINTO_HOME, { recursive: true });
|
|
116
|
+
}
|
|
117
|
+
writeFileSync(MINTO_SYNC_STATE_PATH, JSON.stringify(state, null, 2), "utf-8");
|
|
118
|
+
}
|
|
119
|
+
function hasClaudeCodeInstallation() {
|
|
120
|
+
return existsSync(CC_REGISTRY_PATH);
|
|
121
|
+
}
|
|
122
|
+
function getClaudeCodePluginCount() {
|
|
123
|
+
const registry = loadCCRegistry();
|
|
124
|
+
if (!registry) return 0;
|
|
125
|
+
return Object.keys(registry.plugins).length;
|
|
126
|
+
}
|
|
127
|
+
function needsSync() {
|
|
128
|
+
if (!existsSync(CC_REGISTRY_PATH)) return false;
|
|
129
|
+
const state = loadSyncState();
|
|
130
|
+
if (!state) return true;
|
|
131
|
+
try {
|
|
132
|
+
const stat = statSync(CC_REGISTRY_PATH);
|
|
133
|
+
const mtime = stat.mtime.toISOString();
|
|
134
|
+
return mtime !== state.lastRegistryModified;
|
|
135
|
+
} catch {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const EXCLUDE_PATTERNS = /* @__PURE__ */ new Set([
|
|
140
|
+
".git",
|
|
141
|
+
".orphaned_at",
|
|
142
|
+
".DS_Store",
|
|
143
|
+
"node_modules",
|
|
144
|
+
".github"
|
|
145
|
+
]);
|
|
146
|
+
function shouldCopy(src) {
|
|
147
|
+
const name = basename(src);
|
|
148
|
+
return !EXCLUDE_PATTERNS.has(name);
|
|
149
|
+
}
|
|
150
|
+
function copyPluginFromCache(sourcePath, targetPath) {
|
|
151
|
+
if (!existsSync(sourcePath)) {
|
|
152
|
+
throw new Error(`Source path does not exist: ${sourcePath}`);
|
|
153
|
+
}
|
|
154
|
+
if (!existsSync(targetPath)) {
|
|
155
|
+
mkdirSync(targetPath, { recursive: true });
|
|
156
|
+
}
|
|
157
|
+
cpSync(sourcePath, targetPath, {
|
|
158
|
+
recursive: true,
|
|
159
|
+
filter: shouldCopy
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
function loadMarketplacePluginMeta(marketplaceName, pluginName) {
|
|
163
|
+
const knownMPs = loadCCKnownMarketplaces();
|
|
164
|
+
if (!knownMPs) return null;
|
|
165
|
+
const mp = knownMPs[marketplaceName];
|
|
166
|
+
if (!mp?.installLocation) return null;
|
|
167
|
+
const mpJsonPath = join(
|
|
168
|
+
mp.installLocation,
|
|
169
|
+
".claude-plugin",
|
|
170
|
+
"marketplace.json"
|
|
171
|
+
);
|
|
172
|
+
if (!existsSync(mpJsonPath)) return null;
|
|
173
|
+
try {
|
|
174
|
+
const manifest = JSON.parse(readFileSync(mpJsonPath, "utf-8"));
|
|
175
|
+
const plugins = manifest.plugins || [];
|
|
176
|
+
return plugins.find((p) => p.name === pluginName) ?? null;
|
|
177
|
+
} catch {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function generatePluginManifest(pluginName, marketplace, ccEntry, meta) {
|
|
182
|
+
const agents = [];
|
|
183
|
+
const commands = [];
|
|
184
|
+
const skills = [];
|
|
185
|
+
const agentsDir = join(ccEntry.installPath, "agents");
|
|
186
|
+
if (existsSync(agentsDir)) {
|
|
187
|
+
try {
|
|
188
|
+
agents.push(
|
|
189
|
+
...readdirSync(agentsDir).filter((f) => f.endsWith(".md")).map((f) => `agents/${f}`)
|
|
190
|
+
);
|
|
191
|
+
} catch {
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const commandsDir = join(ccEntry.installPath, "commands");
|
|
195
|
+
if (existsSync(commandsDir)) {
|
|
196
|
+
try {
|
|
197
|
+
commands.push(
|
|
198
|
+
...readdirSync(commandsDir).filter((f) => f.endsWith(".md")).map((f) => `commands/${f}`)
|
|
199
|
+
);
|
|
200
|
+
} catch {
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const skillsDir = join(ccEntry.installPath, "skills");
|
|
204
|
+
if (existsSync(skillsDir)) {
|
|
205
|
+
try {
|
|
206
|
+
for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
|
|
207
|
+
if (entry.isDirectory()) {
|
|
208
|
+
const skillMd = join(skillsDir, entry.name, "SKILL.md");
|
|
209
|
+
if (existsSync(skillMd)) {
|
|
210
|
+
skills.push(`skills/${entry.name}/SKILL.md`);
|
|
211
|
+
}
|
|
212
|
+
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
213
|
+
skills.push(`skills/${entry.name}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
} catch {
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
name: pluginName,
|
|
221
|
+
version: meta?.version || ccEntry.version || "1.0.0",
|
|
222
|
+
description: meta?.description || `Claude Code plugin: ${pluginName}`,
|
|
223
|
+
displayName: pluginName,
|
|
224
|
+
author: meta?.author,
|
|
225
|
+
homepage: meta?.homepage,
|
|
226
|
+
repository: meta?.repository,
|
|
227
|
+
license: meta?.license,
|
|
228
|
+
agents,
|
|
229
|
+
commands,
|
|
230
|
+
skills
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function syncSinglePlugin(pluginName, marketplace, entry, enabled, syncState, dryRun, knownMarketplaces) {
|
|
234
|
+
const targetPath = join(MINTO_PLUGINS_DIR, pluginName);
|
|
235
|
+
const ccSyncPath = join(targetPath, ".cc-sync.json");
|
|
236
|
+
if (existsSync(targetPath) && !existsSync(ccSyncPath)) {
|
|
237
|
+
return "skipped";
|
|
238
|
+
}
|
|
239
|
+
if (existsSync(ccSyncPath)) {
|
|
240
|
+
try {
|
|
241
|
+
const existing = JSON.parse(readFileSync(ccSyncPath, "utf-8"));
|
|
242
|
+
if (existing.version === entry.version && existing.gitCommitSha === entry.gitCommitSha) {
|
|
243
|
+
return "skipped";
|
|
244
|
+
}
|
|
245
|
+
} catch {
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
const isUpdate = existsSync(targetPath);
|
|
249
|
+
if (dryRun) {
|
|
250
|
+
return isUpdate ? "updated" : "installed";
|
|
251
|
+
}
|
|
252
|
+
if (isUpdate) {
|
|
253
|
+
rmSync(targetPath, { recursive: true, force: true });
|
|
254
|
+
}
|
|
255
|
+
copyPluginFromCache(entry.installPath, targetPath);
|
|
256
|
+
const meta = loadMarketplacePluginMeta(marketplace, pluginName);
|
|
257
|
+
const manifest = generatePluginManifest(pluginName, marketplace, entry, meta);
|
|
258
|
+
const mintoPluginDir = join(targetPath, ".minto-plugin");
|
|
259
|
+
mkdirSync(mintoPluginDir, { recursive: true });
|
|
260
|
+
writeFileSync(
|
|
261
|
+
join(mintoPluginDir, "plugin.json"),
|
|
262
|
+
JSON.stringify(manifest, null, 2),
|
|
263
|
+
"utf-8"
|
|
264
|
+
);
|
|
265
|
+
const realSource = resolveMarketplaceSource(marketplace, knownMarketplaces);
|
|
266
|
+
writeFileSync(
|
|
267
|
+
join(targetPath, ".marketplace-meta.json"),
|
|
268
|
+
JSON.stringify(
|
|
269
|
+
{
|
|
270
|
+
marketplace,
|
|
271
|
+
plugin: pluginName,
|
|
272
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
273
|
+
source: realSource ?? { source: "claude-code" },
|
|
274
|
+
...realSource ? { syncedFrom: "claude-code" } : {}
|
|
275
|
+
},
|
|
276
|
+
null,
|
|
277
|
+
2
|
|
278
|
+
),
|
|
279
|
+
"utf-8"
|
|
280
|
+
);
|
|
281
|
+
writeFileSync(
|
|
282
|
+
join(targetPath, ".cc-sync.json"),
|
|
283
|
+
JSON.stringify(
|
|
284
|
+
{
|
|
285
|
+
name: pluginName,
|
|
286
|
+
version: entry.version,
|
|
287
|
+
gitCommitSha: entry.gitCommitSha,
|
|
288
|
+
marketplace,
|
|
289
|
+
syncedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
290
|
+
source: entry.installPath
|
|
291
|
+
},
|
|
292
|
+
null,
|
|
293
|
+
2
|
|
294
|
+
),
|
|
295
|
+
"utf-8"
|
|
296
|
+
);
|
|
297
|
+
writeFileSync(
|
|
298
|
+
join(targetPath, ".plugin-config.json"),
|
|
299
|
+
JSON.stringify({ enabled }, null, 2),
|
|
300
|
+
"utf-8"
|
|
301
|
+
);
|
|
302
|
+
return isUpdate ? "updated" : "installed";
|
|
303
|
+
}
|
|
304
|
+
async function syncFromClaudeCode(options = {}) {
|
|
305
|
+
const { force = false, clean = false, dryRun = false, onProgress } = options;
|
|
306
|
+
const result = {
|
|
307
|
+
installed: [],
|
|
308
|
+
updated: [],
|
|
309
|
+
skipped: [],
|
|
310
|
+
failed: [],
|
|
311
|
+
cleaned: [],
|
|
312
|
+
total: 0,
|
|
313
|
+
marketplaces: { registered: [], skipped: [], failed: [] }
|
|
314
|
+
};
|
|
315
|
+
const registry = loadCCRegistry();
|
|
316
|
+
if (!registry) {
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
319
|
+
const settings = loadCCSettings();
|
|
320
|
+
const enabledPlugins = settings.enabledPlugins || {};
|
|
321
|
+
const syncState = force ? null : loadSyncState();
|
|
322
|
+
const knownMarketplaces = loadCCKnownMarketplaces();
|
|
323
|
+
if (!existsSync(MINTO_PLUGINS_DIR)) {
|
|
324
|
+
mkdirSync(MINTO_PLUGINS_DIR, { recursive: true });
|
|
325
|
+
}
|
|
326
|
+
try {
|
|
327
|
+
for (const dir of readdirSync(MINTO_PLUGINS_DIR, { withFileTypes: true })) {
|
|
328
|
+
if (!dir.isDirectory()) continue;
|
|
329
|
+
const pluginDir = join(MINTO_PLUGINS_DIR, dir.name);
|
|
330
|
+
const rootManifest = join(pluginDir, "plugin.json");
|
|
331
|
+
const mintoManifest = join(pluginDir, ".minto-plugin", "plugin.json");
|
|
332
|
+
const ccSyncMarker = join(pluginDir, ".cc-sync.json");
|
|
333
|
+
if (existsSync(ccSyncMarker) && existsSync(rootManifest) && !existsSync(mintoManifest)) {
|
|
334
|
+
mkdirSync(join(pluginDir, ".minto-plugin"), { recursive: true });
|
|
335
|
+
cpSync(rootManifest, mintoManifest);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
} catch {
|
|
339
|
+
}
|
|
340
|
+
onProgress?.("Scanning Claude Code registry...");
|
|
341
|
+
const pluginKeys = Object.keys(registry.plugins);
|
|
342
|
+
result.total = pluginKeys.length;
|
|
343
|
+
for (const pluginKey of pluginKeys) {
|
|
344
|
+
const atIdx = pluginKey.indexOf("@");
|
|
345
|
+
if (atIdx === -1) continue;
|
|
346
|
+
const pluginName = pluginKey.slice(0, atIdx);
|
|
347
|
+
const marketplace = pluginKey.slice(atIdx + 1);
|
|
348
|
+
const entries = registry.plugins[pluginKey];
|
|
349
|
+
const entry = entries.find((e) => e.scope === "user") || entries[0];
|
|
350
|
+
if (!entry) continue;
|
|
351
|
+
const enabled = enabledPlugins[pluginKey] !== false;
|
|
352
|
+
try {
|
|
353
|
+
onProgress?.(
|
|
354
|
+
existsSync(join(MINTO_PLUGINS_DIR, pluginName)) ? `Updating ${pluginName}...` : `Installing ${pluginName}...`
|
|
355
|
+
);
|
|
356
|
+
const action = syncSinglePlugin(
|
|
357
|
+
pluginName,
|
|
358
|
+
marketplace,
|
|
359
|
+
entry,
|
|
360
|
+
enabled,
|
|
361
|
+
syncState,
|
|
362
|
+
dryRun,
|
|
363
|
+
knownMarketplaces
|
|
364
|
+
);
|
|
365
|
+
switch (action) {
|
|
366
|
+
case "installed":
|
|
367
|
+
result.installed.push(pluginName);
|
|
368
|
+
break;
|
|
369
|
+
case "updated":
|
|
370
|
+
result.updated.push(pluginName);
|
|
371
|
+
break;
|
|
372
|
+
case "skipped":
|
|
373
|
+
result.skipped.push(pluginName);
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
} catch (err) {
|
|
377
|
+
result.failed.push({
|
|
378
|
+
name: pluginName,
|
|
379
|
+
error: err instanceof Error ? err.message : String(err)
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (clean && !dryRun && existsSync(MINTO_PLUGINS_DIR)) {
|
|
384
|
+
const ccPluginNames = new Set(
|
|
385
|
+
pluginKeys.map((k) => k.slice(0, k.indexOf("@")))
|
|
386
|
+
);
|
|
387
|
+
for (const dir of readdirSync(MINTO_PLUGINS_DIR)) {
|
|
388
|
+
const pluginPath = join(MINTO_PLUGINS_DIR, dir);
|
|
389
|
+
const ccSyncPath = join(pluginPath, ".cc-sync.json");
|
|
390
|
+
if (!existsSync(ccSyncPath)) continue;
|
|
391
|
+
if (ccPluginNames.has(dir)) continue;
|
|
392
|
+
rmSync(pluginPath, { recursive: true, force: true });
|
|
393
|
+
result.cleaned.push(dir);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
try {
|
|
397
|
+
onProgress?.("Syncing marketplaces...");
|
|
398
|
+
result.marketplaces = syncMarketplaces(
|
|
399
|
+
knownMarketplaces,
|
|
400
|
+
dryRun,
|
|
401
|
+
onProgress
|
|
402
|
+
);
|
|
403
|
+
} catch {
|
|
404
|
+
}
|
|
405
|
+
if (!dryRun) {
|
|
406
|
+
const registryStat = statSync(CC_REGISTRY_PATH);
|
|
407
|
+
const newState = {
|
|
408
|
+
lastSyncedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
409
|
+
lastRegistryModified: registryStat.mtime.toISOString(),
|
|
410
|
+
plugins: {}
|
|
411
|
+
};
|
|
412
|
+
if (existsSync(MINTO_PLUGINS_DIR)) {
|
|
413
|
+
for (const dir of readdirSync(MINTO_PLUGINS_DIR)) {
|
|
414
|
+
const ccSyncPath = join(MINTO_PLUGINS_DIR, dir, ".cc-sync.json");
|
|
415
|
+
if (!existsSync(ccSyncPath)) continue;
|
|
416
|
+
try {
|
|
417
|
+
const meta = JSON.parse(readFileSync(ccSyncPath, "utf-8"));
|
|
418
|
+
newState.plugins[dir] = {
|
|
419
|
+
version: meta.version,
|
|
420
|
+
gitCommitSha: meta.gitCommitSha,
|
|
421
|
+
syncedAt: meta.syncedAt,
|
|
422
|
+
marketplace: meta.marketplace
|
|
423
|
+
};
|
|
424
|
+
} catch {
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
saveSyncState(newState);
|
|
429
|
+
}
|
|
430
|
+
return result;
|
|
431
|
+
}
|
|
432
|
+
export {
|
|
433
|
+
getClaudeCodePluginCount,
|
|
434
|
+
hasClaudeCodeInstallation,
|
|
435
|
+
loadCCKnownMarketplaces,
|
|
436
|
+
needsSync,
|
|
437
|
+
syncFromClaudeCode
|
|
438
|
+
};
|
|
439
|
+
//# sourceMappingURL=claudeCodeSync.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/claudeCodeSync.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Claude Code \u2192 Minto Plugin Sync\n *\n * Reads Claude Code's installed_plugins.json registry, compares with Minto's\n * sync state, and copies new/updated plugins into ~/.minto/plugins/.\n *\n * Design:\n * - Never modifies Claude Code files\n * - Minto-manual plugins (no .cc-sync.json) are never overwritten\n * - Sync state tracked in ~/.minto/cc-sync-state.json\n */\n\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n rmSync,\n cpSync,\n readdirSync,\n statSync,\n} from 'fs'\nimport { join, basename } from 'path'\nimport { homedir } from 'os'\nimport type { MarketplaceSource } from '../types/marketplace'\nimport {\n isMarketplaceRegistered,\n registerMarketplaceFromDirectory,\n} from './marketplaceManager'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface CCPluginEntry {\n scope: 'user' | 'project'\n installPath: string\n version: string\n installedAt: string\n lastUpdated: string\n gitCommitSha?: string\n}\n\ninterface CCRegistry {\n version: number\n plugins: Record<string, CCPluginEntry[]> // key = \"name@marketplace\"\n}\n\ninterface CCSettings {\n enabledPlugins?: Record<string, boolean>\n}\n\ninterface CCKnownMarketplace {\n source: { source: string; repo?: string; url?: string; ref?: string }\n installLocation: string\n lastUpdated: string\n}\n\ninterface CCSyncPluginState {\n version: string\n gitCommitSha?: string\n syncedAt: string\n marketplace: string\n}\n\ninterface CCSyncState {\n lastSyncedAt: string\n lastRegistryModified: string // mtime ISO string\n plugins: Record<string, CCSyncPluginState> // key = plugin name\n}\n\nexport interface MarketplaceSyncResult {\n registered: string[]\n skipped: string[]\n failed: Array<{ name: string; error: string }>\n}\n\nexport interface SyncResult {\n installed: string[]\n updated: string[]\n skipped: string[]\n failed: Array<{ name: string; error: string }>\n cleaned: string[]\n total: number\n marketplaces: MarketplaceSyncResult\n}\n\nexport interface SyncOptions {\n force?: boolean\n clean?: boolean\n dryRun?: boolean\n onProgress?: (msg: string) => void\n}\n\n// ---------------------------------------------------------------------------\n// Path constants\n// ---------------------------------------------------------------------------\n\nconst CC_HOME = join(homedir(), '.claude')\nconst CC_REGISTRY_PATH = join(CC_HOME, 'plugins', 'installed_plugins.json')\nconst CC_SETTINGS_PATH = join(CC_HOME, 'settings.json')\nconst CC_MARKETPLACES_PATH = join(CC_HOME, 'plugins', 'known_marketplaces.json')\nconst MINTO_HOME = join(homedir(), '.minto')\nconst MINTO_SYNC_STATE_PATH = join(MINTO_HOME, 'cc-sync-state.json')\nconst MINTO_PLUGINS_DIR = join(MINTO_HOME, 'plugins')\n\n// ---------------------------------------------------------------------------\n// Helpers \u2014 load CC data\n// ---------------------------------------------------------------------------\n\nfunction loadJSON<T>(path: string): T | null {\n if (!existsSync(path)) return null\n try {\n return JSON.parse(readFileSync(path, 'utf-8')) as T\n } catch {\n return null\n }\n}\n\nfunction loadCCRegistry(): CCRegistry | null {\n return loadJSON<CCRegistry>(CC_REGISTRY_PATH)\n}\n\nfunction loadCCSettings(): CCSettings {\n return loadJSON<CCSettings>(CC_SETTINGS_PATH) ?? {}\n}\n\nexport function loadCCKnownMarketplaces(): Record<\n string,\n CCKnownMarketplace\n> | null {\n return loadJSON<Record<string, CCKnownMarketplace>>(CC_MARKETPLACES_PATH)\n}\n\n// ---------------------------------------------------------------------------\n// Helpers \u2014 CC\u2192Minto source conversion\n// ---------------------------------------------------------------------------\n\n/**\n * Convert Claude Code's marketplace source format to Minto's MarketplaceSource.\n * CC uses `{ source: 'github', repo }` while Minto uses `{ type: 'github', repo }`.\n * Returns null for unknown types or missing required fields.\n */\nfunction convertCCSourceToMintoSource(\n ccSource: CCKnownMarketplace['source'],\n): MarketplaceSource | null {\n switch (ccSource.source) {\n case 'github':\n if (!ccSource.repo) return null\n return { type: 'github', repo: ccSource.repo, ref: ccSource.ref }\n case 'url':\n if (!ccSource.url) return null\n return { type: 'url', url: ccSource.url, ref: ccSource.ref }\n case 'local':\n // Local sources from CC don't transfer meaningfully\n return null\n default:\n return null\n }\n}\n\n/**\n * Resolve a marketplace source for a plugin from CC's known_marketplaces.json.\n * Used to write real source info into .marketplace-meta.json instead of `{ source: 'claude-code' }`.\n */\nfunction resolveMarketplaceSource(\n marketplace: string,\n knownMarketplaces: Record<string, CCKnownMarketplace> | null,\n): MarketplaceSource | null {\n if (!knownMarketplaces) return null\n const mp = knownMarketplaces[marketplace]\n if (!mp) return null\n return convertCCSourceToMintoSource(mp.source)\n}\n\n/**\n * Sync marketplaces from Claude Code's known_marketplaces.json into Minto's registry.\n * Non-blocking: errors per-marketplace are caught and recorded.\n */\nfunction syncMarketplaces(\n knownMarketplaces: Record<string, CCKnownMarketplace> | null,\n dryRun: boolean,\n onProgress?: (msg: string) => void,\n): MarketplaceSyncResult {\n const result: MarketplaceSyncResult = {\n registered: [],\n skipped: [],\n failed: [],\n }\n\n if (!knownMarketplaces) return result\n\n for (const [name, mp] of Object.entries(knownMarketplaces)) {\n try {\n // Already in Minto registry?\n if (isMarketplaceRegistered(name)) {\n result.skipped.push(name)\n continue\n }\n\n // Convert source format\n const mintoSource = convertCCSourceToMintoSource(mp.source)\n if (!mintoSource) {\n result.skipped.push(name)\n continue\n }\n\n // Verify CC's local clone exists\n if (!mp.installLocation || !existsSync(mp.installLocation)) {\n result.failed.push({\n name,\n error: `Install location not found: ${mp.installLocation || '(empty)'}`,\n })\n continue\n }\n\n if (dryRun) {\n result.registered.push(name)\n continue\n }\n\n onProgress?.(`Registering marketplace ${name}...`)\n const registered = registerMarketplaceFromDirectory(\n name,\n mintoSource,\n mp.installLocation,\n )\n\n if (registered) {\n result.registered.push(name)\n } else {\n result.skipped.push(name) // race: registered between check and call\n }\n } catch (err) {\n result.failed.push({\n name,\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Helpers \u2014 sync state\n// ---------------------------------------------------------------------------\n\nfunction loadSyncState(): CCSyncState | null {\n return loadJSON<CCSyncState>(MINTO_SYNC_STATE_PATH)\n}\n\nfunction saveSyncState(state: CCSyncState): void {\n if (!existsSync(MINTO_HOME)) {\n mkdirSync(MINTO_HOME, { recursive: true })\n }\n writeFileSync(MINTO_SYNC_STATE_PATH, JSON.stringify(state, null, 2), 'utf-8')\n}\n\n// ---------------------------------------------------------------------------\n// Public \u2014 quick checks\n// ---------------------------------------------------------------------------\n\n/** Returns true if Claude Code is installed with plugins */\nexport function hasClaudeCodeInstallation(): boolean {\n return existsSync(CC_REGISTRY_PATH)\n}\n\n/** Returns total plugin count in CC registry (for prompts) */\nexport function getClaudeCodePluginCount(): number {\n const registry = loadCCRegistry()\n if (!registry) return 0\n return Object.keys(registry.plugins).length\n}\n\n/**\n * Fast check: does Minto need to sync from CC?\n * O(1) \u2014 only stats one file.\n */\nexport function needsSync(): boolean {\n if (!existsSync(CC_REGISTRY_PATH)) return false\n\n const state = loadSyncState()\n if (!state) return true // never synced\n\n try {\n const stat = statSync(CC_REGISTRY_PATH)\n const mtime = stat.mtime.toISOString()\n return mtime !== state.lastRegistryModified\n } catch {\n return false\n }\n}\n\n// ---------------------------------------------------------------------------\n// Core \u2014 copy plugin from CC cache\n// ---------------------------------------------------------------------------\n\nconst EXCLUDE_PATTERNS = new Set([\n '.git',\n '.orphaned_at',\n '.DS_Store',\n 'node_modules',\n '.github',\n])\n\nfunction shouldCopy(src: string): boolean {\n const name = basename(src)\n return !EXCLUDE_PATTERNS.has(name)\n}\n\nfunction copyPluginFromCache(sourcePath: string, targetPath: string): void {\n if (!existsSync(sourcePath)) {\n throw new Error(`Source path does not exist: ${sourcePath}`)\n }\n\n if (!existsSync(targetPath)) {\n mkdirSync(targetPath, { recursive: true })\n }\n\n cpSync(sourcePath, targetPath, {\n recursive: true,\n filter: shouldCopy,\n })\n}\n\n// ---------------------------------------------------------------------------\n// Core \u2014 generate Minto plugin.json from CC metadata\n// ---------------------------------------------------------------------------\n\ninterface MarketplacePluginMeta {\n name: string\n description?: string\n version?: string\n author?: string | { name: string; url?: string; email?: string }\n homepage?: string\n repository?: string\n license?: string\n keywords?: string[]\n category?: string\n}\n\nfunction loadMarketplacePluginMeta(\n marketplaceName: string,\n pluginName: string,\n): MarketplacePluginMeta | null {\n const knownMPs = loadCCKnownMarketplaces()\n if (!knownMPs) return null\n\n const mp = knownMPs[marketplaceName]\n if (!mp?.installLocation) return null\n\n // Try .claude-plugin/marketplace.json\n const mpJsonPath = join(\n mp.installLocation,\n '.claude-plugin',\n 'marketplace.json',\n )\n if (!existsSync(mpJsonPath)) return null\n\n try {\n const manifest = JSON.parse(readFileSync(mpJsonPath, 'utf-8'))\n const plugins: MarketplacePluginMeta[] = manifest.plugins || []\n return plugins.find(p => p.name === pluginName) ?? null\n } catch {\n return null\n }\n}\n\nfunction generatePluginManifest(\n pluginName: string,\n marketplace: string,\n ccEntry: CCPluginEntry,\n meta: MarketplacePluginMeta | null,\n): Record<string, unknown> {\n // Scan for component directories\n const agents: string[] = []\n const commands: string[] = []\n const skills: string[] = []\n\n const agentsDir = join(ccEntry.installPath, 'agents')\n if (existsSync(agentsDir)) {\n try {\n agents.push(\n ...readdirSync(agentsDir)\n .filter(f => f.endsWith('.md'))\n .map(f => `agents/${f}`),\n )\n } catch {\n /* ignore */\n }\n }\n\n const commandsDir = join(ccEntry.installPath, 'commands')\n if (existsSync(commandsDir)) {\n try {\n commands.push(\n ...readdirSync(commandsDir)\n .filter(f => f.endsWith('.md'))\n .map(f => `commands/${f}`),\n )\n } catch {\n /* ignore */\n }\n }\n\n const skillsDir = join(ccEntry.installPath, 'skills')\n if (existsSync(skillsDir)) {\n try {\n for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n const skillMd = join(skillsDir, entry.name, 'SKILL.md')\n if (existsSync(skillMd)) {\n skills.push(`skills/${entry.name}/SKILL.md`)\n }\n } else if (entry.isFile() && entry.name.endsWith('.md')) {\n skills.push(`skills/${entry.name}`)\n }\n }\n } catch {\n /* ignore */\n }\n }\n\n return {\n name: pluginName,\n version: meta?.version || ccEntry.version || '1.0.0',\n description: meta?.description || `Claude Code plugin: ${pluginName}`,\n displayName: pluginName,\n author: meta?.author,\n homepage: meta?.homepage,\n repository: meta?.repository,\n license: meta?.license,\n agents,\n commands,\n skills,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Core \u2014 sync a single plugin\n// ---------------------------------------------------------------------------\n\ntype SyncAction = 'installed' | 'updated' | 'skipped'\n\nfunction syncSinglePlugin(\n pluginName: string,\n marketplace: string,\n entry: CCPluginEntry,\n enabled: boolean,\n syncState: CCSyncState | null,\n dryRun: boolean,\n knownMarketplaces: Record<string, CCKnownMarketplace> | null,\n): SyncAction {\n const targetPath = join(MINTO_PLUGINS_DIR, pluginName)\n const ccSyncPath = join(targetPath, '.cc-sync.json')\n\n // Conflict check: plugin exists without .cc-sync.json \u2192 manually installed, skip\n if (existsSync(targetPath) && !existsSync(ccSyncPath)) {\n return 'skipped'\n }\n\n // Already synced and up to date?\n if (existsSync(ccSyncPath)) {\n try {\n const existing = JSON.parse(readFileSync(ccSyncPath, 'utf-8'))\n if (\n existing.version === entry.version &&\n existing.gitCommitSha === entry.gitCommitSha\n ) {\n return 'skipped'\n }\n } catch {\n /* re-sync on corrupt file */\n }\n }\n\n const isUpdate = existsSync(targetPath)\n\n if (dryRun) {\n return isUpdate ? 'updated' : 'installed'\n }\n\n // Clear target for update\n if (isUpdate) {\n rmSync(targetPath, { recursive: true, force: true })\n }\n\n // Copy from CC cache\n copyPluginFromCache(entry.installPath, targetPath)\n\n // Generate plugin.json in .minto-plugin/ (highest priority for loadManifest)\n const meta = loadMarketplacePluginMeta(marketplace, pluginName)\n const manifest = generatePluginManifest(pluginName, marketplace, entry, meta)\n const mintoPluginDir = join(targetPath, '.minto-plugin')\n mkdirSync(mintoPluginDir, { recursive: true })\n writeFileSync(\n join(mintoPluginDir, 'plugin.json'),\n JSON.stringify(manifest, null, 2),\n 'utf-8',\n )\n\n // Write .marketplace-meta.json with real source info when available\n const realSource = resolveMarketplaceSource(marketplace, knownMarketplaces)\n writeFileSync(\n join(targetPath, '.marketplace-meta.json'),\n JSON.stringify(\n {\n marketplace,\n plugin: pluginName,\n installedAt: new Date().toISOString(),\n source: realSource ?? { source: 'claude-code' },\n ...(realSource ? { syncedFrom: 'claude-code' } : {}),\n },\n null,\n 2,\n ),\n 'utf-8',\n )\n\n // Write .cc-sync.json\n writeFileSync(\n join(targetPath, '.cc-sync.json'),\n JSON.stringify(\n {\n name: pluginName,\n version: entry.version,\n gitCommitSha: entry.gitCommitSha,\n marketplace,\n syncedAt: new Date().toISOString(),\n source: entry.installPath,\n },\n null,\n 2,\n ),\n 'utf-8',\n )\n\n // Write .plugin-config.json (enabled state)\n writeFileSync(\n join(targetPath, '.plugin-config.json'),\n JSON.stringify({ enabled }, null, 2),\n 'utf-8',\n )\n\n return isUpdate ? 'updated' : 'installed'\n}\n\n// ---------------------------------------------------------------------------\n// Public \u2014 full sync\n// ---------------------------------------------------------------------------\n\nexport async function syncFromClaudeCode(\n options: SyncOptions = {},\n): Promise<SyncResult> {\n const { force = false, clean = false, dryRun = false, onProgress } = options\n\n const result: SyncResult = {\n installed: [],\n updated: [],\n skipped: [],\n failed: [],\n cleaned: [],\n total: 0,\n marketplaces: { registered: [], skipped: [], failed: [] },\n }\n\n // Load CC data\n const registry = loadCCRegistry()\n if (!registry) {\n return result\n }\n\n const settings = loadCCSettings()\n const enabledPlugins = settings.enabledPlugins || {}\n const syncState = force ? null : loadSyncState()\n const knownMarketplaces = loadCCKnownMarketplaces()\n\n // Ensure plugins directory\n if (!existsSync(MINTO_PLUGINS_DIR)) {\n mkdirSync(MINTO_PLUGINS_DIR, { recursive: true })\n }\n\n // Migrate: promote root plugin.json \u2192 .minto-plugin/plugin.json for older syncs\n try {\n for (const dir of readdirSync(MINTO_PLUGINS_DIR, { withFileTypes: true })) {\n if (!dir.isDirectory()) continue\n const pluginDir = join(MINTO_PLUGINS_DIR, dir.name)\n const rootManifest = join(pluginDir, 'plugin.json')\n const mintoManifest = join(pluginDir, '.minto-plugin', 'plugin.json')\n const ccSyncMarker = join(pluginDir, '.cc-sync.json')\n if (\n existsSync(ccSyncMarker) &&\n existsSync(rootManifest) &&\n !existsSync(mintoManifest)\n ) {\n mkdirSync(join(pluginDir, '.minto-plugin'), { recursive: true })\n cpSync(rootManifest, mintoManifest)\n }\n }\n } catch {\n /* non-fatal */\n }\n\n onProgress?.('Scanning Claude Code registry...')\n\n // Process each CC plugin\n const pluginKeys = Object.keys(registry.plugins)\n result.total = pluginKeys.length\n\n for (const pluginKey of pluginKeys) {\n // Parse \"name@marketplace\"\n const atIdx = pluginKey.indexOf('@')\n if (atIdx === -1) continue\n const pluginName = pluginKey.slice(0, atIdx)\n const marketplace = pluginKey.slice(atIdx + 1)\n\n // Get the user-scope entry (prefer user over project)\n const entries = registry.plugins[pluginKey]\n const entry = entries.find(e => e.scope === 'user') || entries[0]\n if (!entry) continue\n\n const enabled = enabledPlugins[pluginKey] !== false\n\n try {\n onProgress?.(\n existsSync(join(MINTO_PLUGINS_DIR, pluginName))\n ? `Updating ${pluginName}...`\n : `Installing ${pluginName}...`,\n )\n\n const action = syncSinglePlugin(\n pluginName,\n marketplace,\n entry,\n enabled,\n syncState,\n dryRun,\n knownMarketplaces,\n )\n\n switch (action) {\n case 'installed':\n result.installed.push(pluginName)\n break\n case 'updated':\n result.updated.push(pluginName)\n break\n case 'skipped':\n result.skipped.push(pluginName)\n break\n }\n } catch (err) {\n result.failed.push({\n name: pluginName,\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n\n // Clean orphans: CC-synced plugins that are no longer in CC registry\n if (clean && !dryRun && existsSync(MINTO_PLUGINS_DIR)) {\n const ccPluginNames = new Set(\n pluginKeys.map(k => k.slice(0, k.indexOf('@'))),\n )\n\n for (const dir of readdirSync(MINTO_PLUGINS_DIR)) {\n const pluginPath = join(MINTO_PLUGINS_DIR, dir)\n const ccSyncPath = join(pluginPath, '.cc-sync.json')\n\n if (!existsSync(ccSyncPath)) continue // not CC-synced\n if (ccPluginNames.has(dir)) continue // still in CC\n\n rmSync(pluginPath, { recursive: true, force: true })\n result.cleaned.push(dir)\n }\n }\n\n // Sync marketplaces from CC \u2192 Minto registry (non-blocking)\n try {\n onProgress?.('Syncing marketplaces...')\n result.marketplaces = syncMarketplaces(\n knownMarketplaces,\n dryRun,\n onProgress,\n )\n } catch {\n // Never block plugin sync if marketplace sync fails\n }\n\n // Save sync state\n if (!dryRun) {\n const registryStat = statSync(CC_REGISTRY_PATH)\n const newState: CCSyncState = {\n lastSyncedAt: new Date().toISOString(),\n lastRegistryModified: registryStat.mtime.toISOString(),\n plugins: {},\n }\n\n // Rebuild state from what's now on disk\n if (existsSync(MINTO_PLUGINS_DIR)) {\n for (const dir of readdirSync(MINTO_PLUGINS_DIR)) {\n const ccSyncPath = join(MINTO_PLUGINS_DIR, dir, '.cc-sync.json')\n if (!existsSync(ccSyncPath)) continue\n try {\n const meta = JSON.parse(readFileSync(ccSyncPath, 'utf-8'))\n newState.plugins[dir] = {\n version: meta.version,\n gitCommitSha: meta.gitCommitSha,\n syncedAt: meta.syncedAt,\n marketplace: meta.marketplace,\n }\n } catch {\n /* ignore corrupt */\n }\n }\n }\n\n saveSyncState(newState)\n }\n\n return result\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/utils/config.js
CHANGED
|
@@ -40,23 +40,6 @@ function getVerboseLabel(verbose) {
|
|
|
40
40
|
return verbose ? "Verbose: On" : "Verbose: Off";
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
function getDisplayModeLabel(mode) {
|
|
44
|
-
return mode === "detailed" ? "Verbose: On" : "Verbose: Off";
|
|
45
|
-
}
|
|
46
|
-
const DISPLAY_MODE_LABELS = {
|
|
47
|
-
minimal: "Verbose: Off",
|
|
48
|
-
compact: "Verbose: Off",
|
|
49
|
-
detailed: "Verbose: On"
|
|
50
|
-
};
|
|
51
|
-
function getNextDisplayMode(current) {
|
|
52
|
-
return current === "detailed" ? "compact" : "detailed";
|
|
53
|
-
}
|
|
54
|
-
function displayModeToVerbose(mode) {
|
|
55
|
-
return mode === "detailed";
|
|
56
|
-
}
|
|
57
|
-
function verboseToDisplayMode(verbose) {
|
|
58
|
-
return verbose ? "detailed" : "compact";
|
|
59
|
-
}
|
|
60
43
|
const DEFAULT_GLOBAL_CONFIG = {
|
|
61
44
|
numStartups: 0,
|
|
62
45
|
autoUpdaterStatus: "not_configured",
|
|
@@ -181,7 +164,39 @@ function getGlobalConfig() {
|
|
|
181
164
|
}
|
|
182
165
|
const config = getConfig(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG);
|
|
183
166
|
const migratedConfig = migrateModelProfilesRemoveId(config);
|
|
184
|
-
|
|
167
|
+
const displayMigratedConfig = migrateDisplayModeToVerbose(migratedConfig);
|
|
168
|
+
if (displayMigratedConfig.modelProfiles && displayMigratedConfig.modelProfiles.length > 0) {
|
|
169
|
+
const originalCount = displayMigratedConfig.modelProfiles.length;
|
|
170
|
+
const deduplicatedProfiles = deduplicateModelProfiles(
|
|
171
|
+
displayMigratedConfig.modelProfiles
|
|
172
|
+
);
|
|
173
|
+
const deduplicatedCount = deduplicatedProfiles.length;
|
|
174
|
+
if (deduplicatedCount < originalCount) {
|
|
175
|
+
debugLogger.state("CONFIG_DEDUPLICATE_PROFILES", {
|
|
176
|
+
originalCount: String(originalCount),
|
|
177
|
+
deduplicatedCount: String(deduplicatedCount),
|
|
178
|
+
removedCount: String(originalCount - deduplicatedCount)
|
|
179
|
+
});
|
|
180
|
+
const configToSave = {
|
|
181
|
+
...displayMigratedConfig,
|
|
182
|
+
modelProfiles: deduplicatedProfiles
|
|
183
|
+
};
|
|
184
|
+
saveConfig(
|
|
185
|
+
GLOBAL_CONFIG_FILE,
|
|
186
|
+
{
|
|
187
|
+
...configToSave,
|
|
188
|
+
projects: config.projects
|
|
189
|
+
},
|
|
190
|
+
DEFAULT_GLOBAL_CONFIG
|
|
191
|
+
);
|
|
192
|
+
return configToSave;
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
...displayMigratedConfig,
|
|
196
|
+
modelProfiles: deduplicatedProfiles
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
return displayMigratedConfig;
|
|
185
200
|
}
|
|
186
201
|
function getAnthropicApiKey() {
|
|
187
202
|
return process.env.ANTHROPIC_API_KEY || null;
|
|
@@ -547,6 +562,23 @@ function migrateModelProfilesRemoveId(config) {
|
|
|
547
562
|
defaultModelName
|
|
548
563
|
};
|
|
549
564
|
}
|
|
565
|
+
function deduplicateModelProfiles(profiles) {
|
|
566
|
+
if (!profiles || profiles.length === 0) {
|
|
567
|
+
return [];
|
|
568
|
+
}
|
|
569
|
+
const profileMap = /* @__PURE__ */ new Map();
|
|
570
|
+
for (const profile of profiles) {
|
|
571
|
+
const existing = profileMap.get(profile.modelName);
|
|
572
|
+
if (!existing) {
|
|
573
|
+
profileMap.set(profile.modelName, profile);
|
|
574
|
+
} else {
|
|
575
|
+
if (profile.createdAt > existing.createdAt) {
|
|
576
|
+
profileMap.set(profile.modelName, profile);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return Array.from(profileMap.values());
|
|
581
|
+
}
|
|
550
582
|
function setAllPointersToModel(modelName) {
|
|
551
583
|
const config = getGlobalConfig();
|
|
552
584
|
const updatedConfig = {
|
|
@@ -721,7 +753,6 @@ function createGPT5ModelProfile(name, modelName, apiKey, baseURL, provider = "op
|
|
|
721
753
|
}
|
|
722
754
|
export {
|
|
723
755
|
DEFAULT_GLOBAL_CONFIG,
|
|
724
|
-
DISPLAY_MODE_LABELS,
|
|
725
756
|
GLOBAL_CONFIG_KEYS,
|
|
726
757
|
PROJECT_CONFIG_KEYS,
|
|
727
758
|
TEST_MCPRC_CONFIG_FOR_TESTING,
|
|
@@ -729,18 +760,16 @@ export {
|
|
|
729
760
|
checkHasTrustDialogAccepted,
|
|
730
761
|
clearMcprcConfigForTesting,
|
|
731
762
|
createGPT5ModelProfile,
|
|
763
|
+
deduplicateModelProfiles,
|
|
732
764
|
deleteConfigForCLI,
|
|
733
|
-
displayModeToVerbose,
|
|
734
765
|
enableConfigs,
|
|
735
766
|
getAnthropicApiKey,
|
|
736
767
|
getConfigForCLI,
|
|
737
768
|
getCurrentProjectConfig,
|
|
738
769
|
getCustomApiKeyStatus,
|
|
739
|
-
getDisplayModeLabel,
|
|
740
770
|
getGPT5ConfigRecommendations,
|
|
741
771
|
getGlobalConfig,
|
|
742
772
|
getMcprcConfig,
|
|
743
|
-
getNextDisplayMode,
|
|
744
773
|
getOpenAIApiKey,
|
|
745
774
|
getOrCreateUserID,
|
|
746
775
|
getVerboseLabel,
|
|
@@ -759,7 +788,6 @@ export {
|
|
|
759
788
|
setConfigForCLI,
|
|
760
789
|
setModelPointer,
|
|
761
790
|
validateAndRepairAllGPT5Profiles,
|
|
762
|
-
validateAndRepairGPT5Profile
|
|
763
|
-
verboseToDisplayMode
|
|
791
|
+
validateAndRepairGPT5Profile
|
|
764
792
|
};
|
|
765
793
|
//# sourceMappingURL=config.js.map
|