Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- src/commands/add-dir/add-dir.tsx +126 -0
- src/commands/add-dir/index.ts +11 -0
- src/commands/agents/agents.tsx +12 -0
- src/commands/agents/index.ts +10 -0
- src/commands/ant-trace/index.js +1 -0
- src/commands/autofix-pr/index.js +1 -0
- src/commands/branch/branch.ts +296 -0
- src/commands/branch/index.ts +14 -0
- src/commands/break-cache/index.js +1 -0
- src/commands/btw/index.ts +13 -0
- src/commands/chrome/index.ts +13 -0
- src/commands/clear/clear.ts +7 -0
- src/commands/clear/index.ts +19 -0
- src/commands/color/color.ts +93 -0
- src/commands/mcp/addCommand.ts +280 -0
- src/commands/mcp/index.ts +12 -0
- src/commands/mcp/mcp.tsx +85 -0
- src/commands/mcp/xaaIdpCommand.ts +266 -0
- src/commands/memory/index.ts +10 -0
- src/commands/memory/memory.tsx +90 -0
- src/commands/mobile/index.ts +11 -0
- src/commands/mobile/mobile.tsx +274 -0
- src/commands/mock-limits/index.js +1 -0
- src/commands/model/index.ts +16 -0
- src/commands/model/model.tsx +297 -0
- src/commands/oauth-refresh/index.js +1 -0
- src/commands/onboarding/index.js +1 -0
- src/commands/output-style/index.ts +11 -0
- src/commands/output-style/output-style.tsx +7 -0
- src/commands/passes/index.ts +22 -0
- src/commands/passes/passes.tsx +24 -0
- src/commands/perf-issue/index.js +1 -0
- src/commands/permissions/index.ts +11 -0
- src/commands/permissions/permissions.tsx +10 -0
- src/commands/plan/index.ts +11 -0
- src/commands/plan/plan.tsx +122 -0
- src/commands/plugin/AddMarketplace.tsx +162 -0
- src/commands/plugin/BrowseMarketplace.tsx +0 -0
- src/commands/plugin/DiscoverPlugins.tsx +0 -0
- src/commands/plugin/ManageMarketplaces.tsx +0 -0
- src/commands/plugin/ManagePlugins.tsx +0 -0
- src/commands/plugin/PluginErrors.tsx +124 -0
- src/commands/plugin/PluginOptionsDialog.tsx +357 -0
- src/commands/plugin/PluginOptionsFlow.tsx +135 -0
- src/commands/plugin/PluginSettings.tsx +0 -0
- src/commands/plugin/PluginTrustWarning.tsx +32 -0
- src/commands/plugin/UnifiedInstalledCell.tsx +565 -0
- src/commands/plugin/ValidatePlugin.tsx +98 -0
- src/commands/plugin/index.tsx +11 -0
- src/commands/plugin/parseArgs.ts +103 -0
src/commands/add-dir/add-dir.tsx
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { c as _c } from "react/compiler-runtime";
|
| 2 |
+
import chalk from 'chalk';
|
| 3 |
+
import figures from 'figures';
|
| 4 |
+
import React, { useEffect } from 'react';
|
| 5 |
+
import { getAdditionalDirectoriesForClaudeMd, setAdditionalDirectoriesForClaudeMd } from '../../bootstrap/state.js';
|
| 6 |
+
import type { LocalJSXCommandContext } from '../../commands.js';
|
| 7 |
+
import { MessageResponse } from '../../components/MessageResponse.js';
|
| 8 |
+
import { AddWorkspaceDirectory } from '../../components/permissions/rules/AddWorkspaceDirectory.js';
|
| 9 |
+
import { Box, Text } from '../../ink.js';
|
| 10 |
+
import type { LocalJSXCommandOnDone } from '../../types/command.js';
|
| 11 |
+
import { applyPermissionUpdate, persistPermissionUpdate } from '../../utils/permissions/PermissionUpdate.js';
|
| 12 |
+
import type { PermissionUpdateDestination } from '../../utils/permissions/PermissionUpdateSchema.js';
|
| 13 |
+
import { SandboxManager } from '../../utils/sandbox/sandbox-adapter.js';
|
| 14 |
+
import { addDirHelpMessage, validateDirectoryForWorkspace } from './validation.js';
|
| 15 |
+
function AddDirError(t0) {
|
| 16 |
+
const $ = _c(10);
|
| 17 |
+
const {
|
| 18 |
+
message,
|
| 19 |
+
args,
|
| 20 |
+
onDone
|
| 21 |
+
} = t0;
|
| 22 |
+
let t1;
|
| 23 |
+
let t2;
|
| 24 |
+
if ($[0] !== onDone) {
|
| 25 |
+
t1 = () => {
|
| 26 |
+
const timer = setTimeout(onDone, 0);
|
| 27 |
+
return () => clearTimeout(timer);
|
| 28 |
+
};
|
| 29 |
+
t2 = [onDone];
|
| 30 |
+
$[0] = onDone;
|
| 31 |
+
$[1] = t1;
|
| 32 |
+
$[2] = t2;
|
| 33 |
+
} else {
|
| 34 |
+
t1 = $[1];
|
| 35 |
+
t2 = $[2];
|
| 36 |
+
}
|
| 37 |
+
useEffect(t1, t2);
|
| 38 |
+
let t3;
|
| 39 |
+
if ($[3] !== args) {
|
| 40 |
+
t3 = <Text dimColor={true}>{figures.pointer} /add-dir {args}</Text>;
|
| 41 |
+
$[3] = args;
|
| 42 |
+
$[4] = t3;
|
| 43 |
+
} else {
|
| 44 |
+
t3 = $[4];
|
| 45 |
+
}
|
| 46 |
+
let t4;
|
| 47 |
+
if ($[5] !== message) {
|
| 48 |
+
t4 = <MessageResponse><Text>{message}</Text></MessageResponse>;
|
| 49 |
+
$[5] = message;
|
| 50 |
+
$[6] = t4;
|
| 51 |
+
} else {
|
| 52 |
+
t4 = $[6];
|
| 53 |
+
}
|
| 54 |
+
let t5;
|
| 55 |
+
if ($[7] !== t3 || $[8] !== t4) {
|
| 56 |
+
t5 = <Box flexDirection="column">{t3}{t4}</Box>;
|
| 57 |
+
$[7] = t3;
|
| 58 |
+
$[8] = t4;
|
| 59 |
+
$[9] = t5;
|
| 60 |
+
} else {
|
| 61 |
+
t5 = $[9];
|
| 62 |
+
}
|
| 63 |
+
return t5;
|
| 64 |
+
}
|
| 65 |
+
export async function call(onDone: LocalJSXCommandOnDone, context: LocalJSXCommandContext, args?: string): Promise<React.ReactNode> {
|
| 66 |
+
const directoryPath = (args ?? '').trim();
|
| 67 |
+
const appState = context.getAppState();
|
| 68 |
+
|
| 69 |
+
// Helper to handle adding a directory (shared by both with-path and no-path cases)
|
| 70 |
+
const handleAddDirectory = async (path: string, remember = false) => {
|
| 71 |
+
const destination: PermissionUpdateDestination = remember ? 'localSettings' : 'session';
|
| 72 |
+
const permissionUpdate = {
|
| 73 |
+
type: 'addDirectories' as const,
|
| 74 |
+
directories: [path],
|
| 75 |
+
destination
|
| 76 |
+
};
|
| 77 |
+
|
| 78 |
+
// Apply to session context
|
| 79 |
+
const latestAppState = context.getAppState();
|
| 80 |
+
const updatedContext = applyPermissionUpdate(latestAppState.toolPermissionContext, permissionUpdate);
|
| 81 |
+
context.setAppState(prev => ({
|
| 82 |
+
...prev,
|
| 83 |
+
toolPermissionContext: updatedContext
|
| 84 |
+
}));
|
| 85 |
+
|
| 86 |
+
// Update sandbox config so Bash commands can access the new directory.
|
| 87 |
+
// Bootstrap state is the source of truth for session-only dirs; persisted
|
| 88 |
+
// dirs are picked up via the settings subscription, but we refresh
|
| 89 |
+
// eagerly here to avoid a race when the user acts immediately.
|
| 90 |
+
const currentDirs = getAdditionalDirectoriesForClaudeMd();
|
| 91 |
+
if (!currentDirs.includes(path)) {
|
| 92 |
+
setAdditionalDirectoriesForClaudeMd([...currentDirs, path]);
|
| 93 |
+
}
|
| 94 |
+
SandboxManager.refreshConfig();
|
| 95 |
+
let message: string;
|
| 96 |
+
if (remember) {
|
| 97 |
+
try {
|
| 98 |
+
persistPermissionUpdate(permissionUpdate);
|
| 99 |
+
message = `Added ${chalk.bold(path)} as a working directory and saved to local settings`;
|
| 100 |
+
} catch (error) {
|
| 101 |
+
message = `Added ${chalk.bold(path)} as a working directory. Failed to save to local settings: ${error instanceof Error ? error.message : 'Unknown error'}`;
|
| 102 |
+
}
|
| 103 |
+
} else {
|
| 104 |
+
message = `Added ${chalk.bold(path)} as a working directory for this session`;
|
| 105 |
+
}
|
| 106 |
+
const messageWithHint = `${message} ${chalk.dim('· /permissions to manage')}`;
|
| 107 |
+
onDone(messageWithHint);
|
| 108 |
+
};
|
| 109 |
+
|
| 110 |
+
// When no path is provided, show AddWorkspaceDirectory input form directly
|
| 111 |
+
// and return to REPL after confirmation
|
| 112 |
+
if (!directoryPath) {
|
| 113 |
+
return <AddWorkspaceDirectory permissionContext={appState.toolPermissionContext} onAddDirectory={handleAddDirectory} onCancel={() => {
|
| 114 |
+
onDone('Did not add a working directory.');
|
| 115 |
+
}} />;
|
| 116 |
+
}
|
| 117 |
+
const result = await validateDirectoryForWorkspace(directoryPath, appState.toolPermissionContext);
|
| 118 |
+
if (result.resultType !== 'success') {
|
| 119 |
+
const message = addDirHelpMessage(result);
|
| 120 |
+
return <AddDirError message={message} args={args ?? ''} onDone={() => onDone(message)} />;
|
| 121 |
+
}
|
| 122 |
+
return <AddWorkspaceDirectory directoryPath={result.absolutePath} permissionContext={appState.toolPermissionContext} onAddDirectory={handleAddDirectory} onCancel={() => {
|
| 123 |
+
onDone(`Did not add ${chalk.bold(result.absolutePath)} as a working directory.`);
|
| 124 |
+
}} />;
|
| 125 |
+
}
|
| 126 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjaGFsayIsImZpZ3VyZXMiLCJSZWFjdCIsInVzZUVmZmVjdCIsImdldEFkZGl0aW9uYWxEaXJlY3Rvcmllc0ZvckNsYXVkZU1kIiwic2V0QWRkaXRpb25hbERpcmVjdG9yaWVzRm9yQ2xhdWRlTWQiLCJMb2NhbEpTWENvbW1hbmRDb250ZXh0IiwiTWVzc2FnZVJlc3BvbnNlIiwiQWRkV29ya3NwYWNlRGlyZWN0b3J5IiwiQm94IiwiVGV4dCIsIkxvY2FsSlNYQ29tbWFuZE9uRG9uZSIsImFwcGx5UGVybWlzc2lvblVwZGF0ZSIsInBlcnNpc3RQZXJtaXNzaW9uVXBkYXRlIiwiUGVybWlzc2lvblVwZGF0ZURlc3RpbmF0aW9uIiwiU2FuZGJveE1hbmFnZXIiLCJhZGREaXJIZWxwTWVzc2FnZSIsInZhbGlkYXRlRGlyZWN0b3J5Rm9yV29ya3NwYWNlIiwiQWRkRGlyRXJyb3IiLCJ0MCIsIiQiLCJfYyIsIm1lc3NhZ2UiLCJhcmdzIiwib25Eb25lIiwidDEiLCJ0MiIsInRpbWVyIiwic2V0VGltZW91dCIsImNsZWFyVGltZW91dCIsInQzIiwicG9pbnRlciIsInQ0IiwidDUiLCJjYWxsIiwiY29udGV4dCIsIlByb21pc2UiLCJSZWFjdE5vZGUiLCJkaXJlY3RvcnlQYXRoIiwidHJpbSIsImFwcFN0YXRlIiwiZ2V0QXBwU3RhdGUiLCJoYW5kbGVBZGREaXJlY3RvcnkiLCJwYXRoIiwicmVtZW1iZXIiLCJkZXN0aW5hdGlvbiIsInBlcm1pc3Npb25VcGRhdGUiLCJ0eXBlIiwiY29uc3QiLCJkaXJlY3RvcmllcyIsImxhdGVzdEFwcFN0YXRlIiwidXBkYXRlZENvbnRleHQiLCJ0b29sUGVybWlzc2lvbkNvbnRleHQiLCJzZXRBcHBTdGF0ZSIsInByZXYiLCJjdXJyZW50RGlycyIsImluY2x1ZGVzIiwicmVmcmVzaENvbmZpZyIsImJvbGQiLCJlcnJvciIsIkVycm9yIiwibWVzc2FnZVdpdGhIaW50IiwiZGltIiwicmVzdWx0IiwicmVzdWx0VHlwZSIsImFic29sdXRlUGF0aCJdLCJzb3VyY2VzIjpbImFkZC1kaXIudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjaGFsayBmcm9tICdjaGFsaydcbmltcG9ydCBmaWd1cmVzIGZyb20gJ2ZpZ3VyZXMnXG5pbXBvcnQgUmVhY3QsIHsgdXNlRWZmZWN0IH0gZnJvbSAncmVhY3QnXG5pbXBvcnQge1xuICBnZXRBZGRpdGlvbmFsRGlyZWN0b3JpZXNGb3JDbGF1ZGVNZCxcbiAgc2V0QWRkaXRpb25hbERpcmVjdG9yaWVzRm9yQ2xhdWRlTWQsXG59IGZyb20gJy4uLy4uL2Jvb3RzdHJhcC9zdGF0ZS5qcydcbmltcG9ydCB0eXBlIHsgTG9jYWxKU1hDb21tYW5kQ29udGV4dCB9IGZyb20gJy4uLy4uL2NvbW1hbmRzLmpzJ1xuaW1wb3J0IHsgTWVzc2FnZVJlc3BvbnNlIH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9NZXNzYWdlUmVzcG9uc2UuanMnXG5pbXBvcnQgeyBBZGRXb3Jrc3BhY2VEaXJlY3RvcnkgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL3Blcm1pc3Npb25zL3J1bGVzL0FkZFdvcmtzcGFjZURpcmVjdG9yeS5qcydcbmltcG9ydCB7IEJveCwgVGV4dCB9IGZyb20gJy4uLy4uL2luay5qcydcbmltcG9ydCB0eXBlIHsgTG9jYWxKU1hDb21tYW5kT25Eb25lIH0gZnJvbSAnLi4vLi4vdHlwZXMvY29tbWFuZC5qcydcbmltcG9ydCB7XG4gIGFwcGx5UGVybWlzc2lvblVwZGF0ZSxcbiAgcGVyc2lzdFBlcm1pc3Npb25VcGRhdGUsXG59IGZyb20gJy4uLy4uL3V0aWxzL3Blcm1pc3Npb25zL1Blcm1pc3Npb25VcGRhdGUuanMnXG5pbXBvcnQgdHlwZSB7IFBlcm1pc3Npb25VcGRhdGVEZXN0aW5hdGlvbiB9IGZyb20gJy4uLy4uL3V0aWxzL3Blcm1pc3Npb25zL1Blcm1pc3Npb25VcGRhdGVTY2hlbWEuanMnXG5pbXBvcnQgeyBTYW5kYm94TWFuYWdlciB9IGZyb20gJy4uLy4uL3V0aWxzL3NhbmRib3gvc2FuZGJveC1hZGFwdGVyLmpzJ1xuaW1wb3J0IHtcbiAgYWRkRGlySGVscE1lc3NhZ2UsXG4gIHZhbGlkYXRlRGlyZWN0b3J5Rm9yV29ya3NwYWNlLFxufSBmcm9tICcuL3ZhbGlkYXRpb24uanMnXG5cbmZ1bmN0aW9uIEFkZERpckVycm9yKHtcbiAgbWVzc2FnZSxcbiAgYXJncyxcbiAgb25Eb25lLFxufToge1xuICBtZXNzYWdlOiBzdHJpbmdcbiAgYXJnczogc3RyaW5nXG4gIG9uRG9uZTogKCkgPT4gdm9pZFxufSk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgLy8gV2UgbmVlZCB0byBkZWZlciBjYWxsaW5nIG9uRG9uZSB0byBhdm9pZCB0aGUgXCJyZXR1cm4gbnVsbFwiIGJ1ZyB3aGVyZVxuICAgIC8vIHRoZSBjb21wb25lbnQgdW5tb3VudHMgYmVmb3JlIFJlYWN0IGNhbiByZW5kZXIgdGhlIGVycm9yIG1lc3NhZ2UuXG4gICAgLy8gVXNpbmcgc2V0VGltZW91dCBlbnN1cmVzIHRoZSBlcnJvciBkaXNwbGF5cyBiZWZvcmUgdGhlIGNvbW1hbmQgZXhpdHMuXG4gICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KG9uRG9uZSwgMClcbiAgICByZXR1cm4gKCkgPT4gY2xlYXJUaW1lb3V0KHRpbWVyKVxuICB9LCBbb25Eb25lXSlcblxuICByZXR1cm4gKFxuICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiPlxuICAgICAgPFRleHQgZGltQ29sb3I+XG4gICAgICAgIHtmaWd1cmVzLnBvaW50ZXJ9IC9hZGQtZGlyIHthcmdzfVxuICAgICAgPC9UZXh0PlxuICAgICAgPE1lc3NhZ2VSZXNwb25zZT5cbiAgICAgICAgPFRleHQ+e21lc3NhZ2V9PC9UZXh0PlxuICAgICAgPC9NZXNzYWdlUmVzcG9uc2U+XG4gICAgPC9Cb3g+XG4gIClcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNhbGwoXG4gIG9uRG9uZTogTG9jYWxKU1hDb21tYW5kT25Eb25lLFxuICBjb250ZXh0OiBMb2NhbEpTWENvbW1hbmRDb250ZXh0LFxuICBhcmdzPzogc3RyaW5nLFxuKTogUHJvbWlzZTxSZWFjdC5SZWFjdE5vZGU+IHtcbiAgY29uc3QgZGlyZWN0b3J5UGF0aCA9IChhcmdzID8/ICcnKS50cmltKClcbiAgY29uc3QgYXBwU3RhdGUgPSBjb250ZXh0LmdldEFwcFN0YXRlKClcblxuICAvLyBIZWxwZXIgdG8gaGFuZGxlIGFkZGluZyBhIGRpcmVjdG9yeSAoc2hhcmVkIGJ5IGJvdGggd2l0aC1wYXRoIGFuZCBuby1wYXRoIGNhc2VzKVxuICBjb25zdCBoYW5kbGVBZGREaXJlY3RvcnkgPSBhc3luYyAocGF0aDogc3RyaW5nLCByZW1lbWJlciA9IGZhbHNlKSA9PiB7XG4gICAgY29uc3QgZGVzdGluYXRpb246IFBlcm1pc3Npb25VcGRhdGVEZXN0aW5hdGlvbiA9IHJlbWVtYmVyXG4gICAgICA/ICdsb2NhbFNldHRpbmdzJ1xuICAgICAgOiAnc2Vzc2lvbidcblxuICAgIGNvbnN0IHBlcm1pc3Npb25VcGRhdGUgPSB7XG4gICAgICB0eXBlOiAnYWRkRGlyZWN0b3JpZXMnIGFzIGNvbnN0LFxuICAgICAgZGlyZWN0b3JpZXM6IFtwYXRoXSxcbiAgICAgIGRlc3RpbmF0aW9uLFxuICAgIH1cblxuICAgIC8vIEFwcGx5IHRvIHNlc3Npb24gY29udGV4dFxuICAgIGNvbnN0IGxhdGVzdEFwcFN0YXRlID0gY29udGV4dC5nZXRBcHBTdGF0ZSgpXG4gICAgY29uc3QgdXBkYXRlZENvbnRleHQgPSBhcHBseVBlcm1pc3Npb25VcGRhdGUoXG4gICAgICBsYXRlc3RBcHBTdGF0ZS50b29sUGVybWlzc2lvbkNvbnRleHQsXG4gICAgICBwZXJtaXNzaW9uVXBkYXRlLFxuICAgIClcbiAgICBjb250ZXh0LnNldEFwcFN0YXRlKHByZXYgPT4gKHtcbiAgICAgIC4uLnByZXYsXG4gICAgICB0b29sUGVybWlzc2lvbkNvbnRleHQ6IHVwZGF0ZWRDb250ZXh0LFxuICAgIH0pKVxuXG4gICAgLy8gVXBkYXRlIHNhbmRib3ggY29uZmlnIHNvIEJhc2ggY29tbWFuZHMgY2FuIGFjY2VzcyB0aGUgbmV3IGRpcmVjdG9yeS5cbiAgICAvLyBCb290c3RyYXAgc3RhdGUgaXMgdGhlIHNvdXJjZSBvZiB0cnV0aCBmb3Igc2Vzc2lvbi1vbmx5IGRpcnM7IHBlcnNpc3RlZFxuICAgIC8vIGRpcnMgYXJlIHBpY2tlZCB1cCB2aWEgdGhlIHNldHRpbmdzIHN1YnNjcmlwdGlvbiwgYnV0IHdlIHJlZnJlc2hcbiAgICAvLyBlYWdlcmx5IGhlcmUgdG8gYXZvaWQgYSByYWNlIHdoZW4gdGhlIHVzZXIgYWN0cyBpbW1lZGlhdGVseS5cbiAgICBjb25zdCBjdXJyZW50RGlycyA9IGdldEFkZGl0aW9uYWxEaXJlY3Rvcmllc0ZvckNsYXVkZU1kKClcbiAgICBpZiAoIWN1cnJlbnREaXJzLmluY2x1ZGVzKHBhdGgpKSB7XG4gICAgICBzZXRBZGRpdGlvbmFsRGlyZWN0b3JpZXNGb3JDbGF1ZGVNZChbLi4uY3VycmVudERpcnMsIHBhdGhdKVxuICAgIH1cbiAgICBTYW5kYm94TWFuYWdlci5yZWZyZXNoQ29uZmlnKClcblxuICAgIGxldCBtZXNzYWdlOiBzdHJpbmdcblxuICAgIGlmIChyZW1lbWJlcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcGVyc2lzdFBlcm1pc3Npb25VcGRhdGUocGVybWlzc2lvblVwZGF0ZSlcbiAgICAgICAgbWVzc2FnZSA9IGBBZGRlZCAke2NoYWxrLmJvbGQocGF0aCl9IGFzIGEgd29ya2luZyBkaXJlY3RvcnkgYW5kIHNhdmVkIHRvIGxvY2FsIHNldHRpbmdzYFxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbWVzc2FnZSA9IGBBZGRlZCAke2NoYWxrLmJvbGQocGF0aCl9IGFzIGEgd29ya2luZyBkaXJlY3RvcnkuIEZhaWxlZCB0byBzYXZlIHRvIGxvY2FsIHNldHRpbmdzOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InfWBcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbWVzc2FnZSA9IGBBZGRlZCAke2NoYWxrLmJvbGQocGF0aCl9IGFzIGEgd29ya2luZyBkaXJlY3RvcnkgZm9yIHRoaXMgc2Vzc2lvbmBcbiAgICB9XG5cbiAgICBjb25zdCBtZXNzYWdlV2l0aEhpbnQgPSBgJHttZXNzYWdlfSAke2NoYWxrLmRpbSgnwrcgL3Blcm1pc3Npb25zIHRvIG1hbmFnZScpfWBcbiAgICBvbkRvbmUobWVzc2FnZVdpdGhIaW50KVxuICB9XG5cbiAgLy8gV2hlbiBubyBwYXRoIGlzIHByb3ZpZGVkLCBzaG93IEFkZFdvcmtzcGFjZURpcmVjdG9yeSBpbnB1dCBmb3JtIGRpcmVjdGx5XG4gIC8vIGFuZCByZXR1cm4gdG8gUkVQTCBhZnRlciBjb25maXJtYXRpb25cbiAgaWYgKCFkaXJlY3RvcnlQYXRoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxBZGRXb3Jrc3BhY2VEaXJlY3RvcnlcbiAgICAgICAgcGVybWlzc2lvbkNvbnRleHQ9e2FwcFN0YXRlLnRvb2xQZXJtaXNzaW9uQ29udGV4dH1cbiAgICAgICAgb25BZGREaXJlY3Rvcnk9e2hhbmRsZUFkZERpcmVjdG9yeX1cbiAgICAgICAgb25DYW5jZWw9eygpID0+IHtcbiAgICAgICAgICBvbkRvbmUoJ0RpZCBub3QgYWRkIGEgd29ya2luZyBkaXJlY3RvcnkuJylcbiAgICAgICAgfX1cbiAgICAgIC8+XG4gICAgKVxuICB9XG5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmFsaWRhdGVEaXJlY3RvcnlGb3JXb3Jrc3BhY2UoXG4gICAgZGlyZWN0b3J5UGF0aCxcbiAgICBhcHBTdGF0ZS50b29sUGVybWlzc2lvbkNvbnRleHQsXG4gIClcblxuICBpZiAocmVzdWx0LnJlc3VsdFR5cGUgIT09ICdzdWNjZXNzJykge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBhZGREaXJIZWxwTWVzc2FnZShyZXN1bHQpXG5cbiAgICByZXR1cm4gKFxuICAgICAgPEFkZERpckVycm9yXG4gICAgICAgIG1lc3NhZ2U9e21lc3NhZ2V9XG4gICAgICAgIGFyZ3M9e2FyZ3MgPz8gJyd9XG4gICAgICAgIG9uRG9uZT17KCkgPT4gb25Eb25lKG1lc3NhZ2UpfVxuICAgICAgLz5cbiAgICApXG4gIH1cblxuICByZXR1cm4gKFxuICAgIDxBZGRXb3Jrc3BhY2VEaXJlY3RvcnlcbiAgICAgIGRpcmVjdG9yeVBhdGg9e3Jlc3VsdC5hYnNvbHV0ZVBhdGh9XG4gICAgICBwZXJtaXNzaW9uQ29udGV4dD17YXBwU3RhdGUudG9vbFBlcm1pc3Npb25Db250ZXh0fVxuICAgICAgb25BZGREaXJlY3Rvcnk9e2hhbmRsZUFkZERpcmVjdG9yeX1cbiAgICAgIG9uQ2FuY2VsPXsoKSA9PiB7XG4gICAgICAgIG9uRG9uZShcbiAgICAgICAgICBgRGlkIG5vdCBhZGQgJHtjaGFsay5ib2xkKHJlc3VsdC5hYnNvbHV0ZVBhdGgpfSBhcyBhIHdvcmtpbmcgZGlyZWN0b3J5LmAsXG4gICAgICAgIClcbiAgICAgIH19XG4gICAgLz5cbiAgKVxufVxuIl0sIm1hcHBpbmdzIjoiO0FBQUEsT0FBT0EsS0FBSyxNQUFNLE9BQU87QUFDekIsT0FBT0MsT0FBTyxNQUFNLFNBQVM7QUFDN0IsT0FBT0MsS0FBSyxJQUFJQyxTQUFTLFFBQVEsT0FBTztBQUN4QyxTQUNFQyxtQ0FBbUMsRUFDbkNDLG1DQUFtQyxRQUM5QiwwQkFBMEI7QUFDakMsY0FBY0Msc0JBQXNCLFFBQVEsbUJBQW1CO0FBQy9ELFNBQVNDLGVBQWUsUUFBUSxxQ0FBcUM7QUFDckUsU0FBU0MscUJBQXFCLFFBQVEsNkRBQTZEO0FBQ25HLFNBQVNDLEdBQUcsRUFBRUMsSUFBSSxRQUFRLGNBQWM7QUFDeEMsY0FBY0MscUJBQXFCLFFBQVEsd0JBQXdCO0FBQ25FLFNBQ0VDLHFCQUFxQixFQUNyQkMsdUJBQXVCLFFBQ2xCLDZDQUE2QztBQUNwRCxjQUFjQywyQkFBMkIsUUFBUSxtREFBbUQ7QUFDcEcsU0FBU0MsY0FBYyxRQUFRLHdDQUF3QztBQUN2RSxTQUNFQyxp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
|
src/commands/add-dir/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js'
|
| 2 |
+
|
| 3 |
+
const addDir = {
|
| 4 |
+
type: 'local-jsx',
|
| 5 |
+
name: 'add-dir',
|
| 6 |
+
description: 'Add a new working directory',
|
| 7 |
+
argumentHint: '<path>',
|
| 8 |
+
load: () => import('./add-dir.js'),
|
| 9 |
+
} satisfies Command
|
| 10 |
+
|
| 11 |
+
export default addDir
|
src/commands/agents/agents.tsx
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from 'react';
|
| 2 |
+
import { AgentsMenu } from '../../components/agents/AgentsMenu.js';
|
| 3 |
+
import type { ToolUseContext } from '../../Tool.js';
|
| 4 |
+
import { getTools } from '../../tools.js';
|
| 5 |
+
import type { LocalJSXCommandOnDone } from '../../types/command.js';
|
| 6 |
+
export async function call(onDone: LocalJSXCommandOnDone, context: ToolUseContext): Promise<React.ReactNode> {
|
| 7 |
+
const appState = context.getAppState();
|
| 8 |
+
const permissionContext = appState.toolPermissionContext;
|
| 9 |
+
const tools = getTools(permissionContext);
|
| 10 |
+
return <AgentsMenu tools={tools} onExit={onDone} />;
|
| 11 |
+
}
|
| 12 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsIkFnZW50c01lbnUiLCJUb29sVXNlQ29udGV4dCIsImdldFRvb2xzIiwiTG9jYWxKU1hDb21tYW5kT25Eb25lIiwiY2FsbCIsIm9uRG9uZSIsImNvbnRleHQiLCJQcm9taXNlIiwiUmVhY3ROb2RlIiwiYXBwU3RhdGUiLCJnZXRBcHBTdGF0ZSIsInBlcm1pc3Npb25Db250ZXh0IiwidG9vbFBlcm1pc3Npb25Db250ZXh0IiwidG9vbHMiXSwic291cmNlcyI6WyJhZ2VudHMudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgQWdlbnRzTWVudSB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvYWdlbnRzL0FnZW50c01lbnUuanMnXG5pbXBvcnQgdHlwZSB7IFRvb2xVc2VDb250ZXh0IH0gZnJvbSAnLi4vLi4vVG9vbC5qcydcbmltcG9ydCB7IGdldFRvb2xzIH0gZnJvbSAnLi4vLi4vdG9vbHMuanMnXG5pbXBvcnQgdHlwZSB7IExvY2FsSlNYQ29tbWFuZE9uRG9uZSB9IGZyb20gJy4uLy4uL3R5cGVzL2NvbW1hbmQuanMnXG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjYWxsKFxuICBvbkRvbmU6IExvY2FsSlNYQ29tbWFuZE9uRG9uZSxcbiAgY29udGV4dDogVG9vbFVzZUNvbnRleHQsXG4pOiBQcm9taXNlPFJlYWN0LlJlYWN0Tm9kZT4ge1xuICBjb25zdCBhcHBTdGF0ZSA9IGNvbnRleHQuZ2V0QXBwU3RhdGUoKVxuICBjb25zdCBwZXJtaXNzaW9uQ29udGV4dCA9IGFwcFN0YXRlLnRvb2xQZXJtaXNzaW9uQ29udGV4dFxuICBjb25zdCB0b29scyA9IGdldFRvb2xzKHBlcm1pc3Npb25Db250ZXh0KVxuXG4gIHJldHVybiA8QWdlbnRzTWVudSB0b29scz17dG9vbHN9IG9uRXhpdD17b25Eb25lfSAvPlxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUtBLEtBQUssTUFBTSxPQUFPO0FBQzlCLFNBQVNDLFVBQVUsUUFBUSx1Q0FBdUM7QUFDbEUsY0FBY0MsY0FBYyxRQUFRLGVBQWU7QUFDbkQsU0FBU0MsUUFBUSxRQUFRLGdCQUFnQjtBQUN6QyxjQUFjQyxxQkFBcUIsUUFBUSx3QkFBd0I7QUFFbkUsT0FBTyxlQUFlQyxJQUFJQSxDQUN4QkMsTUFBTSxFQUFFRixxQkFBcUIsRUFDN0JHLE9BQU8sRUFBRUwsY0FBYyxDQUN4QixFQUFFTSxPQUFPLENBQUNSLEtBQUssQ0FBQ1MsU0FBUyxDQUFDLENBQUM7RUFDMUIsTUFBTUMsUUFBUSxHQUFHSCxPQUFPLENBQUNJLFdBQVcsQ0FBQyxDQUFDO0VBQ3RDLE1BQU1DLGlCQUFpQixHQUFHRixRQUFRLENBQUNHLHFCQUFxQjtFQUN4RCxNQUFNQyxLQUFLLEdBQUdYLFFBQVEsQ0FBQ1MsaUJBQWlCLENBQUM7RUFFekMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQ0UsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUNSLE1BQU0sQ0FBQyxHQUFHO0FBQ3JEIiwiaWdub3JlTGlzdCI6W119
|
src/commands/agents/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js'
|
| 2 |
+
|
| 3 |
+
const agents = {
|
| 4 |
+
type: 'local-jsx',
|
| 5 |
+
name: 'agents',
|
| 6 |
+
description: 'Manage agent configurations',
|
| 7 |
+
load: () => import('./agents.js'),
|
| 8 |
+
} satisfies Command
|
| 9 |
+
|
| 10 |
+
export default agents
|
src/commands/ant-trace/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
export default { isEnabled: () => false, isHidden: true, name: 'stub' };
|
src/commands/autofix-pr/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
export default { isEnabled: () => false, isHidden: true, name: 'stub' };
|
src/commands/branch/branch.ts
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { randomUUID, type UUID } from 'crypto'
|
| 2 |
+
import { mkdir, readFile, writeFile } from 'fs/promises'
|
| 3 |
+
import { getOriginalCwd, getSessionId } from '../../bootstrap/state.js'
|
| 4 |
+
import type { LocalJSXCommandContext } from '../../commands.js'
|
| 5 |
+
import { logEvent } from '../../services/analytics/index.js'
|
| 6 |
+
import type { LocalJSXCommandOnDone } from '../../types/command.js'
|
| 7 |
+
import type {
|
| 8 |
+
ContentReplacementEntry,
|
| 9 |
+
Entry,
|
| 10 |
+
LogOption,
|
| 11 |
+
SerializedMessage,
|
| 12 |
+
TranscriptMessage,
|
| 13 |
+
} from '../../types/logs.js'
|
| 14 |
+
import { parseJSONL } from '../../utils/json.js'
|
| 15 |
+
import {
|
| 16 |
+
getProjectDir,
|
| 17 |
+
getTranscriptPath,
|
| 18 |
+
getTranscriptPathForSession,
|
| 19 |
+
isTranscriptMessage,
|
| 20 |
+
saveCustomTitle,
|
| 21 |
+
searchSessionsByCustomTitle,
|
| 22 |
+
} from '../../utils/sessionStorage.js'
|
| 23 |
+
import { jsonStringify } from '../../utils/slowOperations.js'
|
| 24 |
+
import { escapeRegExp } from '../../utils/stringUtils.js'
|
| 25 |
+
|
| 26 |
+
type TranscriptEntry = TranscriptMessage & {
|
| 27 |
+
forkedFrom?: {
|
| 28 |
+
sessionId: string
|
| 29 |
+
messageUuid: UUID
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
/**
|
| 34 |
+
* Derive a single-line title base from the first user message.
|
| 35 |
+
* Collapses whitespace — multiline first messages (pasted stacks, code)
|
| 36 |
+
* otherwise flow into the saved title and break the resume hint.
|
| 37 |
+
*/
|
| 38 |
+
export function deriveFirstPrompt(
|
| 39 |
+
firstUserMessage: Extract<SerializedMessage, { type: 'user' }> | undefined,
|
| 40 |
+
): string {
|
| 41 |
+
const content = firstUserMessage?.message?.content
|
| 42 |
+
if (!content) return 'Branched conversation'
|
| 43 |
+
const raw =
|
| 44 |
+
typeof content === 'string'
|
| 45 |
+
? content
|
| 46 |
+
: content.find(
|
| 47 |
+
(block): block is { type: 'text'; text: string } =>
|
| 48 |
+
block.type === 'text',
|
| 49 |
+
)?.text
|
| 50 |
+
if (!raw) return 'Branched conversation'
|
| 51 |
+
return (
|
| 52 |
+
raw.replace(/\s+/g, ' ').trim().slice(0, 100) || 'Branched conversation'
|
| 53 |
+
)
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
/**
|
| 57 |
+
* Creates a fork of the current conversation by copying from the transcript file.
|
| 58 |
+
* Preserves all original metadata (timestamps, gitBranch, etc.) while updating
|
| 59 |
+
* sessionId and adding forkedFrom traceability.
|
| 60 |
+
*/
|
| 61 |
+
async function createFork(customTitle?: string): Promise<{
|
| 62 |
+
sessionId: UUID
|
| 63 |
+
title: string | undefined
|
| 64 |
+
forkPath: string
|
| 65 |
+
serializedMessages: SerializedMessage[]
|
| 66 |
+
contentReplacementRecords: ContentReplacementEntry['replacements']
|
| 67 |
+
}> {
|
| 68 |
+
const forkSessionId = randomUUID() as UUID
|
| 69 |
+
const originalSessionId = getSessionId()
|
| 70 |
+
const projectDir = getProjectDir(getOriginalCwd())
|
| 71 |
+
const forkSessionPath = getTranscriptPathForSession(forkSessionId)
|
| 72 |
+
const currentTranscriptPath = getTranscriptPath()
|
| 73 |
+
|
| 74 |
+
// Ensure project directory exists
|
| 75 |
+
await mkdir(projectDir, { recursive: true, mode: 0o700 })
|
| 76 |
+
|
| 77 |
+
// Read current transcript file
|
| 78 |
+
let transcriptContent: Buffer
|
| 79 |
+
try {
|
| 80 |
+
transcriptContent = await readFile(currentTranscriptPath)
|
| 81 |
+
} catch {
|
| 82 |
+
throw new Error('No conversation to branch')
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
if (transcriptContent.length === 0) {
|
| 86 |
+
throw new Error('No conversation to branch')
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
// Parse all transcript entries (messages + metadata entries like content-replacement)
|
| 90 |
+
const entries = parseJSONL<Entry>(transcriptContent)
|
| 91 |
+
|
| 92 |
+
// Filter to only main conversation messages (exclude sidechains and non-message entries)
|
| 93 |
+
const mainConversationEntries = entries.filter(
|
| 94 |
+
(entry): entry is TranscriptMessage =>
|
| 95 |
+
isTranscriptMessage(entry) && !entry.isSidechain,
|
| 96 |
+
)
|
| 97 |
+
|
| 98 |
+
// Content-replacement entries for the original session. These record which
|
| 99 |
+
// tool_result blocks were replaced with previews by the per-message budget.
|
| 100 |
+
// Without them in the fork JSONL, `claude -r {forkId}` reconstructs state
|
| 101 |
+
// with an empty replacements Map → previously-replaced results are classified
|
| 102 |
+
// as FROZEN and sent as full content (prompt cache miss + permanent overage).
|
| 103 |
+
// sessionId must be rewritten since loadTranscriptFile keys lookup by the
|
| 104 |
+
// session's messages' sessionId.
|
| 105 |
+
const contentReplacementRecords = entries
|
| 106 |
+
.filter(
|
| 107 |
+
(entry): entry is ContentReplacementEntry =>
|
| 108 |
+
entry.type === 'content-replacement' &&
|
| 109 |
+
entry.sessionId === originalSessionId,
|
| 110 |
+
)
|
| 111 |
+
.flatMap(entry => entry.replacements)
|
| 112 |
+
|
| 113 |
+
if (mainConversationEntries.length === 0) {
|
| 114 |
+
throw new Error('No messages to branch')
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
// Build forked entries with new sessionId and preserved metadata
|
| 118 |
+
let parentUuid: UUID | null = null
|
| 119 |
+
const lines: string[] = []
|
| 120 |
+
const serializedMessages: SerializedMessage[] = []
|
| 121 |
+
|
| 122 |
+
for (const entry of mainConversationEntries) {
|
| 123 |
+
// Create forked transcript entry preserving all original metadata
|
| 124 |
+
const forkedEntry: TranscriptEntry = {
|
| 125 |
+
...entry,
|
| 126 |
+
sessionId: forkSessionId,
|
| 127 |
+
parentUuid,
|
| 128 |
+
isSidechain: false,
|
| 129 |
+
forkedFrom: {
|
| 130 |
+
sessionId: originalSessionId,
|
| 131 |
+
messageUuid: entry.uuid,
|
| 132 |
+
},
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
// Build serialized message for LogOption
|
| 136 |
+
const serialized: SerializedMessage = {
|
| 137 |
+
...entry,
|
| 138 |
+
sessionId: forkSessionId,
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
serializedMessages.push(serialized)
|
| 142 |
+
lines.push(jsonStringify(forkedEntry))
|
| 143 |
+
if (entry.type !== 'progress') {
|
| 144 |
+
parentUuid = entry.uuid
|
| 145 |
+
}
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
// Append content-replacement entry (if any) with the fork's sessionId.
|
| 149 |
+
// Written as a SINGLE entry (same shape as insertContentReplacement) so
|
| 150 |
+
// loadTranscriptFile's content-replacement branch picks it up.
|
| 151 |
+
if (contentReplacementRecords.length > 0) {
|
| 152 |
+
const forkedReplacementEntry: ContentReplacementEntry = {
|
| 153 |
+
type: 'content-replacement',
|
| 154 |
+
sessionId: forkSessionId,
|
| 155 |
+
replacements: contentReplacementRecords,
|
| 156 |
+
}
|
| 157 |
+
lines.push(jsonStringify(forkedReplacementEntry))
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
// Write the fork session file
|
| 161 |
+
await writeFile(forkSessionPath, lines.join('\n') + '\n', {
|
| 162 |
+
encoding: 'utf8',
|
| 163 |
+
mode: 0o600,
|
| 164 |
+
})
|
| 165 |
+
|
| 166 |
+
return {
|
| 167 |
+
sessionId: forkSessionId,
|
| 168 |
+
title: customTitle,
|
| 169 |
+
forkPath: forkSessionPath,
|
| 170 |
+
serializedMessages,
|
| 171 |
+
contentReplacementRecords,
|
| 172 |
+
}
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
/**
|
| 176 |
+
* Generates a unique fork name by checking for collisions with existing session names.
|
| 177 |
+
* If "baseName (Branch)" already exists, tries "baseName (Branch 2)", "baseName (Branch 3)", etc.
|
| 178 |
+
*/
|
| 179 |
+
async function getUniqueForkName(baseName: string): Promise<string> {
|
| 180 |
+
const candidateName = `${baseName} (Branch)`
|
| 181 |
+
|
| 182 |
+
// Check if this exact name already exists
|
| 183 |
+
const existingWithExactName = await searchSessionsByCustomTitle(
|
| 184 |
+
candidateName,
|
| 185 |
+
{ exact: true },
|
| 186 |
+
)
|
| 187 |
+
|
| 188 |
+
if (existingWithExactName.length === 0) {
|
| 189 |
+
return candidateName
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
// Name collision - find a unique numbered suffix
|
| 193 |
+
// Search for all sessions that start with the base pattern
|
| 194 |
+
const existingForks = await searchSessionsByCustomTitle(`${baseName} (Branch`)
|
| 195 |
+
|
| 196 |
+
// Extract existing fork numbers to find the next available
|
| 197 |
+
const usedNumbers = new Set<number>([1]) // Consider " (Branch)" as number 1
|
| 198 |
+
const forkNumberPattern = new RegExp(
|
| 199 |
+
`^${escapeRegExp(baseName)} \\(Branch(?: (\\d+))?\\)$`,
|
| 200 |
+
)
|
| 201 |
+
|
| 202 |
+
for (const session of existingForks) {
|
| 203 |
+
const match = session.customTitle?.match(forkNumberPattern)
|
| 204 |
+
if (match) {
|
| 205 |
+
if (match[1]) {
|
| 206 |
+
usedNumbers.add(parseInt(match[1], 10))
|
| 207 |
+
} else {
|
| 208 |
+
usedNumbers.add(1) // " (Branch)" without number is treated as 1
|
| 209 |
+
}
|
| 210 |
+
}
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
// Find the next available number
|
| 214 |
+
let nextNumber = 2
|
| 215 |
+
while (usedNumbers.has(nextNumber)) {
|
| 216 |
+
nextNumber++
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
return `${baseName} (Branch ${nextNumber})`
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
export async function call(
|
| 223 |
+
onDone: LocalJSXCommandOnDone,
|
| 224 |
+
context: LocalJSXCommandContext,
|
| 225 |
+
args: string,
|
| 226 |
+
): Promise<React.ReactNode> {
|
| 227 |
+
const customTitle = args?.trim() || undefined
|
| 228 |
+
|
| 229 |
+
const originalSessionId = getSessionId()
|
| 230 |
+
|
| 231 |
+
try {
|
| 232 |
+
const {
|
| 233 |
+
sessionId,
|
| 234 |
+
title,
|
| 235 |
+
forkPath,
|
| 236 |
+
serializedMessages,
|
| 237 |
+
contentReplacementRecords,
|
| 238 |
+
} = await createFork(customTitle)
|
| 239 |
+
|
| 240 |
+
// Build LogOption for resume
|
| 241 |
+
const now = new Date()
|
| 242 |
+
const firstPrompt = deriveFirstPrompt(
|
| 243 |
+
serializedMessages.find(m => m.type === 'user'),
|
| 244 |
+
)
|
| 245 |
+
|
| 246 |
+
// Save custom title - use provided title or firstPrompt as default
|
| 247 |
+
// This ensures /status and /resume show the same session name
|
| 248 |
+
// Always add " (Branch)" suffix to make it clear this is a branched session
|
| 249 |
+
// Handle collisions by adding a number suffix (e.g., " (Branch 2)", " (Branch 3)")
|
| 250 |
+
const baseName = title ?? firstPrompt
|
| 251 |
+
const effectiveTitle = await getUniqueForkName(baseName)
|
| 252 |
+
await saveCustomTitle(sessionId, effectiveTitle, forkPath)
|
| 253 |
+
|
| 254 |
+
logEvent('tengu_conversation_forked', {
|
| 255 |
+
message_count: serializedMessages.length,
|
| 256 |
+
has_custom_title: !!title,
|
| 257 |
+
})
|
| 258 |
+
|
| 259 |
+
const forkLog: LogOption = {
|
| 260 |
+
date: now.toISOString().split('T')[0]!,
|
| 261 |
+
messages: serializedMessages,
|
| 262 |
+
fullPath: forkPath,
|
| 263 |
+
value: now.getTime(),
|
| 264 |
+
created: now,
|
| 265 |
+
modified: now,
|
| 266 |
+
firstPrompt,
|
| 267 |
+
messageCount: serializedMessages.length,
|
| 268 |
+
isSidechain: false,
|
| 269 |
+
sessionId,
|
| 270 |
+
customTitle: effectiveTitle,
|
| 271 |
+
contentReplacements: contentReplacementRecords,
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
// Resume into the fork
|
| 275 |
+
const titleInfo = title ? ` "${title}"` : ''
|
| 276 |
+
const resumeHint = `\nTo resume the original: claude -r ${originalSessionId}`
|
| 277 |
+
const successMessage = `Branched conversation${titleInfo}. You are now in the branch.${resumeHint}`
|
| 278 |
+
|
| 279 |
+
if (context.resume) {
|
| 280 |
+
await context.resume(sessionId, forkLog, 'fork')
|
| 281 |
+
onDone(successMessage, { display: 'system' })
|
| 282 |
+
} else {
|
| 283 |
+
// Fallback if resume not available
|
| 284 |
+
onDone(
|
| 285 |
+
`Branched conversation${titleInfo}. Resume with: /resume ${sessionId}`,
|
| 286 |
+
)
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
return null
|
| 290 |
+
} catch (error) {
|
| 291 |
+
const message =
|
| 292 |
+
error instanceof Error ? error.message : 'Unknown error occurred'
|
| 293 |
+
onDone(`Failed to branch conversation: ${message}`)
|
| 294 |
+
return null
|
| 295 |
+
}
|
| 296 |
+
}
|
src/commands/branch/index.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { feature } from 'bun:bundle'
|
| 2 |
+
import type { Command } from '../../commands.js'
|
| 3 |
+
|
| 4 |
+
const branch = {
|
| 5 |
+
type: 'local-jsx',
|
| 6 |
+
name: 'branch',
|
| 7 |
+
// 'fork' alias only when /fork doesn't exist as its own command
|
| 8 |
+
aliases: feature('FORK_SUBAGENT') ? [] : ['fork'],
|
| 9 |
+
description: 'Create a branch of the current conversation at this point',
|
| 10 |
+
argumentHint: '[name]',
|
| 11 |
+
load: () => import('./branch.js'),
|
| 12 |
+
} satisfies Command
|
| 13 |
+
|
| 14 |
+
export default branch
|
src/commands/break-cache/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
export default { isEnabled: () => false, isHidden: true, name: 'stub' };
|
src/commands/btw/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js'
|
| 2 |
+
|
| 3 |
+
const btw = {
|
| 4 |
+
type: 'local-jsx',
|
| 5 |
+
name: 'btw',
|
| 6 |
+
description:
|
| 7 |
+
'Ask a quick side question without interrupting the main conversation',
|
| 8 |
+
immediate: true,
|
| 9 |
+
argumentHint: '<question>',
|
| 10 |
+
load: () => import('./btw.js'),
|
| 11 |
+
} satisfies Command
|
| 12 |
+
|
| 13 |
+
export default btw
|
src/commands/chrome/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { getIsNonInteractiveSession } from '../../bootstrap/state.js'
|
| 2 |
+
import type { Command } from '../../commands.js'
|
| 3 |
+
|
| 4 |
+
const command: Command = {
|
| 5 |
+
name: 'chrome',
|
| 6 |
+
description: 'Claude in Chrome (Beta) settings',
|
| 7 |
+
availability: ['claude-ai'],
|
| 8 |
+
isEnabled: () => !getIsNonInteractiveSession(),
|
| 9 |
+
type: 'local-jsx',
|
| 10 |
+
load: () => import('./chrome.js'),
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
export default command
|
src/commands/clear/clear.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { LocalCommandCall } from '../../types/command.js'
|
| 2 |
+
import { clearConversation } from './conversation.js'
|
| 3 |
+
|
| 4 |
+
export const call: LocalCommandCall = async (_, context) => {
|
| 5 |
+
await clearConversation(context)
|
| 6 |
+
return { type: 'text', value: '' }
|
| 7 |
+
}
|
src/commands/clear/index.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Clear command - minimal metadata only.
|
| 3 |
+
* Implementation is lazy-loaded from clear.ts to reduce startup time.
|
| 4 |
+
* Utility functions:
|
| 5 |
+
* - clearSessionCaches: import from './clear/caches.js'
|
| 6 |
+
* - clearConversation: import from './clear/conversation.js'
|
| 7 |
+
*/
|
| 8 |
+
import type { Command } from '../../commands.js'
|
| 9 |
+
|
| 10 |
+
const clear = {
|
| 11 |
+
type: 'local',
|
| 12 |
+
name: 'clear',
|
| 13 |
+
description: 'Clear conversation history and free up context',
|
| 14 |
+
aliases: ['reset', 'new'],
|
| 15 |
+
supportsNonInteractive: false, // Should just create a new session
|
| 16 |
+
load: () => import('./clear.js'),
|
| 17 |
+
} satisfies Command
|
| 18 |
+
|
| 19 |
+
export default clear
|
src/commands/color/color.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { UUID } from 'crypto'
|
| 2 |
+
import { getSessionId } from '../../bootstrap/state.js'
|
| 3 |
+
import type { ToolUseContext } from '../../Tool.js'
|
| 4 |
+
import {
|
| 5 |
+
AGENT_COLORS,
|
| 6 |
+
type AgentColorName,
|
| 7 |
+
} from '../../tools/AgentTool/agentColorManager.js'
|
| 8 |
+
import type {
|
| 9 |
+
LocalJSXCommandContext,
|
| 10 |
+
LocalJSXCommandOnDone,
|
| 11 |
+
} from '../../types/command.js'
|
| 12 |
+
import {
|
| 13 |
+
getTranscriptPath,
|
| 14 |
+
saveAgentColor,
|
| 15 |
+
} from '../../utils/sessionStorage.js'
|
| 16 |
+
import { isTeammate } from '../../utils/teammate.js'
|
| 17 |
+
|
| 18 |
+
const RESET_ALIASES = ['default', 'reset', 'none', 'gray', 'grey'] as const
|
| 19 |
+
|
| 20 |
+
export async function call(
|
| 21 |
+
onDone: LocalJSXCommandOnDone,
|
| 22 |
+
context: ToolUseContext & LocalJSXCommandContext,
|
| 23 |
+
args: string,
|
| 24 |
+
): Promise<null> {
|
| 25 |
+
// Teammates cannot set their own color
|
| 26 |
+
if (isTeammate()) {
|
| 27 |
+
onDone(
|
| 28 |
+
'Cannot set color: This session is a swarm teammate. Teammate colors are assigned by the team leader.',
|
| 29 |
+
{ display: 'system' },
|
| 30 |
+
)
|
| 31 |
+
return null
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
if (!args || args.trim() === '') {
|
| 35 |
+
const colorList = AGENT_COLORS.join(', ')
|
| 36 |
+
onDone(`Please provide a color. Available colors: ${colorList}, default`, {
|
| 37 |
+
display: 'system',
|
| 38 |
+
})
|
| 39 |
+
return null
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
const colorArg = args.trim().toLowerCase()
|
| 43 |
+
|
| 44 |
+
// Handle reset to default (gray)
|
| 45 |
+
if (RESET_ALIASES.includes(colorArg as (typeof RESET_ALIASES)[number])) {
|
| 46 |
+
const sessionId = getSessionId() as UUID
|
| 47 |
+
const fullPath = getTranscriptPath()
|
| 48 |
+
|
| 49 |
+
// Use "default" sentinel (not empty string) so truthiness guards
|
| 50 |
+
// in sessionStorage.ts persist the reset across session restarts
|
| 51 |
+
await saveAgentColor(sessionId, 'default', fullPath)
|
| 52 |
+
|
| 53 |
+
context.setAppState(prev => ({
|
| 54 |
+
...prev,
|
| 55 |
+
standaloneAgentContext: {
|
| 56 |
+
...prev.standaloneAgentContext,
|
| 57 |
+
name: prev.standaloneAgentContext?.name ?? '',
|
| 58 |
+
color: undefined,
|
| 59 |
+
},
|
| 60 |
+
}))
|
| 61 |
+
|
| 62 |
+
onDone('Session color reset to default', { display: 'system' })
|
| 63 |
+
return null
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
if (!AGENT_COLORS.includes(colorArg as AgentColorName)) {
|
| 67 |
+
const colorList = AGENT_COLORS.join(', ')
|
| 68 |
+
onDone(
|
| 69 |
+
`Invalid color "${colorArg}". Available colors: ${colorList}, default`,
|
| 70 |
+
{ display: 'system' },
|
| 71 |
+
)
|
| 72 |
+
return null
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
const sessionId = getSessionId() as UUID
|
| 76 |
+
const fullPath = getTranscriptPath()
|
| 77 |
+
|
| 78 |
+
// Save to transcript for persistence across sessions
|
| 79 |
+
await saveAgentColor(sessionId, colorArg, fullPath)
|
| 80 |
+
|
| 81 |
+
// Update AppState for immediate effect
|
| 82 |
+
context.setAppState(prev => ({
|
| 83 |
+
...prev,
|
| 84 |
+
standaloneAgentContext: {
|
| 85 |
+
...prev.standaloneAgentContext,
|
| 86 |
+
name: prev.standaloneAgentContext?.name ?? '',
|
| 87 |
+
color: colorArg as AgentColorName,
|
| 88 |
+
},
|
| 89 |
+
}))
|
| 90 |
+
|
| 91 |
+
onDone(`Session color set to: ${colorArg}`, { display: 'system' })
|
| 92 |
+
return null
|
| 93 |
+
}
|
src/commands/mcp/addCommand.ts
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* MCP add CLI subcommand
|
| 3 |
+
*
|
| 4 |
+
* Extracted from main.tsx to enable direct testing.
|
| 5 |
+
*/
|
| 6 |
+
import { type Command, Option } from '@commander-js/extra-typings'
|
| 7 |
+
import { cliError, cliOk } from '../../cli/exit.js'
|
| 8 |
+
import {
|
| 9 |
+
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
| 10 |
+
logEvent,
|
| 11 |
+
} from '../../services/analytics/index.js'
|
| 12 |
+
import {
|
| 13 |
+
readClientSecret,
|
| 14 |
+
saveMcpClientSecret,
|
| 15 |
+
} from '../../services/mcp/auth.js'
|
| 16 |
+
import { addMcpConfig } from '../../services/mcp/config.js'
|
| 17 |
+
import {
|
| 18 |
+
describeMcpConfigFilePath,
|
| 19 |
+
ensureConfigScope,
|
| 20 |
+
ensureTransport,
|
| 21 |
+
parseHeaders,
|
| 22 |
+
} from '../../services/mcp/utils.js'
|
| 23 |
+
import {
|
| 24 |
+
getXaaIdpSettings,
|
| 25 |
+
isXaaEnabled,
|
| 26 |
+
} from '../../services/mcp/xaaIdpLogin.js'
|
| 27 |
+
import { parseEnvVars } from '../../utils/envUtils.js'
|
| 28 |
+
import { jsonStringify } from '../../utils/slowOperations.js'
|
| 29 |
+
|
| 30 |
+
/**
|
| 31 |
+
* Registers the `mcp add` subcommand on the given Commander command.
|
| 32 |
+
*/
|
| 33 |
+
export function registerMcpAddCommand(mcp: Command): void {
|
| 34 |
+
mcp
|
| 35 |
+
.command('add <name> <commandOrUrl> [args...]')
|
| 36 |
+
.description(
|
| 37 |
+
'Add an MCP server to Claude Code.\n\n' +
|
| 38 |
+
'Examples:\n' +
|
| 39 |
+
' # Add HTTP server:\n' +
|
| 40 |
+
' claude mcp add --transport http sentry https://mcp.sentry.dev/mcp\n\n' +
|
| 41 |
+
' # Add HTTP server with headers:\n' +
|
| 42 |
+
' claude mcp add --transport http corridor https://app.corridor.dev/api/mcp --header "Authorization: Bearer ..."\n\n' +
|
| 43 |
+
' # Add stdio server with environment variables:\n' +
|
| 44 |
+
' claude mcp add -e API_KEY=xxx my-server -- npx my-mcp-server\n\n' +
|
| 45 |
+
' # Add stdio server with subprocess flags:\n' +
|
| 46 |
+
' claude mcp add my-server -- my-command --some-flag arg1',
|
| 47 |
+
)
|
| 48 |
+
.option(
|
| 49 |
+
'-s, --scope <scope>',
|
| 50 |
+
'Configuration scope (local, user, or project)',
|
| 51 |
+
'local',
|
| 52 |
+
)
|
| 53 |
+
.option(
|
| 54 |
+
'-t, --transport <transport>',
|
| 55 |
+
'Transport type (stdio, sse, http). Defaults to stdio if not specified.',
|
| 56 |
+
)
|
| 57 |
+
.option(
|
| 58 |
+
'-e, --env <env...>',
|
| 59 |
+
'Set environment variables (e.g. -e KEY=value)',
|
| 60 |
+
)
|
| 61 |
+
.option(
|
| 62 |
+
'-H, --header <header...>',
|
| 63 |
+
'Set WebSocket headers (e.g. -H "X-Api-Key: abc123" -H "X-Custom: value")',
|
| 64 |
+
)
|
| 65 |
+
.option('--client-id <clientId>', 'OAuth client ID for HTTP/SSE servers')
|
| 66 |
+
.option(
|
| 67 |
+
'--client-secret',
|
| 68 |
+
'Prompt for OAuth client secret (or set MCP_CLIENT_SECRET env var)',
|
| 69 |
+
)
|
| 70 |
+
.option(
|
| 71 |
+
'--callback-port <port>',
|
| 72 |
+
'Fixed port for OAuth callback (for servers requiring pre-registered redirect URIs)',
|
| 73 |
+
)
|
| 74 |
+
.helpOption('-h, --help', 'Display help for command')
|
| 75 |
+
.addOption(
|
| 76 |
+
new Option(
|
| 77 |
+
'--xaa',
|
| 78 |
+
"Enable XAA (SEP-990) for this server. Requires 'claude mcp xaa setup' first. Also requires --client-id and --client-secret (for the MCP server's AS).",
|
| 79 |
+
).hideHelp(!isXaaEnabled()),
|
| 80 |
+
)
|
| 81 |
+
.action(async (name, commandOrUrl, args, options) => {
|
| 82 |
+
// Commander.js handles -- natively: it consumes -- and everything after becomes args
|
| 83 |
+
const actualCommand = commandOrUrl
|
| 84 |
+
const actualArgs = args
|
| 85 |
+
|
| 86 |
+
// If no name is provided, error
|
| 87 |
+
if (!name) {
|
| 88 |
+
cliError(
|
| 89 |
+
'Error: Server name is required.\n' +
|
| 90 |
+
'Usage: claude mcp add <name> <command> [args...]',
|
| 91 |
+
)
|
| 92 |
+
} else if (!actualCommand) {
|
| 93 |
+
cliError(
|
| 94 |
+
'Error: Command is required when server name is provided.\n' +
|
| 95 |
+
'Usage: claude mcp add <name> <command> [args...]',
|
| 96 |
+
)
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
try {
|
| 100 |
+
const scope = ensureConfigScope(options.scope)
|
| 101 |
+
const transport = ensureTransport(options.transport)
|
| 102 |
+
|
| 103 |
+
// XAA fail-fast: validate at add-time, not auth-time.
|
| 104 |
+
if (options.xaa && !isXaaEnabled()) {
|
| 105 |
+
cliError(
|
| 106 |
+
'Error: --xaa requires CLAUDE_CODE_ENABLE_XAA=1 in your environment',
|
| 107 |
+
)
|
| 108 |
+
}
|
| 109 |
+
const xaa = Boolean(options.xaa)
|
| 110 |
+
if (xaa) {
|
| 111 |
+
const missing: string[] = []
|
| 112 |
+
if (!options.clientId) missing.push('--client-id')
|
| 113 |
+
if (!options.clientSecret) missing.push('--client-secret')
|
| 114 |
+
if (!getXaaIdpSettings()) {
|
| 115 |
+
missing.push(
|
| 116 |
+
"'claude mcp xaa setup' (settings.xaaIdp not configured)",
|
| 117 |
+
)
|
| 118 |
+
}
|
| 119 |
+
if (missing.length) {
|
| 120 |
+
cliError(`Error: --xaa requires: ${missing.join(', ')}`)
|
| 121 |
+
}
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
// Check if transport was explicitly provided
|
| 125 |
+
const transportExplicit = options.transport !== undefined
|
| 126 |
+
|
| 127 |
+
// Check if the command looks like a URL (likely incorrect usage)
|
| 128 |
+
const looksLikeUrl =
|
| 129 |
+
actualCommand.startsWith('http://') ||
|
| 130 |
+
actualCommand.startsWith('https://') ||
|
| 131 |
+
actualCommand.startsWith('localhost') ||
|
| 132 |
+
actualCommand.endsWith('/sse') ||
|
| 133 |
+
actualCommand.endsWith('/mcp')
|
| 134 |
+
|
| 135 |
+
logEvent('tengu_mcp_add', {
|
| 136 |
+
type: transport as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
| 137 |
+
scope:
|
| 138 |
+
scope as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
| 139 |
+
source:
|
| 140 |
+
'command' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
| 141 |
+
transport:
|
| 142 |
+
transport as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
| 143 |
+
transportExplicit: transportExplicit,
|
| 144 |
+
looksLikeUrl: looksLikeUrl,
|
| 145 |
+
})
|
| 146 |
+
|
| 147 |
+
if (transport === 'sse') {
|
| 148 |
+
if (!actualCommand) {
|
| 149 |
+
cliError('Error: URL is required for SSE transport.')
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
const headers = options.header
|
| 153 |
+
? parseHeaders(options.header)
|
| 154 |
+
: undefined
|
| 155 |
+
|
| 156 |
+
const callbackPort = options.callbackPort
|
| 157 |
+
? parseInt(options.callbackPort, 10)
|
| 158 |
+
: undefined
|
| 159 |
+
const oauth =
|
| 160 |
+
options.clientId || callbackPort || xaa
|
| 161 |
+
? {
|
| 162 |
+
...(options.clientId ? { clientId: options.clientId } : {}),
|
| 163 |
+
...(callbackPort ? { callbackPort } : {}),
|
| 164 |
+
...(xaa ? { xaa: true } : {}),
|
| 165 |
+
}
|
| 166 |
+
: undefined
|
| 167 |
+
|
| 168 |
+
const clientSecret =
|
| 169 |
+
options.clientSecret && options.clientId
|
| 170 |
+
? await readClientSecret()
|
| 171 |
+
: undefined
|
| 172 |
+
|
| 173 |
+
const serverConfig = {
|
| 174 |
+
type: 'sse' as const,
|
| 175 |
+
url: actualCommand,
|
| 176 |
+
headers,
|
| 177 |
+
oauth,
|
| 178 |
+
}
|
| 179 |
+
await addMcpConfig(name, serverConfig, scope)
|
| 180 |
+
|
| 181 |
+
if (clientSecret) {
|
| 182 |
+
saveMcpClientSecret(name, serverConfig, clientSecret)
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
process.stdout.write(
|
| 186 |
+
`Added SSE MCP server ${name} with URL: ${actualCommand} to ${scope} config\n`,
|
| 187 |
+
)
|
| 188 |
+
if (headers) {
|
| 189 |
+
process.stdout.write(
|
| 190 |
+
`Headers: ${jsonStringify(headers, null, 2)}\n`,
|
| 191 |
+
)
|
| 192 |
+
}
|
| 193 |
+
} else if (transport === 'http') {
|
| 194 |
+
if (!actualCommand) {
|
| 195 |
+
cliError('Error: URL is required for HTTP transport.')
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
const headers = options.header
|
| 199 |
+
? parseHeaders(options.header)
|
| 200 |
+
: undefined
|
| 201 |
+
|
| 202 |
+
const callbackPort = options.callbackPort
|
| 203 |
+
? parseInt(options.callbackPort, 10)
|
| 204 |
+
: undefined
|
| 205 |
+
const oauth =
|
| 206 |
+
options.clientId || callbackPort || xaa
|
| 207 |
+
? {
|
| 208 |
+
...(options.clientId ? { clientId: options.clientId } : {}),
|
| 209 |
+
...(callbackPort ? { callbackPort } : {}),
|
| 210 |
+
...(xaa ? { xaa: true } : {}),
|
| 211 |
+
}
|
| 212 |
+
: undefined
|
| 213 |
+
|
| 214 |
+
const clientSecret =
|
| 215 |
+
options.clientSecret && options.clientId
|
| 216 |
+
? await readClientSecret()
|
| 217 |
+
: undefined
|
| 218 |
+
|
| 219 |
+
const serverConfig = {
|
| 220 |
+
type: 'http' as const,
|
| 221 |
+
url: actualCommand,
|
| 222 |
+
headers,
|
| 223 |
+
oauth,
|
| 224 |
+
}
|
| 225 |
+
await addMcpConfig(name, serverConfig, scope)
|
| 226 |
+
|
| 227 |
+
if (clientSecret) {
|
| 228 |
+
saveMcpClientSecret(name, serverConfig, clientSecret)
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
process.stdout.write(
|
| 232 |
+
`Added HTTP MCP server ${name} with URL: ${actualCommand} to ${scope} config\n`,
|
| 233 |
+
)
|
| 234 |
+
if (headers) {
|
| 235 |
+
process.stdout.write(
|
| 236 |
+
`Headers: ${jsonStringify(headers, null, 2)}\n`,
|
| 237 |
+
)
|
| 238 |
+
}
|
| 239 |
+
} else {
|
| 240 |
+
if (
|
| 241 |
+
options.clientId ||
|
| 242 |
+
options.clientSecret ||
|
| 243 |
+
options.callbackPort ||
|
| 244 |
+
options.xaa
|
| 245 |
+
) {
|
| 246 |
+
process.stderr.write(
|
| 247 |
+
`Warning: --client-id, --client-secret, --callback-port, and --xaa are only supported for HTTP/SSE transports and will be ignored for stdio.\n`,
|
| 248 |
+
)
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
// Warn if this looks like a URL but transport wasn't explicitly specified
|
| 252 |
+
if (!transportExplicit && looksLikeUrl) {
|
| 253 |
+
process.stderr.write(
|
| 254 |
+
`\nWarning: The command "${actualCommand}" looks like a URL, but is being interpreted as a stdio server as --transport was not specified.\n`,
|
| 255 |
+
)
|
| 256 |
+
process.stderr.write(
|
| 257 |
+
`If this is an HTTP server, use: claude mcp add --transport http ${name} ${actualCommand}\n`,
|
| 258 |
+
)
|
| 259 |
+
process.stderr.write(
|
| 260 |
+
`If this is an SSE server, use: claude mcp add --transport sse ${name} ${actualCommand}\n`,
|
| 261 |
+
)
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
const env = parseEnvVars(options.env)
|
| 265 |
+
await addMcpConfig(
|
| 266 |
+
name,
|
| 267 |
+
{ type: 'stdio', command: actualCommand, args: actualArgs, env },
|
| 268 |
+
scope,
|
| 269 |
+
)
|
| 270 |
+
|
| 271 |
+
process.stdout.write(
|
| 272 |
+
`Added stdio MCP server ${name} with command: ${actualCommand} ${actualArgs.join(' ')} to ${scope} config\n`,
|
| 273 |
+
)
|
| 274 |
+
}
|
| 275 |
+
cliOk(`File modified: ${describeMcpConfigFilePath(scope)}`)
|
| 276 |
+
} catch (error) {
|
| 277 |
+
cliError((error as Error).message)
|
| 278 |
+
}
|
| 279 |
+
})
|
| 280 |
+
}
|
src/commands/mcp/index.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js'
|
| 2 |
+
|
| 3 |
+
const mcp = {
|
| 4 |
+
type: 'local-jsx',
|
| 5 |
+
name: 'mcp',
|
| 6 |
+
description: 'Manage MCP servers',
|
| 7 |
+
immediate: true,
|
| 8 |
+
argumentHint: '[enable|disable [server-name]]',
|
| 9 |
+
load: () => import('./mcp.js'),
|
| 10 |
+
} satisfies Command
|
| 11 |
+
|
| 12 |
+
export default mcp
|
src/commands/mcp/mcp.tsx
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { c as _c } from "react/compiler-runtime";
|
| 2 |
+
import React, { useEffect, useRef } from 'react';
|
| 3 |
+
import { MCPSettings } from '../../components/mcp/index.js';
|
| 4 |
+
import { MCPReconnect } from '../../components/mcp/MCPReconnect.js';
|
| 5 |
+
import { useMcpToggleEnabled } from '../../services/mcp/MCPConnectionManager.js';
|
| 6 |
+
import { useAppState } from '../../state/AppState.js';
|
| 7 |
+
import type { LocalJSXCommandOnDone } from '../../types/command.js';
|
| 8 |
+
import { PluginSettings } from '../plugin/PluginSettings.js';
|
| 9 |
+
|
| 10 |
+
// TODO: This is a hack to get the context value from toggleMcpServer (useContext only works in a component)
|
| 11 |
+
// Ideally, all MCP state and functions would be in global state.
|
| 12 |
+
function MCPToggle(t0) {
|
| 13 |
+
const $ = _c(7);
|
| 14 |
+
const {
|
| 15 |
+
action,
|
| 16 |
+
target,
|
| 17 |
+
onComplete
|
| 18 |
+
} = t0;
|
| 19 |
+
const mcpClients = useAppState(_temp);
|
| 20 |
+
const toggleMcpServer = useMcpToggleEnabled();
|
| 21 |
+
const didRun = useRef(false);
|
| 22 |
+
let t1;
|
| 23 |
+
let t2;
|
| 24 |
+
if ($[0] !== action || $[1] !== mcpClients || $[2] !== onComplete || $[3] !== target || $[4] !== toggleMcpServer) {
|
| 25 |
+
t1 = () => {
|
| 26 |
+
if (didRun.current) {
|
| 27 |
+
return;
|
| 28 |
+
}
|
| 29 |
+
didRun.current = true;
|
| 30 |
+
const isEnabling = action === "enable";
|
| 31 |
+
const clients = mcpClients.filter(_temp2);
|
| 32 |
+
const toToggle = target === "all" ? clients.filter(c_0 => isEnabling ? c_0.type === "disabled" : c_0.type !== "disabled") : clients.filter(c_1 => c_1.name === target);
|
| 33 |
+
if (toToggle.length === 0) {
|
| 34 |
+
onComplete(target === "all" ? `All MCP servers are already ${isEnabling ? "enabled" : "disabled"}` : `MCP server "${target}" not found`);
|
| 35 |
+
return;
|
| 36 |
+
}
|
| 37 |
+
for (const s_0 of toToggle) {
|
| 38 |
+
toggleMcpServer(s_0.name);
|
| 39 |
+
}
|
| 40 |
+
onComplete(target === "all" ? `${isEnabling ? "Enabled" : "Disabled"} ${toToggle.length} MCP server(s)` : `MCP server "${target}" ${isEnabling ? "enabled" : "disabled"}`);
|
| 41 |
+
};
|
| 42 |
+
t2 = [action, target, mcpClients, toggleMcpServer, onComplete];
|
| 43 |
+
$[0] = action;
|
| 44 |
+
$[1] = mcpClients;
|
| 45 |
+
$[2] = onComplete;
|
| 46 |
+
$[3] = target;
|
| 47 |
+
$[4] = toggleMcpServer;
|
| 48 |
+
$[5] = t1;
|
| 49 |
+
$[6] = t2;
|
| 50 |
+
} else {
|
| 51 |
+
t1 = $[5];
|
| 52 |
+
t2 = $[6];
|
| 53 |
+
}
|
| 54 |
+
useEffect(t1, t2);
|
| 55 |
+
return null;
|
| 56 |
+
}
|
| 57 |
+
function _temp2(c) {
|
| 58 |
+
return c.name !== "ide";
|
| 59 |
+
}
|
| 60 |
+
function _temp(s) {
|
| 61 |
+
return s.mcp.clients;
|
| 62 |
+
}
|
| 63 |
+
export async function call(onDone: LocalJSXCommandOnDone, _context: unknown, args?: string): Promise<React.ReactNode> {
|
| 64 |
+
if (args) {
|
| 65 |
+
const parts = args.trim().split(/\s+/);
|
| 66 |
+
|
| 67 |
+
// Allow /mcp no-redirect to bypass the redirect for testing
|
| 68 |
+
if (parts[0] === 'no-redirect') {
|
| 69 |
+
return <MCPSettings onComplete={onDone} />;
|
| 70 |
+
}
|
| 71 |
+
if (parts[0] === 'reconnect' && parts[1]) {
|
| 72 |
+
return <MCPReconnect serverName={parts.slice(1).join(' ')} onComplete={onDone} />;
|
| 73 |
+
}
|
| 74 |
+
if (parts[0] === 'enable' || parts[0] === 'disable') {
|
| 75 |
+
return <MCPToggle action={parts[0]} target={parts.length > 1 ? parts.slice(1).join(' ') : 'all'} onComplete={onDone} />;
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
// Redirect base /mcp command to /plugins installed tab for ant users
|
| 80 |
+
if ("external" === 'ant') {
|
| 81 |
+
return <PluginSettings onComplete={onDone} args="manage" showMcpRedirectMessage />;
|
| 82 |
+
}
|
| 83 |
+
return <MCPSettings onComplete={onDone} />;
|
| 84 |
+
}
|
| 85 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsInVzZUVmZmVjdCIsInVzZVJlZiIsIk1DUFNldHRpbmdzIiwiTUNQUmVjb25uZWN0IiwidXNlTWNwVG9nZ2xlRW5hYmxlZCIsInVzZUFwcFN0YXRlIiwiTG9jYWxKU1hDb21tYW5kT25Eb25lIiwiUGx1Z2luU2V0dGluZ3MiLCJNQ1BUb2dnbGUiLCJ0MCIsIiQiLCJfYyIsImFjdGlvbiIsInRhcmdldCIsIm9uQ29tcGxldGUiLCJtY3BDbGllbnRzIiwiX3RlbXAiLCJ0b2dnbGVNY3BTZXJ2ZXIiLCJkaWRSdW4iLCJ0MSIsInQyIiwiY3VycmVudCIsImlzRW5hYmxpbmciLCJjbGllbnRzIiwiZmlsdGVyIiwiX3RlbXAyIiwidG9Ub2dnbGUiLCJjXzAiLCJjIiwidHlwZSIsImNfMSIsIm5hbWUiLCJsZW5ndGgiLCJzXzAiLCJzIiwibWNwIiwiY2FsbCIsIm9uRG9uZSIsIl9jb250ZXh0IiwiYXJncyIsIlByb21pc2UiLCJSZWFjdE5vZGUiLCJwYXJ0cyIsInRyaW0iLCJzcGxpdCIsInNsaWNlIiwiam9pbiJdLCJzb3VyY2VzIjpbIm1jcC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0LCB7IHVzZUVmZmVjdCwgdXNlUmVmIH0gZnJvbSAncmVhY3QnXG5pbXBvcnQgeyBNQ1BTZXR0aW5ncyB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvbWNwL2luZGV4LmpzJ1xuaW1wb3J0IHsgTUNQUmVjb25uZWN0IH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9tY3AvTUNQUmVjb25uZWN0LmpzJ1xuaW1wb3J0IHsgdXNlTWNwVG9nZ2xlRW5hYmxlZCB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL21jcC9NQ1BDb25uZWN0aW9uTWFuYWdlci5qcydcbmltcG9ydCB7IHVzZUFwcFN0YXRlIH0gZnJvbSAnLi4vLi4vc3RhdGUvQXBwU3RhdGUuanMnXG5pbXBvcnQgdHlwZSB7IExvY2FsSlNYQ29tbWFuZE9uRG9uZSB9IGZyb20gJy4uLy4uL3R5cGVzL2NvbW1hbmQuanMnXG5pbXBvcnQgeyBQbHVnaW5TZXR0aW5ncyB9IGZyb20gJy4uL3BsdWdpbi9QbHVnaW5TZXR0aW5ncy5qcydcblxuLy8gVE9ETzogVGhpcyBpcyBhIGhhY2sgdG8gZ2V0IHRoZSBjb250ZXh0IHZhbHVlIGZyb20gdG9nZ2xlTWNwU2VydmVyICh1c2VDb250ZXh0IG9ubHkgd29ya3MgaW4gYSBjb21wb25lbnQpXG4vLyBJZGVhbGx5LCBhbGwgTUNQIHN0YXRlIGFuZCBmdW5jdGlvbnMgd291bGQgYmUgaW4gZ2xvYmFsIHN0YXRlLlxuZnVuY3Rpb24gTUNQVG9nZ2xlKHtcbiAgYWN0aW9uLFxuICB0YXJnZXQsXG4gIG9uQ29tcGxldGUsXG59OiB7XG4gIGFjdGlvbjogJ2VuYWJsZScgfCAnZGlzYWJsZSdcbiAgdGFyZ2V0OiBzdHJpbmdcbiAgb25Db21wbGV0ZTogKHJlc3VsdDogc3RyaW5nKSA9PiB2b2lkXG59KTogbnVsbCB7XG4gIGNvbnN0IG1jcENsaWVudHMgPSB1c2VBcHBTdGF0ZShzID0+IHMubWNwLmNsaWVudHMpXG4gIGNvbnN0IHRvZ2dsZU1jcFNlcnZlciA9IHVzZU1jcFRvZ2dsZUVuYWJsZWQoKVxuICBjb25zdCBkaWRSdW4gPSB1c2VSZWYoZmFsc2UpXG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoZGlkUnVuLmN1cnJlbnQpIHJldHVyblxuICAgIGRpZFJ1bi5jdXJyZW50ID0gdHJ1ZVxuXG4gICAgY29uc3QgaXNFbmFibGluZyA9IGFjdGlvbiA9PT0gJ2VuYWJsZSdcbiAgICBjb25zdCBjbGllbnRzID0gbWNwQ2xpZW50cy5maWx0ZXIoYyA9PiBjLm5hbWUgIT09ICdpZGUnKVxuICAgIGNvbnN0IHRvVG9nZ2xlID1cbiAgICAgIHRhcmdldCA9PT0gJ2FsbCdcbiAgICAgICAgPyBjbGllbnRzLmZpbHRlcihjID0+XG4gICAgICAgICAgICBpc0VuYWJsaW5nID8gYy50eXBlID09PSAnZGlzYWJsZWQnIDogYy50eXBlICE9PSAnZGlzYWJsZWQnLFxuICAgICAgICAgIClcbiAgICAgICAgOiBjbGllbnRzLmZpbHRlcihjID0+IGMubmFtZSA9PT0gdGFyZ2V0KVxuXG4gICAgaWYgKHRvVG9nZ2xlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgb25Db21wbGV0ZShcbiAgICAgICAgdGFyZ2V0ID09PSAnYWxsJ1xuICAgICAgICAgID8gYEFsbCBNQ1Agc2VydmVycyBhcmUgYWxyZWFkeSAke2lzRW5hYmxpbmcgPyAnZW5hYmxlZCcgOiAnZGlzYWJsZWQnfWBcbiAgICAgICAgICA6IGBNQ1Agc2VydmVyIFwiJHt0YXJnZXR9XCIgbm90IGZvdW5kYCxcbiAgICAgIClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGZvciAoY29uc3QgcyBvZiB0b1RvZ2dsZSkge1xuICAgICAgdm9pZCB0b2dnbGVNY3BTZXJ2ZXIocy5uYW1lKVxuICAgIH1cblxuICAgIG9uQ29tcGxldGUoXG4gICAgICB0YXJnZXQgPT09ICdhbGwnXG4gICAgICAgID8gYCR7aXNFbmFibGluZyA/ICdFbmFibGVkJyA6ICdEaXNhYmxlZCd9ICR7dG9Ub2dnbGUubGVuZ3RofSBNQ1Agc2VydmVyKHMpYFxuICAgICAgICA6IGBNQ1Agc2VydmVyIFwiJHt0YXJnZXR9XCIgJHtpc0VuYWJsaW5nID8gJ2VuYWJsZWQnIDogJ2Rpc2FibGVkJ31gLFxuICAgIClcbiAgfSwgW2FjdGlvbiwgdGFyZ2V0LCBtY3BDbGllbnRzLCB0b2dnbGVNY3BTZXJ2ZXIsIG9uQ29tcGxldGVdKVxuXG4gIHJldHVybiBudWxsXG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjYWxsKFxuICBvbkRvbmU6IExvY2FsSlNYQ29tbWFuZE9uRG9uZSxcbiAgX2NvbnRleHQ6IHVua25vd24sXG4gIGFyZ3M/OiBzdHJpbmcsXG4pOiBQcm9taXNlPFJlYWN0LlJlYWN0Tm9kZT4ge1xuICBpZiAoYXJncykge1xuICAgIGNvbnN0IHBhcnRzID0gYXJncy50cmltKCkuc3BsaXQoL1xccysvKVxuXG4gICAgLy8gQWxsb3cgL21jcCBuby1yZWRpcmVjdCB0byBieXBhc3MgdGhlIHJlZGlyZWN0IGZvciB0ZXN0aW5nXG4gICAgaWYgKHBhcnRzWzBdID09PSAnbm8tcmVkaXJlY3QnKSB7XG4gICAgICByZXR1cm4gPE1DUFNldHRpbmdzIG9uQ29tcGxldGU9e29uRG9uZX0gLz5cbiAgICB9XG5cbiAgICBpZiAocGFydHNbMF0gPT09ICdyZWNvbm5lY3QnICYmIHBhcnRzWzFdKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8TUNQUmVjb25uZWN0XG4gICAgICAgICAgc2VydmVyTmFtZT17cGFydHMuc2xpY2UoMSkuam9pbignICcpfVxuICAgICAgICAgIG9uQ29tcGxldGU9e29uRG9uZX1cbiAgICAgICAgLz5cbiAgICAgIClcbiAgICB9XG5cbiAgICBpZiAocGFydHNbMF0gPT09ICdlbmFibGUnIHx8IHBhcnRzWzBdID09PSAnZGlzYWJsZScpIHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxNQ1BUb2dnbGVcbiAgICAgICAgICBhY3Rpb249e3BhcnRzWzBdfVxuICAgICAgICAgIHRhcmdldD17cGFydHMubGVuZ3RoID4gMSA/IHBhcnRzLnNsaWNlKDEpLmpvaW4oJyAnKSA6ICdhbGwnfVxuICAgICAgICAgIG9uQ29tcGxldGU9e29uRG9uZX1cbiAgICAgICAgLz5cbiAgICAgIClcbiAgICB9XG4gIH1cblxuICAvLyBSZWRpcmVjdCBiYXNlIC9tY3AgY29tbWFuZCB0byAvcGx1Z2lucyBpbnN0YWxsZWQgdGFiIGZvciBhbnQgdXNlcnNcbiAgaWYgKFwiZXh0ZXJuYWxcIiA9PT0gJ2FudCcpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPFBsdWdpblNldHRpbmdzXG4gICAgICAgIG9uQ29tcGxldGU9e29uRG9uZX1cbiAgICAgICAgYXJncz1cIm1hbmFnZVwiXG4gICAgICAgIHNob3dNY3BSZWRpcmVjdE1lc3NhZ2VcbiAgICAgIC8+XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIDxNQ1BTZXR0aW5ncyBvbkNvbXBsZXRlPXtvbkRvbmV9IC8+XG59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
|
src/commands/mcp/xaaIdpCommand.ts
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* `claude mcp xaa` — manage the XAA (SEP-990) IdP connection.
|
| 3 |
+
*
|
| 4 |
+
* The IdP connection is user-level: configure once, all XAA-enabled MCP
|
| 5 |
+
* servers reuse it. Lives in settings.xaaIdp (non-secret) + a keychain slot
|
| 6 |
+
* keyed by issuer (secret). Separate trust domain from per-server AS secrets.
|
| 7 |
+
*/
|
| 8 |
+
import type { Command } from '@commander-js/extra-typings'
|
| 9 |
+
import { cliError, cliOk } from '../../cli/exit.js'
|
| 10 |
+
import {
|
| 11 |
+
acquireIdpIdToken,
|
| 12 |
+
clearIdpClientSecret,
|
| 13 |
+
clearIdpIdToken,
|
| 14 |
+
getCachedIdpIdToken,
|
| 15 |
+
getIdpClientSecret,
|
| 16 |
+
getXaaIdpSettings,
|
| 17 |
+
issuerKey,
|
| 18 |
+
saveIdpClientSecret,
|
| 19 |
+
saveIdpIdTokenFromJwt,
|
| 20 |
+
} from '../../services/mcp/xaaIdpLogin.js'
|
| 21 |
+
import { errorMessage } from '../../utils/errors.js'
|
| 22 |
+
import { updateSettingsForSource } from '../../utils/settings/settings.js'
|
| 23 |
+
|
| 24 |
+
export function registerMcpXaaIdpCommand(mcp: Command): void {
|
| 25 |
+
const xaaIdp = mcp
|
| 26 |
+
.command('xaa')
|
| 27 |
+
.description('Manage the XAA (SEP-990) IdP connection')
|
| 28 |
+
|
| 29 |
+
xaaIdp
|
| 30 |
+
.command('setup')
|
| 31 |
+
.description(
|
| 32 |
+
'Configure the IdP connection (one-time setup for all XAA-enabled servers)',
|
| 33 |
+
)
|
| 34 |
+
.requiredOption('--issuer <url>', 'IdP issuer URL (OIDC discovery)')
|
| 35 |
+
.requiredOption('--client-id <id>', "Claude Code's client_id at the IdP")
|
| 36 |
+
.option(
|
| 37 |
+
'--client-secret',
|
| 38 |
+
'Read IdP client secret from MCP_XAA_IDP_CLIENT_SECRET env var',
|
| 39 |
+
)
|
| 40 |
+
.option(
|
| 41 |
+
'--callback-port <port>',
|
| 42 |
+
'Fixed loopback callback port (only if IdP does not honor RFC 8252 port-any matching)',
|
| 43 |
+
)
|
| 44 |
+
.action(options => {
|
| 45 |
+
// Validate everything BEFORE any writes. An exit(1) mid-write leaves
|
| 46 |
+
// settings configured but keychain missing — confusing state.
|
| 47 |
+
// updateSettingsForSource doesn't schema-check on write; a non-URL
|
| 48 |
+
// issuer lands on disk and then poisons the whole userSettings source
|
| 49 |
+
// on next launch (SettingsSchema .url() fails → parseSettingsFile
|
| 50 |
+
// returns { settings: null }, dropping everything, not just xaaIdp).
|
| 51 |
+
let issuerUrl: URL
|
| 52 |
+
try {
|
| 53 |
+
issuerUrl = new URL(options.issuer)
|
| 54 |
+
} catch {
|
| 55 |
+
return cliError(
|
| 56 |
+
`Error: --issuer must be a valid URL (got "${options.issuer}")`,
|
| 57 |
+
)
|
| 58 |
+
}
|
| 59 |
+
// OIDC discovery + token exchange run against this host. Allow http://
|
| 60 |
+
// only for loopback (conformance harness mock IdP); anything else leaks
|
| 61 |
+
// the client secret and authorization code over plaintext.
|
| 62 |
+
if (
|
| 63 |
+
issuerUrl.protocol !== 'https:' &&
|
| 64 |
+
!(
|
| 65 |
+
issuerUrl.protocol === 'http:' &&
|
| 66 |
+
(issuerUrl.hostname === 'localhost' ||
|
| 67 |
+
issuerUrl.hostname === '127.0.0.1' ||
|
| 68 |
+
issuerUrl.hostname === '[::1]')
|
| 69 |
+
)
|
| 70 |
+
) {
|
| 71 |
+
return cliError(
|
| 72 |
+
`Error: --issuer must use https:// (got "${issuerUrl.protocol}//${issuerUrl.host}")`,
|
| 73 |
+
)
|
| 74 |
+
}
|
| 75 |
+
const callbackPort = options.callbackPort
|
| 76 |
+
? parseInt(options.callbackPort, 10)
|
| 77 |
+
: undefined
|
| 78 |
+
// callbackPort <= 0 fails Zod's .positive() on next launch — same
|
| 79 |
+
// settings-poisoning failure mode as the issuer check above.
|
| 80 |
+
if (
|
| 81 |
+
callbackPort !== undefined &&
|
| 82 |
+
(!Number.isInteger(callbackPort) || callbackPort <= 0)
|
| 83 |
+
) {
|
| 84 |
+
return cliError('Error: --callback-port must be a positive integer')
|
| 85 |
+
}
|
| 86 |
+
const secret = options.clientSecret
|
| 87 |
+
? process.env.MCP_XAA_IDP_CLIENT_SECRET
|
| 88 |
+
: undefined
|
| 89 |
+
if (options.clientSecret && !secret) {
|
| 90 |
+
return cliError(
|
| 91 |
+
'Error: --client-secret requires MCP_XAA_IDP_CLIENT_SECRET env var',
|
| 92 |
+
)
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
// Read old config now (before settings overwrite) so we can clear stale
|
| 96 |
+
// keychain slots after a successful write. `clear` can't do this after
|
| 97 |
+
// the fact — it reads the *current* settings.xaaIdp, which by then is
|
| 98 |
+
// the new one.
|
| 99 |
+
const old = getXaaIdpSettings()
|
| 100 |
+
const oldIssuer = old?.issuer
|
| 101 |
+
const oldClientId = old?.clientId
|
| 102 |
+
|
| 103 |
+
// callbackPort MUST be present (even as undefined) — mergeWith deep-merges
|
| 104 |
+
// and only deletes on explicit `undefined`, not on absent key. A conditional
|
| 105 |
+
// spread would leak a prior fixed port into a new IdP's config.
|
| 106 |
+
const { error } = updateSettingsForSource('userSettings', {
|
| 107 |
+
xaaIdp: {
|
| 108 |
+
issuer: options.issuer,
|
| 109 |
+
clientId: options.clientId,
|
| 110 |
+
callbackPort,
|
| 111 |
+
},
|
| 112 |
+
})
|
| 113 |
+
if (error) {
|
| 114 |
+
return cliError(`Error writing settings: ${error.message}`)
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
// Clear stale keychain slots only after settings write succeeded —
|
| 118 |
+
// otherwise a write failure leaves settings pointing at oldIssuer with
|
| 119 |
+
// its secret already gone. Compare via issuerKey(): trailing-slash or
|
| 120 |
+
// host-case differences normalize to the same keychain slot.
|
| 121 |
+
if (oldIssuer) {
|
| 122 |
+
if (issuerKey(oldIssuer) !== issuerKey(options.issuer)) {
|
| 123 |
+
clearIdpIdToken(oldIssuer)
|
| 124 |
+
clearIdpClientSecret(oldIssuer)
|
| 125 |
+
} else if (oldClientId !== options.clientId) {
|
| 126 |
+
// Same issuer slot but different OAuth client registration — the
|
| 127 |
+
// cached id_token's aud claim and the stored secret are both for the
|
| 128 |
+
// old client. `xaa login` would send {new clientId, old secret} and
|
| 129 |
+
// fail with opaque `invalid_client`; downstream SEP-990 exchange
|
| 130 |
+
// would fail aud validation. Keep both when clientId is unchanged:
|
| 131 |
+
// re-setup without --client-secret means "tweak port, keep secret".
|
| 132 |
+
clearIdpIdToken(oldIssuer)
|
| 133 |
+
clearIdpClientSecret(oldIssuer)
|
| 134 |
+
}
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
if (secret) {
|
| 138 |
+
const { success, warning } = saveIdpClientSecret(options.issuer, secret)
|
| 139 |
+
if (!success) {
|
| 140 |
+
return cliError(
|
| 141 |
+
`Error: settings written but keychain save failed${warning ? ` — ${warning}` : ''}. ` +
|
| 142 |
+
`Re-run with --client-secret once keychain is available.`,
|
| 143 |
+
)
|
| 144 |
+
}
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
cliOk(`XAA IdP connection configured for ${options.issuer}`)
|
| 148 |
+
})
|
| 149 |
+
|
| 150 |
+
xaaIdp
|
| 151 |
+
.command('login')
|
| 152 |
+
.description(
|
| 153 |
+
'Cache an IdP id_token so XAA-enabled MCP servers authenticate ' +
|
| 154 |
+
'silently. Default: run the OIDC browser login. With --id-token: ' +
|
| 155 |
+
'write a pre-obtained JWT directly (used by conformance/e2e tests ' +
|
| 156 |
+
'where the mock IdP does not serve /authorize).',
|
| 157 |
+
)
|
| 158 |
+
.option(
|
| 159 |
+
'--force',
|
| 160 |
+
'Ignore any cached id_token and re-login (useful after IdP-side revocation)',
|
| 161 |
+
)
|
| 162 |
+
// TODO(paulc): read the JWT from stdin instead of argv to keep it out of
|
| 163 |
+
// shell history. Fine for conformance (docker exec uses argv directly,
|
| 164 |
+
// no shell parser), but a real user would want `echo $TOKEN | ... --stdin`.
|
| 165 |
+
.option(
|
| 166 |
+
'--id-token <jwt>',
|
| 167 |
+
'Write this pre-obtained id_token directly to cache, skipping the OIDC browser login',
|
| 168 |
+
)
|
| 169 |
+
.action(async options => {
|
| 170 |
+
const idp = getXaaIdpSettings()
|
| 171 |
+
if (!idp) {
|
| 172 |
+
return cliError(
|
| 173 |
+
"Error: no XAA IdP connection. Run 'claude mcp xaa setup' first.",
|
| 174 |
+
)
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
// Direct-inject path: skip cache check, skip OIDC. Writing IS the
|
| 178 |
+
// operation. Issuer comes from settings (single source of truth), not
|
| 179 |
+
// a separate flag — one less thing to desync.
|
| 180 |
+
if (options.idToken) {
|
| 181 |
+
const expiresAt = saveIdpIdTokenFromJwt(idp.issuer, options.idToken)
|
| 182 |
+
return cliOk(
|
| 183 |
+
`id_token cached for ${idp.issuer} (expires ${new Date(expiresAt).toISOString()})`,
|
| 184 |
+
)
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
if (options.force) {
|
| 188 |
+
clearIdpIdToken(idp.issuer)
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
const wasCached = getCachedIdpIdToken(idp.issuer) !== undefined
|
| 192 |
+
if (wasCached) {
|
| 193 |
+
return cliOk(
|
| 194 |
+
`Already logged in to ${idp.issuer} (cached id_token still valid). Use --force to re-login.`,
|
| 195 |
+
)
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
process.stdout.write(`Opening browser for IdP login at ${idp.issuer}…\n`)
|
| 199 |
+
try {
|
| 200 |
+
await acquireIdpIdToken({
|
| 201 |
+
idpIssuer: idp.issuer,
|
| 202 |
+
idpClientId: idp.clientId,
|
| 203 |
+
idpClientSecret: getIdpClientSecret(idp.issuer),
|
| 204 |
+
callbackPort: idp.callbackPort,
|
| 205 |
+
onAuthorizationUrl: url => {
|
| 206 |
+
process.stdout.write(
|
| 207 |
+
`If the browser did not open, visit:\n ${url}\n`,
|
| 208 |
+
)
|
| 209 |
+
},
|
| 210 |
+
})
|
| 211 |
+
cliOk(
|
| 212 |
+
`Logged in. MCP servers with --xaa will now authenticate silently.`,
|
| 213 |
+
)
|
| 214 |
+
} catch (e) {
|
| 215 |
+
cliError(`IdP login failed: ${errorMessage(e)}`)
|
| 216 |
+
}
|
| 217 |
+
})
|
| 218 |
+
|
| 219 |
+
xaaIdp
|
| 220 |
+
.command('show')
|
| 221 |
+
.description('Show the current IdP connection config')
|
| 222 |
+
.action(() => {
|
| 223 |
+
const idp = getXaaIdpSettings()
|
| 224 |
+
if (!idp) {
|
| 225 |
+
return cliOk('No XAA IdP connection configured.')
|
| 226 |
+
}
|
| 227 |
+
const hasSecret = getIdpClientSecret(idp.issuer) !== undefined
|
| 228 |
+
const hasIdToken = getCachedIdpIdToken(idp.issuer) !== undefined
|
| 229 |
+
process.stdout.write(`Issuer: ${idp.issuer}\n`)
|
| 230 |
+
process.stdout.write(`Client ID: ${idp.clientId}\n`)
|
| 231 |
+
if (idp.callbackPort !== undefined) {
|
| 232 |
+
process.stdout.write(`Callback port: ${idp.callbackPort}\n`)
|
| 233 |
+
}
|
| 234 |
+
process.stdout.write(
|
| 235 |
+
`Client secret: ${hasSecret ? '(stored in keychain)' : '(not set — PKCE-only)'}\n`,
|
| 236 |
+
)
|
| 237 |
+
process.stdout.write(
|
| 238 |
+
`Logged in: ${hasIdToken ? 'yes (id_token cached)' : "no — run 'claude mcp xaa login'"}\n`,
|
| 239 |
+
)
|
| 240 |
+
cliOk()
|
| 241 |
+
})
|
| 242 |
+
|
| 243 |
+
xaaIdp
|
| 244 |
+
.command('clear')
|
| 245 |
+
.description('Clear the IdP connection config and cached id_token')
|
| 246 |
+
.action(() => {
|
| 247 |
+
// Read issuer first so we can clear the right keychain slots.
|
| 248 |
+
const idp = getXaaIdpSettings()
|
| 249 |
+
// updateSettingsForSource uses mergeWith: set to undefined (not delete)
|
| 250 |
+
// to signal key removal.
|
| 251 |
+
const { error } = updateSettingsForSource('userSettings', {
|
| 252 |
+
xaaIdp: undefined,
|
| 253 |
+
})
|
| 254 |
+
if (error) {
|
| 255 |
+
return cliError(`Error writing settings: ${error.message}`)
|
| 256 |
+
}
|
| 257 |
+
// Clear keychain only after settings write succeeded — otherwise a
|
| 258 |
+
// write failure leaves settings pointing at the IdP with its secrets
|
| 259 |
+
// already gone (same pattern as `setup`'s old-issuer cleanup).
|
| 260 |
+
if (idp) {
|
| 261 |
+
clearIdpIdToken(idp.issuer)
|
| 262 |
+
clearIdpClientSecret(idp.issuer)
|
| 263 |
+
}
|
| 264 |
+
cliOk('XAA IdP connection cleared')
|
| 265 |
+
})
|
| 266 |
+
}
|
src/commands/memory/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js'
|
| 2 |
+
|
| 3 |
+
const memory: Command = {
|
| 4 |
+
type: 'local-jsx',
|
| 5 |
+
name: 'memory',
|
| 6 |
+
description: 'Edit Claude memory files',
|
| 7 |
+
load: () => import('./memory.js'),
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
export default memory
|
src/commands/memory/memory.tsx
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { mkdir, writeFile } from 'fs/promises';
|
| 2 |
+
import * as React from 'react';
|
| 3 |
+
import type { CommandResultDisplay } from '../../commands.js';
|
| 4 |
+
import { Dialog } from '../../components/design-system/Dialog.js';
|
| 5 |
+
import { MemoryFileSelector } from '../../components/memory/MemoryFileSelector.js';
|
| 6 |
+
import { getRelativeMemoryPath } from '../../components/memory/MemoryUpdateNotification.js';
|
| 7 |
+
import { Box, Link, Text } from '../../ink.js';
|
| 8 |
+
import type { LocalJSXCommandCall } from '../../types/command.js';
|
| 9 |
+
import { clearMemoryFileCaches, getMemoryFiles } from '../../utils/claudemd.js';
|
| 10 |
+
import { getClaudeConfigHomeDir } from '../../utils/envUtils.js';
|
| 11 |
+
import { getErrnoCode } from '../../utils/errors.js';
|
| 12 |
+
import { logError } from '../../utils/log.js';
|
| 13 |
+
import { editFileInEditor } from '../../utils/promptEditor.js';
|
| 14 |
+
function MemoryCommand({
|
| 15 |
+
onDone
|
| 16 |
+
}: {
|
| 17 |
+
onDone: (result?: string, options?: {
|
| 18 |
+
display?: CommandResultDisplay;
|
| 19 |
+
}) => void;
|
| 20 |
+
}): React.ReactNode {
|
| 21 |
+
const handleSelectMemoryFile = async (memoryPath: string) => {
|
| 22 |
+
try {
|
| 23 |
+
// Create claude directory if it doesn't exist (idempotent with recursive)
|
| 24 |
+
if (memoryPath.includes(getClaudeConfigHomeDir())) {
|
| 25 |
+
await mkdir(getClaudeConfigHomeDir(), {
|
| 26 |
+
recursive: true
|
| 27 |
+
});
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
// Create file if it doesn't exist (wx flag fails if file exists,
|
| 31 |
+
// which we catch to preserve existing content)
|
| 32 |
+
try {
|
| 33 |
+
await writeFile(memoryPath, '', {
|
| 34 |
+
encoding: 'utf8',
|
| 35 |
+
flag: 'wx'
|
| 36 |
+
});
|
| 37 |
+
} catch (e: unknown) {
|
| 38 |
+
if (getErrnoCode(e) !== 'EEXIST') {
|
| 39 |
+
throw e;
|
| 40 |
+
}
|
| 41 |
+
}
|
| 42 |
+
await editFileInEditor(memoryPath);
|
| 43 |
+
|
| 44 |
+
// Determine which environment variable controls the editor
|
| 45 |
+
let editorSource = 'default';
|
| 46 |
+
let editorValue = '';
|
| 47 |
+
if (process.env.VISUAL) {
|
| 48 |
+
editorSource = '$VISUAL';
|
| 49 |
+
editorValue = process.env.VISUAL;
|
| 50 |
+
} else if (process.env.EDITOR) {
|
| 51 |
+
editorSource = '$EDITOR';
|
| 52 |
+
editorValue = process.env.EDITOR;
|
| 53 |
+
}
|
| 54 |
+
const editorInfo = editorSource !== 'default' ? `Using ${editorSource}="${editorValue}".` : '';
|
| 55 |
+
const editorHint = editorInfo ? `> ${editorInfo} To change editor, set $EDITOR or $VISUAL environment variable.` : `> To use a different editor, set the $EDITOR or $VISUAL environment variable.`;
|
| 56 |
+
onDone(`Opened memory file at ${getRelativeMemoryPath(memoryPath)}\n\n${editorHint}`, {
|
| 57 |
+
display: 'system'
|
| 58 |
+
});
|
| 59 |
+
} catch (error) {
|
| 60 |
+
logError(error);
|
| 61 |
+
onDone(`Error opening memory file: ${error}`);
|
| 62 |
+
}
|
| 63 |
+
};
|
| 64 |
+
const handleCancel = () => {
|
| 65 |
+
onDone('Cancelled memory editing', {
|
| 66 |
+
display: 'system'
|
| 67 |
+
});
|
| 68 |
+
};
|
| 69 |
+
return <Dialog title="Memory" onCancel={handleCancel} color="remember">
|
| 70 |
+
<Box flexDirection="column">
|
| 71 |
+
<React.Suspense fallback={null}>
|
| 72 |
+
<MemoryFileSelector onSelect={handleSelectMemoryFile} onCancel={handleCancel} />
|
| 73 |
+
</React.Suspense>
|
| 74 |
+
|
| 75 |
+
<Box marginTop={1}>
|
| 76 |
+
<Text dimColor>
|
| 77 |
+
Learn more: <Link url="https://code.claude.com/docs/en/memory" />
|
| 78 |
+
</Text>
|
| 79 |
+
</Box>
|
| 80 |
+
</Box>
|
| 81 |
+
</Dialog>;
|
| 82 |
+
}
|
| 83 |
+
export const call: LocalJSXCommandCall = async onDone => {
|
| 84 |
+
// Clear + prime before rendering — Suspense handles the unprimed case,
|
| 85 |
+
// but awaiting here avoids a fallback flash on initial open.
|
| 86 |
+
clearMemoryFileCaches();
|
| 87 |
+
await getMemoryFiles();
|
| 88 |
+
return <MemoryCommand onDone={onDone} />;
|
| 89 |
+
};
|
| 90 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJta2RpciIsIndyaXRlRmlsZSIsIlJlYWN0IiwiQ29tbWFuZFJlc3VsdERpc3BsYXkiLCJEaWFsb2ciLCJNZW1vcnlGaWxlU2VsZWN0b3IiLCJnZXRSZWxhdGl2ZU1lbW9yeVBhdGgiLCJCb3giLCJMaW5rIiwiVGV4dCIsIkxvY2FsSlNYQ29tbWFuZENhbGwiLCJjbGVhck1lbW9yeUZpbGVDYWNoZXMiLCJnZXRNZW1vcnlGaWxlcyIsImdldENsYXVkZUNvbmZpZ0hvbWVEaXIiLCJnZXRFcnJub0NvZGUiLCJsb2dFcnJvciIsImVkaXRGaWxlSW5FZGl0b3IiLCJNZW1vcnlDb21tYW5kIiwib25Eb25lIiwicmVzdWx0Iiwib3B0aW9ucyIsImRpc3BsYXkiLCJSZWFjdE5vZGUiLCJoYW5kbGVTZWxlY3RNZW1vcnlGaWxlIiwibWVtb3J5UGF0aCIsImluY2x1ZGVzIiwicmVjdXJzaXZlIiwiZW5jb2RpbmciLCJmbGFnIiwiZSIsImVkaXRvclNvdXJjZSIsImVkaXRvclZhbHVlIiwicHJvY2VzcyIsImVudiIsIlZJU1VBTCIsIkVESVRPUiIsImVkaXRvckluZm8iLCJlZGl0b3JIaW50IiwiZXJyb3IiLCJoYW5kbGVDYW5jZWwiLCJjYWxsIl0sInNvdXJjZXMiOlsibWVtb3J5LnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBta2Rpciwgd3JpdGVGaWxlIH0gZnJvbSAnZnMvcHJvbWlzZXMnXG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCdcbmltcG9ydCB0eXBlIHsgQ29tbWFuZFJlc3VsdERpc3BsYXkgfSBmcm9tICcuLi8uLi9jb21tYW5kcy5qcydcbmltcG9ydCB7IERpYWxvZyB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvZGVzaWduLXN5c3RlbS9EaWFsb2cuanMnXG5pbXBvcnQgeyBNZW1vcnlGaWxlU2VsZWN0b3IgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL21lbW9yeS9NZW1vcnlGaWxlU2VsZWN0b3IuanMnXG5pbXBvcnQgeyBnZXRSZWxhdGl2ZU1lbW9yeVBhdGggfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL21lbW9yeS9NZW1vcnlVcGRhdGVOb3RpZmljYXRpb24uanMnXG5pbXBvcnQgeyBCb3gsIExpbmssIFRleHQgfSBmcm9tICcuLi8uLi9pbmsuanMnXG5pbXBvcnQgdHlwZSB7IExvY2FsSlNYQ29tbWFuZENhbGwgfSBmcm9tICcuLi8uLi90eXBlcy9jb21tYW5kLmpzJ1xuaW1wb3J0IHsgY2xlYXJNZW1vcnlGaWxlQ2FjaGVzLCBnZXRNZW1vcnlGaWxlcyB9IGZyb20gJy4uLy4uL3V0aWxzL2NsYXVkZW1kLmpzJ1xuaW1wb3J0IHsgZ2V0Q2xhdWRlQ29uZmlnSG9tZURpciB9IGZyb20gJy4uLy4uL3V0aWxzL2VudlV0aWxzLmpzJ1xuaW1wb3J0IHsgZ2V0RXJybm9Db2RlIH0gZnJvbSAnLi4vLi4vdXRpbHMvZXJyb3JzLmpzJ1xuaW1wb3J0IHsgbG9nRXJyb3IgfSBmcm9tICcuLi8uLi91dGlscy9sb2cuanMnXG5pbXBvcnQgeyBlZGl0RmlsZUluRWRpdG9yIH0gZnJvbSAnLi4vLi4vdXRpbHMvcHJvbXB0RWRpdG9yLmpzJ1xuXG5mdW5jdGlvbiBNZW1vcnlDb21tYW5kKHtcbiAgb25Eb25lLFxufToge1xuICBvbkRvbmU6IChcbiAgICByZXN1bHQ/OiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IHsgZGlzcGxheT86IENvbW1hbmRSZXN1bHREaXNwbGF5IH0sXG4gICkgPT4gdm9pZFxufSk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGNvbnN0IGhhbmRsZVNlbGVjdE1lbW9yeUZpbGUgPSBhc3luYyAobWVtb3J5UGF0aDogc3RyaW5nKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIENyZWF0ZSBjbGF1ZGUgZGlyZWN0b3J5IGlmIGl0IGRvZXNuJ3QgZXhpc3QgKGlkZW1wb3RlbnQgd2l0aCByZWN1cnNpdmUpXG4gICAgICBpZiAobWVtb3J5UGF0aC5pbmNsdWRlcyhnZXRDbGF1ZGVDb25maWdIb21lRGlyKCkpKSB7XG4gICAgICAgIGF3YWl0IG1rZGlyKGdldENsYXVkZUNvbmZpZ0hvbWVEaXIoKSwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgICAgIH1cblxuICAgICAgLy8gQ3JlYXRlIGZpbGUgaWYgaXQgZG9lc24ndCBleGlzdCAod3ggZmxhZyBmYWlscyBpZiBmaWxlIGV4aXN0cyxcbiAgICAgIC8vIHdoaWNoIHdlIGNhdGNoIHRvIHByZXNlcnZlIGV4aXN0aW5nIGNvbnRlbnQpXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3cml0ZUZpbGUobWVtb3J5UGF0aCwgJycsIHsgZW5jb2Rpbmc6ICd1dGY4JywgZmxhZzogJ3d4JyB9KVxuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICBpZiAoZ2V0RXJybm9Db2RlKGUpICE9PSAnRUVYSVNUJykge1xuICAgICAgICAgIHRocm93IGVcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhd2FpdCBlZGl0RmlsZUluRWRpdG9yKG1lbW9yeVBhdGgpXG5cbiAgICAgIC8vIERldGVybWluZSB3aGljaCBlbnZpcm9ubWVudCB2YXJpYWJsZSBjb250cm9scyB0aGUgZWRpdG9yXG4gICAgICBsZXQgZWRpdG9yU291cmNlID0gJ2RlZmF1bHQnXG4gICAgICBsZXQgZWRpdG9yVmFsdWUgPSAnJ1xuICAgICAgaWYgKHByb2Nlc3MuZW52LlZJU1VBTCkge1xuICAgICAgICBlZGl0b3JTb3VyY2UgPSAnJFZJU1VBTCdcbiAgICAgICAgZWRpdG9yVmFsdWUgPSBwcm9jZXNzLmVudi5WSVNVQUxcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuRURJVE9SKSB7XG4gICAgICAgIGVkaXRvclNvdXJjZSA9ICckRURJVE9SJ1xuICAgICAgICBlZGl0b3JWYWx1ZSA9IHByb2Nlc3MuZW52LkVESVRPUlxuICAgICAgfVxuXG4gICAgICBjb25zdCBlZGl0b3JJbmZvID1cbiAgICAgICAgZWRpdG9yU291cmNlICE9PSAnZGVmYXVsdCdcbiAgICAgICAgICA/IGBVc2luZyAke2VkaXRvclNvdXJjZX09XCIke2VkaXRvclZhbHVlfVwiLmBcbiAgICAgICAgICA6ICcnXG5cbiAgICAgIGNvbnN0IGVkaXRvckhpbnQgPSBlZGl0b3JJbmZvXG4gICAgICAgID8gYD4gJHtlZGl0b3JJbmZvfSBUbyBjaGFuZ2UgZWRpdG9yLCBzZXQgJEVESVRPUiBvciAkVklTVUFMIGVudmlyb25tZW50IHZhcmlhYmxlLmBcbiAgICAgICAgOiBgPiBUbyB1c2UgYSBkaWZmZXJlbnQgZWRpdG9yLCBzZXQgdGhlICRFRElUT1Igb3IgJFZJU1VBTCBlbnZpcm9ubWVudCB2YXJpYWJsZS5gXG5cbiAgICAgIG9uRG9uZShcbiAgICAgICAgYE9wZW5lZCBtZW1vcnkgZmlsZSBhdCAke2dldFJlbGF0aXZlTWVtb3J5UGF0aChtZW1vcnlQYXRoKX1cXG5cXG4ke2VkaXRvckhpbnR9YCxcbiAgICAgICAgeyBkaXNwbGF5OiAnc3lzdGVtJyB9LFxuICAgICAgKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dFcnJvcihlcnJvcilcbiAgICAgIG9uRG9uZShgRXJyb3Igb3BlbmluZyBtZW1vcnkgZmlsZTogJHtlcnJvcn1gKVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGhhbmRsZUNhbmNlbCA9ICgpID0+IHtcbiAgICBvbkRvbmUoJ0NhbmNlbGxlZCBtZW1vcnkgZWRpdGluZycsIHsgZGlzcGxheTogJ3N5c3RlbScgfSlcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPERpYWxvZyB0aXRsZT1cIk1lbW9yeVwiIG9uQ2FuY2VsPXtoYW5kbGVDYW5jZWx9IGNvbG9yPVwicmVtZW1iZXJcIj5cbiAgICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiPlxuICAgICAgICA8UmVhY3QuU3VzcGVuc2UgZmFsbGJhY2s9e251bGx9PlxuICAgICAgICAgIDxNZW1vcnlGaWxlU2VsZWN0b3JcbiAgICAgICAgICAgIG9uU2VsZWN0PXtoYW5kbGVTZWxlY3RNZW1vcnlGaWxlfVxuICAgICAgICAgICAgb25DYW5jZWw9e2hhbmRsZUNhbmNlbH1cbiAgICAgICAgICAvPlxuICAgICAgICA8L1JlYWN0LlN1c3BlbnNlPlxuXG4gICAgICAgIDxCb3ggbWFyZ2luVG9wPXsxfT5cbiAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5cbiAgICAgICAgICAgIExlYXJuIG1vcmU6IDxMaW5rIHVybD1cImh0dHBzOi8vY29kZS5jbGF1ZGUuY29tL2RvY3MvZW4vbWVtb3J5XCIgLz5cbiAgICAgICAgICA8L1RleHQ+XG4gICAgICAgIDwvQm94PlxuICAgICAgPC9Cb3g+XG4gICAgPC9EaWFsb2c+XG4gIClcbn1cblxuZXhwb3J0IGNvbnN0IGNhbGw6IExvY2FsSlNYQ29tbWFuZENhbGwgPSBhc3luYyBvbkRvbmUgPT4ge1xuICAvLyBDbGVhciArIHByaW1lIGJlZm9yZSByZW5kZXJpbmcg4oCUIFN1c3BlbnNlIGhhbmRsZXMgdGhlIHVucHJpbWVkIGNhc2UsXG4gIC8vIGJ1dCBhd2FpdGluZyBoZXJlIGF2b2lkcyBhIGZhbGxiYWNrIGZsYXNoIG9uIGluaXRpYWwgb3Blbi5cbiAgY2xlYXJNZW1vcnlGaWxlQ2FjaGVzKClcbiAgYXdhaXQgZ2V0TWVtb3J5RmlsZXMoKVxuICByZXR1cm4gPE1lbW9yeUNvbW1hbmQgb25Eb25lPXtvbkRvbmV9IC8+XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLEtBQUssRUFBRUMsU0FBUyxRQUFRLGFBQWE7QUFDOUMsT0FBTyxLQUFLQyxLQUFLLE1BQU0sT0FBTztBQUM5QixjQUFjQyxvQkFBb0IsUUFBUSxtQkFBbUI7QUFDN0QsU0FBU0MsTUFBTSxRQUFRLDBDQUEwQztBQUNqRSxTQUFTQyxrQkFBa0IsUUFBUSwrQ0FBK0M7QUFDbEYsU0FBU0MscUJBQXFCLFFBQVEscURBQXFEO0FBQzNGLFNBQVNDLEdBQUcsRUFBRUMsSUFBSSxFQUFFQyxJQUFJLFFBQVEsY0FBYztBQUM5QyxjQUFjQyxtQkFBbUIsUUFBUSx3QkFBd0I7QUFDakUsU0FBU0MscUJBQXFCLEVBQUVDLGNBQWMsUUFBUSx5QkFBeUI7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
|
src/commands/mobile/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js'
|
| 2 |
+
|
| 3 |
+
const mobile = {
|
| 4 |
+
type: 'local-jsx',
|
| 5 |
+
name: 'mobile',
|
| 6 |
+
aliases: ['ios', 'android'],
|
| 7 |
+
description: 'Show QR code to download the Claude mobile app',
|
| 8 |
+
load: () => import('./mobile.js'),
|
| 9 |
+
} satisfies Command
|
| 10 |
+
|
| 11 |
+
export default mobile
|
src/commands/mobile/mobile.tsx
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { c as _c } from "react/compiler-runtime";
|
| 2 |
+
import { toString as qrToString } from 'qrcode';
|
| 3 |
+
import * as React from 'react';
|
| 4 |
+
import { useCallback, useEffect, useState } from 'react';
|
| 5 |
+
import { Pane } from '../../components/design-system/Pane.js';
|
| 6 |
+
import type { KeyboardEvent } from '../../ink/events/keyboard-event.js';
|
| 7 |
+
import { Box, Text } from '../../ink.js';
|
| 8 |
+
import { useKeybinding } from '../../keybindings/useKeybinding.js';
|
| 9 |
+
import type { LocalJSXCommandOnDone } from '../../types/command.js';
|
| 10 |
+
type Platform = 'ios' | 'android';
|
| 11 |
+
type Props = {
|
| 12 |
+
onDone: () => void;
|
| 13 |
+
};
|
| 14 |
+
const PLATFORMS: Record<Platform, {
|
| 15 |
+
url: string;
|
| 16 |
+
}> = {
|
| 17 |
+
ios: {
|
| 18 |
+
url: 'https://apps.apple.com/app/claude-by-anthropic/id6473753684'
|
| 19 |
+
},
|
| 20 |
+
android: {
|
| 21 |
+
url: 'https://play.google.com/store/apps/details?id=com.anthropic.claude'
|
| 22 |
+
}
|
| 23 |
+
};
|
| 24 |
+
function MobileQRCode(t0) {
|
| 25 |
+
const $ = _c(52);
|
| 26 |
+
const {
|
| 27 |
+
onDone
|
| 28 |
+
} = t0;
|
| 29 |
+
const [platform, setPlatform] = useState("ios");
|
| 30 |
+
let t1;
|
| 31 |
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
| 32 |
+
t1 = {
|
| 33 |
+
ios: "",
|
| 34 |
+
android: ""
|
| 35 |
+
};
|
| 36 |
+
$[0] = t1;
|
| 37 |
+
} else {
|
| 38 |
+
t1 = $[0];
|
| 39 |
+
}
|
| 40 |
+
const [qrCodes, setQrCodes] = useState(t1);
|
| 41 |
+
const {
|
| 42 |
+
url
|
| 43 |
+
} = PLATFORMS[platform];
|
| 44 |
+
const qrCode = qrCodes[platform];
|
| 45 |
+
let t2;
|
| 46 |
+
let t3;
|
| 47 |
+
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
| 48 |
+
t2 = () => {
|
| 49 |
+
const generateQRCodes = async function generateQRCodes() {
|
| 50 |
+
const [ios, android] = await Promise.all([qrToString(PLATFORMS.ios.url, {
|
| 51 |
+
type: "utf8",
|
| 52 |
+
errorCorrectionLevel: "L"
|
| 53 |
+
}), qrToString(PLATFORMS.android.url, {
|
| 54 |
+
type: "utf8",
|
| 55 |
+
errorCorrectionLevel: "L"
|
| 56 |
+
})]);
|
| 57 |
+
setQrCodes({
|
| 58 |
+
ios,
|
| 59 |
+
android
|
| 60 |
+
});
|
| 61 |
+
};
|
| 62 |
+
generateQRCodes().catch(_temp);
|
| 63 |
+
};
|
| 64 |
+
t3 = [];
|
| 65 |
+
$[1] = t2;
|
| 66 |
+
$[2] = t3;
|
| 67 |
+
} else {
|
| 68 |
+
t2 = $[1];
|
| 69 |
+
t3 = $[2];
|
| 70 |
+
}
|
| 71 |
+
useEffect(t2, t3);
|
| 72 |
+
let t4;
|
| 73 |
+
if ($[3] !== onDone) {
|
| 74 |
+
t4 = () => {
|
| 75 |
+
onDone();
|
| 76 |
+
};
|
| 77 |
+
$[3] = onDone;
|
| 78 |
+
$[4] = t4;
|
| 79 |
+
} else {
|
| 80 |
+
t4 = $[4];
|
| 81 |
+
}
|
| 82 |
+
const handleClose = t4;
|
| 83 |
+
let t5;
|
| 84 |
+
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
|
| 85 |
+
t5 = {
|
| 86 |
+
context: "Confirmation"
|
| 87 |
+
};
|
| 88 |
+
$[5] = t5;
|
| 89 |
+
} else {
|
| 90 |
+
t5 = $[5];
|
| 91 |
+
}
|
| 92 |
+
useKeybinding("confirm:no", handleClose, t5);
|
| 93 |
+
let t6;
|
| 94 |
+
if ($[6] !== onDone) {
|
| 95 |
+
t6 = function handleKeyDown(e) {
|
| 96 |
+
if (e.key === "q" || e.ctrl && e.key === "c") {
|
| 97 |
+
e.preventDefault();
|
| 98 |
+
onDone();
|
| 99 |
+
return;
|
| 100 |
+
}
|
| 101 |
+
if (e.key === "tab" || e.key === "left" || e.key === "right") {
|
| 102 |
+
e.preventDefault();
|
| 103 |
+
setPlatform(_temp2);
|
| 104 |
+
}
|
| 105 |
+
};
|
| 106 |
+
$[6] = onDone;
|
| 107 |
+
$[7] = t6;
|
| 108 |
+
} else {
|
| 109 |
+
t6 = $[7];
|
| 110 |
+
}
|
| 111 |
+
const handleKeyDown = t6;
|
| 112 |
+
let T0;
|
| 113 |
+
let T1;
|
| 114 |
+
let t10;
|
| 115 |
+
let t11;
|
| 116 |
+
let t12;
|
| 117 |
+
let t13;
|
| 118 |
+
let t7;
|
| 119 |
+
let t8;
|
| 120 |
+
let t9;
|
| 121 |
+
if ($[8] !== handleKeyDown || $[9] !== qrCode) {
|
| 122 |
+
const lines = qrCode.split("\n").filter(_temp3);
|
| 123 |
+
T1 = Pane;
|
| 124 |
+
T0 = Box;
|
| 125 |
+
t7 = "column";
|
| 126 |
+
t8 = 0;
|
| 127 |
+
t9 = true;
|
| 128 |
+
t10 = handleKeyDown;
|
| 129 |
+
if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
|
| 130 |
+
t11 = <Text> </Text>;
|
| 131 |
+
t12 = <Text> </Text>;
|
| 132 |
+
$[19] = t11;
|
| 133 |
+
$[20] = t12;
|
| 134 |
+
} else {
|
| 135 |
+
t11 = $[19];
|
| 136 |
+
t12 = $[20];
|
| 137 |
+
}
|
| 138 |
+
t13 = lines.map(_temp4);
|
| 139 |
+
$[8] = handleKeyDown;
|
| 140 |
+
$[9] = qrCode;
|
| 141 |
+
$[10] = T0;
|
| 142 |
+
$[11] = T1;
|
| 143 |
+
$[12] = t10;
|
| 144 |
+
$[13] = t11;
|
| 145 |
+
$[14] = t12;
|
| 146 |
+
$[15] = t13;
|
| 147 |
+
$[16] = t7;
|
| 148 |
+
$[17] = t8;
|
| 149 |
+
$[18] = t9;
|
| 150 |
+
} else {
|
| 151 |
+
T0 = $[10];
|
| 152 |
+
T1 = $[11];
|
| 153 |
+
t10 = $[12];
|
| 154 |
+
t11 = $[13];
|
| 155 |
+
t12 = $[14];
|
| 156 |
+
t13 = $[15];
|
| 157 |
+
t7 = $[16];
|
| 158 |
+
t8 = $[17];
|
| 159 |
+
t9 = $[18];
|
| 160 |
+
}
|
| 161 |
+
let t14;
|
| 162 |
+
let t15;
|
| 163 |
+
if ($[21] === Symbol.for("react.memo_cache_sentinel")) {
|
| 164 |
+
t14 = <Text> </Text>;
|
| 165 |
+
t15 = <Text> </Text>;
|
| 166 |
+
$[21] = t14;
|
| 167 |
+
$[22] = t15;
|
| 168 |
+
} else {
|
| 169 |
+
t14 = $[21];
|
| 170 |
+
t15 = $[22];
|
| 171 |
+
}
|
| 172 |
+
const t16 = platform === "ios";
|
| 173 |
+
const t17 = platform === "ios";
|
| 174 |
+
let t18;
|
| 175 |
+
if ($[23] !== t16 || $[24] !== t17) {
|
| 176 |
+
t18 = <Text bold={t16} underline={t17}>iOS</Text>;
|
| 177 |
+
$[23] = t16;
|
| 178 |
+
$[24] = t17;
|
| 179 |
+
$[25] = t18;
|
| 180 |
+
} else {
|
| 181 |
+
t18 = $[25];
|
| 182 |
+
}
|
| 183 |
+
let t19;
|
| 184 |
+
if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
|
| 185 |
+
t19 = <Text dimColor={true}>{" / "}</Text>;
|
| 186 |
+
$[26] = t19;
|
| 187 |
+
} else {
|
| 188 |
+
t19 = $[26];
|
| 189 |
+
}
|
| 190 |
+
const t20 = platform === "android";
|
| 191 |
+
const t21 = platform === "android";
|
| 192 |
+
let t22;
|
| 193 |
+
if ($[27] !== t20 || $[28] !== t21) {
|
| 194 |
+
t22 = <Text bold={t20} underline={t21}>Android</Text>;
|
| 195 |
+
$[27] = t20;
|
| 196 |
+
$[28] = t21;
|
| 197 |
+
$[29] = t22;
|
| 198 |
+
} else {
|
| 199 |
+
t22 = $[29];
|
| 200 |
+
}
|
| 201 |
+
let t23;
|
| 202 |
+
if ($[30] !== t18 || $[31] !== t22) {
|
| 203 |
+
t23 = <Text>{t18}{t19}{t22}</Text>;
|
| 204 |
+
$[30] = t18;
|
| 205 |
+
$[31] = t22;
|
| 206 |
+
$[32] = t23;
|
| 207 |
+
} else {
|
| 208 |
+
t23 = $[32];
|
| 209 |
+
}
|
| 210 |
+
let t24;
|
| 211 |
+
if ($[33] === Symbol.for("react.memo_cache_sentinel")) {
|
| 212 |
+
t24 = <Text dimColor={true}>(tab to switch, esc to close)</Text>;
|
| 213 |
+
$[33] = t24;
|
| 214 |
+
} else {
|
| 215 |
+
t24 = $[33];
|
| 216 |
+
}
|
| 217 |
+
let t25;
|
| 218 |
+
if ($[34] !== t23) {
|
| 219 |
+
t25 = <Box flexDirection="row" gap={2}>{t23}{t24}</Box>;
|
| 220 |
+
$[34] = t23;
|
| 221 |
+
$[35] = t25;
|
| 222 |
+
} else {
|
| 223 |
+
t25 = $[35];
|
| 224 |
+
}
|
| 225 |
+
let t26;
|
| 226 |
+
if ($[36] !== url) {
|
| 227 |
+
t26 = <Text dimColor={true}>{url}</Text>;
|
| 228 |
+
$[36] = url;
|
| 229 |
+
$[37] = t26;
|
| 230 |
+
} else {
|
| 231 |
+
t26 = $[37];
|
| 232 |
+
}
|
| 233 |
+
let t27;
|
| 234 |
+
if ($[38] !== T0 || $[39] !== t10 || $[40] !== t11 || $[41] !== t12 || $[42] !== t13 || $[43] !== t25 || $[44] !== t26 || $[45] !== t7 || $[46] !== t8 || $[47] !== t9) {
|
| 235 |
+
t27 = <T0 flexDirection={t7} tabIndex={t8} autoFocus={t9} onKeyDown={t10}>{t11}{t12}{t13}{t14}{t15}{t25}{t26}</T0>;
|
| 236 |
+
$[38] = T0;
|
| 237 |
+
$[39] = t10;
|
| 238 |
+
$[40] = t11;
|
| 239 |
+
$[41] = t12;
|
| 240 |
+
$[42] = t13;
|
| 241 |
+
$[43] = t25;
|
| 242 |
+
$[44] = t26;
|
| 243 |
+
$[45] = t7;
|
| 244 |
+
$[46] = t8;
|
| 245 |
+
$[47] = t9;
|
| 246 |
+
$[48] = t27;
|
| 247 |
+
} else {
|
| 248 |
+
t27 = $[48];
|
| 249 |
+
}
|
| 250 |
+
let t28;
|
| 251 |
+
if ($[49] !== T1 || $[50] !== t27) {
|
| 252 |
+
t28 = <T1>{t27}</T1>;
|
| 253 |
+
$[49] = T1;
|
| 254 |
+
$[50] = t27;
|
| 255 |
+
$[51] = t28;
|
| 256 |
+
} else {
|
| 257 |
+
t28 = $[51];
|
| 258 |
+
}
|
| 259 |
+
return t28;
|
| 260 |
+
}
|
| 261 |
+
function _temp4(line_0, i) {
|
| 262 |
+
return <Text key={i}>{line_0}</Text>;
|
| 263 |
+
}
|
| 264 |
+
function _temp3(line) {
|
| 265 |
+
return line.length > 0;
|
| 266 |
+
}
|
| 267 |
+
function _temp2(prev) {
|
| 268 |
+
return prev === "ios" ? "android" : "ios";
|
| 269 |
+
}
|
| 270 |
+
function _temp() {}
|
| 271 |
+
export async function call(onDone: LocalJSXCommandOnDone): Promise<React.ReactNode> {
|
| 272 |
+
return <MobileQRCode onDone={onDone} />;
|
| 273 |
+
}
|
| 274 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ0b1N0cmluZyIsInFyVG9TdHJpbmciLCJSZWFjdCIsInVzZUNhbGxiYWNrIiwidXNlRWZmZWN0IiwidXNlU3RhdGUiLCJQYW5lIiwiS2V5Ym9hcmRFdmVudCIsIkJveCIsIlRleHQiLCJ1c2VLZXliaW5kaW5nIiwiTG9jYWxKU1hDb21tYW5kT25Eb25lIiwiUGxhdGZvcm0iLCJQcm9wcyIsIm9uRG9uZSIsIlBMQVRGT1JNUyIsIlJlY29yZCIsInVybCIsImlvcyIsImFuZHJvaWQiLCJNb2JpbGVRUkNvZGUiLCJ0MCIsIiQiLCJfYyIsInBsYXRmb3JtIiwic2V0UGxhdGZvcm0iLCJ0MSIsIlN5bWJvbCIsImZvciIsInFyQ29kZXMiLCJzZXRRckNvZGVzIiwicXJDb2RlIiwidDIiLCJ0MyIsImdlbmVyYXRlUVJDb2RlcyIsIlByb21pc2UiLCJhbGwiLCJ0eXBlIiwiZXJyb3JDb3JyZWN0aW9uTGV2ZWwiLCJjYXRjaCIsIl90ZW1wIiwidDQiLCJoYW5kbGVDbG9zZSIsInQ1IiwiY29udGV4dCIsInQ2IiwiaGFuZGxlS2V5RG93biIsImUiLCJrZXkiLCJjdHJsIiwicHJldmVudERlZmF1bHQiLCJfdGVtcDIiLCJUMCIsIlQxIiwidDEwIiwidDExIiwidDEyIiwidDEzIiwidDciLCJ0OCIsInQ5IiwibGluZXMiLCJzcGxpdCIsImZpbHRlciIsIl90ZW1wMyIsIm1hcCIsIl90ZW1wNCIsInQxNCIsInQxNSIsInQxNiIsInQxNyIsInQxOCIsInQxOSIsInQyMCIsInQyMSIsInQyMiIsInQyMyIsInQyNCIsInQyNSIsInQyNiIsInQyNyIsInQyOCIsImxpbmVfMCIsImkiLCJsaW5lIiwibGVuZ3RoIiwicHJldiIsImNhbGwiLCJSZWFjdE5vZGUiXSwic291cmNlcyI6WyJtb2JpbGUudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHRvU3RyaW5nIGFzIHFyVG9TdHJpbmcgfSBmcm9tICdxcmNvZGUnXG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCdcbmltcG9ydCB7IHVzZUNhbGxiYWNrLCB1c2VFZmZlY3QsIHVzZVN0YXRlIH0gZnJvbSAncmVhY3QnXG5pbXBvcnQgeyBQYW5lIH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9kZXNpZ24tc3lzdGVtL1BhbmUuanMnXG5pbXBvcnQgdHlwZSB7IEtleWJvYXJkRXZlbnQgfSBmcm9tICcuLi8uLi9pbmsvZXZlbnRzL2tleWJvYXJkLWV2ZW50LmpzJ1xuaW1wb3J0IHsgQm94LCBUZXh0IH0gZnJvbSAnLi4vLi4vaW5rLmpzJ1xuaW1wb3J0IHsgdXNlS2V5YmluZGluZyB9IGZyb20gJy4uLy4uL2tleWJpbmRpbmdzL3VzZUtleWJpbmRpbmcuanMnXG5pbXBvcnQgdHlwZSB7IExvY2FsSlNYQ29tbWFuZE9uRG9uZSB9IGZyb20gJy4uLy4uL3R5cGVzL2NvbW1hbmQuanMnXG5cbnR5cGUgUGxhdGZvcm0gPSAnaW9zJyB8ICdhbmRyb2lkJ1xuXG50eXBlIFByb3BzID0ge1xuICBvbkRvbmU6ICgpID0+IHZvaWRcbn1cblxuY29uc3QgUExBVEZPUk1TOiBSZWNvcmQ8UGxhdGZvcm0sIHsgdXJsOiBzdHJpbmcgfT4gPSB7XG4gIGlvczoge1xuICAgIHVybDogJ2h0dHBzOi8vYXBwcy5hcHBsZS5jb20vYXBwL2NsYXVkZS1ieS1hbnRocm9waWMvaWQ2NDczNzUzNjg0JyxcbiAgfSxcbiAgYW5kcm9pZDoge1xuICAgIHVybDogJ2h0dHBzOi8vcGxheS5nb29nbGUuY29tL3N0b3JlL2FwcHMvZGV0YWlscz9pZD1jb20uYW50aHJvcGljLmNsYXVkZScsXG4gIH0sXG59XG5cbmZ1bmN0aW9uIE1vYmlsZVFSQ29kZSh7IG9uRG9uZSB9OiBQcm9wcyk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGNvbnN0IFtwbGF0Zm9ybSwgc2V0UGxhdGZvcm1dID0gdXNlU3RhdGU8UGxhdGZvcm0+KCdpb3MnKVxuICBjb25zdCBbcXJDb2Rlcywgc2V0UXJDb2Rlc10gPSB1c2VTdGF0ZTxSZWNvcmQ8UGxhdGZvcm0sIHN0cmluZz4+KHtcbiAgICBpb3M6ICcnLFxuICAgIGFuZHJvaWQ6ICcnLFxuICB9KVxuXG4gIGNvbnN0IHsgdXJsIH0gPSBQTEFURk9STVNbcGxhdGZvcm1dXG4gIGNvbnN0IHFyQ29kZSA9IHFyQ29kZXNbcGxhdGZvcm1dXG5cbiAgLy8gR2VuZXJhdGUgYm90aCBRUiBjb2RlcyB1cGZyb250IHRvIGF2b2lkIGZsaWNrZXIgd2hlbiBzd2l0Y2hpbmdcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZVFSQ29kZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCBbaW9zLCBhbmRyb2lkXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgcXJUb1N0cmluZyhQTEFURk9STVMuaW9zLnVybCwge1xuICAgICAgICAgIHR5cGU6ICd1dGY4JyxcbiAgICAgICAgICBlcnJvckNvcnJlY3Rpb25MZXZlbDogJ0wnLFxuICAgICAgICB9KSxcbiAgICAgICAgcXJUb1N0cmluZyhQTEFURk9STVMuYW5kcm9pZC51cmwsIHtcbiAgICAgICAgICB0eXBlOiAndXRmOCcsXG4gICAgICAgICAgZXJyb3JDb3JyZWN0aW9uTGV2ZWw6ICdMJyxcbiAgICAgICAgfSksXG4gICAgICBdKVxuICAgICAgc2V0UXJDb2Rlcyh7IGlvcywgYW5kcm9pZCB9KVxuICAgIH1cbiAgICBnZW5lcmF0ZVFSQ29kZXMoKS5jYXRjaCgoKSA9PiB7XG4gICAgICAvLyBRUiBnZW5lcmF0aW9uIGZhaWxlZCwgbGVhdmUgZW1wdHlcbiAgICB9KVxuICB9LCBbXSlcblxuICBjb25zdCBoYW5kbGVDbG9zZSA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBvbkRvbmUoKVxuICB9LCBbb25Eb25lXSlcblxuICB1c2VLZXliaW5kaW5nKCdjb25maXJtOm5vJywgaGFuZGxlQ2xvc2UsIHsgY29udGV4dDogJ0NvbmZpcm1hdGlvbicgfSlcblxuICBmdW5jdGlvbiBoYW5kbGVLZXlEb3duKGU6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZS5rZXkgPT09ICdxJyB8fCAoZS5jdHJsICYmIGUua2V5ID09PSAnYycpKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgIG9uRG9uZSgpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGUua2V5ID09PSAndGFiJyB8fCBlLmtleSA9PT0gJ2xlZnQnIHx8IGUua2V5ID09PSAncmlnaHQnKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgIHNldFBsYXRmb3JtKHByZXYgPT4gKHByZXYgPT09ICdpb3MnID8gJ2FuZHJvaWQnIDogJ2lvcycpKVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGxpbmVzID0gcXJDb2RlLnNwbGl0KCdcXG4nKS5maWx0ZXIobGluZSA9PiBsaW5lLmxlbmd0aCA+IDApXG5cbiAgcmV0dXJuIChcbiAgICA8UGFuZT5cbiAgICAgIDxCb3hcbiAgICAgICAgZmxleERpcmVjdGlvbj1cImNvbHVtblwiXG4gICAgICAgIHRhYkluZGV4PXswfVxuICAgICAgICBhdXRvRm9jdXNcbiAgICAgICAgb25LZXlEb3duPXtoYW5kbGVLZXlEb3dufVxuICAgICAgPlxuICAgICAgICA8VGV4dD4gPC9UZXh0PlxuICAgICAgICA8VGV4dD4gPC9UZXh0PlxuICAgICAgICB7bGluZXMubWFwKChsaW5lLCBpKSA9PiAoXG4gICAgICAgICAgPFRleHQga2V5PXtpfT57bGluZX08L1RleHQ+XG4gICAgICAgICkpfVxuICAgICAgICA8VGV4dD4gPC9UZXh0PlxuICAgICAgICA8VGV4dD4gPC9UZXh0PlxuXG4gICAgICAgIHsvKiBDb250cm9scyAqL31cbiAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwicm93XCIgZ2FwPXsyfT5cbiAgICAgICAgICA8VGV4dD5cbiAgICAgICAgICAgIDxUZXh0IGJvbGQ9e3BsYXRmb3JtID09PSAnaW9zJ30gdW5kZXJsaW5lPXtwbGF0Zm9ybSA9PT0gJ2lvcyd9PlxuICAgICAgICAgICAgICBpT1NcbiAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPnsnIC8gJ308L1RleHQ+XG4gICAgICAgICAgICA8VGV4dFxuICAgICAgICAgICAgICBib2xkPXtwbGF0Zm9ybSA9PT0gJ2FuZHJvaWQnfVxuICAgICAgICAgICAgICB1bmRlcmxpbmU9e3BsYXRmb3JtID09PSAnYW5kcm9pZCd9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIEFuZHJvaWRcbiAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgPFRleHQgZGltQ29sb3I+KHRhYiB0byBzd2l0Y2gsIGVzYyB0byBjbG9zZSk8L1RleHQ+XG4gICAgICAgIDwvQm94PlxuICAgICAgICA8VGV4dCBkaW1Db2xvcj57dXJsfTwvVGV4dD5cbiAgICAgIDwvQm94PlxuICAgIDwvUGFuZT5cbiAgKVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2FsbChcbiAgb25Eb25lOiBMb2NhbEpTWENvbW1hbmRPbkRvbmUsXG4pOiBQcm9taXNlPFJlYWN0LlJlYWN0Tm9kZT4ge1xuICByZXR1cm4gPE1vYmlsZVFSQ29kZSBvbkRvbmU9e29uRG9uZX0gLz5cbn1cbiJdLCJtYXBwaW5ncyI6IjtBQUFBLFNBQVNBLFFBQVEsSUFBSUMsVUFBVSxRQUFRLFFBQVE7QUFDL0MsT0FBTyxLQUFLQyxLQUFLLE1BQU0sT0FBTztBQUM5QixTQUFTQyxXQUFXLEVBQUVDLFNBQVMsRUFBRUMsUUFBUSxRQUFRLE9BQU87QUFDeEQsU0FBU0MsSUFBSSxRQUFRLHdDQUF3QztBQUM3RCxjQUFjQyxhQUFhLFFBQVEsb0NBQW9DO0FBQ3ZFLFNBQVNDLEdBQUcsRUFBRUMsSUFBSSxRQUFRLGNBQWM7QUFDeEMsU0FBU0MsYUFBYSxRQUFRLG9DQUFvQztBQUNsRSxjQUFjQyxxQkFBcUIsUUFBUSx3QkFBd0I7QUFFbkUsS0FBS0MsUUFBUSxHQUFHLEtBQUssR0FBRyxTQUFTO0FBRWpDLEtBQUtDLEtBQUssR0FBRztFQUNYQyxNQUFN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
|
src/commands/mock-limits/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
export default { isEnabled: () => false, isHidden: true, name: 'stub' };
|
src/commands/model/index.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js'
|
| 2 |
+
import { shouldInferenceConfigCommandBeImmediate } from '../../utils/immediateCommand.js'
|
| 3 |
+
import { getMainLoopModel, renderModelName } from '../../utils/model/model.js'
|
| 4 |
+
|
| 5 |
+
export default {
|
| 6 |
+
type: 'local-jsx',
|
| 7 |
+
name: 'model',
|
| 8 |
+
get description() {
|
| 9 |
+
return `Set the AI model for Claude Code (currently ${renderModelName(getMainLoopModel())})`
|
| 10 |
+
},
|
| 11 |
+
argumentHint: '[model]',
|
| 12 |
+
get immediate() {
|
| 13 |
+
return shouldInferenceConfigCommandBeImmediate()
|
| 14 |
+
},
|
| 15 |
+
load: () => import('./model.js'),
|
| 16 |
+
} satisfies Command
|
src/commands/model/model.tsx
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { c as _c } from "react/compiler-runtime";
|
| 2 |
+
import chalk from 'chalk';
|
| 3 |
+
import * as React from 'react';
|
| 4 |
+
import type { CommandResultDisplay } from '../../commands.js';
|
| 5 |
+
import { ModelPicker } from '../../components/ModelPicker.js';
|
| 6 |
+
import { COMMON_HELP_ARGS, COMMON_INFO_ARGS } from '../../constants/xml.js';
|
| 7 |
+
import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from '../../services/analytics/index.js';
|
| 8 |
+
import { useAppState, useSetAppState } from '../../state/AppState.js';
|
| 9 |
+
import type { LocalJSXCommandCall } from '../../types/command.js';
|
| 10 |
+
import type { EffortLevel } from '../../utils/effort.js';
|
| 11 |
+
import { isBilledAsExtraUsage } from '../../utils/extraUsage.js';
|
| 12 |
+
import { clearFastModeCooldown, isFastModeAvailable, isFastModeEnabled, isFastModeSupportedByModel } from '../../utils/fastMode.js';
|
| 13 |
+
import { MODEL_ALIASES } from '../../utils/model/aliases.js';
|
| 14 |
+
import { checkOpus1mAccess, checkSonnet1mAccess } from '../../utils/model/check1mAccess.js';
|
| 15 |
+
import { getDefaultMainLoopModelSetting, isOpus1mMergeEnabled, renderDefaultModelSetting } from '../../utils/model/model.js';
|
| 16 |
+
import { isModelAllowed } from '../../utils/model/modelAllowlist.js';
|
| 17 |
+
import { validateModel } from '../../utils/model/validateModel.js';
|
| 18 |
+
function ModelPickerWrapper(t0) {
|
| 19 |
+
const $ = _c(17);
|
| 20 |
+
const {
|
| 21 |
+
onDone
|
| 22 |
+
} = t0;
|
| 23 |
+
const mainLoopModel = useAppState(_temp);
|
| 24 |
+
const mainLoopModelForSession = useAppState(_temp2);
|
| 25 |
+
const isFastMode = useAppState(_temp3);
|
| 26 |
+
const setAppState = useSetAppState();
|
| 27 |
+
let t1;
|
| 28 |
+
if ($[0] !== mainLoopModel || $[1] !== onDone) {
|
| 29 |
+
t1 = function handleCancel() {
|
| 30 |
+
logEvent("tengu_model_command_menu", {
|
| 31 |
+
action: "cancel" as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
|
| 32 |
+
});
|
| 33 |
+
const displayModel = renderModelLabel(mainLoopModel);
|
| 34 |
+
onDone(`Kept model as ${chalk.bold(displayModel)}`, {
|
| 35 |
+
display: "system"
|
| 36 |
+
});
|
| 37 |
+
};
|
| 38 |
+
$[0] = mainLoopModel;
|
| 39 |
+
$[1] = onDone;
|
| 40 |
+
$[2] = t1;
|
| 41 |
+
} else {
|
| 42 |
+
t1 = $[2];
|
| 43 |
+
}
|
| 44 |
+
const handleCancel = t1;
|
| 45 |
+
let t2;
|
| 46 |
+
if ($[3] !== isFastMode || $[4] !== mainLoopModel || $[5] !== onDone || $[6] !== setAppState) {
|
| 47 |
+
t2 = function handleSelect(model, effort) {
|
| 48 |
+
logEvent("tengu_model_command_menu", {
|
| 49 |
+
action: model as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
| 50 |
+
from_model: mainLoopModel as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
| 51 |
+
to_model: model as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
|
| 52 |
+
});
|
| 53 |
+
setAppState(prev => ({
|
| 54 |
+
...prev,
|
| 55 |
+
mainLoopModel: model,
|
| 56 |
+
mainLoopModelForSession: null
|
| 57 |
+
}));
|
| 58 |
+
let message = `Set model to ${chalk.bold(renderModelLabel(model))}`;
|
| 59 |
+
if (effort !== undefined) {
|
| 60 |
+
message = message + ` with ${chalk.bold(effort)} effort`;
|
| 61 |
+
}
|
| 62 |
+
let wasFastModeToggledOn = undefined;
|
| 63 |
+
if (isFastModeEnabled()) {
|
| 64 |
+
clearFastModeCooldown();
|
| 65 |
+
if (!isFastModeSupportedByModel(model) && isFastMode) {
|
| 66 |
+
setAppState(_temp4);
|
| 67 |
+
wasFastModeToggledOn = false;
|
| 68 |
+
} else {
|
| 69 |
+
if (isFastModeSupportedByModel(model) && isFastModeAvailable() && isFastMode) {
|
| 70 |
+
message = message + " \xB7 Fast mode ON";
|
| 71 |
+
wasFastModeToggledOn = true;
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
if (isBilledAsExtraUsage(model, wasFastModeToggledOn === true, isOpus1mMergeEnabled())) {
|
| 76 |
+
message = message + " \xB7 Billed as extra usage";
|
| 77 |
+
}
|
| 78 |
+
if (wasFastModeToggledOn === false) {
|
| 79 |
+
message = message + " \xB7 Fast mode OFF";
|
| 80 |
+
}
|
| 81 |
+
onDone(message);
|
| 82 |
+
};
|
| 83 |
+
$[3] = isFastMode;
|
| 84 |
+
$[4] = mainLoopModel;
|
| 85 |
+
$[5] = onDone;
|
| 86 |
+
$[6] = setAppState;
|
| 87 |
+
$[7] = t2;
|
| 88 |
+
} else {
|
| 89 |
+
t2 = $[7];
|
| 90 |
+
}
|
| 91 |
+
const handleSelect = t2;
|
| 92 |
+
let t3;
|
| 93 |
+
if ($[8] !== isFastMode || $[9] !== mainLoopModel) {
|
| 94 |
+
t3 = isFastModeEnabled() && isFastMode && isFastModeSupportedByModel(mainLoopModel) && isFastModeAvailable();
|
| 95 |
+
$[8] = isFastMode;
|
| 96 |
+
$[9] = mainLoopModel;
|
| 97 |
+
$[10] = t3;
|
| 98 |
+
} else {
|
| 99 |
+
t3 = $[10];
|
| 100 |
+
}
|
| 101 |
+
let t4;
|
| 102 |
+
if ($[11] !== handleCancel || $[12] !== handleSelect || $[13] !== mainLoopModel || $[14] !== mainLoopModelForSession || $[15] !== t3) {
|
| 103 |
+
t4 = <ModelPicker initial={mainLoopModel} sessionModel={mainLoopModelForSession} onSelect={handleSelect} onCancel={handleCancel} isStandaloneCommand={true} showFastModeNotice={t3} />;
|
| 104 |
+
$[11] = handleCancel;
|
| 105 |
+
$[12] = handleSelect;
|
| 106 |
+
$[13] = mainLoopModel;
|
| 107 |
+
$[14] = mainLoopModelForSession;
|
| 108 |
+
$[15] = t3;
|
| 109 |
+
$[16] = t4;
|
| 110 |
+
} else {
|
| 111 |
+
t4 = $[16];
|
| 112 |
+
}
|
| 113 |
+
return t4;
|
| 114 |
+
}
|
| 115 |
+
function _temp4(prev_0) {
|
| 116 |
+
return {
|
| 117 |
+
...prev_0,
|
| 118 |
+
fastMode: false
|
| 119 |
+
};
|
| 120 |
+
}
|
| 121 |
+
function _temp3(s_1) {
|
| 122 |
+
return s_1.fastMode;
|
| 123 |
+
}
|
| 124 |
+
function _temp2(s_0) {
|
| 125 |
+
return s_0.mainLoopModelForSession;
|
| 126 |
+
}
|
| 127 |
+
function _temp(s) {
|
| 128 |
+
return s.mainLoopModel;
|
| 129 |
+
}
|
| 130 |
+
function SetModelAndClose({
|
| 131 |
+
args,
|
| 132 |
+
onDone
|
| 133 |
+
}: {
|
| 134 |
+
args: string;
|
| 135 |
+
onDone: (result?: string, options?: {
|
| 136 |
+
display?: CommandResultDisplay;
|
| 137 |
+
}) => void;
|
| 138 |
+
}): React.ReactNode {
|
| 139 |
+
const isFastMode = useAppState(s => s.fastMode);
|
| 140 |
+
const setAppState = useSetAppState();
|
| 141 |
+
const model = args === 'default' ? null : args;
|
| 142 |
+
React.useEffect(() => {
|
| 143 |
+
async function handleModelChange(): Promise<void> {
|
| 144 |
+
if (model && !isModelAllowed(model)) {
|
| 145 |
+
onDone(`Model '${model}' is not available. Your organization restricts model selection.`, {
|
| 146 |
+
display: 'system'
|
| 147 |
+
});
|
| 148 |
+
return;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
// @[MODEL LAUNCH]: Update check for 1M access.
|
| 152 |
+
if (model && isOpus1mUnavailable(model)) {
|
| 153 |
+
onDone(`Opus 4.6 with 1M context is not available for your account. Learn more: https://code.claude.com/docs/en/model-config#extended-context-with-1m`, {
|
| 154 |
+
display: 'system'
|
| 155 |
+
});
|
| 156 |
+
return;
|
| 157 |
+
}
|
| 158 |
+
if (model && isSonnet1mUnavailable(model)) {
|
| 159 |
+
onDone(`Sonnet 4.6 with 1M context is not available for your account. Learn more: https://code.claude.com/docs/en/model-config#extended-context-with-1m`, {
|
| 160 |
+
display: 'system'
|
| 161 |
+
});
|
| 162 |
+
return;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
// Skip validation for default model
|
| 166 |
+
if (!model) {
|
| 167 |
+
setModel(null);
|
| 168 |
+
return;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
// Skip validation for known aliases - they're predefined and should work
|
| 172 |
+
if (isKnownAlias(model)) {
|
| 173 |
+
setModel(model);
|
| 174 |
+
return;
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
// Validate and set custom model
|
| 178 |
+
try {
|
| 179 |
+
// Don't use parseUserSpecifiedModel for non-aliases since it lowercases the input
|
| 180 |
+
// and model names are case-sensitive
|
| 181 |
+
const {
|
| 182 |
+
valid,
|
| 183 |
+
error: error_0
|
| 184 |
+
} = await validateModel(model);
|
| 185 |
+
if (valid) {
|
| 186 |
+
setModel(model);
|
| 187 |
+
} else {
|
| 188 |
+
onDone(error_0 || `Model '${model}' not found`, {
|
| 189 |
+
display: 'system'
|
| 190 |
+
});
|
| 191 |
+
}
|
| 192 |
+
} catch (error) {
|
| 193 |
+
onDone(`Failed to validate model: ${(error as Error).message}`, {
|
| 194 |
+
display: 'system'
|
| 195 |
+
});
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
function setModel(modelValue: string | null): void {
|
| 199 |
+
setAppState(prev => ({
|
| 200 |
+
...prev,
|
| 201 |
+
mainLoopModel: modelValue,
|
| 202 |
+
mainLoopModelForSession: null
|
| 203 |
+
}));
|
| 204 |
+
let message = `Set model to ${chalk.bold(renderModelLabel(modelValue))}`;
|
| 205 |
+
let wasFastModeToggledOn = undefined;
|
| 206 |
+
if (isFastModeEnabled()) {
|
| 207 |
+
clearFastModeCooldown();
|
| 208 |
+
if (!isFastModeSupportedByModel(modelValue) && isFastMode) {
|
| 209 |
+
setAppState(prev_0 => ({
|
| 210 |
+
...prev_0,
|
| 211 |
+
fastMode: false
|
| 212 |
+
}));
|
| 213 |
+
wasFastModeToggledOn = false;
|
| 214 |
+
// Do not update fast mode in settings since this is an automatic downgrade
|
| 215 |
+
} else if (isFastModeSupportedByModel(modelValue) && isFastMode) {
|
| 216 |
+
message += ` · Fast mode ON`;
|
| 217 |
+
wasFastModeToggledOn = true;
|
| 218 |
+
}
|
| 219 |
+
}
|
| 220 |
+
if (isBilledAsExtraUsage(modelValue, wasFastModeToggledOn === true, isOpus1mMergeEnabled())) {
|
| 221 |
+
message += ` · Billed as extra usage`;
|
| 222 |
+
}
|
| 223 |
+
if (wasFastModeToggledOn === false) {
|
| 224 |
+
// Fast mode was toggled off, show suffix after extra usage billing
|
| 225 |
+
message += ` · Fast mode OFF`;
|
| 226 |
+
}
|
| 227 |
+
onDone(message);
|
| 228 |
+
}
|
| 229 |
+
void handleModelChange();
|
| 230 |
+
}, [model, onDone, setAppState]);
|
| 231 |
+
return null;
|
| 232 |
+
}
|
| 233 |
+
function isKnownAlias(model: string): boolean {
|
| 234 |
+
return (MODEL_ALIASES as readonly string[]).includes(model.toLowerCase().trim());
|
| 235 |
+
}
|
| 236 |
+
function isOpus1mUnavailable(model: string): boolean {
|
| 237 |
+
const m = model.toLowerCase();
|
| 238 |
+
return !checkOpus1mAccess() && !isOpus1mMergeEnabled() && m.includes('opus') && m.includes('[1m]');
|
| 239 |
+
}
|
| 240 |
+
function isSonnet1mUnavailable(model: string): boolean {
|
| 241 |
+
const m = model.toLowerCase();
|
| 242 |
+
// Warn about Sonnet and Sonnet 4.6, but not Sonnet 4.5 since that had
|
| 243 |
+
// a different access criteria.
|
| 244 |
+
return !checkSonnet1mAccess() && (m.includes('sonnet[1m]') || m.includes('sonnet-4-6[1m]'));
|
| 245 |
+
}
|
| 246 |
+
function ShowModelAndClose(t0) {
|
| 247 |
+
const {
|
| 248 |
+
onDone
|
| 249 |
+
} = t0;
|
| 250 |
+
const mainLoopModel = useAppState(_temp7);
|
| 251 |
+
const mainLoopModelForSession = useAppState(_temp8);
|
| 252 |
+
const effortValue = useAppState(_temp9);
|
| 253 |
+
const displayModel = renderModelLabel(mainLoopModel);
|
| 254 |
+
const effortInfo = effortValue !== undefined ? ` (effort: ${effortValue})` : "";
|
| 255 |
+
if (mainLoopModelForSession) {
|
| 256 |
+
onDone(`Current model: ${chalk.bold(renderModelLabel(mainLoopModelForSession))} (session override from plan mode)\nBase model: ${displayModel}${effortInfo}`);
|
| 257 |
+
} else {
|
| 258 |
+
onDone(`Current model: ${displayModel}${effortInfo}`);
|
| 259 |
+
}
|
| 260 |
+
return null;
|
| 261 |
+
}
|
| 262 |
+
function _temp9(s_1) {
|
| 263 |
+
return s_1.effortValue;
|
| 264 |
+
}
|
| 265 |
+
function _temp8(s_0) {
|
| 266 |
+
return s_0.mainLoopModelForSession;
|
| 267 |
+
}
|
| 268 |
+
function _temp7(s) {
|
| 269 |
+
return s.mainLoopModel;
|
| 270 |
+
}
|
| 271 |
+
export const call: LocalJSXCommandCall = async (onDone, _context, args) => {
|
| 272 |
+
args = args?.trim() || '';
|
| 273 |
+
if (COMMON_INFO_ARGS.includes(args)) {
|
| 274 |
+
logEvent('tengu_model_command_inline_help', {
|
| 275 |
+
args: args as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
|
| 276 |
+
});
|
| 277 |
+
return <ShowModelAndClose onDone={onDone} />;
|
| 278 |
+
}
|
| 279 |
+
if (COMMON_HELP_ARGS.includes(args)) {
|
| 280 |
+
onDone('Run /model to open the model selection menu, or /model [modelName] to set the model.', {
|
| 281 |
+
display: 'system'
|
| 282 |
+
});
|
| 283 |
+
return;
|
| 284 |
+
}
|
| 285 |
+
if (args) {
|
| 286 |
+
logEvent('tengu_model_command_inline', {
|
| 287 |
+
args: args as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
|
| 288 |
+
});
|
| 289 |
+
return <SetModelAndClose args={args} onDone={onDone} />;
|
| 290 |
+
}
|
| 291 |
+
return <ModelPickerWrapper onDone={onDone} />;
|
| 292 |
+
};
|
| 293 |
+
function renderModelLabel(model: string | null): string {
|
| 294 |
+
const rendered = renderDefaultModelSetting(model ?? getDefaultMainLoopModelSetting());
|
| 295 |
+
return model === null ? `${rendered} (default)` : rendered;
|
| 296 |
+
}
|
| 297 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjaGFsayIsIlJlYWN0IiwiQ29tbWFuZFJlc3VsdERpc3BsYXkiLCJNb2RlbFBpY2tlciIsIkNPTU1PTl9IRUxQX0FSR1MiLCJDT01NT05fSU5GT19BUkdTIiwiQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIUyIsImxvZ0V2ZW50IiwidXNlQXBwU3RhdGUiLCJ1c2VTZXRBcHBTdGF0ZSIsIkxvY2FsSlNYQ29tbWFuZENhbGwiLCJFZmZvcnRMZXZlbCIsImlzQmlsbGVkQXNFeHRyYVVzYWdlIiwiY2xlYXJGYXN0TW9kZUNvb2xkb3duIiwiaXNGYXN0TW9kZUF2YWlsYWJsZSIsImlzRmFzdE1vZGVFbmFibGVkIiwiaXNGYXN0TW9kZVN1cHBvcnRlZEJ5TW9kZWwiLCJNT0RFTF9BTElBU0VTIiwiY2hlY2tPcHVzMW1BY2Nlc3MiLCJjaGVja1Nvbm5ldDFtQWNjZXNzIiwiZ2V0RGVmYXVsdE1haW5Mb29wTW9kZWxTZXR0aW5nIiwiaXNPcHVzMW1NZXJnZUVuYWJsZWQiLCJyZW5kZXJEZWZhdWx0TW9kZWxTZXR0aW5nIiwiaXNNb2RlbEFsbG93ZWQiLCJ2YWxpZGF0ZU1vZGVsIiwiTW9kZWxQaWNrZXJXcmFwcGVyIiwidDAiLCIkIiwiX2MiLCJvbkRvbmUiLCJtYWluTG9vcE1vZGVsIiwiX3RlbXAiLCJtYWluTG9vcE1vZGVsRm9yU2Vzc2lvbiIsIl90ZW1wMiIsImlzRmFzdE1vZGUiLCJfdGVtcDMiLCJzZXRBcHBTdGF0ZSIsInQxIiwiaGFuZGxlQ2FuY2VsIiwiYWN0aW9uIiwiZGlzcGxheU1vZGVsIiwicmVuZGVyTW9kZWxMYWJlbCIsImJvbGQiLCJkaXNwbGF5IiwidDIiLCJoYW5kbGVTZWxlY3QiLCJtb2RlbCIsImVmZm9ydCIsImZyb21fbW9kZWwiLCJ0b19tb2RlbCIsInByZXYiLCJtZXNzYWdlIiwidW5kZWZpbmVkIiwid2FzRmFzdE1vZGVUb2dnbGVkT24iLCJfdGVtcDQiLCJ0MyIsInQ0IiwicHJldl8wIiwiZmFzdE1vZGUiLCJzXzEiLCJzIiwic18wIiwiU2V0TW9kZWxBbmRDbG9zZSIsImFyZ3MiLCJyZXN1bHQiLCJvcHRpb25zIiwiUmVhY3ROb2RlIiwidXNlRWZmZWN0IiwiaGFuZGxlTW9kZWxDaGFuZ2UiLCJQcm9taXNlIiwiaXNPcHVzMW1VbmF2YWlsYWJsZSIsImlzU29ubmV0MW1VbmF2YWlsYWJsZSIsInNldE1vZGVsIiwiaXNLbm93bkFsaWFzIiwidmFsaWQiLCJlcnJvciIsIkVycm9yIiwibW9kZWxWYWx1ZSIsImluY2x1ZGVzIiwidG9Mb3dlckNhc2UiLCJ0cmltIiwibSIsIlNob3dNb2RlbEFuZENsb3NlIiwiX3RlbXA3IiwiX3RlbXA4IiwiZWZmb3J0VmFsdWUiLCJfdGVtcDkiLCJlZmZvcnRJbmZvIiwiY2FsbCIsIl9jb250ZXh0IiwicmVuZGVyZWQiXSwic291cmNlcyI6WyJtb2RlbC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNoYWxrIGZyb20gJ2NoYWxrJ1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnXG5pbXBvcnQgdHlwZSB7IENvbW1hbmRSZXN1bHREaXNwbGF5IH0gZnJvbSAnLi4vLi4vY29tbWFuZHMuanMnXG5pbXBvcnQgeyBNb2RlbFBpY2tlciB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvTW9kZWxQaWNrZXIuanMnXG5pbXBvcnQgeyBDT01NT05fSEVMUF9BUkdTLCBDT01NT05fSU5GT19BUkdTIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzL3htbC5qcydcbmltcG9ydCB7XG4gIHR5cGUgQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIUyxcbiAgbG9nRXZlbnQsXG59IGZyb20gJy4uLy4uL3NlcnZpY2VzL2FuYWx5dGljcy9pbmRleC5qcydcbmltcG9ydCB7IHVzZUFwcFN0YXRlLCB1c2VTZXRBcHBTdGF0ZSB9IGZyb20gJy4uLy4uL3N0YXRlL0FwcFN0YXRlLmpzJ1xuaW1wb3J0IHR5cGUgeyBMb2NhbEpTWENvbW1hbmRDYWxsIH0gZnJvbSAnLi4vLi4vdHlwZXMvY29tbWFuZC5qcydcbmltcG9ydCB0eXBlIHsgRWZmb3J0TGV2ZWwgfSBmcm9tICcuLi8uLi91dGlscy9lZmZvcnQuanMnXG5pbXBvcnQgeyBpc0JpbGxlZEFzRXh0cmFVc2FnZSB9IGZyb20gJy4uLy4uL3V0aWxzL2V4dHJhVXNhZ2UuanMnXG5pbXBvcnQge1xuICBjbGVhckZhc3RNb2RlQ29vbGRvd24sXG4gIGlzRmFzdE1vZGVBdmFpbGFibGUsXG4gIGlzRmFzdE1vZGVFbmFibGVkLFxuICBpc0Zhc3RNb2RlU3VwcG9ydGVkQnlNb2RlbCxcbn0gZnJvbSAnLi4vLi4vdXRpbHMvZmFzdE1vZGUuanMnXG5pbXBvcnQgeyBNT0RFTF9BTElBU0VTIH0gZnJvbSAnLi4vLi4vdXRpbHMvbW9kZWwvYWxpYXNlcy5qcydcbmltcG9ydCB7XG4gIGNoZWNrT3B1czFtQWNjZXNzLFxuICBjaGVja1Nvbm5ldDFtQWNjZXNzLFxufSBmcm9tICcuLi8uLi91dGlscy9tb2RlbC9jaGVjazFtQWNjZXNzLmpzJ1xuaW1wb3J0IHtcbiAgZ2V0RGVmYXVsdE1haW5Mb29wTW9kZWxTZXR0aW5nLFxuICBpc09wdXMxbU1lcmdlRW5hYmxlZCxcbiAgcmVuZGVyRGVmYXVsdE1vZGVsU2V0dGluZyxcbn0gZnJvbSAnLi4vLi4vdXRpbHMvbW9kZWwvbW9kZWwuanMnXG5pbXBvcnQgeyBpc01vZGVsQWxsb3dlZCB9IGZyb20gJy4uLy4uL3V0aWxzL21vZGVsL21vZGVsQWxsb3dsaXN0LmpzJ1xuaW1wb3J0IHsgdmFsaWRhdGVNb2RlbCB9IGZyb20gJy4uLy4uL3V0aWxzL21vZGVsL3ZhbGlkYXRlTW9kZWwuanMnXG5cbmZ1bmN0aW9uIE1vZGVsUGlja2VyV3JhcHBlcih7XG4gIG9uRG9uZSxcbn06IHtcbiAgb25Eb25lOiAoXG4gICAgcmVzdWx0Pzogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiB7IGRpc3BsYXk/OiBDb21tYW5kUmVzdWx0RGlzcGxheSB9LFxuICApID0+IHZvaWRcbn0pOiBSZWFjdC5SZWFjdE5vZGUge1xuICBjb25zdCBtYWluTG9vcE1vZGVsID0gdXNlQXBwU3RhdGUocyA9PiBzLm1haW5Mb29wTW9kZWwpXG4gIGNvbnN0IG1haW5Mb29wTW9kZWxGb3JTZXNzaW9uID0gdXNlQXBwU3RhdGUocyA9PiBzLm1haW5Mb29wTW9kZWxGb3JTZXNzaW9uKVxuICBjb25zdCBpc0Zhc3RNb2RlID0gdXNlQXBwU3RhdGUocyA9PiBzLmZhc3RNb2RlKVxuICBjb25zdCBzZXRBcHBTdGF0ZSA9IHVzZVNldEFwcFN0YXRlKClcblxuICBmdW5jdGlvbiBoYW5kbGVDYW5jZWwoKTogdm9pZCB7XG4gICAgbG9nRXZlbnQoJ3Rlbmd1X21vZGVsX2NvbW1hbmRfbWVudScsIHtcbiAgICAgIGFjdGlvbjpcbiAgICAgICAgJ2NhbmNlbCcgYXMgQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIUyxcbiAgICB9KVxuICAgIGNvbnN0IGRpc3BsYXlNb2RlbCA9IHJlbmRlck1vZGVsTGFiZWwobWFpbkxvb3BNb2RlbClcbiAgICBvbkRvbmUoYEtlcHQgbW9kZWwgYXMgJHtjaGFsay5ib2xkKGRpc3BsYXlNb2RlbCl9YCwge1xuICAgICAgZGlzcGxheTogJ3N5c3RlbScsXG4gICAgfSlcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZVNlbGVjdChcbiAgICBtb2RlbDogc3RyaW5nIHwgbnVsbCxcbiAgICBlZmZvcnQ6IEVmZm9ydExldmVsIHwgdW5kZWZpbmVkLFxuICApOiB2b2lkIHtcbiAgICBsb2dFdmVudCgndGVuZ3VfbW9kZWxfY29tbWFuZF9tZW51Jywge1xuICAgICAgYWN0aW9uOlxuICAgICAgICBtb2RlbCBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgICAgZnJvbV9tb2RlbDpcbiAgICAgICAgbWFpbkxvb3BNb2RlbCBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgICAgdG9fbW9kZWw6XG4gICAgICAgIG1vZGVsIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgfSlcbiAgICBzZXRBcHBTdGF0ZShwcmV2ID0+ICh7XG4gICAgICAuLi5wcmV2LFxuICAgICAgbWFpbkxvb3BNb2RlbDogbW9kZWwsXG4gICAgICBtYWluTG9vcE1vZGVsRm9yU2Vzc2lvbjogbnVsbCxcbiAgICB9KSlcblxuICAgIGxldCBtZXNzYWdlID0gYFNldCBtb2RlbCB0byAke2NoYWxrLmJvbGQocmVuZGVyTW9kZWxMYWJlbChtb2RlbCkpfWBcbiAgICBpZiAoZWZmb3J0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1lc3NhZ2UgKz0gYCB3aXRoICR7Y2hhbGsuYm9sZChlZmZvcnQpfSBlZmZvcnRgXG4gICAgfVxuXG4gICAgLy8gVHVybiBvZmYgZmFzdCBtb2RlIGlmIHN3aXRjaGluZyB0byB1bnN1cHBvcnRlZCBtb2RlbFxuICAgIGxldCB3YXNGYXN0TW9kZVRvZ2dsZWRPbiA9IHVuZGVmaW5lZFxuICAgIGlmIChpc0Zhc3RNb2RlRW5hYmxlZCgpKSB7XG4gICAgICBjbGVhckZhc3RNb2RlQ29vbGRvd24oKVxuICAgICAgaWYgKCFpc0Zhc3RNb2RlU3VwcG9ydGVkQnlNb2RlbChtb2RlbCkgJiYgaXNGYXN0TW9kZSkge1xuICAgICAgICBzZXRBcHBTdGF0ZShwcmV2ID0+ICh7XG4gICAgICAgICAgLi4ucHJldixcbiAgICAgICAgICBmYXN0TW9kZTogZmFsc2UsXG4gICAgICAgIH0pKVxuICAgICAgICB3YXNGYXN0TW9kZVRvZ2dsZWRPbiA9IGZhbHNlXG4gICAgICAgIC8vIERvIG5vdCB1cGRhdGUgZmFzdCBtb2RlIGluIHNldHRpbmdzIHNpbmNlIHRoaXMgaXMgYW4gYXV0b21hdGljIGRvd25ncmFkZVxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgaXNGYXN0TW9kZVN1cHBvcnRlZEJ5TW9kZWwobW9kZWwpICYmXG4gICAgICAgIGlzRmFzdE1vZGVBdmFpbGFibGUoKSAmJlxuICAgICAgICBpc0Zhc3RNb2RlXG4gICAgICApIHtcbiAgICAgICAgbWVzc2FnZSArPSBgIMK3IEZhc3QgbW9kZSBPTmBcbiAgICAgICAgd2FzRmFzdE1vZGVUb2dnbGVkT24gPSB0cnVlXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgaXNCaWxsZWRBc0V4dHJhVXNhZ2UoXG4gICAgICAgIG1vZGVsLFxuICAgICAgICB3YXNGYXN0TW9kZVRvZ2dsZWRPbiA9PT0gdHJ1ZSxcbiAgICAgICAgaXNPcHVzMW1NZXJnZUVuYWJsZWQoKSxcbiAgICAgIClcbiAgICApIHtcbiAgICAgIG1lc3NhZ2UgKz0gYCDCtyBCaWxsZWQgYXMgZXh0cmEgdXNhZ2VgXG4gICAgfVxuXG4gICAgaWYgKHdhc0Zhc3RNb2RlVG9nZ2xlZE9uID09PSBmYWxzZSkge1xuICAgICAgLy8gRmFzdCBtb2RlIHdhcyB0b2dnbGVkIG9mZiwgc2hvdyBzdWZmaXggYWZ0ZXIgZXh0cmEgdXNhZ2UgYmlsbGluZ1xuICAgICAgbWVzc2FnZSArPSBgIMK3IEZhc3QgbW9kZSBPRkZgXG4gICAgfVxuXG4gICAgb25Eb25lKG1lc3NhZ2UpXG4gIH1cblxuICByZXR1cm4gKFxuICAgIDxNb2RlbFBpY2tlclxuICAgICAgaW5pdGlhbD17bWFpbkxvb3BNb2RlbH1cbiAgICAgIHNlc3Npb25Nb2RlbD17bWFpbkxvb3BNb2RlbEZvclNlc3Npb259XG4gICAgICBvblNlbGVjdD17aGFuZGxlU2VsZWN0fVxuICAgICAgb25DYW5jZWw9e2hhbmRsZUNhbmNlbH1cbiAgICAgIGlzU3RhbmRhbG9uZUNvbW1hbmRcbiAgICAgIHNob3dGYXN0TW9kZU5vdGljZT17XG4gICAgICAgIGlzRmFzdE1vZGVFbmFibGVkKCkgJiZcbiAgICAgICAgaXNGYXN0TW9kZSAmJlxuICAgICAgICBpc0Zhc3RNb2RlU3VwcG9ydGVkQnlNb2RlbChtYWluTG9vcE1vZGVsKSAmJlxuICAgICAgICBpc0Zhc3RNb2RlQXZhaWxhYmxlKClcbiAgICAgIH1cbiAgICAvPlxuICApXG59XG5cbmZ1bmN0aW9uIFNldE1vZGVsQW5kQ2xvc2Uoe1xuICBhcmdzLFxuICBvbkRvbmUsXG59OiB7XG4gIGFyZ3M6IHN0cmluZ1xuICBvbkRvbmU6IChcbiAgICByZXN1bHQ/OiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IHsgZGlzcGxheT86IENvbW1hbmRSZXN1bHREaXNwbGF5IH0sXG4gICkgPT4gdm9pZFxufSk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGNvbnN0IGlzRmFzdE1vZGUgPSB1c2VBcHBTdGF0ZShzID0+IHMuZmFzdE1vZGUpXG4gIGNvbnN0IHNldEFwcFN0YXRlID0gdXNlU2V0QXBwU3RhdGUoKVxuICBjb25zdCBtb2RlbCA9IGFyZ3MgPT09ICdkZWZhdWx0JyA/IG51bGwgOiBhcmdzXG5cbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBhc3luYyBmdW5jdGlvbiBoYW5kbGVNb2RlbENoYW5nZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGlmIChtb2RlbCAmJiAhaXNNb2RlbEFsbG93ZWQobW9kZWwpKSB7XG4gICAgICAgIG9uRG9uZShcbiAgICAgICAgICBgTW9kZWwgJyR7bW9kZWx9JyBpcyBub3QgYXZhaWxhYmxlLiBZb3VyIG9yZ2FuaXphdGlvbiByZXN0cmljdHMgbW9kZWwgc2VsZWN0aW9uLmAsXG4gICAgICAgICAgeyBkaXNwbGF5OiAnc3lzdGVtJyB9LFxuICAgICAgICApXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICAvLyBAW01PREVMIExBVU5DSF06IFVwZGF0ZSBjaGVjayBmb3IgMU0gYWNjZXNzLlxuICAgICAgaWYgKG1vZGVsICYmIGlzT3B1czFtVW5hdmFpbGFibGUobW9kZWwpKSB7XG4gICAgICAgIG9uRG9uZShcbiAgICAgICAgICBgT3B1cyA0LjYgd2l0aCAxTSBjb250ZXh0IGlzIG5vdCBhdmFpbGFibGUgZm9yIHlvdXIgYWNjb3VudC4gTGVhcm4gbW9yZTogaHR0cHM6Ly9jb2RlLmNsYXVkZS5jb20vZG9jcy9lbi9tb2RlbC1jb25maWcjZXh0ZW5kZWQtY29udGV4dC13aXRoLTFtYCxcbiAgICAgICAgICB7IGRpc3BsYXk6ICdzeXN0ZW0nIH0sXG4gICAgICAgIClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGlmIChtb2RlbCAmJiBpc1Nvbm5ldDFtVW5hdmFpbGFibGUobW9kZWwpKSB7XG4gICAgICAgIG9uRG9uZShcbiAgICAgICAgICBgU29ubmV0IDQuNiB3aXRoIDFNIGNvbnRleHQgaXMgbm90IGF2YWlsYWJsZSBmb3IgeW91ciBhY2NvdW50LiBMZWFybiBtb3JlOiBodHRwczovL2NvZGUuY2xhdWRlLmNvbS9kb2NzL2VuL21vZGVsLWNvbmZpZyNleHRlbmRlZC1jb250ZXh0LXdpdGgtMW1gLFxuICAgICAgICAgIHsgZGlzcGxheTogJ3N5c3RlbScgfSxcbiAgICAgICAgKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgLy8gU2tpcCB2YWxpZGF0aW9uIGZvciBkZWZhdWx0IG1vZGVsXG4gICAgICBpZiAoIW1vZGVsKSB7XG4gICAgICAgIHNldE1vZGVsKG51bGwpXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICAvLyBTa2lwIHZhbGlkYXRpb24gZm9yIGtub3duIGFsaWFzZXMgLSB0aGV5J3JlIHByZWRlZmluZWQgYW5kIHNob3VsZCB3b3JrXG4gICAgICBpZiAoaXNLbm93bkFsaWFzKG1vZGVsKSkge1xuICAgICAgICBzZXRNb2RlbChtb2RlbClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIC8vIFZhbGlkYXRlIGFuZCBzZXQgY3VzdG9tIG1vZGVsXG4gICAgICB0cnkge1xuICAgICAgICAvLyBEb24ndCB1c2UgcGFyc2VVc2VyU3BlY2lmaWVkTW9kZWwgZm9yIG5vbi1hbGlhc2VzIHNpbmNlIGl0IGxvd2VyY2FzZXMgdGhlIGlucHV0XG4gICAgICAgIC8vIGFuZCBtb2RlbCBuYW1lcyBhcmUgY2FzZS1zZW5zaXRpdmVcbiAgICAgICAgY29uc3QgeyB2YWxpZCwgZXJyb3IgfSA9IGF3YWl0IHZhbGlkYXRlTW9kZWwobW9kZWwpXG5cbiAgICAgICAgaWYgKHZhbGlkKSB7XG4gICAgICAgICAgc2V0TW9kZWwobW9kZWwpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb25Eb25lKGVycm9yIHx8IGBNb2RlbCAnJHttb2RlbH0nIG5vdCBmb3VuZGAsIHtcbiAgICAgICAgICAgIGRpc3BsYXk6ICdzeXN0ZW0nLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIG9uRG9uZShgRmFpbGVkIHRvIHZhbGlkYXRlIG1vZGVsOiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gLCB7XG4gICAgICAgICAgZGlzcGxheTogJ3N5c3RlbScsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0TW9kZWwobW9kZWxWYWx1ZTogc3RyaW5nIHwgbnVsbCk6IHZvaWQge1xuICAgICAgc2V0QXBwU3RhdGUocHJldiA9PiAoe1xuICAgICAgICAuLi5wcmV2LFxuICAgICAgICBtYWluTG9vcE1vZGVsOiBtb2RlbFZhbHVlLFxuICAgICAgICBtYWluTG9vcE1vZGVsRm9yU2Vzc2lvbjogbnVsbCxcbiAgICAgIH0pKVxuICAgICAgbGV0IG1lc3NhZ2UgPSBgU2V0IG1vZGVsIHRvICR7Y2hhbGsuYm9sZChyZW5kZXJNb2RlbExhYmVsKG1vZGVsVmFsdWUpKX1gXG5cbiAgICAgIGxldCB3YXNGYXN0TW9kZVRvZ2dsZWRPbiA9IHVuZGVmaW5lZFxuICAgICAgaWYgKGlzRmFzdE1vZGVFbmFibGVkKCkpIHtcbiAgICAgICAgY2xlYXJGYXN0TW9kZUNvb2xkb3duKClcbiAgICAgICAgaWYgKCFpc0Zhc3RNb2RlU3VwcG9ydGVkQnlNb2RlbChtb2RlbFZhbHVlKSAmJiBpc0Zhc3RNb2RlKSB7XG4gICAgICAgICAgc2V0QXBwU3RhdGUocHJldiA9PiAoe1xuICAgICAgICAgICAgLi4ucHJldixcbiAgICAgICAgICAgIGZhc3RNb2RlOiBmYWxzZSxcbiAgICAgICAgICB9KSlcbiAgICAgICAgICB3YXNGYXN0TW9kZVRvZ2dsZWRPbiA9IGZhbHNlXG4gICAgICAgICAgLy8gRG8gbm90IHVwZGF0ZSBmYXN0IG1vZGUgaW4gc2V0dGluZ3Mgc2luY2UgdGhpcyBpcyBhbiBhdXRvbWF0aWMgZG93bmdyYWRlXG4gICAgICAgIH0gZWxzZSBpZiAoaXNGYXN0TW9kZVN1cHBvcnRlZEJ5TW9kZWwobW9kZWxWYWx1ZSkgJiYgaXNGYXN0TW9kZSkge1xuICAgICAgICAgIG1lc3NhZ2UgKz0gYCDCtyBGYXN0IG1vZGUgT05gXG4gICAgICAgICAgd2FzRmFzdE1vZGVUb2dnbGVkT24gPSB0cnVlXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBpc0JpbGxlZEFzRXh0cmFVc2FnZShcbiAgICAgICAgICBtb2RlbFZhbHVlLFxuICAgICAgICAgIHdhc0Zhc3RNb2RlVG9nZ2xlZE9uID09PSB0cnVlLFxuICAgICAgICAgIGlzT3B1czFtTWVyZ2VFbmFibGVkKCksXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICBtZXNzYWdlICs9IGAgwrcgQmlsbGVkIGFzIGV4dHJhIHVzYWdlYFxuICAgICAgfVxuXG4gICAgICBpZiAod2FzRmFzdE1vZGVUb2dnbGVkT24gPT09IGZhbHNlKSB7XG4gICAgICAgIC8vIEZhc3QgbW9kZSB3YXMgdG9nZ2xlZCBvZmYsIHNob3cgc3VmZml4IGFmdGVyIGV4dHJhIHVzYWdlIGJpbGxpbmdcbiAgICAgICAgbWVzc2FnZSArPSBgIMK3IEZhc3QgbW9kZSBPRkZgXG4gICAgICB9XG5cbiAgICAgIG9uRG9uZShtZXNzYWdlKVxuICAgIH1cblxuICAgIHZvaWQgaGFuZGxlTW9kZWxDaGFuZ2UoKVxuICB9LCBbbW9kZWwsIG9uRG9uZSwgc2V0QXBwU3RhdGVdKVxuXG4gIHJldHVybiBudWxsXG59XG5cbmZ1bmN0aW9uIGlzS25vd25BbGlhcyhtb2RlbDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAoTU9ERUxfQUxJQVNFUyBhcyByZWFkb25seSBzdHJpbmdbXSkuaW5jbHVkZXMoXG4gICAgbW9kZWwudG9Mb3dlckNhc2UoKS50cmltKCksXG4gIClcbn1cblxuZnVuY3Rpb24gaXNPcHVzMW1VbmF2YWlsYWJsZShtb2RlbDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IG0gPSBtb2RlbC50b0xvd2VyQ2FzZSgpXG4gIHJldHVybiAoXG4gICAgIWNoZWNrT3B1czFtQWNjZXNzKCkgJiZcbiAgICAhaXNPcHVzMW1NZXJnZUVuYWJsZWQoKSAmJlxuICAgIG0uaW5jbHVkZXMoJ29wdXMnKSAmJlxuICAgIG0uaW5jbHVkZXMoJ1sxbV0nKVxuICApXG59XG5cbmZ1bmN0aW9uIGlzU29ubmV0MW1VbmF2YWlsYWJsZShtb2RlbDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IG0gPSBtb2RlbC50b0xvd2VyQ2FzZSgpXG4gIC8vIFdhcm4gYWJvdXQgU29ubmV0IGFuZCBTb25uZXQgNC42LCBidXQgbm90IFNvbm5ldCA0LjUgc2luY2UgdGhhdCBoYWRcbiAgLy8gYSBkaWZmZXJlbnQgYWNjZXNzIGNyaXRlcmlhLlxuICByZXR1cm4gKFxuICAgICFjaGVja1Nvbm5ldDFtQWNjZXNzKCkgJiZcbiAgICAobS5pbmNsdWRlcygnc29ubmV0WzFtXScpIHx8IG0uaW5jbHVkZXMoJ3Nvbm5ldC00LTZbMW1dJykpXG4gIClcbn1cblxuZnVuY3Rpb24gU2hvd01vZGVsQW5kQ2xvc2Uoe1xuICBvbkRvbmUsXG59OiB7XG4gIG9uRG9uZTogKHJlc3VsdD86IHN0cmluZykgPT4gdm9pZFxufSk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGNvbnN0IG1haW5Mb29wTW9kZWwgPSB1c2VBcHBTdGF0ZShzID0+IHMubWFpbkxvb3BNb2RlbClcbiAgY29uc3QgbWFpbkxvb3BNb2RlbEZvclNlc3Npb24gPSB1c2VBcHBTdGF0ZShzID0+IHMubWFpbkxvb3BNb2RlbEZvclNlc3Npb24pXG4gIGNvbnN0IGVmZm9ydFZhbHVlID0gdXNlQXBwU3RhdGUocyA9PiBzLmVmZm9ydFZhbHVlKVxuICBjb25zdCBkaXNwbGF5TW9kZWwgPSByZW5kZXJNb2RlbExhYmVsKG1haW5Mb29wTW9kZWwpXG4gIGNvbnN0IGVmZm9ydEluZm8gPVxuICAgIGVmZm9ydFZhbHVlICE9PSB1bmRlZmluZWQgPyBgIChlZmZvcnQ6ICR7ZWZmb3J0VmFsdWV9KWAgOiAnJ1xuXG4gIGlmIChtYWluTG9vcE1vZGVsRm9yU2Vzc2lvbikge1xuICAgIG9uRG9uZShcbiAgICAgIGBDdXJyZW50IG1vZGVsOiAke2NoYWxrLmJvbGQocmVuZGVyTW9kZWxMYWJlbChtYWluTG9vcE1vZGVsRm9yU2Vzc2lvbikpfSAoc2Vzc2lvbiBvdmVycmlkZSBmcm9tIHBsYW4gbW9kZSlcXG5CYXNlIG1vZGVsOiAke2Rpc3BsYXlNb2RlbH0ke2VmZm9ydEluZm99YCxcbiAgICApXG4gIH0gZWxzZSB7XG4gICAgb25Eb25lKGBDdXJyZW50IG1vZGVsOiAke2Rpc3BsYXlNb2RlbH0ke2VmZm9ydEluZm99YClcbiAgfVxuXG4gIHJldHVybiBudWxsXG59XG5cbmV4cG9ydCBjb25zdCBjYWxsOiBMb2NhbEpTWENvbW1hbmRDYWxsID0gYXN5bmMgKG9uRG9uZSwgX2NvbnRleHQsIGFyZ3MpID0+IHtcbiAgYXJncyA9IGFyZ3M/LnRyaW0oKSB8fCAnJ1xuICBpZiAoQ09NTU9OX0lORk9fQVJHUy5pbmNsdWRlcyhhcmdzKSkge1xuICAgIGxvZ0V2ZW50KCd0ZW5ndV9tb2RlbF9jb21tYW5kX2lubGluZV9oZWxwJywge1xuICAgICAgYXJnczogYXJncyBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgIH0pXG4gICAgcmV0dXJuIDxTaG93TW9kZWxBbmRDbG9zZSBvbkRvbmU9e29uRG9uZX0gLz5cbiAgfVxuICBpZiAoQ09NTU9OX0hFTFBfQVJHUy5pbmNsdWRlcyhhcmdzKSkge1xuICAgIG9uRG9uZShcbiAgICAgICdSdW4gL21vZGVsIHRvIG9wZW4gdGhlIG1vZGVsIHNlbGVjdGlvbiBtZW51LCBvciAvbW9kZWwgW21vZGVsTmFtZV0gdG8gc2V0IHRoZSBtb2RlbC4nLFxuICAgICAgeyBkaXNwbGF5OiAnc3lzdGVtJyB9LFxuICAgIClcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmIChhcmdzKSB7XG4gICAgbG9nRXZlbnQoJ3Rlbmd1X21vZGVsX2NvbW1hbmRfaW5saW5lJywge1xuICAgICAgYXJnczogYXJncyBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgIH0pXG4gICAgcmV0dXJuIDxTZXRNb2RlbEFuZENsb3NlIGFyZ3M9e2FyZ3N9IG9uRG9uZT17b25Eb25lfSAvPlxuICB9XG5cbiAgcmV0dXJuIDxNb2RlbFBpY2tlcldyYXBwZXIgb25Eb25lPXtvbkRvbmV9IC8+XG59XG5cbmZ1bmN0aW9uIHJlbmRlck1vZGVsTGFiZWwobW9kZWw6IHN0cmluZyB8IG51bGwpOiBzdHJpbmcge1xuICBjb25zdCByZW5kZXJlZCA9IHJlbmRlckRlZmF1bHRNb2RlbFNldHRpbmcoXG4gICAgbW9kZWwgPz8gZ2V0RGVmYXVsdE1haW5Mb29wTW9kZWxTZXR0aW5nKCksXG4gIClcbiAgcmV0dXJuIG1vZGVsID09PSBudWxsID8gYCR7cmVuZGVyZWR9IChkZWZhdWx0KWAgOiByZW5kZXJlZFxufVxuIl0sIm1hcHBpbmdzIjoiO0FBQUEsT0FBT0EsS0FBSyxNQUFNLE9BQU87QUFDekIsT0FBTyxLQUFLQyxLQUFLLE1BQU0sT0FBTztBQUM5QixjQUFjQyxvQkFBb0IsUUFBUSxtQkFBbUI7QUFDN0QsU0FBU0MsV0FBVyxRQUFRLGlDQUFpQztBQUM3RCxTQUFT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
|
src/commands/oauth-refresh/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
export default { isEnabled: () => false, isHidden: true, name: 'stub' };
|
src/commands/onboarding/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
export default { isEnabled: () => false, isHidden: true, name: 'stub' };
|
src/commands/output-style/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js'
|
| 2 |
+
|
| 3 |
+
const outputStyle = {
|
| 4 |
+
type: 'local-jsx',
|
| 5 |
+
name: 'output-style',
|
| 6 |
+
description: 'Deprecated: use /config to change output style',
|
| 7 |
+
isHidden: true,
|
| 8 |
+
load: () => import('./output-style.js'),
|
| 9 |
+
} satisfies Command
|
| 10 |
+
|
| 11 |
+
export default outputStyle
|
src/commands/output-style/output-style.tsx
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { LocalJSXCommandOnDone } from '../../types/command.js';
|
| 2 |
+
export async function call(onDone: LocalJSXCommandOnDone): Promise<undefined> {
|
| 3 |
+
onDone('/output-style has been deprecated. Use /config to change your output style, or set it in your settings file. Changes take effect on the next session.', {
|
| 4 |
+
display: 'system'
|
| 5 |
+
});
|
| 6 |
+
}
|
| 7 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJMb2NhbEpTWENvbW1hbmRPbkRvbmUiLCJjYWxsIiwib25Eb25lIiwiUHJvbWlzZSIsImRpc3BsYXkiXSwic291cmNlcyI6WyJvdXRwdXQtc3R5bGUudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgTG9jYWxKU1hDb21tYW5kT25Eb25lIH0gZnJvbSAnLi4vLi4vdHlwZXMvY29tbWFuZC5qcydcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNhbGwob25Eb25lOiBMb2NhbEpTWENvbW1hbmRPbkRvbmUpOiBQcm9taXNlPHVuZGVmaW5lZD4ge1xuICBvbkRvbmUoXG4gICAgJy9vdXRwdXQtc3R5bGUgaGFzIGJlZW4gZGVwcmVjYXRlZC4gVXNlIC9jb25maWcgdG8gY2hhbmdlIHlvdXIgb3V0cHV0IHN0eWxlLCBvciBzZXQgaXQgaW4geW91ciBzZXR0aW5ncyBmaWxlLiBDaGFuZ2VzIHRha2UgZWZmZWN0IG9uIHRoZSBuZXh0IHNlc3Npb24uJyxcbiAgICB7IGRpc3BsYXk6ICdzeXN0ZW0nIH0sXG4gIClcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsY0FBY0EscUJBQXFCLFFBQVEsd0JBQXdCO0FBRW5FLE9BQU8sZUFBZUMsSUFBSUEsQ0FBQ0MsTUFBTSxFQUFFRixxQkFBcUIsQ0FBQyxFQUFFRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7RUFDNUVELE1BQU0sQ0FDSix1SkFBdUosRUFDdko7SUFBRUUsT0FBTyxFQUFFO0VBQVMsQ0FDdEIsQ0FBQztBQUNIIiwiaWdub3JlTGlzdCI6W119
|
src/commands/passes/index.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js'
|
| 2 |
+
import {
|
| 3 |
+
checkCachedPassesEligibility,
|
| 4 |
+
getCachedReferrerReward,
|
| 5 |
+
} from '../../services/api/referral.js'
|
| 6 |
+
|
| 7 |
+
export default {
|
| 8 |
+
type: 'local-jsx',
|
| 9 |
+
name: 'passes',
|
| 10 |
+
get description() {
|
| 11 |
+
const reward = getCachedReferrerReward()
|
| 12 |
+
if (reward) {
|
| 13 |
+
return 'Share a free week of Claude Code with friends and earn extra usage'
|
| 14 |
+
}
|
| 15 |
+
return 'Share a free week of Claude Code with friends'
|
| 16 |
+
},
|
| 17 |
+
get isHidden() {
|
| 18 |
+
const { eligible, hasCache } = checkCachedPassesEligibility()
|
| 19 |
+
return !eligible || !hasCache
|
| 20 |
+
},
|
| 21 |
+
load: () => import('./passes.js'),
|
| 22 |
+
} satisfies Command
|
src/commands/passes/passes.tsx
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from 'react';
|
| 2 |
+
import { Passes } from '../../components/Passes/Passes.js';
|
| 3 |
+
import { logEvent } from '../../services/analytics/index.js';
|
| 4 |
+
import { getCachedRemainingPasses } from '../../services/api/referral.js';
|
| 5 |
+
import type { LocalJSXCommandOnDone } from '../../types/command.js';
|
| 6 |
+
import { getGlobalConfig, saveGlobalConfig } from '../../utils/config.js';
|
| 7 |
+
export async function call(onDone: LocalJSXCommandOnDone): Promise<React.ReactNode> {
|
| 8 |
+
// Mark that user has visited /passes so we stop showing the upsell
|
| 9 |
+
const config = getGlobalConfig();
|
| 10 |
+
const isFirstVisit = !config.hasVisitedPasses;
|
| 11 |
+
if (isFirstVisit) {
|
| 12 |
+
const remaining = getCachedRemainingPasses();
|
| 13 |
+
saveGlobalConfig(current => ({
|
| 14 |
+
...current,
|
| 15 |
+
hasVisitedPasses: true,
|
| 16 |
+
passesLastSeenRemaining: remaining ?? current.passesLastSeenRemaining
|
| 17 |
+
}));
|
| 18 |
+
}
|
| 19 |
+
logEvent('tengu_guest_passes_visited', {
|
| 20 |
+
is_first_visit: isFirstVisit
|
| 21 |
+
});
|
| 22 |
+
return <Passes onDone={onDone} />;
|
| 23 |
+
}
|
| 24 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsIlBhc3NlcyIsImxvZ0V2ZW50IiwiZ2V0Q2FjaGVkUmVtYWluaW5nUGFzc2VzIiwiTG9jYWxKU1hDb21tYW5kT25Eb25lIiwiZ2V0R2xvYmFsQ29uZmlnIiwic2F2ZUdsb2JhbENvbmZpZyIsImNhbGwiLCJvbkRvbmUiLCJQcm9taXNlIiwiUmVhY3ROb2RlIiwiY29uZmlnIiwiaXNGaXJzdFZpc2l0IiwiaGFzVmlzaXRlZFBhc3NlcyIsInJlbWFpbmluZyIsImN1cnJlbnQiLCJwYXNzZXNMYXN0U2VlblJlbWFpbmluZyIsImlzX2ZpcnN0X3Zpc2l0Il0sInNvdXJjZXMiOlsicGFzc2VzLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCdcbmltcG9ydCB7IFBhc3NlcyB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvUGFzc2VzL1Bhc3Nlcy5qcydcbmltcG9ydCB7IGxvZ0V2ZW50IH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYW5hbHl0aWNzL2luZGV4LmpzJ1xuaW1wb3J0IHsgZ2V0Q2FjaGVkUmVtYWluaW5nUGFzc2VzIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYXBpL3JlZmVycmFsLmpzJ1xuaW1wb3J0IHR5cGUgeyBMb2NhbEpTWENvbW1hbmRPbkRvbmUgfSBmcm9tICcuLi8uLi90eXBlcy9jb21tYW5kLmpzJ1xuaW1wb3J0IHsgZ2V0R2xvYmFsQ29uZmlnLCBzYXZlR2xvYmFsQ29uZmlnIH0gZnJvbSAnLi4vLi4vdXRpbHMvY29uZmlnLmpzJ1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2FsbChcbiAgb25Eb25lOiBMb2NhbEpTWENvbW1hbmRPbkRvbmUsXG4pOiBQcm9taXNlPFJlYWN0LlJlYWN0Tm9kZT4ge1xuICAvLyBNYXJrIHRoYXQgdXNlciBoYXMgdmlzaXRlZCAvcGFzc2VzIHNvIHdlIHN0b3Agc2hvd2luZyB0aGUgdXBzZWxsXG4gIGNvbnN0IGNvbmZpZyA9IGdldEdsb2JhbENvbmZpZygpXG4gIGNvbnN0IGlzRmlyc3RWaXNpdCA9ICFjb25maWcuaGFzVmlzaXRlZFBhc3Nlc1xuICBpZiAoaXNGaXJzdFZpc2l0KSB7XG4gICAgY29uc3QgcmVtYWluaW5nID0gZ2V0Q2FjaGVkUmVtYWluaW5nUGFzc2VzKClcbiAgICBzYXZlR2xvYmFsQ29uZmlnKGN1cnJlbnQgPT4gKHtcbiAgICAgIC4uLmN1cnJlbnQsXG4gICAgICBoYXNWaXNpdGVkUGFzc2VzOiB0cnVlLFxuICAgICAgcGFzc2VzTGFzdFNlZW5SZW1haW5pbmc6IHJlbWFpbmluZyA/PyBjdXJyZW50LnBhc3Nlc0xhc3RTZWVuUmVtYWluaW5nLFxuICAgIH0pKVxuICB9XG4gIGxvZ0V2ZW50KCd0ZW5ndV9ndWVzdF9wYXNzZXNfdmlzaXRlZCcsIHsgaXNfZmlyc3RfdmlzaXQ6IGlzRmlyc3RWaXNpdCB9KVxuICByZXR1cm4gPFBhc3NlcyBvbkRvbmU9e29uRG9uZX0gLz5cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLQSxLQUFLLE1BQU0sT0FBTztBQUM5QixTQUFTQyxNQUFNLFFBQVEsbUNBQW1DO0FBQzFELFNBQVNDLFFBQVEsUUFBUSxtQ0FBbUM7QUFDNUQsU0FBU0Msd0JBQXdCLFFBQVEsZ0NBQWdDO0FBQ3pFLGNBQWNDLHFCQUFxQixRQUFRLHdCQUF3QjtBQUNuRSxTQUFTQyxlQUFlLEVBQUVDLGdCQUFnQixRQUFRLHVCQUF1QjtBQUV6RSxPQUFPLGVBQWVDLElBQUlBLENBQ3hCQyxNQUFNLEVBQUVKLHFCQUFxQixDQUM5QixFQUFFSyxPQUFPLENBQUNULEtBQUssQ0FBQ1UsU0FBUyxDQUFDLENBQUM7RUFDMUI7RUFDQSxNQUFNQyxNQUFNLEdBQUdOLGVBQWUsQ0FBQyxDQUFDO0VBQ2hDLE1BQU1PLFlBQVksR0FBRyxDQUFDRCxNQUFNLENBQUNFLGdCQUFnQjtFQUM3QyxJQUFJRCxZQUFZLEVBQUU7SUFDaEIsTUFBTUUsU0FBUyxHQUFHWCx3QkFBd0IsQ0FBQyxDQUFDO0lBQzVDRyxnQkFBZ0IsQ0FBQ1MsT0FBTyxLQUFLO01BQzNCLEdBQUdBLE9BQU87TUFDVkYsZ0JBQWdCLEVBQUUsSUFBSTtNQUN0QkcsdUJBQXVCLEVBQUVGLFNBQVMsSUFBSUMsT0FBTyxDQUFDQztJQUNoRCxDQUFDLENBQUMsQ0FBQztFQUNMO0VBQ0FkLFFBQVEsQ0FBQyw0QkFBNEIsRUFBRTtJQUFFZSxjQUFjLEVBQUVMO0VBQWEsQ0FBQyxDQUFDO0VBQ3hFLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUNKLE1BQU0sQ0FBQyxHQUFHO0FBQ25DIiwiaWdub3JlTGlzdCI6W119
|
src/commands/perf-issue/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
export default { isEnabled: () => false, isHidden: true, name: 'stub' };
|
src/commands/permissions/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js'
|
| 2 |
+
|
| 3 |
+
const permissions = {
|
| 4 |
+
type: 'local-jsx',
|
| 5 |
+
name: 'permissions',
|
| 6 |
+
aliases: ['allowed-tools'],
|
| 7 |
+
description: 'Manage allow & deny tool permission rules',
|
| 8 |
+
load: () => import('./permissions.js'),
|
| 9 |
+
} satisfies Command
|
| 10 |
+
|
| 11 |
+
export default permissions
|
src/commands/permissions/permissions.tsx
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from 'react';
|
| 2 |
+
import { PermissionRuleList } from '../../components/permissions/rules/PermissionRuleList.js';
|
| 3 |
+
import type { LocalJSXCommandCall } from '../../types/command.js';
|
| 4 |
+
import { createPermissionRetryMessage } from '../../utils/messages.js';
|
| 5 |
+
export const call: LocalJSXCommandCall = async (onDone, context) => {
|
| 6 |
+
return <PermissionRuleList onExit={onDone} onRetryDenials={commands => {
|
| 7 |
+
context.setMessages(prev => [...prev, createPermissionRetryMessage(commands)]);
|
| 8 |
+
}} />;
|
| 9 |
+
};
|
| 10 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsIlBlcm1pc3Npb25SdWxlTGlzdCIsIkxvY2FsSlNYQ29tbWFuZENhbGwiLCJjcmVhdGVQZXJtaXNzaW9uUmV0cnlNZXNzYWdlIiwiY2FsbCIsIm9uRG9uZSIsImNvbnRleHQiLCJjb21tYW5kcyIsInNldE1lc3NhZ2VzIiwicHJldiJdLCJzb3VyY2VzIjpbInBlcm1pc3Npb25zLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCdcbmltcG9ydCB7IFBlcm1pc3Npb25SdWxlTGlzdCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvcGVybWlzc2lvbnMvcnVsZXMvUGVybWlzc2lvblJ1bGVMaXN0LmpzJ1xuaW1wb3J0IHR5cGUgeyBMb2NhbEpTWENvbW1hbmRDYWxsIH0gZnJvbSAnLi4vLi4vdHlwZXMvY29tbWFuZC5qcydcbmltcG9ydCB7IGNyZWF0ZVBlcm1pc3Npb25SZXRyeU1lc3NhZ2UgfSBmcm9tICcuLi8uLi91dGlscy9tZXNzYWdlcy5qcydcblxuZXhwb3J0IGNvbnN0IGNhbGw6IExvY2FsSlNYQ29tbWFuZENhbGwgPSBhc3luYyAob25Eb25lLCBjb250ZXh0KSA9PiB7XG4gIHJldHVybiAoXG4gICAgPFBlcm1pc3Npb25SdWxlTGlzdFxuICAgICAgb25FeGl0PXtvbkRvbmV9XG4gICAgICBvblJldHJ5RGVuaWFscz17Y29tbWFuZHMgPT4ge1xuICAgICAgICBjb250ZXh0LnNldE1lc3NhZ2VzKHByZXYgPT4gW1xuICAgICAgICAgIC4uLnByZXYsXG4gICAgICAgICAgY3JlYXRlUGVybWlzc2lvblJldHJ5TWVzc2FnZShjb21tYW5kcyksXG4gICAgICAgIF0pXG4gICAgICB9fVxuICAgIC8+XG4gIClcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLQSxLQUFLLE1BQU0sT0FBTztBQUM5QixTQUFTQyxrQkFBa0IsUUFBUSwwREFBMEQ7QUFDN0YsY0FBY0MsbUJBQW1CLFFBQVEsd0JBQXdCO0FBQ2pFLFNBQVNDLDRCQUE0QixRQUFRLHlCQUF5QjtBQUV0RSxPQUFPLE1BQU1DLElBQUksRUFBRUYsbUJBQW1CLEdBQUcsTUFBQUUsQ0FBT0MsTUFBTSxFQUFFQyxPQUFPLEtBQUs7RUFDbEUsT0FDRSxDQUFDLGtCQUFrQixDQUNqQixNQUFNLENBQUMsQ0FBQ0QsTUFBTSxDQUFDLENBQ2YsY0FBYyxDQUFDLENBQUNFLFFBQVEsSUFBSTtJQUMxQkQsT0FBTyxDQUFDRSxXQUFXLENBQUNDLElBQUksSUFBSSxDQUMxQixHQUFHQSxJQUFJLEVBQ1BOLDRCQUE0QixDQUFDSSxRQUFRLENBQUMsQ0FDdkMsQ0FBQztFQUNKLENBQUMsQ0FBQyxHQUNGO0FBRU4sQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==
|
src/commands/plan/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js'
|
| 2 |
+
|
| 3 |
+
const plan = {
|
| 4 |
+
type: 'local-jsx',
|
| 5 |
+
name: 'plan',
|
| 6 |
+
description: 'Enable plan mode or view the current session plan',
|
| 7 |
+
argumentHint: '[open|<description>]',
|
| 8 |
+
load: () => import('./plan.js'),
|
| 9 |
+
} satisfies Command
|
| 10 |
+
|
| 11 |
+
export default plan
|
src/commands/plan/plan.tsx
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { c as _c } from "react/compiler-runtime";
|
| 2 |
+
import * as React from 'react';
|
| 3 |
+
import { handlePlanModeTransition } from '../../bootstrap/state.js';
|
| 4 |
+
import type { LocalJSXCommandContext } from '../../commands.js';
|
| 5 |
+
import { Box, Text } from '../../ink.js';
|
| 6 |
+
import type { LocalJSXCommandOnDone } from '../../types/command.js';
|
| 7 |
+
import { getExternalEditor } from '../../utils/editor.js';
|
| 8 |
+
import { toIDEDisplayName } from '../../utils/ide.js';
|
| 9 |
+
import { applyPermissionUpdate } from '../../utils/permissions/PermissionUpdate.js';
|
| 10 |
+
import { prepareContextForPlanMode } from '../../utils/permissions/permissionSetup.js';
|
| 11 |
+
import { getPlan, getPlanFilePath } from '../../utils/plans.js';
|
| 12 |
+
import { editFileInEditor } from '../../utils/promptEditor.js';
|
| 13 |
+
import { renderToString } from '../../utils/staticRender.js';
|
| 14 |
+
function PlanDisplay(t0) {
|
| 15 |
+
const $ = _c(11);
|
| 16 |
+
const {
|
| 17 |
+
planContent,
|
| 18 |
+
planPath,
|
| 19 |
+
editorName
|
| 20 |
+
} = t0;
|
| 21 |
+
let t1;
|
| 22 |
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
| 23 |
+
t1 = <Text bold={true}>Current Plan</Text>;
|
| 24 |
+
$[0] = t1;
|
| 25 |
+
} else {
|
| 26 |
+
t1 = $[0];
|
| 27 |
+
}
|
| 28 |
+
let t2;
|
| 29 |
+
if ($[1] !== planPath) {
|
| 30 |
+
t2 = <Text dimColor={true}>{planPath}</Text>;
|
| 31 |
+
$[1] = planPath;
|
| 32 |
+
$[2] = t2;
|
| 33 |
+
} else {
|
| 34 |
+
t2 = $[2];
|
| 35 |
+
}
|
| 36 |
+
let t3;
|
| 37 |
+
if ($[3] !== planContent) {
|
| 38 |
+
t3 = <Box marginTop={1}><Text>{planContent}</Text></Box>;
|
| 39 |
+
$[3] = planContent;
|
| 40 |
+
$[4] = t3;
|
| 41 |
+
} else {
|
| 42 |
+
t3 = $[4];
|
| 43 |
+
}
|
| 44 |
+
let t4;
|
| 45 |
+
if ($[5] !== editorName) {
|
| 46 |
+
t4 = editorName && <Box marginTop={1}><Text dimColor={true}>"/plan open"</Text><Text dimColor={true}> to edit this plan in </Text><Text bold={true} dimColor={true}>{editorName}</Text></Box>;
|
| 47 |
+
$[5] = editorName;
|
| 48 |
+
$[6] = t4;
|
| 49 |
+
} else {
|
| 50 |
+
t4 = $[6];
|
| 51 |
+
}
|
| 52 |
+
let t5;
|
| 53 |
+
if ($[7] !== t2 || $[8] !== t3 || $[9] !== t4) {
|
| 54 |
+
t5 = <Box flexDirection="column">{t1}{t2}{t3}{t4}</Box>;
|
| 55 |
+
$[7] = t2;
|
| 56 |
+
$[8] = t3;
|
| 57 |
+
$[9] = t4;
|
| 58 |
+
$[10] = t5;
|
| 59 |
+
} else {
|
| 60 |
+
t5 = $[10];
|
| 61 |
+
}
|
| 62 |
+
return t5;
|
| 63 |
+
}
|
| 64 |
+
export async function call(onDone: LocalJSXCommandOnDone, context: LocalJSXCommandContext, args: string): Promise<React.ReactNode> {
|
| 65 |
+
const {
|
| 66 |
+
getAppState,
|
| 67 |
+
setAppState
|
| 68 |
+
} = context;
|
| 69 |
+
const appState = getAppState();
|
| 70 |
+
const currentMode = appState.toolPermissionContext.mode;
|
| 71 |
+
|
| 72 |
+
// If not in plan mode, enable it
|
| 73 |
+
if (currentMode !== 'plan') {
|
| 74 |
+
handlePlanModeTransition(currentMode, 'plan');
|
| 75 |
+
setAppState(prev => ({
|
| 76 |
+
...prev,
|
| 77 |
+
toolPermissionContext: applyPermissionUpdate(prepareContextForPlanMode(prev.toolPermissionContext), {
|
| 78 |
+
type: 'setMode',
|
| 79 |
+
mode: 'plan',
|
| 80 |
+
destination: 'session'
|
| 81 |
+
})
|
| 82 |
+
}));
|
| 83 |
+
const description = args.trim();
|
| 84 |
+
if (description && description !== 'open') {
|
| 85 |
+
onDone('Enabled plan mode', {
|
| 86 |
+
shouldQuery: true
|
| 87 |
+
});
|
| 88 |
+
} else {
|
| 89 |
+
onDone('Enabled plan mode');
|
| 90 |
+
}
|
| 91 |
+
return null;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
// Already in plan mode - show the current plan
|
| 95 |
+
const planContent = getPlan();
|
| 96 |
+
const planPath = getPlanFilePath();
|
| 97 |
+
if (!planContent) {
|
| 98 |
+
onDone('Already in plan mode. No plan written yet.');
|
| 99 |
+
return null;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
// If user typed "/plan open", open in editor
|
| 103 |
+
const argList = args.trim().split(/\s+/);
|
| 104 |
+
if (argList[0] === 'open') {
|
| 105 |
+
const result = await editFileInEditor(planPath);
|
| 106 |
+
if (result.error) {
|
| 107 |
+
onDone(`Failed to open plan in editor: ${result.error}`);
|
| 108 |
+
} else {
|
| 109 |
+
onDone(`Opened plan in editor: ${planPath}`);
|
| 110 |
+
}
|
| 111 |
+
return null;
|
| 112 |
+
}
|
| 113 |
+
const editor = getExternalEditor();
|
| 114 |
+
const editorName = editor ? toIDEDisplayName(editor) : undefined;
|
| 115 |
+
const display = <PlanDisplay planContent={planContent} planPath={planPath} editorName={editorName} />;
|
| 116 |
+
|
| 117 |
+
// Render to string and pass to onDone like local commands do
|
| 118 |
+
const output = await renderToString(display);
|
| 119 |
+
onDone(output);
|
| 120 |
+
return null;
|
| 121 |
+
}
|
| 122 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsImhhbmRsZVBsYW5Nb2RlVHJhbnNpdGlvbiIsIkxvY2FsSlNYQ29tbWFuZENvbnRleHQiLCJCb3giLCJUZXh0IiwiTG9jYWxKU1hDb21tYW5kT25Eb25lIiwiZ2V0RXh0ZXJuYWxFZGl0b3IiLCJ0b0lERURpc3BsYXlOYW1lIiwiYXBwbHlQZXJtaXNzaW9uVXBkYXRlIiwicHJlcGFyZUNvbnRleHRGb3JQbGFuTW9kZSIsImdldFBsYW4iLCJnZXRQbGFuRmlsZVBhdGgiLCJlZGl0RmlsZUluRWRpdG9yIiwicmVuZGVyVG9TdHJpbmciLCJQbGFuRGlzcGxheSIsInQwIiwiJCIsIl9jIiwicGxhbkNvbnRlbnQiLCJwbGFuUGF0aCIsImVkaXRvck5hbWUiLCJ0MSIsIlN5bWJvbCIsImZvciIsInQyIiwidDMiLCJ0NCIsInQ1IiwiY2FsbCIsIm9uRG9uZSIsImNvbnRleHQiLCJhcmdzIiwiUHJvbWlzZSIsIlJlYWN0Tm9kZSIsImdldEFwcFN0YXRlIiwic2V0QXBwU3RhdGUiLCJhcHBTdGF0ZSIsImN1cnJlbnRNb2RlIiwidG9vbFBlcm1pc3Npb25Db250ZXh0IiwibW9kZSIsInByZXYiLCJ0eXBlIiwiZGVzdGluYXRpb24iLCJkZXNjcmlwdGlvbiIsInRyaW0iLCJzaG91bGRRdWVyeSIsImFyZ0xpc3QiLCJzcGxpdCIsInJlc3VsdCIsImVycm9yIiwiZWRpdG9yIiwidW5kZWZpbmVkIiwiZGlzcGxheSIsIm91dHB1dCJdLCJzb3VyY2VzIjpbInBsYW4udHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgaGFuZGxlUGxhbk1vZGVUcmFuc2l0aW9uIH0gZnJvbSAnLi4vLi4vYm9vdHN0cmFwL3N0YXRlLmpzJ1xuaW1wb3J0IHR5cGUgeyBMb2NhbEpTWENvbW1hbmRDb250ZXh0IH0gZnJvbSAnLi4vLi4vY29tbWFuZHMuanMnXG5pbXBvcnQgeyBCb3gsIFRleHQgfSBmcm9tICcuLi8uLi9pbmsuanMnXG5pbXBvcnQgdHlwZSB7IExvY2FsSlNYQ29tbWFuZE9uRG9uZSB9IGZyb20gJy4uLy4uL3R5cGVzL2NvbW1hbmQuanMnXG5pbXBvcnQgeyBnZXRFeHRlcm5hbEVkaXRvciB9IGZyb20gJy4uLy4uL3V0aWxzL2VkaXRvci5qcydcbmltcG9ydCB7IHRvSURFRGlzcGxheU5hbWUgfSBmcm9tICcuLi8uLi91dGlscy9pZGUuanMnXG5pbXBvcnQgeyBhcHBseVBlcm1pc3Npb25VcGRhdGUgfSBmcm9tICcuLi8uLi91dGlscy9wZXJtaXNzaW9ucy9QZXJtaXNzaW9uVXBkYXRlLmpzJ1xuaW1wb3J0IHsgcHJlcGFyZUNvbnRleHRGb3JQbGFuTW9kZSB9IGZyb20gJy4uLy4uL3V0aWxzL3Blcm1pc3Npb25zL3Blcm1pc3Npb25TZXR1cC5qcydcbmltcG9ydCB7IGdldFBsYW4sIGdldFBsYW5GaWxlUGF0aCB9IGZyb20gJy4uLy4uL3V0aWxzL3BsYW5zLmpzJ1xuaW1wb3J0IHsgZWRpdEZpbGVJbkVkaXRvciB9IGZyb20gJy4uLy4uL3V0aWxzL3Byb21wdEVkaXRvci5qcydcbmltcG9ydCB7IHJlbmRlclRvU3RyaW5nIH0gZnJvbSAnLi4vLi4vdXRpbHMvc3RhdGljUmVuZGVyLmpzJ1xuXG5mdW5jdGlvbiBQbGFuRGlzcGxheSh7XG4gIHBsYW5Db250ZW50LFxuICBwbGFuUGF0aCxcbiAgZWRpdG9yTmFtZSxcbn06IHtcbiAgcGxhbkNvbnRlbnQ6IHN0cmluZ1xuICBwbGFuUGF0aDogc3RyaW5nXG4gIGVkaXRvck5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZFxufSk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIHJldHVybiAoXG4gICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCI+XG4gICAgICA8VGV4dCBib2xkPkN1cnJlbnQgUGxhbjwvVGV4dD5cbiAgICAgIDxUZXh0IGRpbUNvbG9yPntwbGFuUGF0aH08L1RleHQ+XG4gICAgICA8Qm94IG1hcmdpblRvcD17MX0+XG4gICAgICAgIDxUZXh0PntwbGFuQ29udGVudH08L1RleHQ+XG4gICAgICA8L0JveD5cbiAgICAgIHtlZGl0b3JOYW1lICYmIChcbiAgICAgICAgPEJveCBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPiZxdW90Oy9wbGFuIG9wZW4mcXVvdDs8L1RleHQ+XG4gICAgICAgICAgPFRleHQgZGltQ29sb3I+IHRvIGVkaXQgdGhpcyBwbGFuIGluIDwvVGV4dD5cbiAgICAgICAgICA8VGV4dCBib2xkIGRpbUNvbG9yPlxuICAgICAgICAgICAge2VkaXRvck5hbWV9XG4gICAgICAgICAgPC9UZXh0PlxuICAgICAgICA8L0JveD5cbiAgICAgICl9XG4gICAgPC9Cb3g+XG4gIClcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNhbGwoXG4gIG9uRG9uZTogTG9jYWxKU1hDb21tYW5kT25Eb25lLFxuICBjb250ZXh0OiBMb2NhbEpTWENvbW1hbmRDb250ZXh0LFxuICBhcmdzOiBzdHJpbmcsXG4pOiBQcm9taXNlPFJlYWN0LlJlYWN0Tm9kZT4ge1xuICBjb25zdCB7IGdldEFwcFN0YXRlLCBzZXRBcHBTdGF0ZSB9ID0gY29udGV4dFxuICBjb25zdCBhcHBTdGF0ZSA9IGdldEFwcFN0YXRlKClcbiAgY29uc3QgY3VycmVudE1vZGUgPSBhcHBTdGF0ZS50b29sUGVybWlzc2lvbkNvbnRleHQubW9kZVxuXG4gIC8vIElmIG5vdCBpbiBwbGFuIG1vZGUsIGVuYWJsZSBpdFxuICBpZiAoY3VycmVudE1vZGUgIT09ICdwbGFuJykge1xuICAgIGhhbmRsZVBsYW5Nb2RlVHJhbnNpdGlvbihjdXJyZW50TW9kZSwgJ3BsYW4nKVxuICAgIHNldEFwcFN0YXRlKHByZXYgPT4gKHtcbiAgICAgIC4uLnByZXYsXG4gICAgICB0b29sUGVybWlzc2lvbkNvbnRleHQ6IGFwcGx5UGVybWlzc2lvblVwZGF0ZShcbiAgICAgICAgcHJlcGFyZUNvbnRleHRGb3JQbGFuTW9kZShwcmV2LnRvb2xQZXJtaXNzaW9uQ29udGV4dCksXG4gICAgICAgIHsgdHlwZTogJ3NldE1vZGUnLCBtb2RlOiAncGxhbicsIGRlc3RpbmF0aW9uOiAnc2Vzc2lvbicgfSxcbiAgICAgICksXG4gICAgfSkpXG4gICAgY29uc3QgZGVzY3JpcHRpb24gPSBhcmdzLnRyaW0oKVxuICAgIGlmIChkZXNjcmlwdGlvbiAmJiBkZXNjcmlwdGlvbiAhPT0gJ29wZW4nKSB7XG4gICAgICBvbkRvbmUoJ0VuYWJsZWQgcGxhbiBtb2RlJywgeyBzaG91bGRRdWVyeTogdHJ1ZSB9KVxuICAgIH0gZWxzZSB7XG4gICAgICBvbkRvbmUoJ0VuYWJsZWQgcGxhbiBtb2RlJylcbiAgICB9XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8vIEFscmVhZHkgaW4gcGxhbiBtb2RlIC0gc2hvdyB0aGUgY3VycmVudCBwbGFuXG4gIGNvbnN0IHBsYW5Db250ZW50ID0gZ2V0UGxhbigpXG4gIGNvbnN0IHBsYW5QYXRoID0gZ2V0UGxhbkZpbGVQYXRoKClcblxuICBpZiAoIXBsYW5Db250ZW50KSB7XG4gICAgb25Eb25lKCdBbHJlYWR5IGluIHBsYW4gbW9kZS4gTm8gcGxhbiB3cml0dGVuIHlldC4nKVxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvLyBJZiB1c2VyIHR5cGVkIFwiL3BsYW4gb3BlblwiLCBvcGVuIGluIGVkaXRvclxuICBjb25zdCBhcmdMaXN0ID0gYXJncy50cmltKCkuc3BsaXQoL1xccysvKVxuICBpZiAoYXJnTGlzdFswXSA9PT0gJ29wZW4nKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZWRpdEZpbGVJbkVkaXRvcihwbGFuUGF0aClcbiAgICBpZiAocmVzdWx0LmVycm9yKSB7XG4gICAgICBvbkRvbmUoYEZhaWxlZCB0byBvcGVuIHBsYW4gaW4gZWRpdG9yOiAke3Jlc3VsdC5lcnJvcn1gKVxuICAgIH0gZWxzZSB7XG4gICAgICBvbkRvbmUoYE9wZW5lZCBwbGFuIGluIGVkaXRvcjogJHtwbGFuUGF0aH1gKVxuICAgIH1cbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgY29uc3QgZWRpdG9yID0gZ2V0RXh0ZXJuYWxFZGl0b3IoKVxuICBjb25zdCBlZGl0b3JOYW1lID0gZWRpdG9yID8gdG9JREVEaXNwbGF5TmFtZShlZGl0b3IpIDogdW5kZWZpbmVkXG5cbiAgY29uc3QgZGlzcGxheSA9IChcbiAgICA8UGxhbkRpc3BsYXlcbiAgICAgIHBsYW5Db250ZW50PXtwbGFuQ29udGVudH1cbiAgICAgIHBsYW5QYXRoPXtwbGFuUGF0aH1cbiAgICAgIGVkaXRvck5hbWU9e2VkaXRvck5hbWV9XG4gICAgLz5cbiAgKVxuXG4gIC8vIFJlbmRlciB0byBzdHJpbmcgYW5kIHBhc3MgdG8gb25Eb25lIGxpa2UgbG9jYWwgY29tbWFuZHMgZG9cbiAgY29uc3Qgb3V0cHV0ID0gYXdhaXQgcmVuZGVyVG9TdHJpbmcoZGlzcGxheSlcbiAgb25Eb25lKG91dHB1dClcbiAgcmV0dXJuIG51bGxcbn1cbiJdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sS0FBS0EsS0FBSyxNQUFNLE9BQU87QUFDOUIsU0FBU0Msd0JBQXdCLFFBQVEsMEJBQTBCO0FBQ25FLGNBQWNDLHNCQUFzQixRQUFRLG1CQUFtQjtBQUMvRCxTQUFTQyxHQUFHLEVBQUVDLElBQUksUUFBUSxjQUFjO0FBQ3hDLGNBQWNDLHFCQUFxQixRQUFRLHdCQUF3QjtBQUNuRSxTQUFTQyxpQkFBaUIsUUFBUSx1QkFBdUI7QUFDekQsU0FBU0MsZ0JBQWdCLFFBQVEsb0JBQW9CO0FBQ3JELFNBQVNDLHFCQUFxQixRQUFRLDZDQUE2QztBQUNuRixTQUFTQyx5QkFBeUIsUUFBUSw0Q0FBNEM7QUFDdEYsU0FBU0MsT0FBTyxFQUFFQyxlQUFlLFFBQVEsc0JBQXNCO0FBQy9ELFNBQVNDLGdCQUFnQixRQUFRLDZCQUE2QjtBQUM5RCxTQUFTQyxjQUFjLFFBQVEsNkJBQTZCO0FBRTVELFNBQUFDLFlBQUFDLEVBQUE7RUFBQSxNQUFBQyxDQUFBLEdBQUFDLEVBQUE7RUFBcUI7SUFBQUMsV0FBQTtJQUFBQyxRQUFBO0lBQUFDO0VBQUEsSUFB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
|
src/commands/plugin/AddMarketplace.tsx
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from 'react';
|
| 2 |
+
import { useEffect, useRef, useState } from 'react';
|
| 3 |
+
import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from 'src/services/analytics/index.js';
|
| 4 |
+
import { ConfigurableShortcutHint } from '../../components/ConfigurableShortcutHint.js';
|
| 5 |
+
import { Byline } from '../../components/design-system/Byline.js';
|
| 6 |
+
import { KeyboardShortcutHint } from '../../components/design-system/KeyboardShortcutHint.js';
|
| 7 |
+
import { Spinner } from '../../components/Spinner.js';
|
| 8 |
+
import TextInput from '../../components/TextInput.js';
|
| 9 |
+
import { Box, Text } from '../../ink.js';
|
| 10 |
+
import { toError } from '../../utils/errors.js';
|
| 11 |
+
import { logError } from '../../utils/log.js';
|
| 12 |
+
import { clearAllCaches } from '../../utils/plugins/cacheUtils.js';
|
| 13 |
+
import { addMarketplaceSource, saveMarketplaceToSettings } from '../../utils/plugins/marketplaceManager.js';
|
| 14 |
+
import { parseMarketplaceInput } from '../../utils/plugins/parseMarketplaceInput.js';
|
| 15 |
+
import type { ViewState } from './types.js';
|
| 16 |
+
type Props = {
|
| 17 |
+
inputValue: string;
|
| 18 |
+
setInputValue: (value: string) => void;
|
| 19 |
+
cursorOffset: number;
|
| 20 |
+
setCursorOffset: (offset: number) => void;
|
| 21 |
+
error: string | null;
|
| 22 |
+
setError: (error: string | null) => void;
|
| 23 |
+
result: string | null;
|
| 24 |
+
setResult: (result: string | null) => void;
|
| 25 |
+
setViewState: (state: ViewState) => void;
|
| 26 |
+
onAddComplete?: () => void | Promise<void>;
|
| 27 |
+
cliMode?: boolean;
|
| 28 |
+
};
|
| 29 |
+
export function AddMarketplace({
|
| 30 |
+
inputValue,
|
| 31 |
+
setInputValue,
|
| 32 |
+
cursorOffset,
|
| 33 |
+
setCursorOffset,
|
| 34 |
+
error,
|
| 35 |
+
setError,
|
| 36 |
+
result,
|
| 37 |
+
setResult,
|
| 38 |
+
setViewState,
|
| 39 |
+
onAddComplete,
|
| 40 |
+
cliMode = false
|
| 41 |
+
}: Props): React.ReactNode {
|
| 42 |
+
const hasAttemptedAutoAdd = useRef(false);
|
| 43 |
+
const [isLoading, setLoading] = useState(false);
|
| 44 |
+
const [progressMessage, setProgressMessage] = useState<string>('');
|
| 45 |
+
const handleAdd = async () => {
|
| 46 |
+
const input = inputValue.trim();
|
| 47 |
+
if (!input) {
|
| 48 |
+
setError('Please enter a marketplace source');
|
| 49 |
+
return;
|
| 50 |
+
}
|
| 51 |
+
const parsed = await parseMarketplaceInput(input);
|
| 52 |
+
if (!parsed) {
|
| 53 |
+
setError('Invalid marketplace source format. Try: owner/repo, https://..., or ./path');
|
| 54 |
+
return;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
// Check if parseMarketplaceInput returned an error
|
| 58 |
+
if ('error' in parsed) {
|
| 59 |
+
setError(parsed.error);
|
| 60 |
+
return;
|
| 61 |
+
}
|
| 62 |
+
setError(null);
|
| 63 |
+
try {
|
| 64 |
+
setLoading(true);
|
| 65 |
+
setProgressMessage('');
|
| 66 |
+
const {
|
| 67 |
+
name,
|
| 68 |
+
resolvedSource
|
| 69 |
+
} = await addMarketplaceSource(parsed, message => {
|
| 70 |
+
setProgressMessage(message);
|
| 71 |
+
});
|
| 72 |
+
saveMarketplaceToSettings(name, {
|
| 73 |
+
source: resolvedSource
|
| 74 |
+
});
|
| 75 |
+
clearAllCaches();
|
| 76 |
+
let sourceType = parsed.source;
|
| 77 |
+
if (parsed.source === 'github') {
|
| 78 |
+
sourceType = parsed.repo as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS;
|
| 79 |
+
}
|
| 80 |
+
logEvent('tengu_marketplace_added', {
|
| 81 |
+
source_type: sourceType as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
|
| 82 |
+
});
|
| 83 |
+
if (onAddComplete) {
|
| 84 |
+
await onAddComplete();
|
| 85 |
+
}
|
| 86 |
+
setProgressMessage('');
|
| 87 |
+
setLoading(false);
|
| 88 |
+
if (cliMode) {
|
| 89 |
+
// In CLI mode, set result to trigger completion
|
| 90 |
+
setResult(`Successfully added marketplace: ${name}`);
|
| 91 |
+
} else {
|
| 92 |
+
// In interactive mode, switch to browse view
|
| 93 |
+
setViewState({
|
| 94 |
+
type: 'browse-marketplace',
|
| 95 |
+
targetMarketplace: name
|
| 96 |
+
});
|
| 97 |
+
}
|
| 98 |
+
} catch (err) {
|
| 99 |
+
const error = toError(err);
|
| 100 |
+
logError(error);
|
| 101 |
+
setError(error.message);
|
| 102 |
+
setProgressMessage('');
|
| 103 |
+
setLoading(false);
|
| 104 |
+
if (cliMode) {
|
| 105 |
+
// In CLI mode, set result with error to trigger completion
|
| 106 |
+
setResult(`Error: ${error.message}`);
|
| 107 |
+
} else {
|
| 108 |
+
setResult(null);
|
| 109 |
+
}
|
| 110 |
+
}
|
| 111 |
+
};
|
| 112 |
+
|
| 113 |
+
// Auto-add if inputValue is provided
|
| 114 |
+
useEffect(() => {
|
| 115 |
+
if (inputValue && !hasAttemptedAutoAdd.current && !error && !result) {
|
| 116 |
+
hasAttemptedAutoAdd.current = true;
|
| 117 |
+
void handleAdd();
|
| 118 |
+
}
|
| 119 |
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
| 120 |
+
// biome-ignore lint/correctness/useExhaustiveDependencies: intentional
|
| 121 |
+
}, []); // Only run once on mount
|
| 122 |
+
|
| 123 |
+
return <Box flexDirection="column">
|
| 124 |
+
<Box flexDirection="column" paddingX={1} borderStyle="round">
|
| 125 |
+
<Box marginBottom={1}>
|
| 126 |
+
<Text bold>Add Marketplace</Text>
|
| 127 |
+
</Box>
|
| 128 |
+
<Box flexDirection="column">
|
| 129 |
+
<Text>Enter marketplace source:</Text>
|
| 130 |
+
<Text dimColor>Examples:</Text>
|
| 131 |
+
<Text dimColor> · owner/repo (GitHub)</Text>
|
| 132 |
+
<Text dimColor> · git@github.com:owner/repo.git (SSH)</Text>
|
| 133 |
+
<Text dimColor> · https://example.com/marketplace.json</Text>
|
| 134 |
+
<Text dimColor> · ./path/to/marketplace</Text>
|
| 135 |
+
<Box marginTop={1}>
|
| 136 |
+
<TextInput value={inputValue} onChange={setInputValue} onSubmit={handleAdd} columns={80} cursorOffset={cursorOffset} onChangeCursorOffset={setCursorOffset} focus showCursor />
|
| 137 |
+
</Box>
|
| 138 |
+
</Box>
|
| 139 |
+
{isLoading && <Box marginTop={1}>
|
| 140 |
+
<Spinner />
|
| 141 |
+
<Text>
|
| 142 |
+
{progressMessage || 'Adding marketplace to configuration…'}
|
| 143 |
+
</Text>
|
| 144 |
+
</Box>}
|
| 145 |
+
{error && <Box marginTop={1}>
|
| 146 |
+
<Text color="error">{error}</Text>
|
| 147 |
+
</Box>}
|
| 148 |
+
{result && <Box marginTop={1}>
|
| 149 |
+
<Text>{result}</Text>
|
| 150 |
+
</Box>}
|
| 151 |
+
</Box>
|
| 152 |
+
<Box marginLeft={3}>
|
| 153 |
+
<Text dimColor italic>
|
| 154 |
+
<Byline>
|
| 155 |
+
<KeyboardShortcutHint shortcut="Enter" action="add" />
|
| 156 |
+
<ConfigurableShortcutHint action="confirm:no" context="Settings" fallback="Esc" description="cancel" />
|
| 157 |
+
</Byline>
|
| 158 |
+
</Text>
|
| 159 |
+
</Box>
|
| 160 |
+
</Box>;
|
| 161 |
+
}
|
| 162 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsInVzZUVmZmVjdCIsInVzZVJlZiIsInVzZVN0YXRlIiwiQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIUyIsImxvZ0V2ZW50IiwiQ29uZmlndXJhYmxlU2hvcnRjdXRIaW50IiwiQnlsaW5lIiwiS2V5Ym9hcmRTaG9ydGN1dEhpbnQiLCJTcGlubmVyIiwiVGV4dElucHV0IiwiQm94IiwiVGV4dCIsInRvRXJyb3IiLCJsb2dFcnJvciIsImNsZWFyQWxsQ2FjaGVzIiwiYWRkTWFya2V0cGxhY2VTb3VyY2UiLCJzYXZlTWFya2V0cGxhY2VUb1NldHRpbmdzIiwicGFyc2VNYXJrZXRwbGFjZUlucHV0IiwiVmlld1N0YXRlIiwiUHJvcHMiLCJpbnB1dFZhbHVlIiwic2V0SW5wdXRWYWx1ZSIsInZhbHVlIiwiY3Vyc29yT2Zmc2V0Iiwic2V0Q3Vyc29yT2Zmc2V0Iiwib2Zmc2V0IiwiZXJyb3IiLCJzZXRFcnJvciIsInJlc3VsdCIsInNldFJlc3VsdCIsInNldFZpZXdTdGF0ZSIsInN0YXRlIiwib25BZGRDb21wbGV0ZSIsIlByb21pc2UiLCJjbGlNb2RlIiwiQWRkTWFya2V0cGxhY2UiLCJSZWFjdE5vZGUiLCJoYXNBdHRlbXB0ZWRBdXRvQWRkIiwiaXNMb2FkaW5nIiwic2V0TG9hZGluZyIsInByb2dyZXNzTWVzc2FnZSIsInNldFByb2dyZXNzTWVzc2FnZSIsImhhbmRsZUFkZCIsImlucHV0IiwidHJpbSIsInBhcnNlZCIsIm5hbWUiLCJyZXNvbHZlZFNvdXJjZSIsIm1lc3NhZ2UiLCJzb3VyY2UiLCJzb3VyY2VUeXBlIiwicmVwbyIsInNvdXJjZV90eXBlIiwidHlwZSIsInRhcmdldE1hcmtldHBsYWNlIiwiZXJyIiwiY3VycmVudCJdLCJzb3VyY2VzIjpbIkFkZE1hcmtldHBsYWNlLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCdcbmltcG9ydCB7IHVzZUVmZmVjdCwgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHtcbiAgdHlwZSBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICBsb2dFdmVudCxcbn0gZnJvbSAnc3JjL3NlcnZpY2VzL2FuYWx5dGljcy9pbmRleC5qcydcbmltcG9ydCB7IENvbmZpZ3VyYWJsZVNob3J0Y3V0SGludCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvQ29uZmlndXJhYmxlU2hvcnRjdXRIaW50LmpzJ1xuaW1wb3J0IHsgQnlsaW5lIH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9kZXNpZ24tc3lzdGVtL0J5bGluZS5qcydcbmltcG9ydCB7IEtleWJvYXJkU2hvcnRjdXRIaW50IH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9kZXNpZ24tc3lzdGVtL0tleWJvYXJkU2hvcnRjdXRIaW50LmpzJ1xuaW1wb3J0IHsgU3Bpbm5lciB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvU3Bpbm5lci5qcydcbmltcG9ydCBUZXh0SW5wdXQgZnJvbSAnLi4vLi4vY29tcG9uZW50cy9UZXh0SW5wdXQuanMnXG5pbXBvcnQgeyBCb3gsIFRleHQgfSBmcm9tICcuLi8uLi9pbmsuanMnXG5pbXBvcnQgeyB0b0Vycm9yIH0gZnJvbSAnLi4vLi4vdXRpbHMvZXJyb3JzLmpzJ1xuaW1wb3J0IHsgbG9nRXJyb3IgfSBmcm9tICcuLi8uLi91dGlscy9sb2cuanMnXG5pbXBvcnQgeyBjbGVhckFsbENhY2hlcyB9IGZyb20gJy4uLy4uL3V0aWxzL3BsdWdpbnMvY2FjaGVVdGlscy5qcydcbmltcG9ydCB7XG4gIGFkZE1hcmtldHBsYWNlU291cmNlLFxuICBzYXZlTWFya2V0cGxhY2VUb1NldHRpbmdzLFxufSBmcm9tICcuLi8uLi91dGlscy9wbHVnaW5zL21hcmtldHBsYWNlTWFuYWdlci5qcydcbmltcG9ydCB7IHBhcnNlTWFya2V0cGxhY2VJbnB1dCB9IGZyb20gJy4uLy4uL3V0aWxzL3BsdWdpbnMvcGFyc2VNYXJrZXRwbGFjZUlucHV0LmpzJ1xuaW1wb3J0IHR5cGUgeyBWaWV3U3RhdGUgfSBmcm9tICcuL3R5cGVzLmpzJ1xuXG50eXBlIFByb3BzID0ge1xuICBpbnB1dFZhbHVlOiBzdHJpbmdcbiAgc2V0SW5wdXRWYWx1ZTogKHZhbHVlOiBzdHJpbmcpID0+IHZvaWRcbiAgY3Vyc29yT2Zmc2V0OiBudW1iZXJcbiAgc2V0Q3Vyc29yT2Zmc2V0OiAob2Zmc2V0OiBudW1iZXIpID0+IHZvaWRcbiAgZXJyb3I6IHN0cmluZyB8IG51bGxcbiAgc2V0RXJyb3I6IChlcnJvcjogc3RyaW5nIHwgbnVsbCkgPT4gdm9pZFxuICByZXN1bHQ6IHN0cmluZyB8IG51bGxcbiAgc2V0UmVzdWx0OiAocmVzdWx0OiBzdHJpbmcgfCBudWxsKSA9PiB2b2lkXG4gIHNldFZpZXdTdGF0ZTogKHN0YXRlOiBWaWV3U3RhdGUpID0+IHZvaWRcbiAgb25BZGRDb21wbGV0ZT86ICgpID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+XG4gIGNsaU1vZGU/OiBib29sZWFuXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBBZGRNYXJrZXRwbGFjZSh7XG4gIGlucHV0VmFsdWUsXG4gIHNldElucHV0VmFsdWUsXG4gIGN1cnNvck9mZnNldCxcbiAgc2V0Q3Vyc29yT2Zmc2V0LFxuICBlcnJvcixcbiAgc2V0RXJyb3IsXG4gIHJlc3VsdCxcbiAgc2V0UmVzdWx0LFxuICBzZXRWaWV3U3RhdGUsXG4gIG9uQWRkQ29tcGxldGUsXG4gIGNsaU1vZGUgPSBmYWxzZSxcbn06IFByb3BzKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgY29uc3QgaGFzQXR0ZW1wdGVkQXV0b0FkZCA9IHVzZVJlZihmYWxzZSlcbiAgY29uc3QgW2lzTG9hZGluZywgc2V0TG9hZGluZ10gPSB1c2VTdGF0ZShmYWxzZSlcbiAgY29uc3QgW3Byb2dyZXNzTWVzc2FnZSwgc2V0UHJvZ3Jlc3NNZXNzYWdlXSA9IHVzZVN0YXRlPHN0cmluZz4oJycpXG5cbiAgY29uc3QgaGFuZGxlQWRkID0gYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRWYWx1ZS50cmltKClcbiAgICBpZiAoIWlucHV0KSB7XG4gICAgICBzZXRFcnJvcignUGxlYXNlIGVudGVyIGEgbWFya2V0cGxhY2Ugc291cmNlJylcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHBhcnNlZCA9IGF3YWl0IHBhcnNlTWFya2V0cGxhY2VJbnB1dChpbnB1dClcbiAgICBpZiAoIXBhcnNlZCkge1xuICAgICAgc2V0RXJyb3IoXG4gICAgICAgICdJbnZhbGlkIG1hcmtldHBsYWNlIHNvdXJjZSBmb3JtYXQuIFRyeTogb3duZXIvcmVwbywgaHR0cHM6Ly8uLi4sIG9yIC4vcGF0aCcsXG4gICAgICApXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBwYXJzZU1hcmtldHBsYWNlSW5wdXQgcmV0dXJuZWQgYW4gZXJyb3JcbiAgICBpZiAoJ2Vycm9yJyBpbiBwYXJzZWQpIHtcbiAgICAgIHNldEVycm9yKHBhcnNlZC5lcnJvcilcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHNldEVycm9yKG51bGwpXG5cbiAgICB0cnkge1xuICAgICAgc2V0TG9hZGluZyh0cnVlKVxuICAgICAgc2V0UHJvZ3Jlc3NNZXNzYWdlKCcnKVxuICAgICAgY29uc3QgeyBuYW1lLCByZXNvbHZlZFNvdXJjZSB9ID0gYXdhaXQgYWRkTWFya2V0cGxhY2VTb3VyY2UoXG4gICAgICAgIHBhcnNlZCxcbiAgICAgICAgbWVzc2FnZSA9PiB7XG4gICAgICAgICAgc2V0UHJvZ3Jlc3NNZXNzYWdlKG1lc3NhZ2UpXG4gICAgICAgIH0sXG4gICAgICApXG4gICAgICBzYXZlTWFya2V0cGxhY2VUb1NldHRpbmdzKG5hbWUsIHsgc291cmNlOiByZXNvbHZlZFNvdXJjZSB9KVxuICAgICAgY2xlYXJBbGxDYWNoZXMoKVxuXG4gICAgICBsZXQgc291cmNlVHlwZSA9IHBhcnNlZC5zb3VyY2VcbiAgICAgIGlmIChwYXJzZWQuc291cmNlID09PSAnZ2l0aHViJykge1xuICAgICAgICBzb3VyY2VUeXBlID1cbiAgICAgICAgICBwYXJzZWQucmVwbyBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTXG4gICAgICB9XG5cbiAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9tYXJrZXRwbGFjZV9hZGRlZCcsIHtcbiAgICAgICAgc291cmNlX3R5cGU6XG4gICAgICAgICAgc291cmNlVHlwZSBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgICAgfSlcblxuICAgICAgaWYgKG9uQWRkQ29tcGxldGUpIHtcbiAgICAgICAgYXdhaXQgb25BZGRDb21wbGV0ZSgpXG4gICAgICB9XG5cbiAgICAgIHNldFByb2dyZXNzTWVzc2FnZSgnJylcbiAgICAgIHNldExvYWRpbmcoZmFsc2UpXG5cbiAgICAgIGlmIChjbGlNb2RlKSB7XG4gICAgICAgIC8vIEluIENMSSBtb2RlLCBzZXQgcmVzdWx0IHRvIHRyaWdnZXIgY29tcGxldGlvblxuICAgICAgICBzZXRSZXN1bHQoYFN1Y2Nlc3NmdWxseSBhZGRlZCBtYXJrZXRwbGFjZTogJHtuYW1lfWApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJbiBpbnRlcmFjdGl2ZSBtb2RlLCBzd2l0Y2ggdG8gYnJvd3NlIHZpZXdcbiAgICAgICAgc2V0Vmlld1N0YXRlKHsgdHlwZTogJ2Jyb3dzZS1tYXJrZXRwbGFjZScsIHRhcmdldE1hcmtldHBsYWNlOiBuYW1lIH0pXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zdCBlcnJvciA9IHRvRXJyb3IoZXJyKVxuICAgICAgbG9nRXJyb3IoZXJyb3IpXG4gICAgICBzZXRFcnJvcihlcnJvci5tZXNzYWdlKVxuICAgICAgc2V0UHJvZ3Jlc3NNZXNzYWdlKCcnKVxuICAgICAgc2V0TG9hZGluZyhmYWxzZSlcblxuICAgICAgaWYgKGNsaU1vZGUpIHtcbiAgICAgICAgLy8gSW4gQ0xJIG1vZGUsIHNldCByZXN1bHQgd2l0aCBlcnJvciB0byB0cmlnZ2VyIGNvbXBsZXRpb25cbiAgICAgICAgc2V0UmVzdWx0KGBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRSZXN1bHQobnVsbClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBBdXRvLWFkZCBpZiBpbnB1dFZhbHVlIGlzIHByb3ZpZGVkXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGlucHV0VmFsdWUgJiYgIWhhc0F0dGVtcHRlZEF1dG9BZGQuY3VycmVudCAmJiAhZXJyb3IgJiYgIXJlc3VsdCkge1xuICAgICAgaGFzQXR0ZW1wdGVkQXV0b0FkZC5jdXJyZW50ID0gdHJ1ZVxuICAgICAgdm9pZCBoYW5kbGVBZGQoKVxuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvZXhoYXVzdGl2ZS1kZXBzXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvY29ycmVjdG5lc3MvdXNlRXhoYXVzdGl2ZURlcGVuZGVuY2llczogaW50ZW50aW9uYWxcbiAgfSwgW10pIC8vIE9ubHkgcnVuIG9uY2Ugb24gbW91bnRcblxuICByZXR1cm4gKFxuICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiPlxuICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIgcGFkZGluZ1g9ezF9IGJvcmRlclN0eWxlPVwicm91bmRcIj5cbiAgICAgICAgPEJveCBtYXJnaW5Cb3R0b209ezF9PlxuICAgICAgICAgIDxUZXh0IGJvbGQ+QWRkIE1hcmtldHBsYWNlPC9UZXh0PlxuICAgICAgICA8L0JveD5cbiAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCI+XG4gICAgICAgICAgPFRleHQ+RW50ZXIgbWFya2V0cGxhY2Ugc291cmNlOjwvVGV4dD5cbiAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5FeGFtcGxlczo8L1RleHQ+XG4gICAgICAgICAgPFRleHQgZGltQ29sb3I+IMK3IG93bmVyL3JlcG8gKEdpdEh1Yik8L1RleHQ+XG4gICAgICAgICAgPFRleHQgZGltQ29sb3I+IMK3IGdpdEBnaXRodWIuY29tOm93bmVyL3JlcG8uZ2l0IChTU0gpPC9UZXh0PlxuICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPiDCtyBodHRwczovL2V4YW1wbGUuY29tL21hcmtldHBsYWNlLmpzb248L1RleHQ+XG4gICAgICAgICAgPFRleHQgZGltQ29sb3I+IMK3IC4vcGF0aC90by9tYXJrZXRwbGFjZTwvVGV4dD5cbiAgICAgICAgICA8Qm94IG1hcmdpblRvcD17MX0+XG4gICAgICAgICAgICA8VGV4dElucHV0XG4gICAgICAgICAgICAgIHZhbHVlPXtpbnB1dFZhbHVlfVxuICAgICAgICAgICAgICBvbkNoYW5nZT17c2V0SW5wdXRWYWx1ZX1cbiAgICAgICAgICAgICAgb25TdWJtaXQ9e2hhbmRsZUFkZH1cbiAgICAgICAgICAgICAgY29sdW1ucz17ODB9XG4gICAgICAgICAgICAgIGN1cnNvck9mZnNldD17Y3Vyc29yT2Zmc2V0fVxuICAgICAgICAgICAgICBvbkNoYW5nZUN1cnNvck9mZnNldD17c2V0Q3Vyc29yT2Zmc2V0fVxuICAgICAgICAgICAgICBmb2N1c1xuICAgICAgICAgICAgICBzaG93Q3Vyc29yXG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvQm94PlxuICAgICAgICA8L0JveD5cbiAgICAgICAge2lzTG9hZGluZyAmJiAoXG4gICAgICAgICAgPEJveCBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgICAgPFNwaW5uZXIgLz5cbiAgICAgICAgICAgIDxUZXh0PlxuICAgICAgICAgICAgICB7cHJvZ3Jlc3NNZXNzYWdlIHx8ICdBZGRpbmcgbWFya2V0cGxhY2UgdG8gY29uZmlndXJhdGlvbuKApid9XG4gICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgICl9XG4gICAgICAgIHtlcnJvciAmJiAoXG4gICAgICAgICAgPEJveCBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgICAgPFRleHQgY29sb3I9XCJlcnJvclwiPntlcnJvcn08L1RleHQ+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgICl9XG4gICAgICAgIHtyZXN1bHQgJiYgKFxuICAgICAgICAgIDxCb3ggbWFyZ2luVG9wPXsxfT5cbiAgICAgICAgICAgIDxUZXh0PntyZXN1bHR9PC9UZXh0PlxuICAgICAgICAgIDwvQm94PlxuICAgICAgICApfVxuICAgICAgPC9Cb3g+XG4gICAgICA8Qm94IG1hcmdpbkxlZnQ9ezN9PlxuICAgICAgICA8VGV4dCBkaW1Db2xvciBpdGFsaWM+XG4gICAgICAgICAgPEJ5bGluZT5cbiAgICAgICAgICAgIDxLZXlib2FyZFNob3J0Y3V0SGludCBzaG9ydGN1dD1cIkVudGVyXCIgYWN0aW9uPVwiYWRkXCIgLz5cbiAgICAgICAgICAgIDxDb25maWd1cmFibGVTaG9ydGN1dEhpbnRcbiAgICAgICAgICAgICAgYWN0aW9uPVwiY29uZmlybTpub1wiXG4gICAgICAgICAgICAgIGNvbnRleHQ9XCJTZXR0aW5nc1wiXG4gICAgICAgICAgICAgIGZhbGxiYWNrPVwiRXNjXCJcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb249XCJjYW5jZWxcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgICA8L0J5bGluZT5cbiAgICAgICAgPC9UZXh0PlxuICAgICAgPC9Cb3g+XG4gICAgPC9Cb3g+XG4gIClcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLQSxLQUFLLE1BQU0sT0FBTztBQUM5QixTQUFTQyxTQUFTLEVBQUVDLE1BQU0sRUFBRUMsUUFBUSxRQUFRLE9BQU87QUFDbkQsU0FDRSxLQUFLQywwREFBMEQsRUFDL0RDLFFBQVEsUUFDSCxpQ0FBaUM7QUFDeEMsU0FBU0Msd0JBQXdCLFFBQVEsOENBQThD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
|
src/commands/plugin/BrowseMarketplace.tsx
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/commands/plugin/DiscoverPlugins.tsx
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/commands/plugin/ManageMarketplaces.tsx
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/commands/plugin/ManagePlugins.tsx
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/commands/plugin/PluginErrors.tsx
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { getPluginErrorMessage, type PluginError } from '../../types/plugin.js';
|
| 2 |
+
export function formatErrorMessage(error: PluginError): string {
|
| 3 |
+
switch (error.type) {
|
| 4 |
+
case 'path-not-found':
|
| 5 |
+
return `${error.component} path not found: ${error.path}`;
|
| 6 |
+
case 'git-auth-failed':
|
| 7 |
+
return `Git ${error.authType.toUpperCase()} authentication failed for ${error.gitUrl}`;
|
| 8 |
+
case 'git-timeout':
|
| 9 |
+
return `Git ${error.operation} timed out for ${error.gitUrl}`;
|
| 10 |
+
case 'network-error':
|
| 11 |
+
return `Network error accessing ${error.url}${error.details ? `: ${error.details}` : ''}`;
|
| 12 |
+
case 'manifest-parse-error':
|
| 13 |
+
return `Failed to parse manifest at ${error.manifestPath}: ${error.parseError}`;
|
| 14 |
+
case 'manifest-validation-error':
|
| 15 |
+
return `Invalid manifest at ${error.manifestPath}: ${error.validationErrors.join(', ')}`;
|
| 16 |
+
case 'plugin-not-found':
|
| 17 |
+
return `Plugin "${error.pluginId}" not found in marketplace "${error.marketplace}"`;
|
| 18 |
+
case 'marketplace-not-found':
|
| 19 |
+
return `Marketplace "${error.marketplace}" not found`;
|
| 20 |
+
case 'marketplace-load-failed':
|
| 21 |
+
return `Failed to load marketplace "${error.marketplace}": ${error.reason}`;
|
| 22 |
+
case 'mcp-config-invalid':
|
| 23 |
+
return `Invalid MCP server config for "${error.serverName}": ${error.validationError}`;
|
| 24 |
+
case 'mcp-server-suppressed-duplicate':
|
| 25 |
+
{
|
| 26 |
+
const dup = error.duplicateOf.startsWith('plugin:') ? `server provided by plugin "${error.duplicateOf.split(':')[1] ?? '?'}"` : `already-configured "${error.duplicateOf}"`;
|
| 27 |
+
return `MCP server "${error.serverName}" skipped — same command/URL as ${dup}`;
|
| 28 |
+
}
|
| 29 |
+
case 'hook-load-failed':
|
| 30 |
+
return `Failed to load hooks from ${error.hookPath}: ${error.reason}`;
|
| 31 |
+
case 'component-load-failed':
|
| 32 |
+
return `Failed to load ${error.component} from ${error.path}: ${error.reason}`;
|
| 33 |
+
case 'mcpb-download-failed':
|
| 34 |
+
return `Failed to download MCPB from ${error.url}: ${error.reason}`;
|
| 35 |
+
case 'mcpb-extract-failed':
|
| 36 |
+
return `Failed to extract MCPB ${error.mcpbPath}: ${error.reason}`;
|
| 37 |
+
case 'mcpb-invalid-manifest':
|
| 38 |
+
return `MCPB manifest invalid at ${error.mcpbPath}: ${error.validationError}`;
|
| 39 |
+
case 'marketplace-blocked-by-policy':
|
| 40 |
+
return error.blockedByBlocklist ? `Marketplace "${error.marketplace}" is blocked by enterprise policy` : `Marketplace "${error.marketplace}" is not in the allowed marketplace list`;
|
| 41 |
+
case 'dependency-unsatisfied':
|
| 42 |
+
return error.reason === 'not-enabled' ? `Dependency "${error.dependency}" is disabled` : `Dependency "${error.dependency}" is not installed`;
|
| 43 |
+
case 'lsp-config-invalid':
|
| 44 |
+
return `Invalid LSP server config for "${error.serverName}": ${error.validationError}`;
|
| 45 |
+
case 'lsp-server-start-failed':
|
| 46 |
+
return `LSP server "${error.serverName}" failed to start: ${error.reason}`;
|
| 47 |
+
case 'lsp-server-crashed':
|
| 48 |
+
return error.signal ? `LSP server "${error.serverName}" crashed with signal ${error.signal}` : `LSP server "${error.serverName}" crashed with exit code ${error.exitCode ?? 'unknown'}`;
|
| 49 |
+
case 'lsp-request-timeout':
|
| 50 |
+
return `LSP server "${error.serverName}" timed out on ${error.method} after ${error.timeoutMs}ms`;
|
| 51 |
+
case 'lsp-request-failed':
|
| 52 |
+
return `LSP server "${error.serverName}" ${error.method} failed: ${error.error}`;
|
| 53 |
+
case 'plugin-cache-miss':
|
| 54 |
+
return `Plugin "${error.plugin}" not cached at ${error.installPath}`;
|
| 55 |
+
case 'generic-error':
|
| 56 |
+
return error.error;
|
| 57 |
+
}
|
| 58 |
+
const _exhaustive: never = error;
|
| 59 |
+
return getPluginErrorMessage(_exhaustive);
|
| 60 |
+
}
|
| 61 |
+
export function getErrorGuidance(error: PluginError): string | null {
|
| 62 |
+
switch (error.type) {
|
| 63 |
+
case 'path-not-found':
|
| 64 |
+
return 'Check that the path in your manifest or marketplace config is correct';
|
| 65 |
+
case 'git-auth-failed':
|
| 66 |
+
return error.authType === 'ssh' ? 'Configure SSH keys or use HTTPS URL instead' : 'Configure credentials or use SSH URL instead';
|
| 67 |
+
case 'git-timeout':
|
| 68 |
+
case 'network-error':
|
| 69 |
+
return 'Check your internet connection and try again';
|
| 70 |
+
case 'manifest-parse-error':
|
| 71 |
+
return 'Check manifest file syntax in the plugin directory';
|
| 72 |
+
case 'manifest-validation-error':
|
| 73 |
+
return 'Check manifest file follows the required schema';
|
| 74 |
+
case 'plugin-not-found':
|
| 75 |
+
return `Plugin may not exist in marketplace "${error.marketplace}"`;
|
| 76 |
+
case 'marketplace-not-found':
|
| 77 |
+
return error.availableMarketplaces.length > 0 ? `Available marketplaces: ${error.availableMarketplaces.join(', ')}` : 'Add the marketplace first using /plugin marketplace add';
|
| 78 |
+
case 'mcp-config-invalid':
|
| 79 |
+
return 'Check MCP server configuration in .mcp.json or manifest';
|
| 80 |
+
case 'mcp-server-suppressed-duplicate':
|
| 81 |
+
{
|
| 82 |
+
// duplicateOf is "plugin:name:srv" when another plugin won dedup —
|
| 83 |
+
// users can't remove plugin-provided servers from their MCP config,
|
| 84 |
+
// so point them at the winning plugin instead.
|
| 85 |
+
if (error.duplicateOf.startsWith('plugin:')) {
|
| 86 |
+
const winningPlugin = error.duplicateOf.split(':')[1] ?? 'the other plugin';
|
| 87 |
+
return `Disable plugin "${winningPlugin}" if you want this plugin's version instead`;
|
| 88 |
+
}
|
| 89 |
+
return `Remove "${error.duplicateOf}" from your MCP config if you want the plugin's version instead`;
|
| 90 |
+
}
|
| 91 |
+
case 'hook-load-failed':
|
| 92 |
+
return 'Check hooks.json file syntax and structure';
|
| 93 |
+
case 'component-load-failed':
|
| 94 |
+
return `Check ${error.component} directory structure and file permissions`;
|
| 95 |
+
case 'mcpb-download-failed':
|
| 96 |
+
return 'Check your internet connection and URL accessibility';
|
| 97 |
+
case 'mcpb-extract-failed':
|
| 98 |
+
return 'Verify the MCPB file is valid and not corrupted';
|
| 99 |
+
case 'mcpb-invalid-manifest':
|
| 100 |
+
return 'Contact the plugin author about the invalid manifest';
|
| 101 |
+
case 'marketplace-blocked-by-policy':
|
| 102 |
+
if (error.blockedByBlocklist) {
|
| 103 |
+
return 'This marketplace source is explicitly blocked by your administrator';
|
| 104 |
+
}
|
| 105 |
+
return error.allowedSources.length > 0 ? `Allowed sources: ${error.allowedSources.join(', ')}` : 'Contact your administrator to configure allowed marketplace sources';
|
| 106 |
+
case 'dependency-unsatisfied':
|
| 107 |
+
return error.reason === 'not-enabled' ? `Enable "${error.dependency}" or uninstall "${error.plugin}"` : `Install "${error.dependency}" or uninstall "${error.plugin}"`;
|
| 108 |
+
case 'lsp-config-invalid':
|
| 109 |
+
return 'Check LSP server configuration in the plugin manifest';
|
| 110 |
+
case 'lsp-server-start-failed':
|
| 111 |
+
case 'lsp-server-crashed':
|
| 112 |
+
case 'lsp-request-timeout':
|
| 113 |
+
case 'lsp-request-failed':
|
| 114 |
+
return 'Check LSP server logs with --debug for details';
|
| 115 |
+
case 'plugin-cache-miss':
|
| 116 |
+
return 'Run /plugins to refresh the plugin cache';
|
| 117 |
+
case 'marketplace-load-failed':
|
| 118 |
+
case 'generic-error':
|
| 119 |
+
return null;
|
| 120 |
+
}
|
| 121 |
+
const _exhaustive: never = error;
|
| 122 |
+
return null;
|
| 123 |
+
}
|
| 124 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJnZXRQbHVnaW5FcnJvck1lc3NhZ2UiLCJQbHVnaW5FcnJvciIsImZvcm1hdEVycm9yTWVzc2FnZSIsImVycm9yIiwidHlwZSIsImNvbXBvbmVudCIsInBhdGgiLCJhdXRoVHlwZSIsInRvVXBwZXJDYXNlIiwiZ2l0VXJsIiwib3BlcmF0aW9uIiwidXJsIiwiZGV0YWlscyIsIm1hbmlmZXN0UGF0aCIsInBhcnNlRXJyb3IiLCJ2YWxpZGF0aW9uRXJyb3JzIiwiam9pbiIsInBsdWdpbklkIiwibWFya2V0cGxhY2UiLCJyZWFzb24iLCJzZXJ2ZXJOYW1lIiwidmFsaWRhdGlvbkVycm9yIiwiZHVwIiwiZHVwbGljYXRlT2YiLCJzdGFydHNXaXRoIiwic3BsaXQiLCJob29rUGF0aCIsIm1jcGJQYXRoIiwiYmxvY2tlZEJ5QmxvY2tsaXN0IiwiZGVwZW5kZW5jeSIsInNpZ25hbCIsImV4aXRDb2RlIiwibWV0aG9kIiwidGltZW91dE1zIiwicGx1Z2luIiwiaW5zdGFsbFBhdGgiLCJfZXhoYXVzdGl2ZSIsImdldEVycm9yR3VpZGFuY2UiLCJhdmFpbGFibGVNYXJrZXRwbGFjZXMiLCJsZW5ndGgiLCJ3aW5uaW5nUGx1Z2luIiwiYWxsb3dlZFNvdXJjZXMiXSwic291cmNlcyI6WyJQbHVnaW5FcnJvcnMudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGdldFBsdWdpbkVycm9yTWVzc2FnZSwgdHlwZSBQbHVnaW5FcnJvciB9IGZyb20gJy4uLy4uL3R5cGVzL3BsdWdpbi5qcydcblxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdEVycm9yTWVzc2FnZShlcnJvcjogUGx1Z2luRXJyb3IpOiBzdHJpbmcge1xuICBzd2l0Y2ggKGVycm9yLnR5cGUpIHtcbiAgICBjYXNlICdwYXRoLW5vdC1mb3VuZCc6XG4gICAgICByZXR1cm4gYCR7ZXJyb3IuY29tcG9uZW50fSBwYXRoIG5vdCBmb3VuZDogJHtlcnJvci5wYXRofWBcbiAgICBjYXNlICdnaXQtYXV0aC1mYWlsZWQnOlxuICAgICAgcmV0dXJuIGBHaXQgJHtlcnJvci5hdXRoVHlwZS50b1VwcGVyQ2FzZSgpfSBhdXRoZW50aWNhdGlvbiBmYWlsZWQgZm9yICR7ZXJyb3IuZ2l0VXJsfWBcbiAgICBjYXNlICdnaXQtdGltZW91dCc6XG4gICAgICByZXR1cm4gYEdpdCAke2Vycm9yLm9wZXJhdGlvbn0gdGltZWQgb3V0IGZvciAke2Vycm9yLmdpdFVybH1gXG4gICAgY2FzZSAnbmV0d29yay1lcnJvcic6XG4gICAgICByZXR1cm4gYE5ldHdvcmsgZXJyb3IgYWNjZXNzaW5nICR7ZXJyb3IudXJsfSR7ZXJyb3IuZGV0YWlscyA/IGA6ICR7ZXJyb3IuZGV0YWlsc31gIDogJyd9YFxuICAgIGNhc2UgJ21hbmlmZXN0LXBhcnNlLWVycm9yJzpcbiAgICAgIHJldHVybiBgRmFpbGVkIHRvIHBhcnNlIG1hbmlmZXN0IGF0ICR7ZXJyb3IubWFuaWZlc3RQYXRofTogJHtlcnJvci5wYXJzZUVycm9yfWBcbiAgICBjYXNlICdtYW5pZmVzdC12YWxpZGF0aW9uLWVycm9yJzpcbiAgICAgIHJldHVybiBgSW52YWxpZCBtYW5pZmVzdCBhdCAke2Vycm9yLm1hbmlmZXN0UGF0aH06ICR7ZXJyb3IudmFsaWRhdGlvbkVycm9ycy5qb2luKCcsICcpfWBcbiAgICBjYXNlICdwbHVnaW4tbm90LWZvdW5kJzpcbiAgICAgIHJldHVybiBgUGx1Z2luIFwiJHtlcnJvci5wbHVnaW5JZH1cIiBub3QgZm91bmQgaW4gbWFya2V0cGxhY2UgXCIke2Vycm9yLm1hcmtldHBsYWNlfVwiYFxuICAgIGNhc2UgJ21hcmtldHBsYWNlLW5vdC1mb3VuZCc6XG4gICAgICByZXR1cm4gYE1hcmtldHBsYWNlIFwiJHtlcnJvci5tYXJrZXRwbGFjZX1cIiBub3QgZm91bmRgXG4gICAgY2FzZSAnbWFya2V0cGxhY2UtbG9hZC1mYWlsZWQnOlxuICAgICAgcmV0dXJuIGBGYWlsZWQgdG8gbG9hZCBtYXJrZXRwbGFjZSBcIiR7ZXJyb3IubWFya2V0cGxhY2V9XCI6ICR7ZXJyb3IucmVhc29ufWBcbiAgICBjYXNlICdtY3AtY29uZmlnLWludmFsaWQnOlxuICAgICAgcmV0dXJuIGBJbnZhbGlkIE1DUCBzZXJ2ZXIgY29uZmlnIGZvciBcIiR7ZXJyb3Iuc2VydmVyTmFtZX1cIjogJHtlcnJvci52YWxpZGF0aW9uRXJyb3J9YFxuICAgIGNhc2UgJ21jcC1zZXJ2ZXItc3VwcHJlc3NlZC1kdXBsaWNhdGUnOiB7XG4gICAgICBjb25zdCBkdXAgPSBlcnJvci5kdXBsaWNhdGVPZi5zdGFydHNXaXRoKCdwbHVnaW46JylcbiAgICAgICAgPyBgc2VydmVyIHByb3ZpZGVkIGJ5IHBsdWdpbiBcIiR7ZXJyb3IuZHVwbGljYXRlT2Yuc3BsaXQoJzonKVsxXSA/PyAnPyd9XCJgXG4gICAgICAgIDogYGFscmVhZHktY29uZmlndXJlZCBcIiR7ZXJyb3IuZHVwbGljYXRlT2Z9XCJgXG4gICAgICByZXR1cm4gYE1DUCBzZXJ2ZXIgXCIke2Vycm9yLnNlcnZlck5hbWV9XCIgc2tpcHBlZCDigJQgc2FtZSBjb21tYW5kL1VSTCBhcyAke2R1cH1gXG4gICAgfVxuICAgIGNhc2UgJ2hvb2stbG9hZC1mYWlsZWQnOlxuICAgICAgcmV0dXJuIGBGYWlsZWQgdG8gbG9hZCBob29rcyBmcm9tICR7ZXJyb3IuaG9va1BhdGh9OiAke2Vycm9yLnJlYXNvbn1gXG4gICAgY2FzZSAnY29tcG9uZW50LWxvYWQtZmFpbGVkJzpcbiAgICAgIHJldHVybiBgRmFpbGVkIHRvIGxvYWQgJHtlcnJvci5jb21wb25lbnR9IGZyb20gJHtlcnJvci5wYXRofTogJHtlcnJvci5yZWFzb259YFxuICAgIGNhc2UgJ21jcGItZG93bmxvYWQtZmFpbGVkJzpcbiAgICAgIHJldHVybiBgRmFpbGVkIHRvIGRvd25sb2FkIE1DUEIgZnJvbSAke2Vycm9yLnVybH06ICR7ZXJyb3IucmVhc29ufWBcbiAgICBjYXNlICdtY3BiLWV4dHJhY3QtZmFpbGVkJzpcbiAgICAgIHJldHVybiBgRmFpbGVkIHRvIGV4dHJhY3QgTUNQQiAke2Vycm9yLm1jcGJQYXRofTogJHtlcnJvci5yZWFzb259YFxuICAgIGNhc2UgJ21jcGItaW52YWxpZC1tYW5pZmVzdCc6XG4gICAgICByZXR1cm4gYE1DUEIgbWFuaWZlc3QgaW52YWxpZCBhdCAke2Vycm9yLm1jcGJQYXRofTogJHtlcnJvci52YWxpZGF0aW9uRXJyb3J9YFxuICAgIGNhc2UgJ21hcmtldHBsYWNlLWJsb2NrZWQtYnktcG9saWN5JzpcbiAgICAgIHJldHVybiBlcnJvci5ibG9ja2VkQnlCbG9ja2xpc3RcbiAgICAgICAgPyBgTWFya2V0cGxhY2UgXCIke2Vycm9yLm1hcmtldHBsYWNlfVwiIGlzIGJsb2NrZWQgYnkgZW50ZXJwcmlzZSBwb2xpY3lgXG4gICAgICAgIDogYE1hcmtldHBsYWNlIFwiJHtlcnJvci5tYXJrZXRwbGFjZX1cIiBpcyBub3QgaW4gdGhlIGFsbG93ZWQgbWFya2V0cGxhY2UgbGlzdGBcbiAgICBjYXNlICdkZXBlbmRlbmN5LXVuc2F0aXNmaWVkJzpcbiAgICAgIHJldHVybiBlcnJvci5yZWFzb24gPT09ICdub3QtZW5hYmxlZCdcbiAgICAgICAgPyBgRGVwZW5kZW5jeSBcIiR7ZXJyb3IuZGVwZW5kZW5jeX1cIiBpcyBkaXNhYmxlZGBcbiAgICAgICAgOiBgRGVwZW5kZW5jeSBcIiR7ZXJyb3IuZGVwZW5kZW5jeX1cIiBpcyBub3QgaW5zdGFsbGVkYFxuICAgIGNhc2UgJ2xzcC1jb25maWctaW52YWxpZCc6XG4gICAgICByZXR1cm4gYEludmFsaWQgTFNQIHNlcnZlciBjb25maWcgZm9yIFwiJHtlcnJvci5zZXJ2ZXJOYW1lfVwiOiAke2Vycm9yLnZhbGlkYXRpb25FcnJvcn1gXG4gICAgY2FzZSAnbHNwLXNlcnZlci1zdGFydC1mYWlsZWQnOlxuICAgICAgcmV0dXJuIGBMU1Agc2VydmVyIFwiJHtlcnJvci5zZXJ2ZXJOYW1lfVwiIGZhaWxlZCB0byBzdGFydDogJHtlcnJvci5yZWFzb259YFxuICAgIGNhc2UgJ2xzcC1zZXJ2ZXItY3Jhc2hlZCc6XG4gICAgICByZXR1cm4gZXJyb3Iuc2lnbmFsXG4gICAgICAgID8gYExTUCBzZXJ2ZXIgXCIke2Vycm9yLnNlcnZlck5hbWV9XCIgY3Jhc2hlZCB3aXRoIHNpZ25hbCAke2Vycm9yLnNpZ25hbH1gXG4gICAgICAgIDogYExTUCBzZXJ2ZXIgXCIke2Vycm9yLnNlcnZlck5hbWV9XCIgY3Jhc2hlZCB3aXRoIGV4aXQgY29kZSAke2Vycm9yLmV4aXRDb2RlID8/ICd1bmtub3duJ31gXG4gICAgY2FzZSAnbHNwLXJlcXVlc3QtdGltZW91dCc6XG4gICAgICByZXR1cm4gYExTUCBzZXJ2ZXIgXCIke2Vycm9yLnNlcnZlck5hbWV9XCIgdGltZWQgb3V0IG9uICR7ZXJyb3IubWV0aG9kfSBhZnRlciAke2Vycm9yLnRpbWVvdXRNc31tc2BcbiAgICBjYXNlICdsc3AtcmVxdWVzdC1mYWlsZWQnOlxuICAgICAgcmV0dXJuIGBMU1Agc2VydmVyIFwiJHtlcnJvci5zZXJ2ZXJOYW1lfVwiICR7ZXJyb3IubWV0aG9kfSBmYWlsZWQ6ICR7ZXJyb3IuZXJyb3J9YFxuICAgIGNhc2UgJ3BsdWdpbi1jYWNoZS1taXNzJzpcbiAgICAgIHJldHVybiBgUGx1Z2luIFwiJHtlcnJvci5wbHVnaW59XCIgbm90IGNhY2hlZCBhdCAke2Vycm9yLmluc3RhbGxQYXRofWBcbiAgICBjYXNlICdnZW5lcmljLWVycm9yJzpcbiAgICAgIHJldHVybiBlcnJvci5lcnJvclxuICB9XG4gIGNvbnN0IF9leGhhdXN0aXZlOiBuZXZlciA9IGVycm9yXG4gIHJldHVybiBnZXRQbHVnaW5FcnJvck1lc3NhZ2UoX2V4aGF1c3RpdmUpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFcnJvckd1aWRhbmNlKGVycm9yOiBQbHVnaW5FcnJvcik6IHN0cmluZyB8IG51bGwge1xuICBzd2l0Y2ggKGVycm9yLnR5cGUpIHtcbiAgICBjYXNlICdwYXRoLW5vdC1mb3VuZCc6XG4gICAgICByZXR1cm4gJ0NoZWNrIHRoYXQgdGhlIHBhdGggaW4geW91ciBtYW5pZmVzdCBvciBtYXJrZXRwbGFjZSBjb25maWcgaXMgY29ycmVjdCdcbiAgICBjYXNlICdnaXQtYXV0aC1mYWlsZWQnOlxuICAgICAgcmV0dXJuIGVycm9yLmF1dGhUeXBlID09PSAnc3NoJ1xuICAgICAgICA/ICdDb25maWd1cmUgU1NIIGtleXMgb3IgdXNlIEhUVFBTIFVSTCBpbnN0ZWFkJ1xuICAgICAgICA6ICdDb25maWd1cmUgY3JlZGVudGlhbHMgb3IgdXNlIFNTSCBVUkwgaW5zdGVhZCdcbiAgICBjYXNlICdnaXQtdGltZW91dCc6XG4gICAgY2FzZSAnbmV0d29yay1lcnJvcic6XG4gICAgICByZXR1cm4gJ0NoZWNrIHlvdXIgaW50ZXJuZXQgY29ubmVjdGlvbiBhbmQgdHJ5IGFnYWluJ1xuICAgIGNhc2UgJ21hbmlmZXN0LXBhcnNlLWVycm9yJzpcbiAgICAgIHJldHVybiAnQ2hlY2sgbWFuaWZlc3QgZmlsZSBzeW50YXggaW4gdGhlIHBsdWdpbiBkaXJlY3RvcnknXG4gICAgY2FzZSAnbWFuaWZlc3QtdmFsaWRhdGlvbi1lcnJvcic6XG4gICAgICByZXR1cm4gJ0NoZWNrIG1hbmlmZXN0IGZpbGUgZm9sbG93cyB0aGUgcmVxdWlyZWQgc2NoZW1hJ1xuICAgIGNhc2UgJ3BsdWdpbi1ub3QtZm91bmQnOlxuICAgICAgcmV0dXJuIGBQbHVnaW4gbWF5IG5vdCBleGlzdCBpbiBtYXJrZXRwbGFjZSBcIiR7ZXJyb3IubWFya2V0cGxhY2V9XCJgXG4gICAgY2FzZSAnbWFya2V0cGxhY2Utbm90LWZvdW5kJzpcbiAgICAgIHJldHVybiBlcnJvci5hdmFpbGFibGVNYXJrZXRwbGFjZXMubGVuZ3RoID4gMFxuICAgICAgICA/IGBBdmFpbGFibGUgbWFya2V0cGxhY2VzOiAke2Vycm9yLmF2YWlsYWJsZU1hcmtldHBsYWNlcy5qb2luKCcsICcpfWBcbiAgICAgICAgOiAnQWRkIHRoZSBtYXJrZXRwbGFjZSBmaXJzdCB1c2luZyAvcGx1Z2luIG1hcmtldHBsYWNlIGFkZCdcbiAgICBjYXNlICdtY3AtY29uZmlnLWludmFsaWQnOlxuICAgICAgcmV0dXJuICdDaGVjayBNQ1Agc2VydmVyIGNvbmZpZ3VyYXRpb24gaW4gLm1jcC5qc29uIG9yIG1hbmlmZXN0J1xuICAgIGNhc2UgJ21jcC1zZXJ2ZXItc3VwcHJlc3NlZC1kdXBsaWNhdGUnOiB7XG4gICAgICAvLyBkdXBsaWNhdGVPZiBpcyBcInBsdWdpbjpuYW1lOnNydlwiIHdoZW4gYW5vdGhlciBwbHVnaW4gd29uIGRlZHVwIOKAlFxuICAgICAgLy8gdXNlcnMgY2FuJ3QgcmVtb3ZlIHBsdWdpbi1wcm92aWRlZCBzZXJ2ZXJzIGZyb20gdGhlaXIgTUNQIGNvbmZpZyxcbiAgICAgIC8vIHNvIHBvaW50IHRoZW0gYXQgdGhlIHdpbm5pbmcgcGx1Z2luIGluc3RlYWQuXG4gICAgICBpZiAoZXJyb3IuZHVwbGljYXRlT2Yuc3RhcnRzV2l0aCgncGx1Z2luOicpKSB7XG4gICAgICAgIGNvbnN0IHdpbm5pbmdQbHVnaW4gPVxuICAgICAgICAgIGVycm9yLmR1cGxpY2F0ZU9mLnNwbGl0KCc6JylbMV0gPz8gJ3RoZSBvdGhlciBwbHVnaW4nXG4gICAgICAgIHJldHVybiBgRGlzYWJsZSBwbHVnaW4gXCIke3dpbm5pbmdQbHVnaW59XCIgaWYgeW91IHdhbnQgdGhpcyBwbHVnaW4ncyB2ZXJzaW9uIGluc3RlYWRgXG4gICAgICB9XG4gICAgICByZXR1cm4gYFJlbW92ZSBcIiR7ZXJyb3IuZHVwbGljYXRlT2Z9XCIgZnJvbSB5b3VyIE1DUCBjb25maWcgaWYgeW91IHdhbnQgdGhlIHBsdWdpbidzIHZlcnNpb24gaW5zdGVhZGBcbiAgICB9XG4gICAgY2FzZSAnaG9vay1sb2FkLWZhaWxlZCc6XG4gICAgICByZXR1cm4gJ0NoZWNrIGhvb2tzLmpzb24gZmlsZSBzeW50YXggYW5kIHN0cnVjdHVyZSdcbiAgICBjYXNlICdjb21wb25lbnQtbG9hZC1mYWlsZWQnOlxuICAgICAgcmV0dXJuIGBDaGVjayAke2Vycm9yLmNvbXBvbmVudH0gZGlyZWN0b3J5IHN0cnVjdHVyZSBhbmQgZmlsZSBwZXJtaXNzaW9uc2BcbiAgICBjYXNlICdtY3BiLWRvd25sb2FkLWZhaWxlZCc6XG4gICAgICByZXR1cm4gJ0NoZWNrIHlvdXIgaW50ZXJuZXQgY29ubmVjdGlvbiBhbmQgVVJMIGFjY2Vzc2liaWxpdHknXG4gICAgY2FzZSAnbWNwYi1leHRyYWN0LWZhaWxlZCc6XG4gICAgICByZXR1cm4gJ1ZlcmlmeSB0aGUgTUNQQiBmaWxlIGlzIHZhbGlkIGFuZCBub3QgY29ycnVwdGVkJ1xuICAgIGNhc2UgJ21jcGItaW52YWxpZC1tYW5pZmVzdCc6XG4gICAgICByZXR1cm4gJ0NvbnRhY3QgdGhlIHBsdWdpbiBhdXRob3IgYWJvdXQgdGhlIGludmFsaWQgbWFuaWZlc3QnXG4gICAgY2FzZSAnbWFya2V0cGxhY2UtYmxvY2tlZC1ieS1wb2xpY3knOlxuICAgICAgaWYgKGVycm9yLmJsb2NrZWRCeUJsb2NrbGlzdCkge1xuICAgICAgICByZXR1cm4gJ1RoaXMgbWFya2V0cGxhY2Ugc291cmNlIGlzIGV4cGxpY2l0bHkgYmxvY2tlZCBieSB5b3VyIGFkbWluaXN0cmF0b3InXG4gICAgICB9XG4gICAgICByZXR1cm4gZXJyb3IuYWxsb3dlZFNvdXJjZXMubGVuZ3RoID4gMFxuICAgICAgICA/IGBBbGxvd2VkIHNvdXJjZXM6ICR7ZXJyb3IuYWxsb3dlZFNvdXJjZXMuam9pbignLCAnKX1gXG4gICAgICAgIDogJ0NvbnRhY3QgeW91ciBhZG1pbmlzdHJhdG9yIHRvIGNvbmZpZ3VyZSBhbGxvd2VkIG1hcmtldHBsYWNlIHNvdXJjZXMnXG4gICAgY2FzZSAnZGVwZW5kZW5jeS11bnNhdGlzZmllZCc6XG4gICAgICByZXR1cm4gZXJyb3IucmVhc29uID09PSAnbm90LWVuYWJsZWQnXG4gICAgICAgID8gYEVuYWJsZSBcIiR7ZXJyb3IuZGVwZW5kZW5jeX1cIiBvciB1bmluc3RhbGwgXCIke2Vycm9yLnBsdWdpbn1cImBcbiAgICAgICAgOiBgSW5zdGFsbCBcIiR7ZXJyb3IuZGVwZW5kZW5jeX1cIiBvciB1bmluc3RhbGwgXCIke2Vycm9yLnBsdWdpbn1cImBcbiAgICBjYXNlICdsc3AtY29uZmlnLWludmFsaWQnOlxuICAgICAgcmV0dXJuICdDaGVjayBMU1Agc2VydmVyIGNvbmZpZ3VyYXRpb24gaW4gdGhlIHBsdWdpbiBtYW5pZmVzdCdcbiAgICBjYXNlICdsc3Atc2VydmVyLXN0YXJ0LWZhaWxlZCc6XG4gICAgY2FzZSAnbHNwLXNlcnZlci1jcmFzaGVkJzpcbiAgICBjYXNlICdsc3AtcmVxdWVzdC10aW1lb3V0JzpcbiAgICBjYXNlICdsc3AtcmVxdWVzdC1mYWlsZWQnOlxuICAgICAgcmV0dXJuICdDaGVjayBMU1Agc2VydmVyIGxvZ3Mgd2l0aCAtLWRlYnVnIGZvciBkZXRhaWxzJ1xuICAgIGNhc2UgJ3BsdWdpbi1jYWNoZS1taXNzJzpcbiAgICAgIHJldHVybiAnUnVuIC9wbHVnaW5zIHRvIHJlZnJlc2ggdGhlIHBsdWdpbiBjYWNoZSdcbiAgICBjYXNlICdtYXJrZXRwbGFjZS1sb2FkLWZhaWxlZCc6XG4gICAgY2FzZSAnZ2VuZXJpYy1lcnJvcic6XG4gICAgICByZXR1cm4gbnVsbFxuICB9XG4gIGNvbnN0IF9leGhhdXN0aXZlOiBuZXZlciA9IGVycm9yXG4gIHJldHVybiBudWxsXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLHFCQUFxQixFQUFFLEtBQUtDLFdBQVcsUUFBUSx1QkFBdUI7QUFFL0UsT0FBTyxTQUFTQyxrQkFBa0JBLENBQUNDLEtBQUssRUFBRUYsV0FBVyxDQUFDLEVBQUUsTUFBTSxDQUFDO0VBQzdELFFBQVFFLEtBQUssQ0FBQ0MsSUFBSTtJQUNoQixLQUFLLGdCQUFnQjtNQUNuQixPQUFPLEdBQUdELEtBQUssQ0FBQ0UsU0FBUyxvQkFBb0JGLEtBQUssQ0FBQ0csSUFBSSxFQUFFO0lBQzNELEtBQUssaUJBQWlCO01BQ3BCLE9BQU8sT0FBT0gsS0FBSyxDQUFDSSxRQUFRLENBQUNDLFdBQVcsQ0FBQyxDQUFDLDhCQUE4QkwsS0FBSyxDQUFDTSxNQUFNLEVBQUU7SUFDeEYsS0FBSyxh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
|
src/commands/plugin/PluginOptionsDialog.tsx
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { c as _c } from "react/compiler-runtime";
|
| 2 |
+
import figures from 'figures';
|
| 3 |
+
import React, { useCallback, useState } from 'react';
|
| 4 |
+
import { Dialog } from '../../components/design-system/Dialog.js';
|
| 5 |
+
import { stringWidth } from '../../ink/stringWidth.js';
|
| 6 |
+
// eslint-disable-next-line custom-rules/prefer-use-keybindings -- raw text input for config dialog
|
| 7 |
+
import { Box, Text, useInput } from '../../ink.js';
|
| 8 |
+
import { useKeybinding, useKeybindings } from '../../keybindings/useKeybinding.js';
|
| 9 |
+
import { isEnvTruthy } from '../../utils/envUtils.js';
|
| 10 |
+
import type { PluginOptionSchema, PluginOptionValues } from '../../utils/plugins/pluginOptionsStorage.js';
|
| 11 |
+
|
| 12 |
+
/**
|
| 13 |
+
* Build the onSave payload from collected string inputs.
|
| 14 |
+
*
|
| 15 |
+
* Sensitive fields are never prepopulated in the text buffer (security), so
|
| 16 |
+
* by the time the user reaches the last field every sensitive field they
|
| 17 |
+
* stepped through contains '' in collected. To avoid silently wiping saved
|
| 18 |
+
* secrets on reconfigure: if a sensitive field is '' AND initialValues has
|
| 19 |
+
* a value for it, OMIT the key entirely. savePluginOptions only writes keys
|
| 20 |
+
* it receives, so omitting = keep existing.
|
| 21 |
+
*
|
| 22 |
+
* Exported for unit testing.
|
| 23 |
+
*/
|
| 24 |
+
export function buildFinalValues(fields: string[], collected: Record<string, string>, configSchema: PluginOptionSchema, initialValues: PluginOptionValues | undefined): PluginOptionValues {
|
| 25 |
+
const finalValues: PluginOptionValues = {};
|
| 26 |
+
for (const fieldKey of fields) {
|
| 27 |
+
const schema = configSchema[fieldKey];
|
| 28 |
+
const value = collected[fieldKey] ?? '';
|
| 29 |
+
if (schema?.sensitive === true && value === '' && initialValues?.[fieldKey] !== undefined) {
|
| 30 |
+
continue;
|
| 31 |
+
}
|
| 32 |
+
if (schema?.type === 'number') {
|
| 33 |
+
// Number('') returns 0, not NaN — omit blank number inputs so
|
| 34 |
+
// validateUserConfig's required check actually catches them.
|
| 35 |
+
if (value.trim() === '') continue;
|
| 36 |
+
const num = Number(value);
|
| 37 |
+
finalValues[fieldKey] = Number.isNaN(num) ? value : num;
|
| 38 |
+
} else if (schema?.type === 'boolean') {
|
| 39 |
+
finalValues[fieldKey] = isEnvTruthy(value);
|
| 40 |
+
} else {
|
| 41 |
+
finalValues[fieldKey] = value;
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
return finalValues;
|
| 45 |
+
}
|
| 46 |
+
type Props = {
|
| 47 |
+
title: string;
|
| 48 |
+
subtitle: string;
|
| 49 |
+
configSchema: PluginOptionSchema;
|
| 50 |
+
/** Pre-fill fields when reconfiguring. Sensitive fields are not prepopulated. */
|
| 51 |
+
initialValues?: PluginOptionValues;
|
| 52 |
+
onSave: (config: PluginOptionValues) => void;
|
| 53 |
+
onCancel: () => void;
|
| 54 |
+
};
|
| 55 |
+
export function PluginOptionsDialog(t0) {
|
| 56 |
+
const $ = _c(70);
|
| 57 |
+
const {
|
| 58 |
+
title,
|
| 59 |
+
subtitle,
|
| 60 |
+
configSchema,
|
| 61 |
+
initialValues,
|
| 62 |
+
onSave,
|
| 63 |
+
onCancel
|
| 64 |
+
} = t0;
|
| 65 |
+
let t1;
|
| 66 |
+
if ($[0] !== configSchema) {
|
| 67 |
+
t1 = Object.keys(configSchema);
|
| 68 |
+
$[0] = configSchema;
|
| 69 |
+
$[1] = t1;
|
| 70 |
+
} else {
|
| 71 |
+
t1 = $[1];
|
| 72 |
+
}
|
| 73 |
+
const fields = t1;
|
| 74 |
+
let t2;
|
| 75 |
+
if ($[2] !== configSchema || $[3] !== initialValues) {
|
| 76 |
+
t2 = key => {
|
| 77 |
+
if (configSchema[key]?.sensitive === true) {
|
| 78 |
+
return "";
|
| 79 |
+
}
|
| 80 |
+
const v = initialValues?.[key];
|
| 81 |
+
return v === undefined ? "" : String(v);
|
| 82 |
+
};
|
| 83 |
+
$[2] = configSchema;
|
| 84 |
+
$[3] = initialValues;
|
| 85 |
+
$[4] = t2;
|
| 86 |
+
} else {
|
| 87 |
+
t2 = $[4];
|
| 88 |
+
}
|
| 89 |
+
const initialFor = t2;
|
| 90 |
+
const [currentFieldIndex, setCurrentFieldIndex] = useState(0);
|
| 91 |
+
let t3;
|
| 92 |
+
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
|
| 93 |
+
t3 = {};
|
| 94 |
+
$[5] = t3;
|
| 95 |
+
} else {
|
| 96 |
+
t3 = $[5];
|
| 97 |
+
}
|
| 98 |
+
const [values, setValues] = useState(t3);
|
| 99 |
+
let t4;
|
| 100 |
+
if ($[6] !== fields[0] || $[7] !== initialFor) {
|
| 101 |
+
t4 = () => fields[0] ? initialFor(fields[0]) : "";
|
| 102 |
+
$[6] = fields[0];
|
| 103 |
+
$[7] = initialFor;
|
| 104 |
+
$[8] = t4;
|
| 105 |
+
} else {
|
| 106 |
+
t4 = $[8];
|
| 107 |
+
}
|
| 108 |
+
const [currentInput, setCurrentInput] = useState(t4);
|
| 109 |
+
const currentField = fields[currentFieldIndex];
|
| 110 |
+
const fieldSchema = currentField ? configSchema[currentField] : null;
|
| 111 |
+
let t5;
|
| 112 |
+
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
|
| 113 |
+
t5 = {
|
| 114 |
+
context: "Settings"
|
| 115 |
+
};
|
| 116 |
+
$[9] = t5;
|
| 117 |
+
} else {
|
| 118 |
+
t5 = $[9];
|
| 119 |
+
}
|
| 120 |
+
useKeybinding("confirm:no", onCancel, t5);
|
| 121 |
+
let t6;
|
| 122 |
+
if ($[10] !== currentField || $[11] !== currentFieldIndex || $[12] !== currentInput || $[13] !== fields || $[14] !== initialFor) {
|
| 123 |
+
t6 = () => {
|
| 124 |
+
if (currentFieldIndex < fields.length - 1 && currentField) {
|
| 125 |
+
setValues(prev => ({
|
| 126 |
+
...prev,
|
| 127 |
+
[currentField]: currentInput
|
| 128 |
+
}));
|
| 129 |
+
setCurrentFieldIndex(_temp);
|
| 130 |
+
const nextKey = fields[currentFieldIndex + 1];
|
| 131 |
+
setCurrentInput(nextKey ? initialFor(nextKey) : "");
|
| 132 |
+
}
|
| 133 |
+
};
|
| 134 |
+
$[10] = currentField;
|
| 135 |
+
$[11] = currentFieldIndex;
|
| 136 |
+
$[12] = currentInput;
|
| 137 |
+
$[13] = fields;
|
| 138 |
+
$[14] = initialFor;
|
| 139 |
+
$[15] = t6;
|
| 140 |
+
} else {
|
| 141 |
+
t6 = $[15];
|
| 142 |
+
}
|
| 143 |
+
const handleNextField = t6;
|
| 144 |
+
let t7;
|
| 145 |
+
if ($[16] !== configSchema || $[17] !== currentField || $[18] !== currentFieldIndex || $[19] !== currentInput || $[20] !== fields || $[21] !== initialFor || $[22] !== initialValues || $[23] !== onSave || $[24] !== values) {
|
| 146 |
+
t7 = () => {
|
| 147 |
+
if (!currentField) {
|
| 148 |
+
return;
|
| 149 |
+
}
|
| 150 |
+
const newValues = {
|
| 151 |
+
...values,
|
| 152 |
+
[currentField]: currentInput
|
| 153 |
+
};
|
| 154 |
+
if (currentFieldIndex === fields.length - 1) {
|
| 155 |
+
onSave(buildFinalValues(fields, newValues, configSchema, initialValues));
|
| 156 |
+
} else {
|
| 157 |
+
setValues(newValues);
|
| 158 |
+
setCurrentFieldIndex(_temp2);
|
| 159 |
+
const nextKey_0 = fields[currentFieldIndex + 1];
|
| 160 |
+
setCurrentInput(nextKey_0 ? initialFor(nextKey_0) : "");
|
| 161 |
+
}
|
| 162 |
+
};
|
| 163 |
+
$[16] = configSchema;
|
| 164 |
+
$[17] = currentField;
|
| 165 |
+
$[18] = currentFieldIndex;
|
| 166 |
+
$[19] = currentInput;
|
| 167 |
+
$[20] = fields;
|
| 168 |
+
$[21] = initialFor;
|
| 169 |
+
$[22] = initialValues;
|
| 170 |
+
$[23] = onSave;
|
| 171 |
+
$[24] = values;
|
| 172 |
+
$[25] = t7;
|
| 173 |
+
} else {
|
| 174 |
+
t7 = $[25];
|
| 175 |
+
}
|
| 176 |
+
const handleConfirm = t7;
|
| 177 |
+
let t8;
|
| 178 |
+
if ($[26] !== handleConfirm || $[27] !== handleNextField) {
|
| 179 |
+
t8 = {
|
| 180 |
+
"confirm:nextField": handleNextField,
|
| 181 |
+
"confirm:yes": handleConfirm
|
| 182 |
+
};
|
| 183 |
+
$[26] = handleConfirm;
|
| 184 |
+
$[27] = handleNextField;
|
| 185 |
+
$[28] = t8;
|
| 186 |
+
} else {
|
| 187 |
+
t8 = $[28];
|
| 188 |
+
}
|
| 189 |
+
let t9;
|
| 190 |
+
if ($[29] === Symbol.for("react.memo_cache_sentinel")) {
|
| 191 |
+
t9 = {
|
| 192 |
+
context: "Confirmation"
|
| 193 |
+
};
|
| 194 |
+
$[29] = t9;
|
| 195 |
+
} else {
|
| 196 |
+
t9 = $[29];
|
| 197 |
+
}
|
| 198 |
+
useKeybindings(t8, t9);
|
| 199 |
+
let t10;
|
| 200 |
+
if ($[30] === Symbol.for("react.memo_cache_sentinel")) {
|
| 201 |
+
t10 = (char, key_0) => {
|
| 202 |
+
if (key_0.backspace || key_0.delete) {
|
| 203 |
+
setCurrentInput(_temp3);
|
| 204 |
+
return;
|
| 205 |
+
}
|
| 206 |
+
if (char && !key_0.ctrl && !key_0.meta && !key_0.tab && !key_0.return) {
|
| 207 |
+
setCurrentInput(prev_3 => prev_3 + char);
|
| 208 |
+
}
|
| 209 |
+
};
|
| 210 |
+
$[30] = t10;
|
| 211 |
+
} else {
|
| 212 |
+
t10 = $[30];
|
| 213 |
+
}
|
| 214 |
+
useInput(t10);
|
| 215 |
+
if (!fieldSchema || !currentField) {
|
| 216 |
+
return null;
|
| 217 |
+
}
|
| 218 |
+
const isSensitive = fieldSchema.sensitive === true;
|
| 219 |
+
const isRequired = fieldSchema.required === true;
|
| 220 |
+
let t11;
|
| 221 |
+
if ($[31] !== currentInput || $[32] !== isSensitive) {
|
| 222 |
+
t11 = isSensitive ? "*".repeat(stringWidth(currentInput)) : currentInput;
|
| 223 |
+
$[31] = currentInput;
|
| 224 |
+
$[32] = isSensitive;
|
| 225 |
+
$[33] = t11;
|
| 226 |
+
} else {
|
| 227 |
+
t11 = $[33];
|
| 228 |
+
}
|
| 229 |
+
const displayValue = t11;
|
| 230 |
+
const t12 = fieldSchema.title || currentField;
|
| 231 |
+
let t13;
|
| 232 |
+
if ($[34] !== isRequired) {
|
| 233 |
+
t13 = isRequired && <Text color="error"> *</Text>;
|
| 234 |
+
$[34] = isRequired;
|
| 235 |
+
$[35] = t13;
|
| 236 |
+
} else {
|
| 237 |
+
t13 = $[35];
|
| 238 |
+
}
|
| 239 |
+
let t14;
|
| 240 |
+
if ($[36] !== t12 || $[37] !== t13) {
|
| 241 |
+
t14 = <Text bold={true}>{t12}{t13}</Text>;
|
| 242 |
+
$[36] = t12;
|
| 243 |
+
$[37] = t13;
|
| 244 |
+
$[38] = t14;
|
| 245 |
+
} else {
|
| 246 |
+
t14 = $[38];
|
| 247 |
+
}
|
| 248 |
+
let t15;
|
| 249 |
+
if ($[39] !== fieldSchema.description) {
|
| 250 |
+
t15 = fieldSchema.description && <Text dimColor={true}>{fieldSchema.description}</Text>;
|
| 251 |
+
$[39] = fieldSchema.description;
|
| 252 |
+
$[40] = t15;
|
| 253 |
+
} else {
|
| 254 |
+
t15 = $[40];
|
| 255 |
+
}
|
| 256 |
+
let t16;
|
| 257 |
+
if ($[41] === Symbol.for("react.memo_cache_sentinel")) {
|
| 258 |
+
t16 = <Text>{figures.pointerSmall} </Text>;
|
| 259 |
+
$[41] = t16;
|
| 260 |
+
} else {
|
| 261 |
+
t16 = $[41];
|
| 262 |
+
}
|
| 263 |
+
let t17;
|
| 264 |
+
if ($[42] !== displayValue) {
|
| 265 |
+
t17 = <Text>{displayValue}</Text>;
|
| 266 |
+
$[42] = displayValue;
|
| 267 |
+
$[43] = t17;
|
| 268 |
+
} else {
|
| 269 |
+
t17 = $[43];
|
| 270 |
+
}
|
| 271 |
+
let t18;
|
| 272 |
+
if ($[44] === Symbol.for("react.memo_cache_sentinel")) {
|
| 273 |
+
t18 = <Text>█</Text>;
|
| 274 |
+
$[44] = t18;
|
| 275 |
+
} else {
|
| 276 |
+
t18 = $[44];
|
| 277 |
+
}
|
| 278 |
+
let t19;
|
| 279 |
+
if ($[45] !== t17) {
|
| 280 |
+
t19 = <Box marginTop={1}>{t16}{t17}{t18}</Box>;
|
| 281 |
+
$[45] = t17;
|
| 282 |
+
$[46] = t19;
|
| 283 |
+
} else {
|
| 284 |
+
t19 = $[46];
|
| 285 |
+
}
|
| 286 |
+
let t20;
|
| 287 |
+
if ($[47] !== t14 || $[48] !== t15 || $[49] !== t19) {
|
| 288 |
+
t20 = <Box flexDirection="column">{t14}{t15}{t19}</Box>;
|
| 289 |
+
$[47] = t14;
|
| 290 |
+
$[48] = t15;
|
| 291 |
+
$[49] = t19;
|
| 292 |
+
$[50] = t20;
|
| 293 |
+
} else {
|
| 294 |
+
t20 = $[50];
|
| 295 |
+
}
|
| 296 |
+
const t21 = currentFieldIndex + 1;
|
| 297 |
+
let t22;
|
| 298 |
+
if ($[51] !== fields.length || $[52] !== t21) {
|
| 299 |
+
t22 = <Text dimColor={true}>Field {t21} of {fields.length}</Text>;
|
| 300 |
+
$[51] = fields.length;
|
| 301 |
+
$[52] = t21;
|
| 302 |
+
$[53] = t22;
|
| 303 |
+
} else {
|
| 304 |
+
t22 = $[53];
|
| 305 |
+
}
|
| 306 |
+
let t23;
|
| 307 |
+
if ($[54] !== currentFieldIndex || $[55] !== fields.length) {
|
| 308 |
+
t23 = currentFieldIndex < fields.length - 1 && <Text dimColor={true}>Tab: Next field · Enter: Save and continue</Text>;
|
| 309 |
+
$[54] = currentFieldIndex;
|
| 310 |
+
$[55] = fields.length;
|
| 311 |
+
$[56] = t23;
|
| 312 |
+
} else {
|
| 313 |
+
t23 = $[56];
|
| 314 |
+
}
|
| 315 |
+
let t24;
|
| 316 |
+
if ($[57] !== currentFieldIndex || $[58] !== fields.length) {
|
| 317 |
+
t24 = currentFieldIndex === fields.length - 1 && <Text dimColor={true}>Enter: Save configuration</Text>;
|
| 318 |
+
$[57] = currentFieldIndex;
|
| 319 |
+
$[58] = fields.length;
|
| 320 |
+
$[59] = t24;
|
| 321 |
+
} else {
|
| 322 |
+
t24 = $[59];
|
| 323 |
+
}
|
| 324 |
+
let t25;
|
| 325 |
+
if ($[60] !== t22 || $[61] !== t23 || $[62] !== t24) {
|
| 326 |
+
t25 = <Box flexDirection="column">{t22}{t23}{t24}</Box>;
|
| 327 |
+
$[60] = t22;
|
| 328 |
+
$[61] = t23;
|
| 329 |
+
$[62] = t24;
|
| 330 |
+
$[63] = t25;
|
| 331 |
+
} else {
|
| 332 |
+
t25 = $[63];
|
| 333 |
+
}
|
| 334 |
+
let t26;
|
| 335 |
+
if ($[64] !== onCancel || $[65] !== subtitle || $[66] !== t20 || $[67] !== t25 || $[68] !== title) {
|
| 336 |
+
t26 = <Dialog title={title} subtitle={subtitle} onCancel={onCancel} isCancelActive={false}>{t20}{t25}</Dialog>;
|
| 337 |
+
$[64] = onCancel;
|
| 338 |
+
$[65] = subtitle;
|
| 339 |
+
$[66] = t20;
|
| 340 |
+
$[67] = t25;
|
| 341 |
+
$[68] = title;
|
| 342 |
+
$[69] = t26;
|
| 343 |
+
} else {
|
| 344 |
+
t26 = $[69];
|
| 345 |
+
}
|
| 346 |
+
return t26;
|
| 347 |
+
}
|
| 348 |
+
function _temp3(prev_2) {
|
| 349 |
+
return prev_2.slice(0, -1);
|
| 350 |
+
}
|
| 351 |
+
function _temp2(prev_1) {
|
| 352 |
+
return prev_1 + 1;
|
| 353 |
+
}
|
| 354 |
+
function _temp(prev_0) {
|
| 355 |
+
return prev_0 + 1;
|
| 356 |
+
}
|
| 357 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmaWd1cmVzIiwiUmVhY3QiLCJ1c2VDYWxsYmFjayIsInVzZVN0YXRlIiwiRGlhbG9nIiwic3RyaW5nV2lkdGgiLCJCb3giLCJUZXh0IiwidXNlSW5wdXQiLCJ1c2VLZXliaW5kaW5nIiwidXNlS2V5YmluZGluZ3MiLCJpc0VudlRydXRoeSIsIlBsdWdpbk9wdGlvblNjaGVtYSIsIlBsdWdpbk9wdGlvblZhbHVlcyIsImJ1aWxkRmluYWxWYWx1ZXMiLCJmaWVsZHMiLCJjb2xsZWN0ZWQiLCJSZWNvcmQiLCJjb25maWdTY2hlbWEiLCJpbml0aWFsVmFsdWVzIiwiZmluYWxWYWx1ZXMiLCJmaWVsZEtleSIsInNjaGVtYSIsInZhbHVlIiwic2Vuc2l0aXZlIiwidW5kZWZpbmVkIiwidHlwZSIsInRyaW0iLCJudW0iLCJOdW1iZXIiLCJpc05hTiIsIlByb3BzIiwidGl0bGUiLCJzdWJ0aXRsZSIsIm9uU2F2ZSIsImNvbmZpZyIsIm9uQ2FuY2VsIiwiUGx1Z2luT3B0aW9uc0RpYWxvZyIsInQwIiwiJCIsIl9jIiwidDEiLCJPYmplY3QiLCJrZXlzIiwidDIiLCJrZXkiLCJ2IiwiU3RyaW5nIiwiaW5pdGlhbEZvciIsImN1cnJlbnRGaWVsZEluZGV4Iiwic2V0Q3VycmVudEZpZWxkSW5kZXgiLCJ0MyIsIlN5bWJvbCIsImZvciIsInZhbHVlcyIsInNldFZhbHVlcyIsInQ0IiwiY3VycmVudElucHV0Iiwic2V0Q3VycmVudElucHV0IiwiY3VycmVudEZpZWxkIiwiZmllbGRTY2hlbWEiLCJ0NSIsImNvbnRleHQiLCJ0NiIsImxlbmd0aCIsInByZXYiLCJfdGVtcCIsIm5leHRLZXkiLCJoYW5kbGVOZXh0RmllbGQiLCJ0NyIsIm5ld1ZhbHVlcyIsIl90ZW1wMiIsIm5leHRLZXlfMCIsImhhbmRsZUNvbmZpcm0iLCJ0OCIsInQ5IiwidDEwIiwiY2hhciIsImtleV8wIiwiYmFja3NwYWNlIiwiZGVsZXRlIiwiX3RlbXAzIiwiY3RybCIsIm1ldGEiLCJ0YWIiLCJyZXR1cm4iLCJwcmV2XzMiLCJpc1NlbnNpdGl2ZSIsImlzUmVxdWlyZWQiLCJyZXF1aXJlZCIsInQxMSIsInJlcGVhdCIsImRpc3BsYXlWYWx1ZSIsInQxMiIsInQxMyIsInQxNCIsInQxNSIsImRlc2NyaXB0aW9uIiwidDE2IiwicG9pbnRlclNtYWxsIiwidDE3IiwidDE4IiwidDE5IiwidDIwIiwidDIxIiwidDIyIiwidDIzIiwidDI0IiwidDI1IiwidDI2IiwicHJldl8yIiwic2xpY2UiLCJwcmV2XzEiLCJwcmV2XzAiXSwic291cmNlcyI6WyJQbHVnaW5PcHRpb25zRGlhbG9nLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZmlndXJlcyBmcm9tICdmaWd1cmVzJ1xuaW1wb3J0IFJlYWN0LCB7IHVzZUNhbGxiYWNrLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgRGlhbG9nIH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9kZXNpZ24tc3lzdGVtL0RpYWxvZy5qcydcbmltcG9ydCB7IHN0cmluZ1dpZHRoIH0gZnJvbSAnLi4vLi4vaW5rL3N0cmluZ1dpZHRoLmpzJ1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGN1c3RvbS1ydWxlcy9wcmVmZXItdXNlLWtleWJpbmRpbmdzIC0tIHJhdyB0ZXh0IGlucHV0IGZvciBjb25maWcgZGlhbG9nXG5pbXBvcnQgeyBCb3gsIFRleHQsIHVzZUlucHV0IH0gZnJvbSAnLi4vLi4vaW5rLmpzJ1xuaW1wb3J0IHtcbiAgdXNlS2V5YmluZGluZyxcbiAgdXNlS2V5YmluZGluZ3MsXG59IGZyb20gJy4uLy4uL2tleWJpbmRpbmdzL3VzZUtleWJpbmRpbmcuanMnXG5pbXBvcnQgeyBpc0VudlRydXRoeSB9IGZyb20gJy4uLy4uL3V0aWxzL2VudlV0aWxzLmpzJ1xuaW1wb3J0IHR5cGUge1xuICBQbHVnaW5PcHRpb25TY2hlbWEsXG4gIFBsdWdpbk9wdGlvblZhbHVlcyxcbn0gZnJvbSAnLi4vLi4vdXRpbHMvcGx1Z2lucy9wbHVnaW5PcHRpb25zU3RvcmFnZS5qcydcblxuLyoqXG4gKiBCdWlsZCB0aGUgb25TYXZlIHBheWxvYWQgZnJvbSBjb2xsZWN0ZWQgc3RyaW5nIGlucHV0cy5cbiAqXG4gKiBTZW5zaXRpdmUgZmllbGRzIGFyZSBuZXZlciBwcmVwb3B1bGF0ZWQgaW4gdGhlIHRleHQgYnVmZmVyIChzZWN1cml0eSksIHNvXG4gKiBieSB0aGUgdGltZSB0aGUgdXNlciByZWFjaGVzIHRoZSBsYXN0IGZpZWxkIGV2ZXJ5IHNlbnNpdGl2ZSBmaWVsZCB0aGV5XG4gKiBzdGVwcGVkIHRocm91Z2ggY29udGFpbnMgJycgaW4gY29sbGVjdGVkLiBUbyBhdm9pZCBzaWxlbnRseSB3aXBpbmcgc2F2ZWRcbiAqIHNlY3JldHMgb24gcmVjb25maWd1cmU6IGlmIGEgc2Vuc2l0aXZlIGZpZWxkIGlzICcnIEFORCBpbml0aWFsVmFsdWVzIGhhc1xuICogYSB2YWx1ZSBmb3IgaXQsIE9NSVQgdGhlIGtleSBlbnRpcmVseS4gc2F2ZVBsdWdpbk9wdGlvbnMgb25seSB3cml0ZXMga2V5c1xuICogaXQgcmVjZWl2ZXMsIHNvIG9taXR0aW5nID0ga2VlcCBleGlzdGluZy5cbiAqXG4gKiBFeHBvcnRlZCBmb3IgdW5pdCB0ZXN0aW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRGaW5hbFZhbHVlcyhcbiAgZmllbGRzOiBzdHJpbmdbXSxcbiAgY29sbGVjdGVkOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuICBjb25maWdTY2hlbWE6IFBsdWdpbk9wdGlvblNjaGVtYSxcbiAgaW5pdGlhbFZhbHVlczogUGx1Z2luT3B0aW9uVmFsdWVzIHwgdW5kZWZpbmVkLFxuKTogUGx1Z2luT3B0aW9uVmFsdWVzIHtcbiAgY29uc3QgZmluYWxWYWx1ZXM6IFBsdWdpbk9wdGlvblZhbHVlcyA9IHt9XG4gIGZvciAoY29uc3QgZmllbGRLZXkgb2YgZmllbGRzKSB7XG4gICAgY29uc3Qgc2NoZW1hID0gY29uZmlnU2NoZW1hW2ZpZWxkS2V5XVxuICAgIGNvbnN0IHZhbHVlID0gY29sbGVjdGVkW2ZpZWxkS2V5XSA/PyAnJ1xuXG4gICAgaWYgKFxuICAgICAgc2NoZW1hPy5zZW5zaXRpdmUgPT09IHRydWUgJiZcbiAgICAgIHZhbHVlID09PSAnJyAmJlxuICAgICAgaW5pdGlhbFZhbHVlcz8uW2ZpZWxkS2V5XSAhPT0gdW5kZWZpbmVkXG4gICAgKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmIChzY2hlbWE/LnR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAvLyBOdW1iZXIoJycpIHJldHVybnMgMCwgbm90IE5hTiDigJQgb21pdCBibGFuayBudW1iZXIgaW5wdXRzIHNvXG4gICAgICAvLyB2YWxpZGF0ZVVzZXJDb25maWcncyByZXF1aXJlZCBjaGVjayBhY3R1YWxseSBjYXRjaGVzIHRoZW0uXG4gICAgICBpZiAodmFsdWUudHJpbSgpID09PSAnJykgY29udGludWVcbiAgICAgIGNvbnN0IG51bSA9IE51bWJlcih2YWx1ZSlcbiAgICAgIGZpbmFsVmFsdWVzW2ZpZWxkS2V5XSA9IE51bWJlci5pc05hTihudW0pID8gdmFsdWUgOiBudW1cbiAgICB9IGVsc2UgaWYgKHNjaGVtYT8udHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBmaW5hbFZhbHVlc1tmaWVsZEtleV0gPSBpc0VudlRydXRoeSh2YWx1ZSlcbiAgICB9IGVsc2Uge1xuICAgICAgZmluYWxWYWx1ZXNbZmllbGRLZXldID0gdmFsdWVcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZpbmFsVmFsdWVzXG59XG5cbnR5cGUgUHJvcHMgPSB7XG4gIHRpdGxlOiBzdHJpbmdcbiAgc3VidGl0bGU6IHN0cmluZ1xuICBjb25maWdTY2hlbWE6IFBsdWdpbk9wdGlvblNjaGVtYVxuICAvKiogUHJlLWZpbGwgZmllbGRzIHdoZW4gcmVjb25maWd1cmluZy4gU2Vuc2l0aXZlIGZpZWxkcyBhcmUgbm90IHByZXBvcHVsYXRlZC4gKi9cbiAgaW5pdGlhbFZhbHVlcz86IFBsdWdpbk9wdGlvblZhbHVlc1xuICBvblNhdmU6IChjb25maWc6IFBsdWdpbk9wdGlvblZhbHVlcykgPT4gdm9pZFxuICBvbkNhbmNlbDogKCkgPT4gdm9pZFxufVxuXG5leHBvcnQgZnVuY3Rpb24gUGx1Z2luT3B0aW9uc0RpYWxvZyh7XG4gIHRpdGxlLFxuICBzdWJ0aXRsZSxcbiAgY29uZmlnU2NoZW1hLFxuICBpbml0aWFsVmFsdWVzLFxuICBvblNhdmUsXG4gIG9uQ2FuY2VsLFxufTogUHJvcHMpOiBSZWFjdC5SZWFjdE5vZGUge1xuICBjb25zdCBmaWVsZHMgPSBPYmplY3Qua2V5cyhjb25maWdTY2hlbWEpXG5cbiAgLy8gUHJlcG9wdWxhdGUgZnJvbSBpbml0aWFsVmFsdWVzIGJ1dCBza2lwIHNlbnNpdGl2ZSBmaWVsZHMg4oCUIHdlIGRvbid0XG4gIC8vIHdhbnQgdG8gZWNobyBzZWNyZXRzIGJhY2sgaW50byB0aGUgdGV4dCBidWZmZXIuXG4gIGNvbnN0IGluaXRpYWxGb3IgPSB1c2VDYWxsYmFjayhcbiAgICAoa2V5OiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgICAgaWYgKGNvbmZpZ1NjaGVtYVtrZXldPy5zZW5zaXRpdmUgPT09IHRydWUpIHJldHVybiAnJ1xuICAgICAgY29uc3QgdiA9IGluaXRpYWxWYWx1ZXM/LltrZXldXG4gICAgICByZXR1cm4gdiA9PT0gdW5kZWZpbmVkID8gJycgOiBTdHJpbmcodilcbiAgICB9LFxuICAgIFtjb25maWdTY2hlbWEsIGluaXRpYWxWYWx1ZXNdLFxuICApXG5cbiAgY29uc3QgW2N1cnJlbnRGaWVsZEluZGV4LCBzZXRDdXJyZW50RmllbGRJbmRleF0gPSB1c2VTdGF0ZSgwKVxuICBjb25zdCBbdmFsdWVzLCBzZXRWYWx1ZXNdID0gdXNlU3RhdGU8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4oe30pXG4gIGNvbnN0IFtjdXJyZW50SW5wdXQsIHNldEN1cnJlbnRJbnB1dF0gPSB1c2VTdGF0ZSgoKSA9PlxuICAgIGZpZWxkc1swXSA/IGluaXRpYWxGb3IoZmllbGRzWzBdKSA6ICcnLFxuICApXG5cbiAgY29uc3QgY3VycmVudEZpZWxkID0gZmllbGRzW2N1cnJlbnRGaWVsZEluZGV4XVxuICBjb25zdCBmaWVsZFNjaGVtYSA9IGN1cnJlbnRGaWVsZCA/IGNvbmZpZ1NjaGVtYVtjdXJyZW50RmllbGRdIDogbnVsbFxuXG4gIC8vIFVzZSBTZXR0aW5ncyBjb250ZXh0IHNvICduJyBrZXkgZG9lc24ndCBjYW5jZWwgKGFsbG93cyB0eXBpbmcgJ24nIGluIGlucHV0KS5cbiAgLy8gaXNDYW5jZWxBY3RpdmU9e2ZhbHNlfSBvbiBEaWFsb2cga2VlcHMgaXRzIG93biBjb25maXJtOm5vIG91dCBvZiB0aGUgd2F5LlxuICB1c2VLZXliaW5kaW5nKCdjb25maXJtOm5vJywgb25DYW5jZWwsIHsgY29udGV4dDogJ1NldHRpbmdzJyB9KVxuXG4gIC8vIFRhYiB0byBuZXh0IGZpZWxkXG4gIGNvbnN0IGhhbmRsZU5leHRGaWVsZCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBpZiAoY3VycmVudEZpZWxkSW5kZXggPCBmaWVsZHMubGVuZ3RoIC0gMSAmJiBjdXJyZW50RmllbGQpIHtcbiAgICAgIHNldFZhbHVlcyhwcmV2ID0+ICh7IC4uLnByZXYsIFtjdXJyZW50RmllbGRdOiBjdXJyZW50SW5wdXQgfSkpXG4gICAgICBzZXRDdXJyZW50RmllbGRJbmRleChwcmV2ID0+IHByZXYgKyAxKVxuICAgICAgY29uc3QgbmV4dEtleSA9IGZpZWxkc1tjdXJyZW50RmllbGRJbmRleCArIDFdXG4gICAgICBzZXRDdXJyZW50SW5wdXQobmV4dEtleSA/IGluaXRpYWxGb3IobmV4dEtleSkgOiAnJylcbiAgICB9XG4gIH0sIFtjdXJyZW50RmllbGRJbmRleCwgZmllbGRzLCBjdXJyZW50RmllbGQsIGN1cnJlbnRJbnB1dCwgaW5pdGlhbEZvcl0pXG5cbiAgLy8gRW50ZXIgdG8gc2F2ZSBjdXJyZW50IGZpZWxkIGFuZCBtb3ZlIHRvIG5leHQsIG9yIHNhdmUgYWxsIGlmIGxhc3RcbiAgY29uc3QgaGFuZGxlQ29uZmlybSA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBpZiAoIWN1cnJlbnRGaWVsZCkgcmV0dXJuXG5cbiAgICBjb25zdCBuZXdWYWx1ZXMgPSB7IC4uLnZhbHVlcywgW2N1cnJlbnRGaWVsZF06IGN1cnJlbnRJbnB1dCB9XG5cbiAgICBpZiAoY3VycmVudEZpZWxkSW5kZXggPT09IGZpZWxkcy5sZW5ndGggLSAxKSB7XG4gICAgICBvblNhdmUoYnVpbGRGaW5hbFZhbHVlcyhmaWVsZHMsIG5ld1ZhbHVlcywgY29uZmlnU2NoZW1hLCBpbml0aWFsVmFsdWVzKSlcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTW92ZSB0byBuZXh0IGZpZWxkXG4gICAgICBzZXRWYWx1ZXMobmV3VmFsdWVzKVxuICAgICAgc2V0Q3VycmVudEZpZWxkSW5kZXgocHJldiA9PiBwcmV2ICsgMSlcbiAgICAgIGNvbnN0IG5leHRLZXkgPSBmaWVsZHNbY3VycmVudEZpZWxkSW5kZXggKyAxXVxuICAgICAgc2V0Q3VycmVudElucHV0KG5leHRLZXkgPyBpbml0aWFsRm9yKG5leHRLZXkpIDogJycpXG4gICAgfVxuICB9LCBbXG4gICAgY3VycmVudEZpZWxkLFxuICAgIHZhbHVlcyxcbiAgICBjdXJyZW50SW5wdXQsXG4gICAgY3VycmVudEZpZWxkSW5kZXgsXG4gICAgZmllbGRzLFxuICAgIGNvbmZpZ1NjaGVtYSxcbiAgICBvblNhdmUsXG4gICAgaW5pdGlhbEZvcixcbiAgICBpbml0aWFsVmFsdWVzLFxuICBdKVxuXG4gIHVzZUtleWJpbmRpbmdzKFxuICAgIHtcbiAgICAgICdjb25maXJtOm5leHRGaWVsZCc6IGhhbmRsZU5leHRGaWVsZCxcbiAgICAgICdjb25maXJtOnllcyc6IGhhbmRsZUNvbmZpcm0sXG4gICAgfSxcbiAgICB7IGNvbnRleHQ6ICdDb25maXJtYXRpb24nIH0sXG4gIClcblxuICAvLyBDaGFyYWN0ZXIgaW5wdXQgaGFuZGxpbmcgKGJhY2tzcGFjZSwgdHlwaW5nKVxuICB1c2VJbnB1dCgoY2hhciwga2V5KSA9PiB7XG4gICAgLy8gQmFja3NwYWNlXG4gICAgaWYgKGtleS5iYWNrc3BhY2UgfHwga2V5LmRlbGV0ZSkge1xuICAgICAgc2V0Q3VycmVudElucHV0KHByZXYgPT4gcHJldi5zbGljZSgwLCAtMSkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBSZWd1bGFyIGNoYXJhY3RlciBpbnB1dFxuICAgIGlmIChjaGFyICYmICFrZXkuY3RybCAmJiAha2V5Lm1ldGEgJiYgIWtleS50YWIgJiYgIWtleS5yZXR1cm4pIHtcbiAgICAgIHNldEN1cnJlbnRJbnB1dChwcmV2ID0+IHByZXYgKyBjaGFyKVxuICAgIH1cbiAgfSlcblxuICBpZiAoIWZpZWxkU2NoZW1hIHx8ICFjdXJyZW50RmllbGQpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgY29uc3QgaXNTZW5zaXRpdmUgPSBmaWVsZFNjaGVtYS5zZW5zaXRpdmUgPT09IHRydWVcbiAgY29uc3QgaXNSZXF1aXJlZCA9IGZpZWxkU2NoZW1hLnJlcXVpcmVkID09PSB0cnVlXG4gIGNvbnN0IGRpc3BsYXlWYWx1ZSA9IGlzU2Vuc2l0aXZlXG4gICAgPyAnKicucmVwZWF0KHN0cmluZ1dpZHRoKGN1cnJlbnRJbnB1dCkpXG4gICAgOiBjdXJyZW50SW5wdXRcblxuICByZXR1cm4gKFxuICAgIDxEaWFsb2dcbiAgICAgIHRpdGxlPXt0aXRsZX1cbiAgICAgIHN1YnRpdGxlPXtzdWJ0aXRsZX1cbiAgICAgIG9uQ2FuY2VsPXtvbkNhbmNlbH1cbiAgICAgIGlzQ2FuY2VsQWN0aXZlPXtmYWxzZX1cbiAgICA+XG4gICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIj5cbiAgICAgICAgPFRleHQgYm9sZD17dHJ1ZX0+XG4gICAgICAgICAge2ZpZWxkU2NoZW1hLnRpdGxlIHx8IGN1cnJlbnRGaWVsZH1cbiAgICAgICAgICB7aXNSZXF1aXJlZCAmJiA8VGV4dCBjb2xvcj1cImVycm9yXCI+ICo8L1RleHQ+fVxuICAgICAgICA8L1RleHQ+XG4gICAgICAgIHtmaWVsZFNjaGVtYS5kZXNjcmlwdGlvbiAmJiAoXG4gICAgICAgICAgPFRleHQgZGltQ29sb3I9e3RydWV9PntmaWVsZFNjaGVtYS5kZXNjcmlwdGlvbn08L1RleHQ+XG4gICAgICAgICl9XG5cbiAgICAgICAgPEJveCBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgIDxUZXh0PntmaWd1cmVzLnBvaW50ZXJTbWFsbH0gPC9UZXh0PlxuICAgICAgICAgIDxUZXh0PntkaXNwbGF5VmFsdWV9PC9UZXh0PlxuICAgICAgICAgIDxUZXh0PuKWiDwvVGV4dD5cbiAgICAgICAgPC9Cb3g+XG4gICAgICA8L0JveD5cblxuICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCI+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPXt0cnVlfT5cbiAgICAgICAgICBGaWVsZCB7Y3VycmVudEZpZWxkSW5kZXggKyAxfSBvZiB7ZmllbGRzLmxlbmd0aH1cbiAgICAgICAgPC9UZXh0PlxuICAgICAgICB7Y3VycmVudEZpZWxkSW5kZXggPCBmaWVsZHMubGVuZ3RoIC0gMSAmJiAoXG4gICAgICAgICAgPFRleHQgZGltQ29sb3I9e3RydWV9PlxuICAgICAgICAgICAgVGFiOiBOZXh0IGZpZWxkIMK3IEVudGVyOiBTYXZlIGFuZCBjb250aW51ZVxuICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgKX1cbiAgICAgICAge2N1cnJlbnRGaWVsZEluZGV4ID09PSBmaWVsZHMubGVuZ3RoIC0gMSAmJiAoXG4gICAgICAgICAgPFRleHQgZGltQ29sb3I9e3RydWV9PkVudGVyOiBTYXZlIGNvbmZpZ3VyYXRpb248L1RleHQ+XG4gICAgICAgICl9XG4gICAgICA8L0JveD5cbiAgICA8L0RpYWxvZz5cbiAgKVxufVxuIl0sIm1hcHBpbmdzIjoiO0FBQUEsT0FBT0EsT0FBTyxNQUFNLFNBQVM7QUFDN0IsT0FBT0MsS0FBSyxJQUFJQyxXQUFXLEVBQUVDLFFBQVEsUUFBUSxPQUFPO0FBQ3BELFNBQVNDLE1BQU0sUUFBUSww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
|
src/commands/plugin/PluginOptionsFlow.tsx
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Post-install/post-enable config prompt.
|
| 3 |
+
*
|
| 4 |
+
* Given a LoadedPlugin, checks both the top-level manifest.userConfig and the
|
| 5 |
+
* channel-specific userConfig. Walks PluginOptionsDialog through each
|
| 6 |
+
* unconfigured item, saving via the appropriate storage function. Calls
|
| 7 |
+
* onDone('skipped') immediately if nothing needs filling.
|
| 8 |
+
*/
|
| 9 |
+
|
| 10 |
+
import * as React from 'react';
|
| 11 |
+
import type { LoadedPlugin } from '../../types/plugin.js';
|
| 12 |
+
import { errorMessage } from '../../utils/errors.js';
|
| 13 |
+
import { loadMcpServerUserConfig, saveMcpServerUserConfig } from '../../utils/plugins/mcpbHandler.js';
|
| 14 |
+
import { getUnconfiguredChannels, type UnconfiguredChannel } from '../../utils/plugins/mcpPluginIntegration.js';
|
| 15 |
+
import { loadAllPlugins } from '../../utils/plugins/pluginLoader.js';
|
| 16 |
+
import { getUnconfiguredOptions, loadPluginOptions, type PluginOptionSchema, type PluginOptionValues, savePluginOptions } from '../../utils/plugins/pluginOptionsStorage.js';
|
| 17 |
+
import { PluginOptionsDialog } from './PluginOptionsDialog.js';
|
| 18 |
+
|
| 19 |
+
/**
|
| 20 |
+
* Post-install lookup: return the LoadedPlugin for the just-installed
|
| 21 |
+
* pluginId so the caller can divert to PluginOptionsFlow. Returns undefined
|
| 22 |
+
* if the plugin somehow didn't make it into the fresh load — callers treat
|
| 23 |
+
* undefined as "carry on closing."
|
| 24 |
+
*
|
| 25 |
+
* Install should have cleared caches already; loadAllPlugins reads fresh.
|
| 26 |
+
*/
|
| 27 |
+
export async function findPluginOptionsTarget(pluginId: string): Promise<LoadedPlugin | undefined> {
|
| 28 |
+
const {
|
| 29 |
+
enabled,
|
| 30 |
+
disabled
|
| 31 |
+
} = await loadAllPlugins();
|
| 32 |
+
return [...enabled, ...disabled].find(p => p.repository === pluginId || p.source === pluginId);
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
/**
|
| 36 |
+
* A single dialog step in the walk. Top-level options and channels both
|
| 37 |
+
* collapse to this shape — the only difference is which save function runs.
|
| 38 |
+
*/
|
| 39 |
+
type ConfigStep = {
|
| 40 |
+
key: string;
|
| 41 |
+
title: string;
|
| 42 |
+
subtitle: string;
|
| 43 |
+
schema: PluginOptionSchema;
|
| 44 |
+
/** Returns any already-saved values so PluginOptionsDialog can pre-fill and
|
| 45 |
+
* skip unchanged sensitive fields on reconfigure. */
|
| 46 |
+
load: () => PluginOptionValues | undefined;
|
| 47 |
+
save: (values: PluginOptionValues) => void;
|
| 48 |
+
};
|
| 49 |
+
type Props = {
|
| 50 |
+
plugin: LoadedPlugin;
|
| 51 |
+
/** `name@marketplace` — the savePluginOptions / saveMcpServerUserConfig key. */
|
| 52 |
+
pluginId: string;
|
| 53 |
+
/**
|
| 54 |
+
* `configured` = user filled all fields. `skipped` = nothing needed
|
| 55 |
+
* configuring, or user hit cancel. `error` = save threw.
|
| 56 |
+
*/
|
| 57 |
+
onDone: (outcome: 'configured' | 'skipped' | 'error', detail?: string) => void;
|
| 58 |
+
};
|
| 59 |
+
export function PluginOptionsFlow({
|
| 60 |
+
plugin,
|
| 61 |
+
pluginId,
|
| 62 |
+
onDone
|
| 63 |
+
}: Props): React.ReactNode {
|
| 64 |
+
// Build the step list once at mount. Re-calling after a save would drop the
|
| 65 |
+
// item we just configured.
|
| 66 |
+
const [steps] = React.useState<ConfigStep[]>(() => {
|
| 67 |
+
const result: ConfigStep[] = [];
|
| 68 |
+
|
| 69 |
+
// Top-level manifest.userConfig
|
| 70 |
+
const unconfigured = getUnconfiguredOptions(plugin);
|
| 71 |
+
if (Object.keys(unconfigured).length > 0) {
|
| 72 |
+
result.push({
|
| 73 |
+
key: 'top-level',
|
| 74 |
+
title: `Configure ${plugin.name}`,
|
| 75 |
+
subtitle: 'Plugin options',
|
| 76 |
+
schema: unconfigured,
|
| 77 |
+
load: () => loadPluginOptions(pluginId),
|
| 78 |
+
save: values => savePluginOptions(pluginId, values, plugin.manifest.userConfig!)
|
| 79 |
+
});
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
// Per-channel userConfig (assistant-mode channels)
|
| 83 |
+
const channels: UnconfiguredChannel[] = getUnconfiguredChannels(plugin);
|
| 84 |
+
for (const channel of channels) {
|
| 85 |
+
result.push({
|
| 86 |
+
key: `channel:${channel.server}`,
|
| 87 |
+
title: `Configure ${channel.displayName}`,
|
| 88 |
+
subtitle: `Plugin: ${plugin.name}`,
|
| 89 |
+
schema: channel.configSchema,
|
| 90 |
+
load: () => loadMcpServerUserConfig(pluginId, channel.server) ?? undefined,
|
| 91 |
+
save: values_0 => saveMcpServerUserConfig(pluginId, channel.server, values_0, channel.configSchema)
|
| 92 |
+
});
|
| 93 |
+
}
|
| 94 |
+
return result;
|
| 95 |
+
});
|
| 96 |
+
const [index, setIndex] = React.useState(0);
|
| 97 |
+
|
| 98 |
+
// Latest-ref: lets the effect close over the current onDone without
|
| 99 |
+
// re-running when the parent re-renders.
|
| 100 |
+
const onDoneRef = React.useRef(onDone);
|
| 101 |
+
onDoneRef.current = onDone;
|
| 102 |
+
|
| 103 |
+
// Nothing to configure → tell the caller and render nothing. Effect,
|
| 104 |
+
// not inline call: calling setState in the parent during our render
|
| 105 |
+
// is a React rules-of-hooks violation.
|
| 106 |
+
React.useEffect(() => {
|
| 107 |
+
if (steps.length === 0) {
|
| 108 |
+
onDoneRef.current('skipped');
|
| 109 |
+
}
|
| 110 |
+
}, [steps.length]);
|
| 111 |
+
if (steps.length === 0) {
|
| 112 |
+
return null;
|
| 113 |
+
}
|
| 114 |
+
const current = steps[index]!;
|
| 115 |
+
function handleSave(values_1: PluginOptionValues): void {
|
| 116 |
+
try {
|
| 117 |
+
current.save(values_1);
|
| 118 |
+
} catch (err) {
|
| 119 |
+
onDone('error', errorMessage(err));
|
| 120 |
+
return;
|
| 121 |
+
}
|
| 122 |
+
const next = index + 1;
|
| 123 |
+
if (next < steps.length) {
|
| 124 |
+
setIndex(next);
|
| 125 |
+
} else {
|
| 126 |
+
onDone('configured');
|
| 127 |
+
}
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
// key forces a remount when advancing to the next step — React would
|
| 131 |
+
// otherwise reuse the instance and carry PluginOptionsDialog's
|
| 132 |
+
// internal useState (field index, typed values) over.
|
| 133 |
+
return <PluginOptionsDialog key={current.key} title={current.title} subtitle={current.subtitle} configSchema={current.schema} initialValues={current.load()} onSave={handleSave} onCancel={() => onDone('skipped')} />;
|
| 134 |
+
}
|
| 135 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsIkxvYWRlZFBsdWdpbiIsImVycm9yTWVzc2FnZSIsImxvYWRNY3BTZXJ2ZXJVc2VyQ29uZmlnIiwic2F2ZU1jcFNlcnZlclVzZXJDb25maWciLCJnZXRVbmNvbmZpZ3VyZWRDaGFubmVscyIsIlVuY29uZmlndXJlZENoYW5uZWwiLCJsb2FkQWxsUGx1Z2lucyIsImdldFVuY29uZmlndXJlZE9wdGlvbnMiLCJsb2FkUGx1Z2luT3B0aW9ucyIsIlBsdWdpbk9wdGlvblNjaGVtYSIsIlBsdWdpbk9wdGlvblZhbHVlcyIsInNhdmVQbHVnaW5PcHRpb25zIiwiUGx1Z2luT3B0aW9uc0RpYWxvZyIsImZpbmRQbHVnaW5PcHRpb25zVGFyZ2V0IiwicGx1Z2luSWQiLCJQcm9taXNlIiwiZW5hYmxlZCIsImRpc2FibGVkIiwiZmluZCIsInAiLCJyZXBvc2l0b3J5Iiwic291cmNlIiwiQ29uZmlnU3RlcCIsImtleSIsInRpdGxlIiwic3VidGl0bGUiLCJzY2hlbWEiLCJsb2FkIiwic2F2ZSIsInZhbHVlcyIsIlByb3BzIiwicGx1Z2luIiwib25Eb25lIiwib3V0Y29tZSIsImRldGFpbCIsIlBsdWdpbk9wdGlvbnNGbG93IiwiUmVhY3ROb2RlIiwic3RlcHMiLCJ1c2VTdGF0ZSIsInJlc3VsdCIsInVuY29uZmlndXJlZCIsIk9iamVjdCIsImtleXMiLCJsZW5ndGgiLCJwdXNoIiwibmFtZSIsIm1hbmlmZXN0IiwidXNlckNvbmZpZyIsImNoYW5uZWxzIiwiY2hhbm5lbCIsInNlcnZlciIsImRpc3BsYXlOYW1lIiwiY29uZmlnU2NoZW1hIiwidW5kZWZpbmVkIiwiaW5kZXgiLCJzZXRJbmRleCIsIm9uRG9uZVJlZiIsInVzZVJlZiIsImN1cnJlbnQiLCJ1c2VFZmZlY3QiLCJoYW5kbGVTYXZlIiwiZXJyIiwibmV4dCJdLCJzb3VyY2VzIjpbIlBsdWdpbk9wdGlvbnNGbG93LnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBvc3QtaW5zdGFsbC9wb3N0LWVuYWJsZSBjb25maWcgcHJvbXB0LlxuICpcbiAqIEdpdmVuIGEgTG9hZGVkUGx1Z2luLCBjaGVja3MgYm90aCB0aGUgdG9wLWxldmVsIG1hbmlmZXN0LnVzZXJDb25maWcgYW5kIHRoZVxuICogY2hhbm5lbC1zcGVjaWZpYyB1c2VyQ29uZmlnLiBXYWxrcyBQbHVnaW5PcHRpb25zRGlhbG9nIHRocm91Z2ggZWFjaFxuICogdW5jb25maWd1cmVkIGl0ZW0sIHNhdmluZyB2aWEgdGhlIGFwcHJvcHJpYXRlIHN0b3JhZ2UgZnVuY3Rpb24uIENhbGxzXG4gKiBvbkRvbmUoJ3NraXBwZWQnKSBpbW1lZGlhdGVseSBpZiBub3RoaW5nIG5lZWRzIGZpbGxpbmcuXG4gKi9cblxuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnXG5pbXBvcnQgdHlwZSB7IExvYWRlZFBsdWdpbiB9IGZyb20gJy4uLy4uL3R5cGVzL3BsdWdpbi5qcydcbmltcG9ydCB7IGVycm9yTWVzc2FnZSB9IGZyb20gJy4uLy4uL3V0aWxzL2Vycm9ycy5qcydcbmltcG9ydCB7XG4gIGxvYWRNY3BTZXJ2ZXJVc2VyQ29uZmlnLFxuICBzYXZlTWNwU2VydmVyVXNlckNvbmZpZyxcbn0gZnJvbSAnLi4vLi4vdXRpbHMvcGx1Z2lucy9tY3BiSGFuZGxlci5qcydcbmltcG9ydCB7XG4gIGdldFVuY29uZmlndXJlZENoYW5uZWxzLFxuICB0eXBlIFVuY29uZmlndXJlZENoYW5uZWwsXG59IGZyb20gJy4uLy4uL3V0aWxzL3BsdWdpbnMvbWNwUGx1Z2luSW50ZWdyYXRpb24uanMnXG5pbXBvcnQgeyBsb2FkQWxsUGx1Z2lucyB9IGZyb20gJy4uLy4uL3V0aWxzL3BsdWdpbnMvcGx1Z2luTG9hZGVyLmpzJ1xuaW1wb3J0IHtcbiAgZ2V0VW5jb25maWd1cmVkT3B0aW9ucyxcbiAgbG9hZFBsdWdpbk9wdGlvbnMsXG4gIHR5cGUgUGx1Z2luT3B0aW9uU2NoZW1hLFxuICB0eXBlIFBsdWdpbk9wdGlvblZhbHVlcyxcbiAgc2F2ZVBsdWdpbk9wdGlvbnMsXG59IGZyb20gJy4uLy4uL3V0aWxzL3BsdWdpbnMvcGx1Z2luT3B0aW9uc1N0b3JhZ2UuanMnXG5pbXBvcnQgeyBQbHVnaW5PcHRpb25zRGlhbG9nIH0gZnJvbSAnLi9QbHVnaW5PcHRpb25zRGlhbG9nLmpzJ1xuXG4vKipcbiAqIFBvc3QtaW5zdGFsbCBsb29rdXA6IHJldHVybiB0aGUgTG9hZGVkUGx1Z2luIGZvciB0aGUganVzdC1pbnN0YWxsZWRcbiAqIHBsdWdpbklkIHNvIHRoZSBjYWxsZXIgY2FuIGRpdmVydCB0byBQbHVnaW5PcHRpb25zRmxvdy4gUmV0dXJucyB1bmRlZmluZWRcbiAqIGlmIHRoZSBwbHVnaW4gc29tZWhvdyBkaWRuJ3QgbWFrZSBpdCBpbnRvIHRoZSBmcmVzaCBsb2FkIOKAlCBjYWxsZXJzIHRyZWF0XG4gKiB1bmRlZmluZWQgYXMgXCJjYXJyeSBvbiBjbG9zaW5nLlwiXG4gKlxuICogSW5zdGFsbCBzaG91bGQgaGF2ZSBjbGVhcmVkIGNhY2hlcyBhbHJlYWR5OyBsb2FkQWxsUGx1Z2lucyByZWFkcyBmcmVzaC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpbmRQbHVnaW5PcHRpb25zVGFyZ2V0KFxuICBwbHVnaW5JZDogc3RyaW5nLFxuKTogUHJvbWlzZTxMb2FkZWRQbHVnaW4gfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgeyBlbmFibGVkLCBkaXNhYmxlZCB9ID0gYXdhaXQgbG9hZEFsbFBsdWdpbnMoKVxuICByZXR1cm4gWy4uLmVuYWJsZWQsIC4uLmRpc2FibGVkXS5maW5kKFxuICAgIHAgPT4gcC5yZXBvc2l0b3J5ID09PSBwbHVnaW5JZCB8fCBwLnNvdXJjZSA9PT0gcGx1Z2luSWQsXG4gIClcbn1cblxuLyoqXG4gKiBBIHNpbmdsZSBkaWFsb2cgc3RlcCBpbiB0aGUgd2Fsay4gVG9wLWxldmVsIG9wdGlvbnMgYW5kIGNoYW5uZWxzIGJvdGhcbiAqIGNvbGxhcHNlIHRvIHRoaXMgc2hhcGUg4oCUIHRoZSBvbmx5IGRpZmZlcmVuY2UgaXMgd2hpY2ggc2F2ZSBmdW5jdGlvbiBydW5zLlxuICovXG50eXBlIENvbmZpZ1N0ZXAgPSB7XG4gIGtleTogc3RyaW5nXG4gIHRpdGxlOiBzdHJpbmdcbiAgc3VidGl0bGU6IHN0cmluZ1xuICBzY2hlbWE6IFBsdWdpbk9wdGlvblNjaGVtYVxuICAvKiogUmV0dXJucyBhbnkgYWxyZWFkeS1zYXZlZCB2YWx1ZXMgc28gUGx1Z2luT3B0aW9uc0RpYWxvZyBjYW4gcHJlLWZpbGwgYW5kXG4gICAqICBza2lwIHVuY2hhbmdlZCBzZW5zaXRpdmUgZmllbGRzIG9uIHJlY29uZmlndXJlLiAqL1xuICBsb2FkOiAoKSA9PiBQbHVnaW5PcHRpb25WYWx1ZXMgfCB1bmRlZmluZWRcbiAgc2F2ZTogKHZhbHVlczogUGx1Z2luT3B0aW9uVmFsdWVzKSA9PiB2b2lkXG59XG5cbnR5cGUgUHJvcHMgPSB7XG4gIHBsdWdpbjogTG9hZGVkUGx1Z2luXG4gIC8qKiBgbmFtZUBtYXJrZXRwbGFjZWAg4oCUIHRoZSBzYXZlUGx1Z2luT3B0aW9ucyAvIHNhdmVNY3BTZXJ2ZXJVc2VyQ29uZmlnIGtleS4gKi9cbiAgcGx1Z2luSWQ6IHN0cmluZ1xuICAvKipcbiAgICogYGNvbmZpZ3VyZWRgID0gdXNlciBmaWxsZWQgYWxsIGZpZWxkcy4gYHNraXBwZWRgID0gbm90aGluZyBuZWVkZWRcbiAgICogY29uZmlndXJpbmcsIG9yIHVzZXIgaGl0IGNhbmNlbC4gYGVycm9yYCA9IHNhdmUgdGhyZXcuXG4gICAqL1xuICBvbkRvbmU6IChvdXRjb21lOiAnY29uZmlndXJlZCcgfCAnc2tpcHBlZCcgfCAnZXJyb3InLCBkZXRhaWw/OiBzdHJpbmcpID0+IHZvaWRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFBsdWdpbk9wdGlvbnNGbG93KHtcbiAgcGx1Z2luLFxuICBwbHVnaW5JZCxcbiAgb25Eb25lLFxufTogUHJvcHMpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAvLyBCdWlsZCB0aGUgc3RlcCBsaXN0IG9uY2UgYXQgbW91bnQuIFJlLWNhbGxpbmcgYWZ0ZXIgYSBzYXZlIHdvdWxkIGRyb3AgdGhlXG4gIC8vIGl0ZW0gd2UganVzdCBjb25maWd1cmVkLlxuICBjb25zdCBbc3RlcHNdID0gUmVhY3QudXNlU3RhdGU8Q29uZmlnU3RlcFtdPigoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0OiBDb25maWdTdGVwW10gPSBbXVxuXG4gICAgLy8gVG9wLWxldmVsIG1hbmlmZXN0LnVzZXJDb25maWdcbiAgICBjb25zdCB1bmNvbmZpZ3VyZWQgPSBnZXRVbmNvbmZpZ3VyZWRPcHRpb25zKHBsdWdpbilcbiAgICBpZiAoT2JqZWN0LmtleXModW5jb25maWd1cmVkKS5sZW5ndGggPiAwKSB7XG4gICAgICByZXN1bHQucHVzaCh7XG4gICAgICAgIGtleTogJ3RvcC1sZXZlbCcsXG4gICAgICAgIHRpdGxlOiBgQ29uZmlndXJlICR7cGx1Z2luLm5hbWV9YCxcbiAgICAgICAgc3VidGl0bGU6ICdQbHVnaW4gb3B0aW9ucycsXG4gICAgICAgIHNjaGVtYTogdW5jb25maWd1cmVkLFxuICAgICAgICBsb2FkOiAoKSA9PiBsb2FkUGx1Z2luT3B0aW9ucyhwbHVnaW5JZCksXG4gICAgICAgIHNhdmU6IHZhbHVlcyA9PlxuICAgICAgICAgIHNhdmVQbHVnaW5PcHRpb25zKHBsdWdpbklkLCB2YWx1ZXMsIHBsdWdpbi5tYW5pZmVzdC51c2VyQ29uZmlnISksXG4gICAgICB9KVxuICAgIH1cblxuICAgIC8vIFBlci1jaGFubmVsIHVzZXJDb25maWcgKGFzc2lzdGFudC1tb2RlIGNoYW5uZWxzKVxuICAgIGNvbnN0IGNoYW5uZWxzOiBVbmNvbmZpZ3VyZWRDaGFubmVsW10gPSBnZXRVbmNvbmZpZ3VyZWRDaGFubmVscyhwbHVnaW4pXG4gICAgZm9yIChjb25zdCBjaGFubmVsIG9mIGNoYW5uZWxzKSB7XG4gICAgICByZXN1bHQucHVzaCh7XG4gICAgICAgIGtleTogYGNoYW5uZWw6JHtjaGFubmVsLnNlcnZlcn1gLFxuICAgICAgICB0aXRsZTogYENvbmZpZ3VyZSAke2NoYW5uZWwuZGlzcGxheU5hbWV9YCxcbiAgICAgICAgc3VidGl0bGU6IGBQbHVnaW46ICR7cGx1Z2luLm5hbWV9YCxcbiAgICAgICAgc2NoZW1hOiBjaGFubmVsLmNvbmZpZ1NjaGVtYSxcbiAgICAgICAgbG9hZDogKCkgPT5cbiAgICAgICAgICBsb2FkTWNwU2VydmVyVXNlckNvbmZpZyhwbHVnaW5JZCwgY2hhbm5lbC5zZXJ2ZXIpID8/IHVuZGVmaW5lZCxcbiAgICAgICAgc2F2ZTogdmFsdWVzID0+XG4gICAgICAgICAgc2F2ZU1jcFNlcnZlclVzZXJDb25maWcoXG4gICAgICAgICAgICBwbHVnaW5JZCxcbiAgICAgICAgICAgIGNoYW5uZWwuc2VydmVyLFxuICAgICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgY2hhbm5lbC5jb25maWdTY2hlbWEsXG4gICAgICAgICAgKSxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdFxuICB9KVxuXG4gIGNvbnN0IFtpbmRleCwgc2V0SW5kZXhdID0gUmVhY3QudXNlU3RhdGUoMClcblxuICAvLyBMYXRlc3QtcmVmOiBsZXRzIHRoZSBlZmZlY3QgY2xvc2Ugb3ZlciB0aGUgY3VycmVudCBvbkRvbmUgd2l0aG91dFxuICAvLyByZS1ydW5uaW5nIHdoZW4gdGhlIHBhcmVudCByZS1yZW5kZXJzLlxuICBjb25zdCBvbkRvbmVSZWYgPSBSZWFjdC51c2VSZWYob25Eb25lKVxuICBvbkRvbmVSZWYuY3VycmVudCA9IG9uRG9uZVxuXG4gIC8vIE5vdGhpbmcgdG8gY29uZmlndXJlIOKGkiB0ZWxsIHRoZSBjYWxsZXIgYW5kIHJlbmRlciBub3RoaW5nLiBFZmZlY3QsXG4gIC8vIG5vdCBpbmxpbmUgY2FsbDogY2FsbGluZyBzZXRTdGF0ZSBpbiB0aGUgcGFyZW50IGR1cmluZyBvdXIgcmVuZGVyXG4gIC8vIGlzIGEgUmVhY3QgcnVsZXMtb2YtaG9va3MgdmlvbGF0aW9uLlxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChzdGVwcy5sZW5ndGggPT09IDApIHtcbiAgICAgIG9uRG9uZVJlZi5jdXJyZW50KCdza2lwcGVkJylcbiAgICB9XG4gIH0sIFtzdGVwcy5sZW5ndGhdKVxuXG4gIGlmIChzdGVwcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgY29uc3QgY3VycmVudCA9IHN0ZXBzW2luZGV4XSFcblxuICBmdW5jdGlvbiBoYW5kbGVTYXZlKHZhbHVlczogUGx1Z2luT3B0aW9uVmFsdWVzKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIGN1cnJlbnQuc2F2ZSh2YWx1ZXMpXG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBvbkRvbmUoJ2Vycm9yJywgZXJyb3JNZXNzYWdlKGVycikpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgY29uc3QgbmV4dCA9IGluZGV4ICsgMVxuICAgIGlmIChuZXh0IDwgc3RlcHMubGVuZ3RoKSB7XG4gICAgICBzZXRJbmRleChuZXh0KVxuICAgIH0gZWxzZSB7XG4gICAgICBvbkRvbmUoJ2NvbmZpZ3VyZWQnKVxuICAgIH1cbiAgfVxuXG4gIC8vIGtleSBmb3JjZXMgYSByZW1vdW50IHdoZW4gYWR2YW5jaW5nIHRvIHRoZSBuZXh0IHN0ZXAg4oCUIFJlYWN0IHdvdWxkXG4gIC8vIG90aGVyd2lzZSByZXVzZSB0aGUgaW5zdGFuY2UgYW5kIGNhcnJ5IFBsdWdpbk9wdGlvbnNEaWFsb2cnc1xuICAvLyBpbnRlcm5hbCB1c2VTdGF0ZSAoZmllbGQgaW5kZXgsIHR5cGVkIHZhbHVlcykgb3Zlci5cbiAgcmV0dXJuIChcbiAgICA8UGx1Z2luT3B0aW9uc0RpYWxvZ1xuICAgICAga2V5PXtjdXJyZW50LmtleX1cbiAgICAgIHRpdGxlPXtjdXJyZW50LnRpdGxlfVxuICAgICAgc3VidGl0bGU9e2N1cnJlbnQuc3VidGl0bGV9XG4gICAgICBjb25maWdTY2hlbWE9e2N1cnJlbnQuc2NoZW1hfVxuICAgICAgaW5pdGlhbFZhbHVlcz17Y3VycmVudC5sb2FkKCl9XG4gICAgICBvblNhdmU9e2hhbmRsZVNhdmV9XG4gICAgICBvbkNhbmNlbD17KCkgPT4gb25Eb25lKCdza2lwcGVkJyl9XG4gICAgLz5cbiAgKVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU8sS0FBS0EsS0FBSyxNQUFNLE9BQU87QUFDOUIsY0FBY0MsWUFBWSxRQUFRLHVCQUF1QjtBQUN6RCxTQUFTQyxZQUFZLFFBQVEsdUJBQXVCO0FBQ3BELFNBQ0VDLHVCQUF1QixFQUN2QkMsdUJBQXVCLFFBQ2xCLG9DQUFvQztBQUMzQyxTQUNFQyx1QkFBdUIsRUFDdkIsS0FBS0MsbUJBQW1CLFFBQ25CLDZDQUE2QztBQUNwRCxTQUFTQyxjQUFjLFFBQVEscUNBQXFDO0FBQ3BFLFNBQ0VDLHNCQUFzQixFQUN0QkMsaUJBQWlCLEVBQ2pCLEtBQUtDLGtCQUFrQixFQUN2QixLQUFLQyxrQkFBa0IsRUFDdkJDLGlCQUFpQixRQUNaLDZDQUE2QztBQUNwRCxTQUFTQyxtQkFBbUIsUUFBUSwwQkFBMEI7O0FBRTlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLGVBQWVDLHVCQUF1QkEsQ0FDM0NDLFFBQVEsRUFBRSxNQUFNLENBQ2pCLEVBQUVDLE9BQU8sQ0FBQ2YsWUFBWSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0VBQ25DLE1BQU07SUFBRWdCLE9BQU87SUFBRUM7RUFBUyxDQUFDLEdBQUcsTUFBTVgsY0FBYyxDQUFDLENBQUM7RUFDcEQsT0FBTyxDQUFDLEdBQUdVLE9BQU8sRUFBRSxHQUFHQyxRQUFRLENBQUMsQ0FBQ0MsSUFBSSxDQUNuQ0MsQ0FBQyxJQUFJQSxDQUFDLENBQUNDLFVBQVUsS0FBS04sUUFBUSxJQUFJSyxDQUFDLENBQUNFLE1BQU0sS0FBS1AsUUFDakQsQ0FBQztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBS1EsVUFBVSxHQUFHO0VBQ2hCQyxHQUFHLEVBQUUsTUFBTTtFQUNYQyxLQUFLLEVB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TyxHQUFHMUIsTUFBTTs7RUFFMUI7RUFDQTtFQUNBO0VBQ0FqQyxLQUFLLENBQUM0RCxTQUFTLENBQUMsTUFBTTtJQUNwQixJQUFJdEIsS0FBSyxDQUFDTSxNQUFNLEtBQUssQ0FBQyxFQUFFO01BQ3RCYSxTQUFTLENBQUNFLE9BQU8sQ0FBQyxTQUFTLENBQUM7SUFDOUI7RUFDRixDQUFDLEVBQUUsQ0FBQ3JCLEtBQUssQ0FBQ00sTUFBTSxDQUFDLENBQUM7RUFFbEIsSUFBSU4sS0FBSyxDQUFDTSxNQUFNLEtBQUssQ0FBQyxFQUFFO0lBQ3RCLE9BQU8sSUFBSTtFQUNiO0VBRUEsTUFBTWUsT0FBTyxHQUFHckIsS0FBSyxDQUFDaUIsS0FBSyxDQUFDLENBQUM7RUFFN0IsU0FBU00sVUFBVUEsQ0FBQy9CLFFBQU0sRUFBRW5CLGtCQUFrQixDQUFDLEVBQUUsSUFBSSxDQUFDO0lBQ3BELElBQUk7TUFDRmdELE9BQU8sQ0FBQzlCLElBQUksQ0FBQ0MsUUFBTSxDQUFDO0lBQ3RCLENBQUMsQ0FBQyxPQUFPZ0MsR0FBRyxFQUFFO01BQ1o3QixNQUFNLENBQUMsT0FBTyxFQUFFL0IsWUFBWSxDQUFDNEQsR0FBRyxDQUFDLENBQUM7TUFDbEM7SUFDRjtJQUNBLE1BQU1DLElBQUksR0FBR1IsS0FBSyxHQUFHLENBQUM7SUFDdEIsSUFBSVEsSUFBSSxHQUFHekIsS0FBSyxDQUFDTSxNQUFNLEVBQUU7TUFDdkJZLFFBQVEsQ0FBQ08sSUFBSSxDQUFDO0lBQ2hCLENBQUMsTUFBTTtNQUNMOUIsTUFBTSxDQUFDLFlBQVksQ0FBQztJQUN0QjtFQUNGOztFQUVBO0VBQ0E7RUFDQTtFQUNBLE9BQ0UsQ0FBQyxtQkFBbUIsQ0FDbEIsR0FBRyxDQUFDLENBQUMwQixPQUFPLENBQUNuQyxHQUFHLENBQUMsQ0FDakIsS0FBSyxDQUFDLENBQUNtQyxPQUFPLENBQUNsQyxLQUFLLENBQUMsQ0FDckIsUUFBUSxDQUFDLENBQUNrQyxPQUFPLENBQUNqQyxRQUFRLENBQUMsQ0FDM0IsWUFBWSxDQUFDLENBQUNpQyxPQUFPLENBQUNoQyxNQUFNLENBQUMsQ0FDN0IsYUFBYSxDQUFDLENBQUNnQyxPQUFPLENBQUMvQixJQUFJLENBQUMsQ0FBQyxDQUFDLENBQzlCLE1BQU0sQ0FBQyxDQUFDaUMsVUFBVSxDQUFDLENBQ25CLFFBQVEsQ0FBQyxDQUFDLE1BQU01QixNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsR0FDbEM7QUFFTiIsImlnbm9yZUxpc3QiOltdfQ==
|
src/commands/plugin/PluginSettings.tsx
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/commands/plugin/PluginTrustWarning.tsx
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { c as _c } from "react/compiler-runtime";
|
| 2 |
+
import figures from 'figures';
|
| 3 |
+
import * as React from 'react';
|
| 4 |
+
import { Box, Text } from '../../ink.js';
|
| 5 |
+
import { getPluginTrustMessage } from '../../utils/plugins/marketplaceHelpers.js';
|
| 6 |
+
export function PluginTrustWarning() {
|
| 7 |
+
const $ = _c(3);
|
| 8 |
+
let t0;
|
| 9 |
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
| 10 |
+
t0 = getPluginTrustMessage();
|
| 11 |
+
$[0] = t0;
|
| 12 |
+
} else {
|
| 13 |
+
t0 = $[0];
|
| 14 |
+
}
|
| 15 |
+
const customMessage = t0;
|
| 16 |
+
let t1;
|
| 17 |
+
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
| 18 |
+
t1 = <Text color="claude">{figures.warning} </Text>;
|
| 19 |
+
$[1] = t1;
|
| 20 |
+
} else {
|
| 21 |
+
t1 = $[1];
|
| 22 |
+
}
|
| 23 |
+
let t2;
|
| 24 |
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
| 25 |
+
t2 = <Box marginBottom={1}>{t1}<Text dimColor={true} italic={true}>Make sure you trust a plugin before installing, updating, or using it. Anthropic does not control what MCP servers, files, or other software are included in plugins and cannot verify that they will work as intended or that they won't change. See each plugin's homepage for more information.{customMessage ? ` ${customMessage}` : ""}</Text></Box>;
|
| 26 |
+
$[2] = t2;
|
| 27 |
+
} else {
|
| 28 |
+
t2 = $[2];
|
| 29 |
+
}
|
| 30 |
+
return t2;
|
| 31 |
+
}
|
| 32 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmaWd1cmVzIiwiUmVhY3QiLCJCb3giLCJUZXh0IiwiZ2V0UGx1Z2luVHJ1c3RNZXNzYWdlIiwiUGx1Z2luVHJ1c3RXYXJuaW5nIiwiJCIsIl9jIiwidDAiLCJTeW1ib2wiLCJmb3IiLCJjdXN0b21NZXNzYWdlIiwidDEiLCJ3YXJuaW5nIiwidDIiXSwic291cmNlcyI6WyJQbHVnaW5UcnVzdFdhcm5pbmcudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmaWd1cmVzIGZyb20gJ2ZpZ3VyZXMnXG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCdcbmltcG9ydCB7IEJveCwgVGV4dCB9IGZyb20gJy4uLy4uL2luay5qcydcbmltcG9ydCB7IGdldFBsdWdpblRydXN0TWVzc2FnZSB9IGZyb20gJy4uLy4uL3V0aWxzL3BsdWdpbnMvbWFya2V0cGxhY2VIZWxwZXJzLmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gUGx1Z2luVHJ1c3RXYXJuaW5nKCk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGNvbnN0IGN1c3RvbU1lc3NhZ2UgPSBnZXRQbHVnaW5UcnVzdE1lc3NhZ2UoKVxuICByZXR1cm4gKFxuICAgIDxCb3ggbWFyZ2luQm90dG9tPXsxfT5cbiAgICAgIDxUZXh0IGNvbG9yPVwiY2xhdWRlXCI+e2ZpZ3VyZXMud2FybmluZ30gPC9UZXh0PlxuICAgICAgPFRleHQgZGltQ29sb3IgaXRhbGljPlxuICAgICAgICBNYWtlIHN1cmUgeW91IHRydXN0IGEgcGx1Z2luIGJlZm9yZSBpbnN0YWxsaW5nLCB1cGRhdGluZywgb3IgdXNpbmcgaXQuXG4gICAgICAgIEFudGhyb3BpYyBkb2VzIG5vdCBjb250cm9sIHdoYXQgTUNQIHNlcnZlcnMsIGZpbGVzLCBvciBvdGhlciBzb2Z0d2FyZVxuICAgICAgICBhcmUgaW5jbHVkZWQgaW4gcGx1Z2lucyBhbmQgY2Fubm90IHZlcmlmeSB0aGF0IHRoZXkgd2lsbCB3b3JrIGFzXG4gICAgICAgIGludGVuZGVkIG9yIHRoYXQgdGhleSB3b24mYXBvczt0IGNoYW5nZS4gU2VlIGVhY2ggcGx1Z2luJmFwb3M7cyBob21lcGFnZVxuICAgICAgICBmb3IgbW9yZSBpbmZvcm1hdGlvbi57Y3VzdG9tTWVzc2FnZSA/IGAgJHtjdXN0b21NZXNzYWdlfWAgOiAnJ31cbiAgICAgIDwvVGV4dD5cbiAgICA8L0JveD5cbiAgKVxufVxuIl0sIm1hcHBpbmdzIjoiO0FBQUEsT0FBT0EsT0FBTyxNQUFNLFNBQVM7QUFDN0IsT0FBTyxLQUFLQyxLQUFLLE1BQU0sT0FBTztBQUM5QixTQUFTQyxHQUFHLEVBQUVDLElBQUksUUFBUSxjQUFjO0FBQ3hDLFNBQVNDLHFCQUFxQixRQUFRLDJDQUEyQztBQUVqRixPQUFPLFNBQUFDLG1CQUFBO0VBQUEsTUFBQUMsQ0FBQSxHQUFBQyxFQUFBO0VBQUEsSUFBQUMsRUFBQTtFQUFBLElBQUFGLENBQUEsUUFBQUcsTUFBQSxDQUFBQyxHQUFBO0lBQ2lCRixFQUFBLEdBQUFKLHFCQUFxQixDQUFDLENBQUM7SUFBQUUsQ0FBQSxNQUFBRSxFQUFBO0VBQUE7SUFBQUEsRUFBQSxHQUFBRixDQUFBO0VBQUE7RUFBN0MsTUFBQUssYUFBQSxHQUFzQkgsRUFBdUI7RUFBQSxJQUFBSSxFQUFBO0VBQUEsSUFBQU4sQ0FBQSxRQUFBRyxNQUFBLENBQUFDLEdBQUE7SUFHekNFLEVBQUEsSUFBQyxJQUFJLENBQU8sS0FBUSxDQUFSLFFBQVEsQ0FBRSxDQUFBWixPQUFPLENBQUFhLE9BQU8sQ0FBRSxDQUFDLEVBQXRDLElBQUksQ0FBeUM7SUFBQVAsQ0FBQSxNQUFBTSxFQUFBO0VBQUE7SUFBQUEsRUFBQSxHQUFBTixDQUFBO0VBQUE7RUFBQSxJQUFBUSxFQUFBO0VBQUEsSUFBQVIsQ0FBQSxRQUFBRyxNQUFBLENBQUFDLEdBQUE7SUFEaERJLEVBQUEsSUFBQyxHQUFHLENBQWUsWUFBQyxDQUFELEdBQUMsQ0FDbEIsQ0FBQUYsRUFBNkMsQ0FDN0MsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFSLEtBQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBTixLQUFLLENBQUMsQ0FBQyxrU0FLRSxDQUFBRCxhQUFhLEdBQWIsSUFBb0JBLGFBQWEsRUFBTyxHQUF4QyxFQUF1QyxDQUMvRCxFQU5DLElBQUksQ0FPUCxFQVRDLEdBQUcsQ0FTRTtJQUFBTCxDQUFBLE1BQUFRLEVBQUE7RUFBQTtJQUFBQSxFQUFBLEdBQUFSLENBQUE7RUFBQTtFQUFBLE9BVE5RLEVBU007QUFBQSIsImlnbm9yZUxpc3QiOltdfQ==
|
src/commands/plugin/UnifiedInstalledCell.tsx
ADDED
|
@@ -0,0 +1,565 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { c as _c } from "react/compiler-runtime";
|
| 2 |
+
import figures from 'figures';
|
| 3 |
+
import * as React from 'react';
|
| 4 |
+
import { Box, color, Text, useTheme } from '../../ink.js';
|
| 5 |
+
import { plural } from '../../utils/stringUtils.js';
|
| 6 |
+
import type { UnifiedInstalledItem } from './unifiedTypes.js';
|
| 7 |
+
type Props = {
|
| 8 |
+
item: UnifiedInstalledItem;
|
| 9 |
+
isSelected: boolean;
|
| 10 |
+
};
|
| 11 |
+
export function UnifiedInstalledCell(t0) {
|
| 12 |
+
const $ = _c(142);
|
| 13 |
+
const {
|
| 14 |
+
item,
|
| 15 |
+
isSelected
|
| 16 |
+
} = t0;
|
| 17 |
+
const [theme] = useTheme();
|
| 18 |
+
if (item.type === "plugin") {
|
| 19 |
+
let statusIcon;
|
| 20 |
+
let statusText;
|
| 21 |
+
if (item.pendingToggle) {
|
| 22 |
+
let t1;
|
| 23 |
+
if ($[0] !== theme) {
|
| 24 |
+
t1 = color("suggestion", theme)(figures.arrowRight);
|
| 25 |
+
$[0] = theme;
|
| 26 |
+
$[1] = t1;
|
| 27 |
+
} else {
|
| 28 |
+
t1 = $[1];
|
| 29 |
+
}
|
| 30 |
+
statusIcon = t1;
|
| 31 |
+
statusText = item.pendingToggle === "will-enable" ? "will enable" : "will disable";
|
| 32 |
+
} else {
|
| 33 |
+
if (item.errorCount > 0) {
|
| 34 |
+
let t1;
|
| 35 |
+
if ($[2] !== theme) {
|
| 36 |
+
t1 = color("error", theme)(figures.cross);
|
| 37 |
+
$[2] = theme;
|
| 38 |
+
$[3] = t1;
|
| 39 |
+
} else {
|
| 40 |
+
t1 = $[3];
|
| 41 |
+
}
|
| 42 |
+
statusIcon = t1;
|
| 43 |
+
const t2 = item.errorCount;
|
| 44 |
+
let t3;
|
| 45 |
+
if ($[4] !== item.errorCount) {
|
| 46 |
+
t3 = plural(item.errorCount, "error");
|
| 47 |
+
$[4] = item.errorCount;
|
| 48 |
+
$[5] = t3;
|
| 49 |
+
} else {
|
| 50 |
+
t3 = $[5];
|
| 51 |
+
}
|
| 52 |
+
statusText = `${t2} ${t3}`;
|
| 53 |
+
} else {
|
| 54 |
+
if (!item.isEnabled) {
|
| 55 |
+
let t1;
|
| 56 |
+
if ($[6] !== theme) {
|
| 57 |
+
t1 = color("inactive", theme)(figures.radioOff);
|
| 58 |
+
$[6] = theme;
|
| 59 |
+
$[7] = t1;
|
| 60 |
+
} else {
|
| 61 |
+
t1 = $[7];
|
| 62 |
+
}
|
| 63 |
+
statusIcon = t1;
|
| 64 |
+
statusText = "disabled";
|
| 65 |
+
} else {
|
| 66 |
+
let t1;
|
| 67 |
+
if ($[8] !== theme) {
|
| 68 |
+
t1 = color("success", theme)(figures.tick);
|
| 69 |
+
$[8] = theme;
|
| 70 |
+
$[9] = t1;
|
| 71 |
+
} else {
|
| 72 |
+
t1 = $[9];
|
| 73 |
+
}
|
| 74 |
+
statusIcon = t1;
|
| 75 |
+
statusText = "enabled";
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
+
}
|
| 79 |
+
const t1 = isSelected ? "suggestion" : undefined;
|
| 80 |
+
const t2 = isSelected ? `${figures.pointer} ` : " ";
|
| 81 |
+
let t3;
|
| 82 |
+
if ($[10] !== t1 || $[11] !== t2) {
|
| 83 |
+
t3 = <Text color={t1}>{t2}</Text>;
|
| 84 |
+
$[10] = t1;
|
| 85 |
+
$[11] = t2;
|
| 86 |
+
$[12] = t3;
|
| 87 |
+
} else {
|
| 88 |
+
t3 = $[12];
|
| 89 |
+
}
|
| 90 |
+
const t4 = isSelected ? "suggestion" : undefined;
|
| 91 |
+
let t5;
|
| 92 |
+
if ($[13] !== item.name || $[14] !== t4) {
|
| 93 |
+
t5 = <Text color={t4}>{item.name}</Text>;
|
| 94 |
+
$[13] = item.name;
|
| 95 |
+
$[14] = t4;
|
| 96 |
+
$[15] = t5;
|
| 97 |
+
} else {
|
| 98 |
+
t5 = $[15];
|
| 99 |
+
}
|
| 100 |
+
const t6 = !isSelected;
|
| 101 |
+
let t7;
|
| 102 |
+
if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
|
| 103 |
+
t7 = <Text backgroundColor="userMessageBackground">Plugin</Text>;
|
| 104 |
+
$[16] = t7;
|
| 105 |
+
} else {
|
| 106 |
+
t7 = $[16];
|
| 107 |
+
}
|
| 108 |
+
let t8;
|
| 109 |
+
if ($[17] !== t6) {
|
| 110 |
+
t8 = <Text dimColor={t6}>{" "}{t7}</Text>;
|
| 111 |
+
$[17] = t6;
|
| 112 |
+
$[18] = t8;
|
| 113 |
+
} else {
|
| 114 |
+
t8 = $[18];
|
| 115 |
+
}
|
| 116 |
+
let t9;
|
| 117 |
+
if ($[19] !== item.marketplace) {
|
| 118 |
+
t9 = <Text dimColor={true}> · {item.marketplace}</Text>;
|
| 119 |
+
$[19] = item.marketplace;
|
| 120 |
+
$[20] = t9;
|
| 121 |
+
} else {
|
| 122 |
+
t9 = $[20];
|
| 123 |
+
}
|
| 124 |
+
const t10 = !isSelected;
|
| 125 |
+
let t11;
|
| 126 |
+
if ($[21] !== statusIcon || $[22] !== t10) {
|
| 127 |
+
t11 = <Text dimColor={t10}> · {statusIcon} </Text>;
|
| 128 |
+
$[21] = statusIcon;
|
| 129 |
+
$[22] = t10;
|
| 130 |
+
$[23] = t11;
|
| 131 |
+
} else {
|
| 132 |
+
t11 = $[23];
|
| 133 |
+
}
|
| 134 |
+
const t12 = !isSelected;
|
| 135 |
+
let t13;
|
| 136 |
+
if ($[24] !== statusText || $[25] !== t12) {
|
| 137 |
+
t13 = <Text dimColor={t12}>{statusText}</Text>;
|
| 138 |
+
$[24] = statusText;
|
| 139 |
+
$[25] = t12;
|
| 140 |
+
$[26] = t13;
|
| 141 |
+
} else {
|
| 142 |
+
t13 = $[26];
|
| 143 |
+
}
|
| 144 |
+
let t14;
|
| 145 |
+
if ($[27] !== t11 || $[28] !== t13 || $[29] !== t3 || $[30] !== t5 || $[31] !== t8 || $[32] !== t9) {
|
| 146 |
+
t14 = <Box>{t3}{t5}{t8}{t9}{t11}{t13}</Box>;
|
| 147 |
+
$[27] = t11;
|
| 148 |
+
$[28] = t13;
|
| 149 |
+
$[29] = t3;
|
| 150 |
+
$[30] = t5;
|
| 151 |
+
$[31] = t8;
|
| 152 |
+
$[32] = t9;
|
| 153 |
+
$[33] = t14;
|
| 154 |
+
} else {
|
| 155 |
+
t14 = $[33];
|
| 156 |
+
}
|
| 157 |
+
return t14;
|
| 158 |
+
}
|
| 159 |
+
if (item.type === "flagged-plugin") {
|
| 160 |
+
let t1;
|
| 161 |
+
if ($[34] !== theme) {
|
| 162 |
+
t1 = color("warning", theme)(figures.warning);
|
| 163 |
+
$[34] = theme;
|
| 164 |
+
$[35] = t1;
|
| 165 |
+
} else {
|
| 166 |
+
t1 = $[35];
|
| 167 |
+
}
|
| 168 |
+
const statusIcon_0 = t1;
|
| 169 |
+
const t2 = isSelected ? "suggestion" : undefined;
|
| 170 |
+
const t3 = isSelected ? `${figures.pointer} ` : " ";
|
| 171 |
+
let t4;
|
| 172 |
+
if ($[36] !== t2 || $[37] !== t3) {
|
| 173 |
+
t4 = <Text color={t2}>{t3}</Text>;
|
| 174 |
+
$[36] = t2;
|
| 175 |
+
$[37] = t3;
|
| 176 |
+
$[38] = t4;
|
| 177 |
+
} else {
|
| 178 |
+
t4 = $[38];
|
| 179 |
+
}
|
| 180 |
+
const t5 = isSelected ? "suggestion" : undefined;
|
| 181 |
+
let t6;
|
| 182 |
+
if ($[39] !== item.name || $[40] !== t5) {
|
| 183 |
+
t6 = <Text color={t5}>{item.name}</Text>;
|
| 184 |
+
$[39] = item.name;
|
| 185 |
+
$[40] = t5;
|
| 186 |
+
$[41] = t6;
|
| 187 |
+
} else {
|
| 188 |
+
t6 = $[41];
|
| 189 |
+
}
|
| 190 |
+
const t7 = !isSelected;
|
| 191 |
+
let t8;
|
| 192 |
+
if ($[42] === Symbol.for("react.memo_cache_sentinel")) {
|
| 193 |
+
t8 = <Text backgroundColor="userMessageBackground">Plugin</Text>;
|
| 194 |
+
$[42] = t8;
|
| 195 |
+
} else {
|
| 196 |
+
t8 = $[42];
|
| 197 |
+
}
|
| 198 |
+
let t9;
|
| 199 |
+
if ($[43] !== t7) {
|
| 200 |
+
t9 = <Text dimColor={t7}>{" "}{t8}</Text>;
|
| 201 |
+
$[43] = t7;
|
| 202 |
+
$[44] = t9;
|
| 203 |
+
} else {
|
| 204 |
+
t9 = $[44];
|
| 205 |
+
}
|
| 206 |
+
let t10;
|
| 207 |
+
if ($[45] !== item.marketplace) {
|
| 208 |
+
t10 = <Text dimColor={true}> · {item.marketplace}</Text>;
|
| 209 |
+
$[45] = item.marketplace;
|
| 210 |
+
$[46] = t10;
|
| 211 |
+
} else {
|
| 212 |
+
t10 = $[46];
|
| 213 |
+
}
|
| 214 |
+
const t11 = !isSelected;
|
| 215 |
+
let t12;
|
| 216 |
+
if ($[47] !== statusIcon_0 || $[48] !== t11) {
|
| 217 |
+
t12 = <Text dimColor={t11}> · {statusIcon_0} </Text>;
|
| 218 |
+
$[47] = statusIcon_0;
|
| 219 |
+
$[48] = t11;
|
| 220 |
+
$[49] = t12;
|
| 221 |
+
} else {
|
| 222 |
+
t12 = $[49];
|
| 223 |
+
}
|
| 224 |
+
const t13 = !isSelected;
|
| 225 |
+
let t14;
|
| 226 |
+
if ($[50] !== t13) {
|
| 227 |
+
t14 = <Text dimColor={t13}>removed</Text>;
|
| 228 |
+
$[50] = t13;
|
| 229 |
+
$[51] = t14;
|
| 230 |
+
} else {
|
| 231 |
+
t14 = $[51];
|
| 232 |
+
}
|
| 233 |
+
let t15;
|
| 234 |
+
if ($[52] !== t10 || $[53] !== t12 || $[54] !== t14 || $[55] !== t4 || $[56] !== t6 || $[57] !== t9) {
|
| 235 |
+
t15 = <Box>{t4}{t6}{t9}{t10}{t12}{t14}</Box>;
|
| 236 |
+
$[52] = t10;
|
| 237 |
+
$[53] = t12;
|
| 238 |
+
$[54] = t14;
|
| 239 |
+
$[55] = t4;
|
| 240 |
+
$[56] = t6;
|
| 241 |
+
$[57] = t9;
|
| 242 |
+
$[58] = t15;
|
| 243 |
+
} else {
|
| 244 |
+
t15 = $[58];
|
| 245 |
+
}
|
| 246 |
+
return t15;
|
| 247 |
+
}
|
| 248 |
+
if (item.type === "failed-plugin") {
|
| 249 |
+
let t1;
|
| 250 |
+
if ($[59] !== theme) {
|
| 251 |
+
t1 = color("error", theme)(figures.cross);
|
| 252 |
+
$[59] = theme;
|
| 253 |
+
$[60] = t1;
|
| 254 |
+
} else {
|
| 255 |
+
t1 = $[60];
|
| 256 |
+
}
|
| 257 |
+
const statusIcon_1 = t1;
|
| 258 |
+
const t2 = item.errorCount;
|
| 259 |
+
let t3;
|
| 260 |
+
if ($[61] !== item.errorCount) {
|
| 261 |
+
t3 = plural(item.errorCount, "error");
|
| 262 |
+
$[61] = item.errorCount;
|
| 263 |
+
$[62] = t3;
|
| 264 |
+
} else {
|
| 265 |
+
t3 = $[62];
|
| 266 |
+
}
|
| 267 |
+
const statusText_0 = `failed to load · ${t2} ${t3}`;
|
| 268 |
+
const t4 = isSelected ? "suggestion" : undefined;
|
| 269 |
+
const t5 = isSelected ? `${figures.pointer} ` : " ";
|
| 270 |
+
let t6;
|
| 271 |
+
if ($[63] !== t4 || $[64] !== t5) {
|
| 272 |
+
t6 = <Text color={t4}>{t5}</Text>;
|
| 273 |
+
$[63] = t4;
|
| 274 |
+
$[64] = t5;
|
| 275 |
+
$[65] = t6;
|
| 276 |
+
} else {
|
| 277 |
+
t6 = $[65];
|
| 278 |
+
}
|
| 279 |
+
const t7 = isSelected ? "suggestion" : undefined;
|
| 280 |
+
let t8;
|
| 281 |
+
if ($[66] !== item.name || $[67] !== t7) {
|
| 282 |
+
t8 = <Text color={t7}>{item.name}</Text>;
|
| 283 |
+
$[66] = item.name;
|
| 284 |
+
$[67] = t7;
|
| 285 |
+
$[68] = t8;
|
| 286 |
+
} else {
|
| 287 |
+
t8 = $[68];
|
| 288 |
+
}
|
| 289 |
+
const t9 = !isSelected;
|
| 290 |
+
let t10;
|
| 291 |
+
if ($[69] === Symbol.for("react.memo_cache_sentinel")) {
|
| 292 |
+
t10 = <Text backgroundColor="userMessageBackground">Plugin</Text>;
|
| 293 |
+
$[69] = t10;
|
| 294 |
+
} else {
|
| 295 |
+
t10 = $[69];
|
| 296 |
+
}
|
| 297 |
+
let t11;
|
| 298 |
+
if ($[70] !== t9) {
|
| 299 |
+
t11 = <Text dimColor={t9}>{" "}{t10}</Text>;
|
| 300 |
+
$[70] = t9;
|
| 301 |
+
$[71] = t11;
|
| 302 |
+
} else {
|
| 303 |
+
t11 = $[71];
|
| 304 |
+
}
|
| 305 |
+
let t12;
|
| 306 |
+
if ($[72] !== item.marketplace) {
|
| 307 |
+
t12 = <Text dimColor={true}> · {item.marketplace}</Text>;
|
| 308 |
+
$[72] = item.marketplace;
|
| 309 |
+
$[73] = t12;
|
| 310 |
+
} else {
|
| 311 |
+
t12 = $[73];
|
| 312 |
+
}
|
| 313 |
+
const t13 = !isSelected;
|
| 314 |
+
let t14;
|
| 315 |
+
if ($[74] !== statusIcon_1 || $[75] !== t13) {
|
| 316 |
+
t14 = <Text dimColor={t13}> · {statusIcon_1} </Text>;
|
| 317 |
+
$[74] = statusIcon_1;
|
| 318 |
+
$[75] = t13;
|
| 319 |
+
$[76] = t14;
|
| 320 |
+
} else {
|
| 321 |
+
t14 = $[76];
|
| 322 |
+
}
|
| 323 |
+
const t15 = !isSelected;
|
| 324 |
+
let t16;
|
| 325 |
+
if ($[77] !== statusText_0 || $[78] !== t15) {
|
| 326 |
+
t16 = <Text dimColor={t15}>{statusText_0}</Text>;
|
| 327 |
+
$[77] = statusText_0;
|
| 328 |
+
$[78] = t15;
|
| 329 |
+
$[79] = t16;
|
| 330 |
+
} else {
|
| 331 |
+
t16 = $[79];
|
| 332 |
+
}
|
| 333 |
+
let t17;
|
| 334 |
+
if ($[80] !== t11 || $[81] !== t12 || $[82] !== t14 || $[83] !== t16 || $[84] !== t6 || $[85] !== t8) {
|
| 335 |
+
t17 = <Box>{t6}{t8}{t11}{t12}{t14}{t16}</Box>;
|
| 336 |
+
$[80] = t11;
|
| 337 |
+
$[81] = t12;
|
| 338 |
+
$[82] = t14;
|
| 339 |
+
$[83] = t16;
|
| 340 |
+
$[84] = t6;
|
| 341 |
+
$[85] = t8;
|
| 342 |
+
$[86] = t17;
|
| 343 |
+
} else {
|
| 344 |
+
t17 = $[86];
|
| 345 |
+
}
|
| 346 |
+
return t17;
|
| 347 |
+
}
|
| 348 |
+
let statusIcon_2;
|
| 349 |
+
let statusText_1;
|
| 350 |
+
if (item.status === "connected") {
|
| 351 |
+
let t1;
|
| 352 |
+
if ($[87] !== theme) {
|
| 353 |
+
t1 = color("success", theme)(figures.tick);
|
| 354 |
+
$[87] = theme;
|
| 355 |
+
$[88] = t1;
|
| 356 |
+
} else {
|
| 357 |
+
t1 = $[88];
|
| 358 |
+
}
|
| 359 |
+
statusIcon_2 = t1;
|
| 360 |
+
statusText_1 = "connected";
|
| 361 |
+
} else {
|
| 362 |
+
if (item.status === "disabled") {
|
| 363 |
+
let t1;
|
| 364 |
+
if ($[89] !== theme) {
|
| 365 |
+
t1 = color("inactive", theme)(figures.radioOff);
|
| 366 |
+
$[89] = theme;
|
| 367 |
+
$[90] = t1;
|
| 368 |
+
} else {
|
| 369 |
+
t1 = $[90];
|
| 370 |
+
}
|
| 371 |
+
statusIcon_2 = t1;
|
| 372 |
+
statusText_1 = "disabled";
|
| 373 |
+
} else {
|
| 374 |
+
if (item.status === "pending") {
|
| 375 |
+
let t1;
|
| 376 |
+
if ($[91] !== theme) {
|
| 377 |
+
t1 = color("inactive", theme)(figures.radioOff);
|
| 378 |
+
$[91] = theme;
|
| 379 |
+
$[92] = t1;
|
| 380 |
+
} else {
|
| 381 |
+
t1 = $[92];
|
| 382 |
+
}
|
| 383 |
+
statusIcon_2 = t1;
|
| 384 |
+
statusText_1 = "connecting\u2026";
|
| 385 |
+
} else {
|
| 386 |
+
if (item.status === "needs-auth") {
|
| 387 |
+
let t1;
|
| 388 |
+
if ($[93] !== theme) {
|
| 389 |
+
t1 = color("warning", theme)(figures.triangleUpOutline);
|
| 390 |
+
$[93] = theme;
|
| 391 |
+
$[94] = t1;
|
| 392 |
+
} else {
|
| 393 |
+
t1 = $[94];
|
| 394 |
+
}
|
| 395 |
+
statusIcon_2 = t1;
|
| 396 |
+
statusText_1 = "Enter to auth";
|
| 397 |
+
} else {
|
| 398 |
+
let t1;
|
| 399 |
+
if ($[95] !== theme) {
|
| 400 |
+
t1 = color("error", theme)(figures.cross);
|
| 401 |
+
$[95] = theme;
|
| 402 |
+
$[96] = t1;
|
| 403 |
+
} else {
|
| 404 |
+
t1 = $[96];
|
| 405 |
+
}
|
| 406 |
+
statusIcon_2 = t1;
|
| 407 |
+
statusText_1 = "failed";
|
| 408 |
+
}
|
| 409 |
+
}
|
| 410 |
+
}
|
| 411 |
+
}
|
| 412 |
+
if (item.indented) {
|
| 413 |
+
const t1 = isSelected ? "suggestion" : undefined;
|
| 414 |
+
const t2 = isSelected ? `${figures.pointer} ` : " ";
|
| 415 |
+
let t3;
|
| 416 |
+
if ($[97] !== t1 || $[98] !== t2) {
|
| 417 |
+
t3 = <Text color={t1}>{t2}</Text>;
|
| 418 |
+
$[97] = t1;
|
| 419 |
+
$[98] = t2;
|
| 420 |
+
$[99] = t3;
|
| 421 |
+
} else {
|
| 422 |
+
t3 = $[99];
|
| 423 |
+
}
|
| 424 |
+
const t4 = !isSelected;
|
| 425 |
+
let t5;
|
| 426 |
+
if ($[100] !== t4) {
|
| 427 |
+
t5 = <Text dimColor={t4}>└ </Text>;
|
| 428 |
+
$[100] = t4;
|
| 429 |
+
$[101] = t5;
|
| 430 |
+
} else {
|
| 431 |
+
t5 = $[101];
|
| 432 |
+
}
|
| 433 |
+
const t6 = isSelected ? "suggestion" : undefined;
|
| 434 |
+
let t7;
|
| 435 |
+
if ($[102] !== item.name || $[103] !== t6) {
|
| 436 |
+
t7 = <Text color={t6}>{item.name}</Text>;
|
| 437 |
+
$[102] = item.name;
|
| 438 |
+
$[103] = t6;
|
| 439 |
+
$[104] = t7;
|
| 440 |
+
} else {
|
| 441 |
+
t7 = $[104];
|
| 442 |
+
}
|
| 443 |
+
const t8 = !isSelected;
|
| 444 |
+
let t9;
|
| 445 |
+
if ($[105] === Symbol.for("react.memo_cache_sentinel")) {
|
| 446 |
+
t9 = <Text backgroundColor="userMessageBackground">MCP</Text>;
|
| 447 |
+
$[105] = t9;
|
| 448 |
+
} else {
|
| 449 |
+
t9 = $[105];
|
| 450 |
+
}
|
| 451 |
+
let t10;
|
| 452 |
+
if ($[106] !== t8) {
|
| 453 |
+
t10 = <Text dimColor={t8}>{" "}{t9}</Text>;
|
| 454 |
+
$[106] = t8;
|
| 455 |
+
$[107] = t10;
|
| 456 |
+
} else {
|
| 457 |
+
t10 = $[107];
|
| 458 |
+
}
|
| 459 |
+
const t11 = !isSelected;
|
| 460 |
+
let t12;
|
| 461 |
+
if ($[108] !== statusIcon_2 || $[109] !== t11) {
|
| 462 |
+
t12 = <Text dimColor={t11}> · {statusIcon_2} </Text>;
|
| 463 |
+
$[108] = statusIcon_2;
|
| 464 |
+
$[109] = t11;
|
| 465 |
+
$[110] = t12;
|
| 466 |
+
} else {
|
| 467 |
+
t12 = $[110];
|
| 468 |
+
}
|
| 469 |
+
const t13 = !isSelected;
|
| 470 |
+
let t14;
|
| 471 |
+
if ($[111] !== statusText_1 || $[112] !== t13) {
|
| 472 |
+
t14 = <Text dimColor={t13}>{statusText_1}</Text>;
|
| 473 |
+
$[111] = statusText_1;
|
| 474 |
+
$[112] = t13;
|
| 475 |
+
$[113] = t14;
|
| 476 |
+
} else {
|
| 477 |
+
t14 = $[113];
|
| 478 |
+
}
|
| 479 |
+
let t15;
|
| 480 |
+
if ($[114] !== t10 || $[115] !== t12 || $[116] !== t14 || $[117] !== t3 || $[118] !== t5 || $[119] !== t7) {
|
| 481 |
+
t15 = <Box>{t3}{t5}{t7}{t10}{t12}{t14}</Box>;
|
| 482 |
+
$[114] = t10;
|
| 483 |
+
$[115] = t12;
|
| 484 |
+
$[116] = t14;
|
| 485 |
+
$[117] = t3;
|
| 486 |
+
$[118] = t5;
|
| 487 |
+
$[119] = t7;
|
| 488 |
+
$[120] = t15;
|
| 489 |
+
} else {
|
| 490 |
+
t15 = $[120];
|
| 491 |
+
}
|
| 492 |
+
return t15;
|
| 493 |
+
}
|
| 494 |
+
const t1 = isSelected ? "suggestion" : undefined;
|
| 495 |
+
const t2 = isSelected ? `${figures.pointer} ` : " ";
|
| 496 |
+
let t3;
|
| 497 |
+
if ($[121] !== t1 || $[122] !== t2) {
|
| 498 |
+
t3 = <Text color={t1}>{t2}</Text>;
|
| 499 |
+
$[121] = t1;
|
| 500 |
+
$[122] = t2;
|
| 501 |
+
$[123] = t3;
|
| 502 |
+
} else {
|
| 503 |
+
t3 = $[123];
|
| 504 |
+
}
|
| 505 |
+
const t4 = isSelected ? "suggestion" : undefined;
|
| 506 |
+
let t5;
|
| 507 |
+
if ($[124] !== item.name || $[125] !== t4) {
|
| 508 |
+
t5 = <Text color={t4}>{item.name}</Text>;
|
| 509 |
+
$[124] = item.name;
|
| 510 |
+
$[125] = t4;
|
| 511 |
+
$[126] = t5;
|
| 512 |
+
} else {
|
| 513 |
+
t5 = $[126];
|
| 514 |
+
}
|
| 515 |
+
const t6 = !isSelected;
|
| 516 |
+
let t7;
|
| 517 |
+
if ($[127] === Symbol.for("react.memo_cache_sentinel")) {
|
| 518 |
+
t7 = <Text backgroundColor="userMessageBackground">MCP</Text>;
|
| 519 |
+
$[127] = t7;
|
| 520 |
+
} else {
|
| 521 |
+
t7 = $[127];
|
| 522 |
+
}
|
| 523 |
+
let t8;
|
| 524 |
+
if ($[128] !== t6) {
|
| 525 |
+
t8 = <Text dimColor={t6}>{" "}{t7}</Text>;
|
| 526 |
+
$[128] = t6;
|
| 527 |
+
$[129] = t8;
|
| 528 |
+
} else {
|
| 529 |
+
t8 = $[129];
|
| 530 |
+
}
|
| 531 |
+
const t9 = !isSelected;
|
| 532 |
+
let t10;
|
| 533 |
+
if ($[130] !== statusIcon_2 || $[131] !== t9) {
|
| 534 |
+
t10 = <Text dimColor={t9}> · {statusIcon_2} </Text>;
|
| 535 |
+
$[130] = statusIcon_2;
|
| 536 |
+
$[131] = t9;
|
| 537 |
+
$[132] = t10;
|
| 538 |
+
} else {
|
| 539 |
+
t10 = $[132];
|
| 540 |
+
}
|
| 541 |
+
const t11 = !isSelected;
|
| 542 |
+
let t12;
|
| 543 |
+
if ($[133] !== statusText_1 || $[134] !== t11) {
|
| 544 |
+
t12 = <Text dimColor={t11}>{statusText_1}</Text>;
|
| 545 |
+
$[133] = statusText_1;
|
| 546 |
+
$[134] = t11;
|
| 547 |
+
$[135] = t12;
|
| 548 |
+
} else {
|
| 549 |
+
t12 = $[135];
|
| 550 |
+
}
|
| 551 |
+
let t13;
|
| 552 |
+
if ($[136] !== t10 || $[137] !== t12 || $[138] !== t3 || $[139] !== t5 || $[140] !== t8) {
|
| 553 |
+
t13 = <Box>{t3}{t5}{t8}{t10}{t12}</Box>;
|
| 554 |
+
$[136] = t10;
|
| 555 |
+
$[137] = t12;
|
| 556 |
+
$[138] = t3;
|
| 557 |
+
$[139] = t5;
|
| 558 |
+
$[140] = t8;
|
| 559 |
+
$[141] = t13;
|
| 560 |
+
} else {
|
| 561 |
+
t13 = $[141];
|
| 562 |
+
}
|
| 563 |
+
return t13;
|
| 564 |
+
}
|
| 565 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmaWd1cmVzIiwiUmVhY3QiLCJCb3giLCJjb2xvciIsIlRleHQiLCJ1c2VUaGVtZSIsInBsdXJhbCIsIlVuaWZpZWRJbnN0YWxsZWRJdGVtIiwiUHJvcHMiLCJpdGVtIiwiaXNTZWxlY3RlZCIsIlVuaWZpZWRJbnN0YWxsZWRDZWxsIiwidDAiLCIkIiwiX2MiLCJ0aGVtZSIsInR5cGUiLCJzdGF0dXNJY29uIiwic3RhdHVzVGV4dCIsInBlbmRpbmdUb2dnbGUiLCJ0MSIsImFycm93UmlnaHQiLCJlcnJvckNvdW50IiwiY3Jvc3MiLCJ0MiIsInQzIiwiaXNFbmFibGVkIiwicmFkaW9PZmYiLCJ0aWNrIiwidW5kZWZpbmVkIiwicG9pbnRlciIsInQ0IiwidDUiLCJuYW1lIiwidDYiLCJ0NyIsIlN5bWJvbCIsImZvciIsInQ4IiwidDkiLCJtYXJrZXRwbGFjZSIsInQxMCIsInQxMSIsInQxMiIsInQxMyIsInQxNCIsIndhcm5pbmciLCJzdGF0dXNJY29uXzAiLCJ0MTUiLCJzdGF0dXNJY29uXzEiLCJzdGF0dXNUZXh0XzAiLCJ0MTYiLCJ0MTciLCJzdGF0dXMiLCJ0cmlhbmdsZVVwT3V0bGluZSIsImluZGVudGVkIiwic3RhdHVzSWNvbl8yIiwic3RhdHVzVGV4dF8xIl0sInNvdXJjZXMiOlsiVW5pZmllZEluc3RhbGxlZENlbGwudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmaWd1cmVzIGZyb20gJ2ZpZ3VyZXMnXG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCdcbmltcG9ydCB7IEJveCwgY29sb3IsIFRleHQsIHVzZVRoZW1lIH0gZnJvbSAnLi4vLi4vaW5rLmpzJ1xuaW1wb3J0IHsgcGx1cmFsIH0gZnJvbSAnLi4vLi4vdXRpbHMvc3RyaW5nVXRpbHMuanMnXG5pbXBvcnQgdHlwZSB7IFVuaWZpZWRJbnN0YWxsZWRJdGVtIH0gZnJvbSAnLi91bmlmaWVkVHlwZXMuanMnXG5cbnR5cGUgUHJvcHMgPSB7XG4gIGl0ZW06IFVuaWZpZWRJbnN0YWxsZWRJdGVtXG4gIGlzU2VsZWN0ZWQ6IGJvb2xlYW5cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFVuaWZpZWRJbnN0YWxsZWRDZWxsKHtcbiAgaXRlbSxcbiAgaXNTZWxlY3RlZCxcbn06IFByb3BzKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgY29uc3QgW3RoZW1lXSA9IHVzZVRoZW1lKClcblxuICBpZiAoaXRlbS50eXBlID09PSAncGx1Z2luJykge1xuICAgIC8vIFN0YXR1cyBpY29uIGFuZCB0ZXh0XG4gICAgbGV0IHN0YXR1c0ljb246IHN0cmluZ1xuICAgIGxldCBzdGF0dXNUZXh0OiBzdHJpbmdcblxuICAgIC8vIFNob3cgcGVuZGluZyB0b2dnbGUgc3RhdHVzIGlmIHNldCwgb3RoZXJ3aXNlIHNob3cgY3VycmVudCBzdGF0dXNcbiAgICBpZiAoaXRlbS5wZW5kaW5nVG9nZ2xlKSB7XG4gICAgICBzdGF0dXNJY29uID0gY29sb3IoJ3N1Z2dlc3Rpb24nLCB0aGVtZSkoZmlndXJlcy5hcnJvd1JpZ2h0KVxuICAgICAgc3RhdHVzVGV4dCA9XG4gICAgICAgIGl0ZW0ucGVuZGluZ1RvZ2dsZSA9PT0gJ3dpbGwtZW5hYmxlJyA/ICd3aWxsIGVuYWJsZScgOiAnd2lsbCBkaXNhYmxlJ1xuICAgIH0gZWxzZSBpZiAoaXRlbS5lcnJvckNvdW50ID4gMCkge1xuICAgICAgc3RhdHVzSWNvbiA9IGNvbG9yKCdlcnJvcicsIHRoZW1lKShmaWd1cmVzLmNyb3NzKVxuICAgICAgc3RhdHVzVGV4dCA9IGAke2l0ZW0uZXJyb3JDb3VudH0gJHtwbHVyYWwoaXRlbS5lcnJvckNvdW50LCAnZXJyb3InKX1gXG4gICAgfSBlbHNlIGlmICghaXRlbS5pc0VuYWJsZWQpIHtcbiAgICAgIHN0YXR1c0ljb24gPSBjb2xvcignaW5hY3RpdmUnLCB0aGVtZSkoZmlndXJlcy5yYWRpb09mZilcbiAgICAgIHN0YXR1c1RleHQgPSAnZGlzYWJsZWQnXG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXR1c0ljb24gPSBjb2xvcignc3VjY2VzcycsIHRoZW1lKShmaWd1cmVzLnRpY2spXG4gICAgICBzdGF0dXNUZXh0ID0gJ2VuYWJsZWQnXG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIDxCb3g+XG4gICAgICAgIDxUZXh0IGNvbG9yPXtpc1NlbGVjdGVkID8gJ3N1Z2dlc3Rpb24nIDogdW5kZWZpbmVkfT5cbiAgICAgICAgICB7aXNTZWxlY3RlZCA/IGAke2ZpZ3VyZXMucG9pbnRlcn0gYCA6ICcgICd9XG4gICAgICAgIDwvVGV4dD5cbiAgICAgICAgPFRleHQgY29sb3I9e2lzU2VsZWN0ZWQgPyAnc3VnZ2VzdGlvbicgOiB1bmRlZmluZWR9PntpdGVtLm5hbWV9PC9UZXh0PlxuICAgICAgICA8VGV4dCBkaW1Db2xvcj17IWlzU2VsZWN0ZWR9PlxuICAgICAgICAgIHsnICd9XG4gICAgICAgICAgPFRleHQgYmFja2dyb3VuZENvbG9yPVwidXNlck1lc3NhZ2VCYWNrZ3JvdW5kXCI+UGx1Z2luPC9UZXh0PlxuICAgICAgICA8L1RleHQ+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPiDCtyB7aXRlbS5tYXJrZXRwbGFjZX08L1RleHQ+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPXshaXNTZWxlY3RlZH0+IMK3IHtzdGF0dXNJY29ufSA8L1RleHQ+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPXshaXNTZWxlY3RlZH0+e3N0YXR1c1RleHR9PC9UZXh0PlxuICAgICAgPC9Cb3g+XG4gICAgKVxuICB9XG5cbiAgaWYgKGl0ZW0udHlwZSA9PT0gJ2ZsYWdnZWQtcGx1Z2luJykge1xuICAgIGNvbnN0IHN0YXR1c0ljb24gPSBjb2xvcignd2FybmluZycsIHRoZW1lKShmaWd1cmVzLndhcm5pbmcpXG5cbiAgICByZXR1cm4gKFxuICAgICAgPEJveD5cbiAgICAgICAgPFRleHQgY29sb3I9e2lzU2VsZWN0ZWQgPyAnc3VnZ2VzdGlvbicgOiB1bmRlZmluZWR9PlxuICAgICAgICAgIHtpc1NlbGVjdGVkID8gYCR7ZmlndXJlcy5wb2ludGVyfSBgIDogJyAgJ31cbiAgICAgICAgPC9UZXh0PlxuICAgICAgICA8VGV4dCBjb2xvcj17aXNTZWxlY3RlZCA/ICdzdWdnZXN0aW9uJyA6IHVuZGVmaW5lZH0+e2l0ZW0ubmFtZX08L1RleHQ+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPXshaXNTZWxlY3RlZH0+XG4gICAgICAgICAgeycgJ31cbiAgICAgICAgICA8VGV4dCBiYWNrZ3JvdW5kQ29sb3I9XCJ1c2VyTWVzc2FnZUJhY2tncm91bmRcIj5QbHVnaW48L1RleHQ+XG4gICAgICAgIDwvVGV4dD5cbiAgICAgICAgPFRleHQgZGltQ29sb3I+IMK3IHtpdGVtLm1hcmtldHBsYWNlfTwvVGV4dD5cbiAgICAgICAgPFRleHQgZGltQ29sb3I9eyFpc1NlbGVjdGVkfT4gwrcge3N0YXR1c0ljb259IDwvVGV4dD5cbiAgICAgICAgPFRleHQgZGltQ29sb3I9eyFpc1NlbGVjdGVkfT5yZW1vdmVkPC9UZXh0PlxuICAgICAgPC9Cb3g+XG4gICAgKVxuICB9XG5cbiAgaWYgKGl0ZW0udHlwZSA9PT0gJ2ZhaWxlZC1wbHVnaW4nKSB7XG4gICAgY29uc3Qgc3RhdHVzSWNvbiA9IGNvbG9yKCdlcnJvcicsIHRoZW1lKShmaWd1cmVzLmNyb3NzKVxuICAgIGNvbnN0IHN0YXR1c1RleHQgPSBgZmFpbGVkIHRvIGxvYWQgwrcgJHtpdGVtLmVycm9yQ291bnR9ICR7cGx1cmFsKGl0ZW0uZXJyb3JDb3VudCwgJ2Vycm9yJyl9YFxuXG4gICAgcmV0dXJuIChcbiAgICAgIDxCb3g+XG4gICAgICAgIDxUZXh0IGNvbG9yPXtpc1NlbGVjdGVkID8gJ3N1Z2dlc3Rpb24nIDogdW5kZWZpbmVkfT5cbiAgICAgICAgICB7aXNTZWxlY3RlZCA/IGAke2ZpZ3VyZXMucG9pbnRlcn0gYCA6ICcgICd9XG4gICAgICAgIDwvVGV4dD5cbiAgICAgICAgPFRleHQgY29sb3I9e2lzU2VsZWN0ZWQgPyAnc3VnZ2VzdGlvbicgOiB1bmRlZmluZWR9PntpdGVtLm5hbWV9PC9UZXh0PlxuICAgICAgICA8VGV4dCBkaW1Db2xvcj17IWlzU2VsZWN0ZWR9PlxuICAgICAgICAgIHsnICd9XG4gICAgICAgICAgPFRleHQgYmFja2dyb3VuZENvbG9yPVwidXNlck1lc3NhZ2VCYWNrZ3JvdW5kXCI+UGx1Z2luPC9UZXh0PlxuICAgICAgICA8L1RleHQ+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPiDCtyB7aXRlbS5tYXJrZXRwbGFjZX08L1RleHQ+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPXshaXNTZWxlY3RlZH0+IMK3IHtzdGF0dXNJY29ufSA8L1RleHQ+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPXshaXNTZWxlY3RlZH0+e3N0YXR1c1RleHR9PC9UZXh0PlxuICAgICAgPC9Cb3g+XG4gICAgKVxuICB9XG5cbiAgLy8gTUNQIHNlcnZlclxuICBsZXQgc3RhdHVzSWNvbjogc3RyaW5nXG4gIGxldCBzdGF0dXNUZXh0OiBzdHJpbmdcblxuICBpZiAoaXRlbS5zdGF0dXMgPT09ICdjb25uZWN0ZWQnKSB7XG4gICAgc3RhdHVzSWNvbiA9IGNvbG9yKCdzdWNjZXNzJywgdGhlbWUpKGZpZ3VyZXMudGljaylcbiAgICBzdGF0dXNUZXh0ID0gJ2Nvbm5lY3RlZCdcbiAgfSBlbHNlIGlmIChpdGVtLnN0YXR1cyA9PT0gJ2Rpc2FibGVkJykge1xuICAgIHN0YXR1c0ljb24gPSBjb2xvcignaW5hY3RpdmUnLCB0aGVtZSkoZmlndXJlcy5yYWRpb09mZilcbiAgICBzdGF0dXNUZXh0ID0gJ2Rpc2FibGVkJ1xuICB9IGVsc2UgaWYgKGl0ZW0uc3RhdHVzID09PSAncGVuZGluZycpIHtcbiAgICBzdGF0dXNJY29uID0gY29sb3IoJ2luYWN0aXZlJywgdGhlbWUpKGZpZ3VyZXMucmFkaW9PZmYpXG4gICAgc3RhdHVzVGV4dCA9ICdjb25uZWN0aW5n4oCmJ1xuICB9IGVsc2UgaWYgKGl0ZW0uc3RhdHVzID09PSAnbmVlZHMtYXV0aCcpIHtcbiAgICBzdGF0dXNJY29uID0gY29sb3IoJ3dhcm5pbmcnLCB0aGVtZSkoZmlndXJlcy50cmlhbmdsZVVwT3V0bGluZSlcbiAgICBzdGF0dXNUZXh0ID0gJ0VudGVyIHRvIGF1dGgnXG4gIH0gZWxzZSB7XG4gICAgc3RhdHVzSWNvbiA9IGNvbG9yKCdlcnJvcicsIHRoZW1lKShmaWd1cmVzLmNyb3NzKVxuICAgIHN0YXR1c1RleHQgPSAnZmFpbGVkJ1xuICB9XG5cbiAgLy8gSW5kZW50ZWQgTUNQcyAoY2hpbGQgb2YgYSBwbHVnaW4pXG4gIGlmIChpdGVtLmluZGVudGVkKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxCb3g+XG4gICAgICAgIDxUZXh0IGNvbG9yPXtpc1NlbGVjdGVkID8gJ3N1Z2dlc3Rpb24nIDogdW5kZWZpbmVkfT5cbiAgICAgICAgICB7aXNTZWxlY3RlZCA/IGAke2ZpZ3VyZXMucG9pbnRlcn0gYCA6ICcgICd9XG4gICAgICAgIDwvVGV4dD5cbiAgICAgICAgPFRleHQgZGltQ29sb3I9eyFpc1NlbGVjdGVkfT7ilJQgPC9UZXh0PlxuICAgICAgICA8VGV4dCBjb2xvcj17aXNTZWxlY3RlZCA/ICdzdWdnZXN0aW9uJyA6IHVuZGVmaW5lZH0+e2l0ZW0ubmFtZX08L1RleHQ+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPXshaXNTZWxlY3RlZH0+XG4gICAgICAgICAgeycgJ31cbiAgICAgICAgICA8VGV4dCBiYWNrZ3JvdW5kQ29sb3I9XCJ1c2VyTWVzc2FnZUJhY2tncm91bmRcIj5NQ1A8L1RleHQ+XG4gICAgICAgIDwvVGV4dD5cbiAgICAgICAgPFRleHQgZGltQ29sb3I9eyFpc1NlbGVjdGVkfT4gwrcge3N0YXR1c0ljb259IDwvVGV4dD5cbiAgICAgICAgPFRleHQgZGltQ29sb3I9eyFpc1NlbGVjdGVkfT57c3RhdHVzVGV4dH08L1RleHQ+XG4gICAgICA8L0JveD5cbiAgICApXG4gIH1cblxuICByZXR1cm4gKFxuICAgIDxCb3g+XG4gICAgICA8VGV4dCBjb2xvcj17aXNTZWxlY3RlZCA/ICdzdWdnZXN0aW9uJyA6IHVuZGVmaW5lZH0+XG4gICAgICAgIHtpc1NlbGVjdGVkID8gYCR7ZmlndXJlcy5wb2ludGVyfSBgIDogJyAgJ31cbiAgICAgIDwvVGV4dD5cbiAgICAgIDxUZXh0IGNvbG9yPXtpc1NlbGVjdGVkID8gJ3N1Z2dlc3Rpb24nIDogdW5kZWZpbmVkfT57aXRlbS5uYW1lfTwvVGV4dD5cbiAgICAgIDxUZXh0IGRpbUNvbG9yPXshaXNTZWxlY3RlZH0+XG4gICAgICAgIHsnICd9XG4gICAgICAgIDxUZXh0IGJhY2tncm91bmRDb2xvcj1cInVzZXJNZXNzYWdlQmFja2dyb3VuZFwiPk1DUDwvVGV4dD5cbiAgICAgIDwvVGV4dD5cbiAgICAgIDxUZXh0IGRpbUNvbG9yPXshaXNTZWxlY3RlZH0+IMK3IHtzdGF0dXNJY29ufSA8L1RleHQ+XG4gICAgICA8VGV4dCBkaW1Db2xvcj17IWlzU2VsZWN0ZWR9PntzdGF0dXNUZXh0fTwvVGV4dD5cbiAgICA8L0JveD5cbiAgKVxufVxuIl0sIm1hcHBpbmdzIjoiO0FBQUEsT0FBT0EsT0FBTyxNQUFNLFNBQVM7QUFDN0IsT0FBTyxLQUFLQyxLQUFLLE1BQU0sT0FBTztBQUM5QixTQUFTQyxHQUFHLEVBQUVDLEtBQUssRUFBRUMsSUFBSSxFQUFFQyxRQUFRLFFBQVEsY0FBYztBQUN6RCxTQUFTQyxNQUFNLFFBQVEsNEJBQTRCO0FBQ25ELGNBQWNDLG9CQUFvQixRQUFRLG1CQUFtQjtBQUU3RCxLQUFLQyxLQUFLLEdBQUc7RUFDWEMsSUFBSSxFQUFFRixvQkFBb0I7RUFDMUJHLFVBQVUsRUFBRSxPQUFPO0FBQ3JCLENBQUM7QUFFRCxPQUFPLFNBQUFDLHFCQUFBQyxFQUFBO0VBQUEsTUFBQUMsQ0FBQSxHQUFBQyxFQUFBO0VBQThCO0lBQUFMLElBQUE7SUFBQUM7RUFBQSxJQUFBRSxFQUc3QjtFQUNOLE9BQUFHLEtBQUEsSUFBZ0JWLFFBQVEsQ0FBQyxDQUFDO0VBRTFCLElBQUlJLElBQUksQ0FBQU8sSUFBSyxLQUFLLFFBQVE7SUFFcEJDLEdBQUEsQ0FBQUEsVUFBQTtJQUNBQyxHQUFBLENBQUFBLFVBQUE7SUFH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LEVBQUEsR0FBQXpCLENBQUE7RUFBQTtFQUNTLE1BQUEwQixFQUFBLElBQUM3QixVQUFVO0VBQUEsSUFBQStCLEdBQUE7RUFBQSxJQUFBNUIsQ0FBQSxVQUFBMkMsWUFBQSxJQUFBM0MsQ0FBQSxVQUFBMEIsRUFBQTtJQUEzQkUsR0FBQSxJQUFDLElBQUksQ0FBVyxRQUFXLENBQVgsQ0FBQUYsRUFBVSxDQUFDLENBQUUsR0FBSXRCLGFBQVMsQ0FBRSxDQUFDLEVBQTVDLElBQUksQ0FBK0M7SUFBQUosQ0FBQSxRQUFBMkMsWUFBQTtJQUFBM0MsQ0FBQSxRQUFBMEIsRUFBQTtJQUFBMUIsQ0FBQSxRQUFBNEIsR0FBQTtFQUFBO0lBQUFBLEdBQUEsR0FBQTVCLENBQUE7RUFBQTtFQUNwQyxNQUFBNkIsR0FBQSxJQUFDaEMsVUFBVTtFQUFBLElBQUFpQyxHQUFBO0VBQUEsSUFBQTlCLENBQUEsVUFBQTRDLFlBQUEsSUFBQTVDLENBQUEsVUFBQTZCLEdBQUE7SUFBM0JDLEdBQUEsSUFBQyxJQUFJLENBQVcsUUFBVyxDQUFYLENBQUFELEdBQVUsQ0FBQyxDQUFHeEIsYUFBUyxDQUFFLEVBQXhDLElBQUksQ0FBMkM7SUFBQUwsQ0FBQSxRQUFBNEMsWUFBQTtJQUFBNUMsQ0FBQSxRQUFBNkIsR0FBQTtJQUFBN0IsQ0FBQSxRQUFBOEIsR0FBQTtFQUFBO0lBQUFBLEdBQUEsR0FBQTlCLENBQUE7RUFBQTtFQUFBLElBQUErQixHQUFBO0VBQUEsSUFBQS9CLENBQUEsVUFBQTRCLEdBQUEsSUFBQTVCLENBQUEsVUFBQThCLEdBQUEsSUFBQTlCLENBQUEsVUFBQVksRUFBQSxJQUFBWixDQUFBLFVBQUFtQixFQUFBLElBQUFuQixDQUFBLFVBQUF5QixFQUFBO0lBVmxETSxHQUFBLElBQUMsR0FBRyxDQUNGLENBQUFuQixFQUVNLENBQ04sQ0FBQU8sRUFBcUUsQ0FDckUsQ0FBQU0sRUFHTSxDQUNOLENBQUFHLEdBQW1ELENBQ25ELENBQUFFLEdBQStDLENBQ2pELEVBWEMsR0FBRyxDQVdFO0lBQUE5QixDQUFBLFFBQUE0QixHQUFBO0lBQUE1QixDQUFBLFFBQUE4QixHQUFBO0lBQUE5QixDQUFBLFFBQUFZLEVBQUE7SUFBQVosQ0FBQSxRQUFBbUIsRUFBQTtJQUFBbkIsQ0FBQSxRQUFBeUIsRUFBQTtJQUFBekIsQ0FBQSxRQUFBK0IsR0FBQTtFQUFBO0lBQUFBLEdBQUEsR0FBQS9CLENBQUE7RUFBQTtFQUFBLE9BWE4rQixHQVdNO0FBQUEiLCJpZ25vcmVMaXN0IjpbXX0=
|
src/commands/plugin/ValidatePlugin.tsx
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { c as _c } from "react/compiler-runtime";
|
| 2 |
+
import figures from 'figures';
|
| 3 |
+
import * as React from 'react';
|
| 4 |
+
import { useEffect } from 'react';
|
| 5 |
+
import { Box, Text } from '../../ink.js';
|
| 6 |
+
import { errorMessage } from '../../utils/errors.js';
|
| 7 |
+
import { logError } from '../../utils/log.js';
|
| 8 |
+
import { validateManifest } from '../../utils/plugins/validatePlugin.js';
|
| 9 |
+
import { plural } from '../../utils/stringUtils.js';
|
| 10 |
+
type Props = {
|
| 11 |
+
onComplete: (result?: string) => void;
|
| 12 |
+
path?: string;
|
| 13 |
+
};
|
| 14 |
+
export function ValidatePlugin(t0) {
|
| 15 |
+
const $ = _c(5);
|
| 16 |
+
const {
|
| 17 |
+
onComplete,
|
| 18 |
+
path
|
| 19 |
+
} = t0;
|
| 20 |
+
let t1;
|
| 21 |
+
let t2;
|
| 22 |
+
if ($[0] !== onComplete || $[1] !== path) {
|
| 23 |
+
t1 = () => {
|
| 24 |
+
const runValidation = async function runValidation() {
|
| 25 |
+
if (!path) {
|
| 26 |
+
onComplete("Usage: /plugin validate <path>\n\nValidate a plugin or marketplace manifest file or directory.\n\nExamples:\n /plugin validate .claude-plugin/plugin.json\n /plugin validate /path/to/plugin-directory\n /plugin validate .\n\nWhen given a directory, automatically validates .claude-plugin/marketplace.json\nor .claude-plugin/plugin.json (prefers marketplace if both exist).\n\nOr from the command line:\n claude plugin validate <path>");
|
| 27 |
+
return;
|
| 28 |
+
}
|
| 29 |
+
;
|
| 30 |
+
try {
|
| 31 |
+
const result = await validateManifest(path);
|
| 32 |
+
let output = "";
|
| 33 |
+
output = output + `Validating ${result.fileType} manifest: ${result.filePath}\n\n`;
|
| 34 |
+
output;
|
| 35 |
+
if (result.errors.length > 0) {
|
| 36 |
+
output = output + `${figures.cross} Found ${result.errors.length} ${plural(result.errors.length, "error")}:\n\n`;
|
| 37 |
+
output;
|
| 38 |
+
result.errors.forEach(error_0 => {
|
| 39 |
+
output = output + ` ${figures.pointer} ${error_0.path}: ${error_0.message}\n`;
|
| 40 |
+
output;
|
| 41 |
+
});
|
| 42 |
+
output = output + "\n";
|
| 43 |
+
output;
|
| 44 |
+
}
|
| 45 |
+
if (result.warnings.length > 0) {
|
| 46 |
+
output = output + `${figures.warning} Found ${result.warnings.length} ${plural(result.warnings.length, "warning")}:\n\n`;
|
| 47 |
+
output;
|
| 48 |
+
result.warnings.forEach(warning => {
|
| 49 |
+
output = output + ` ${figures.pointer} ${warning.path}: ${warning.message}\n`;
|
| 50 |
+
output;
|
| 51 |
+
});
|
| 52 |
+
output = output + "\n";
|
| 53 |
+
output;
|
| 54 |
+
}
|
| 55 |
+
if (result.success) {
|
| 56 |
+
if (result.warnings.length > 0) {
|
| 57 |
+
output = output + `${figures.tick} Validation passed with warnings\n`;
|
| 58 |
+
output;
|
| 59 |
+
} else {
|
| 60 |
+
output = output + `${figures.tick} Validation passed\n`;
|
| 61 |
+
output;
|
| 62 |
+
}
|
| 63 |
+
process.exitCode = 0;
|
| 64 |
+
} else {
|
| 65 |
+
output = output + `${figures.cross} Validation failed\n`;
|
| 66 |
+
output;
|
| 67 |
+
process.exitCode = 1;
|
| 68 |
+
}
|
| 69 |
+
onComplete(output);
|
| 70 |
+
} catch (t3) {
|
| 71 |
+
const error = t3;
|
| 72 |
+
process.exitCode = 2;
|
| 73 |
+
logError(error);
|
| 74 |
+
onComplete(`${figures.cross} Unexpected error during validation: ${errorMessage(error)}`);
|
| 75 |
+
}
|
| 76 |
+
};
|
| 77 |
+
runValidation();
|
| 78 |
+
};
|
| 79 |
+
t2 = [onComplete, path];
|
| 80 |
+
$[0] = onComplete;
|
| 81 |
+
$[1] = path;
|
| 82 |
+
$[2] = t1;
|
| 83 |
+
$[3] = t2;
|
| 84 |
+
} else {
|
| 85 |
+
t1 = $[2];
|
| 86 |
+
t2 = $[3];
|
| 87 |
+
}
|
| 88 |
+
useEffect(t1, t2);
|
| 89 |
+
let t3;
|
| 90 |
+
if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
|
| 91 |
+
t3 = <Box flexDirection="column"><Text>Running validation...</Text></Box>;
|
| 92 |
+
$[4] = t3;
|
| 93 |
+
} else {
|
| 94 |
+
t3 = $[4];
|
| 95 |
+
}
|
| 96 |
+
return t3;
|
| 97 |
+
}
|
| 98 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmaWd1cmVzIiwiUmVhY3QiLCJ1c2VFZmZlY3QiLCJCb3giLCJUZXh0IiwiZXJyb3JNZXNzYWdlIiwibG9nRXJyb3IiLCJ2YWxpZGF0ZU1hbmlmZXN0IiwicGx1cmFsIiwiUHJvcHMiLCJvbkNvbXBsZXRlIiwicmVzdWx0IiwicGF0aCIsIlZhbGlkYXRlUGx1Z2luIiwidDAiLCIkIiwiX2MiLCJ0MSIsInQyIiwicnVuVmFsaWRhdGlvbiIsIm91dHB1dCIsImZpbGVUeXBlIiwiZmlsZVBhdGgiLCJlcnJvcnMiLCJsZW5ndGgiLCJjcm9zcyIsImZvckVhY2giLCJlcnJvcl8wIiwicG9pbnRlciIsImVycm9yIiwibWVzc2FnZSIsIndhcm5pbmdzIiwid2FybmluZyIsInN1Y2Nlc3MiLCJ0aWNrIiwicHJvY2VzcyIsImV4aXRDb2RlIiwidDMiLCJTeW1ib2wiLCJmb3IiXSwic291cmNlcyI6WyJWYWxpZGF0ZVBsdWdpbi50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZpZ3VyZXMgZnJvbSAnZmlndXJlcydcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgdXNlRWZmZWN0IH0gZnJvbSAncmVhY3QnXG5pbXBvcnQgeyBCb3gsIFRleHQgfSBmcm9tICcuLi8uLi9pbmsuanMnXG5pbXBvcnQgeyBlcnJvck1lc3NhZ2UgfSBmcm9tICcuLi8uLi91dGlscy9lcnJvcnMuanMnXG5pbXBvcnQgeyBsb2dFcnJvciB9IGZyb20gJy4uLy4uL3V0aWxzL2xvZy5qcydcbmltcG9ydCB7IHZhbGlkYXRlTWFuaWZlc3QgfSBmcm9tICcuLi8uLi91dGlscy9wbHVnaW5zL3ZhbGlkYXRlUGx1Z2luLmpzJ1xuaW1wb3J0IHsgcGx1cmFsIH0gZnJvbSAnLi4vLi4vdXRpbHMvc3RyaW5nVXRpbHMuanMnXG5cbnR5cGUgUHJvcHMgPSB7XG4gIG9uQ29tcGxldGU6IChyZXN1bHQ/OiBzdHJpbmcpID0+IHZvaWRcbiAgcGF0aD86IHN0cmluZ1xufVxuXG5leHBvcnQgZnVuY3Rpb24gVmFsaWRhdGVQbHVnaW4oeyBvbkNvbXBsZXRlLCBwYXRoIH06IFByb3BzKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBhc3luYyBmdW5jdGlvbiBydW5WYWxpZGF0aW9uKCkge1xuICAgICAgLy8gSWYgbm8gcGF0aCBwcm92aWRlZCwgc2hvdyB1c2FnZVxuICAgICAgaWYgKCFwYXRoKSB7XG4gICAgICAgIG9uQ29tcGxldGUoXG4gICAgICAgICAgJ1VzYWdlOiAvcGx1Z2luIHZhbGlkYXRlIDxwYXRoPlxcblxcbicgK1xuICAgICAgICAgICAgJ1ZhbGlkYXRlIGEgcGx1Z2luIG9yIG1hcmtldHBsYWNlIG1hbmlmZXN0IGZpbGUgb3IgZGlyZWN0b3J5LlxcblxcbicgK1xuICAgICAgICAgICAgJ0V4YW1wbGVzOlxcbicgK1xuICAgICAgICAgICAgJyAgL3BsdWdpbiB2YWxpZGF0ZSAuY2xhdWRlLXBsdWdpbi9wbHVnaW4uanNvblxcbicgK1xuICAgICAgICAgICAgJyAgL3BsdWdpbiB2YWxpZGF0ZSAvcGF0aC90by9wbHVnaW4tZGlyZWN0b3J5XFxuJyArXG4gICAgICAgICAgICAnICAvcGx1Z2luIHZhbGlkYXRlIC5cXG5cXG4nICtcbiAgICAgICAgICAgICdXaGVuIGdpdmVuIGEgZGlyZWN0b3J5LCBhdXRvbWF0aWNhbGx5IHZhbGlkYXRlcyAuY2xhdWRlLXBsdWdpbi9tYXJrZXRwbGFjZS5qc29uXFxuJyArXG4gICAgICAgICAgICAnb3IgLmNsYXVkZS1wbHVnaW4vcGx1Z2luLmpzb24gKHByZWZlcnMgbWFya2V0cGxhY2UgaWYgYm90aCBleGlzdCkuXFxuXFxuJyArXG4gICAgICAgICAgICAnT3IgZnJvbSB0aGUgY29tbWFuZCBsaW5lOlxcbicgK1xuICAgICAgICAgICAgJyAgY2xhdWRlIHBsdWdpbiB2YWxpZGF0ZSA8cGF0aD4nLFxuICAgICAgICApXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2YWxpZGF0ZU1hbmlmZXN0KHBhdGgpXG5cbiAgICAgICAgbGV0IG91dHB1dCA9ICcnXG5cbiAgICAgICAgLy8gQWRkIGhlYWRlclxuICAgICAgICBvdXRwdXQgKz0gYFZhbGlkYXRpbmcgJHtyZXN1bHQuZmlsZVR5cGV9IG1hbmlmZXN0OiAke3Jlc3VsdC5maWxlUGF0aH1cXG5cXG5gXG5cbiAgICAgICAgLy8gU2hvdyBlcnJvcnNcbiAgICAgICAgaWYgKHJlc3VsdC5lcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIG91dHB1dCArPSBgJHtmaWd1cmVzLmNyb3NzfSBGb3VuZCAke3Jlc3VsdC5lcnJvcnMubGVuZ3RofSAke3BsdXJhbChyZXN1bHQuZXJyb3JzLmxlbmd0aCwgJ2Vycm9yJyl9OlxcblxcbmBcblxuICAgICAgICAgIHJlc3VsdC5lcnJvcnMuZm9yRWFjaChlcnJvciA9PiB7XG4gICAgICAgICAgICBvdXRwdXQgKz0gYCAgJHtmaWd1cmVzLnBvaW50ZXJ9ICR7ZXJyb3IucGF0aH06ICR7ZXJyb3IubWVzc2FnZX1cXG5gXG4gICAgICAgICAgfSlcblxuICAgICAgICAgIG91dHB1dCArPSAnXFxuJ1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2hvdyB3YXJuaW5nc1xuICAgICAgICBpZiAocmVzdWx0Lndhcm5pbmdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBvdXRwdXQgKz0gYCR7ZmlndXJlcy53YXJuaW5nfSBGb3VuZCAke3Jlc3VsdC53YXJuaW5ncy5sZW5ndGh9ICR7cGx1cmFsKHJlc3VsdC53YXJuaW5ncy5sZW5ndGgsICd3YXJuaW5nJyl9OlxcblxcbmBcblxuICAgICAgICAgIHJlc3VsdC53YXJuaW5ncy5mb3JFYWNoKHdhcm5pbmcgPT4ge1xuICAgICAgICAgICAgb3V0cHV0ICs9IGAgICR7ZmlndXJlcy5wb2ludGVyfSAke3dhcm5pbmcucGF0aH06ICR7d2FybmluZy5tZXNzYWdlfVxcbmBcbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgb3V0cHV0ICs9ICdcXG4nXG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaG93IHN1Y2Nlc3Mgb3IgZmFpbHVyZVxuICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICBpZiAocmVzdWx0Lndhcm5pbmdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIG91dHB1dCArPSBgJHtmaWd1cmVzLnRpY2t9IFZhbGlkYXRpb24gcGFzc2VkIHdpdGggd2FybmluZ3NcXG5gXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG91dHB1dCArPSBgJHtmaWd1cmVzLnRpY2t9IFZhbGlkYXRpb24gcGFzc2VkXFxuYFxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEV4aXQgd2l0aCBjb2RlIDAgKHN1Y2Nlc3MpXG4gICAgICAgICAgcHJvY2Vzcy5leGl0Q29kZSA9IDBcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvdXRwdXQgKz0gYCR7ZmlndXJlcy5jcm9zc30gVmFsaWRhdGlvbiBmYWlsZWRcXG5gXG5cbiAgICAgICAgICAvLyBFeGl0IHdpdGggY29kZSAxICh2YWxpZGF0aW9uIGZhaWx1cmUpXG4gICAgICAgICAgcHJvY2Vzcy5leGl0Q29kZSA9IDFcbiAgICAgICAgfVxuXG4gICAgICAgIG9uQ29tcGxldGUob3V0cHV0KVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gRXhpdCB3aXRoIGNvZGUgMiAodW5leHBlY3RlZCBlcnJvcilcbiAgICAgICAgcHJvY2Vzcy5leGl0Q29kZSA9IDJcblxuICAgICAgICBsb2dFcnJvcihlcnJvcilcblxuICAgICAgICBvbkNvbXBsZXRlKFxuICAgICAgICAgIGAke2ZpZ3VyZXMuY3Jvc3N9IFVuZXhwZWN0ZWQgZXJyb3IgZHVyaW5nIHZhbGlkYXRpb246ICR7ZXJyb3JNZXNzYWdlKGVycm9yKX1gLFxuICAgICAgICApXG4gICAgICB9XG4gICAgfVxuXG4gICAgdm9pZCBydW5WYWxpZGF0aW9uKClcbiAgfSwgW29uQ29tcGxldGUsIHBhdGhdKVxuXG4gIHJldHVybiAoXG4gICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCI+XG4gICAgICA8VGV4dD5SdW5uaW5nIHZhbGlkYXRpb24uLi48L1RleHQ+XG4gICAgPC9Cb3g+XG4gIClcbn1cbiJdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU9BLE9BQU8sTUFBTSxTQUFTO0FBQzdCLE9BQU8sS0FBS0MsS0FBSyxNQUFNLE9BQU87QUFDOUIsU0FBU0MsU0FBUyxRQUFRLE9BQU87QUFDakMsU0FBU0MsR0FBRyxFQUFFQyxJQUFJLFFBQVEsY0FBYztBQUN4QyxTQUFTQyxZQUFZLFFBQVEsdUJBQXVCO0FBQ3BELFNBQVNDLFFBQVEsUUFBUSxvQkFBb0I7QUFDN0MsU0FBU0MsZ0JBQWdCLFFBQVEsdUNBQXVDO0FBQ3hFLFNBQVNDLE1BQU0sUUFBUSw0QkFBNEI7QUFFbkQsS0FBS0MsS0FBSyxHQUFHO0VBQ1hDLFVBQVUsRUFBRSxDQUFDQyxNQUFlLENBQVIsRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJO0VBQ3JDQyxJQUFJLENBQUMsRUFBRSxNQUFNO0FBQ2YsQ0FBQztBQUVELE9BQU8sU0FBQUMsZUFBQUMsRUFBQTtFQUFBLE1BQUFDLENBQUEsR0FBQUMsRUFBQTtFQUF3QjtJQUFBTixVQUFBO0lBQUFFO0VBQUEsSUFBQUUsRUFBMkI7RUFBQSxJQUFBRyxFQUFBO0VBQUEsSUFBQUMsRUFBQTtFQUFBLElBQUFILENBQUEsUUFBQUwsVUFBQSxJQUFBSyxDQUFBLFFBQUFILElBQUE7SUFDOUNLLEVBQUEsR0FBQUEsQ0FBQTtNQUNSLE1BQUFFLGFBQUEsa0JBQUFBLGNBQUE7UUFFRSxJQUFJLENBQUNQLElBQUk7VUFDUEYsVUFBVSxDQUNSLHFiQVVGLENBQUM7VUFBQTtRQUFBO1FBRUY7UUFFRDtVQUNFLE1BQUFDLE1BQUEsR0FBZSxNQUFNSixnQkFBZ0IsQ0FBQ0ssSUFBSSxDQUFDO1VBRTNDLElBQUFRLE1BQUEsR0FBYSxFQUFFO1VBR2ZBLE1BQUEsR0FBQUEsTUFBTSxHQUFJLGNBQWNULE1BQU0sQ0FBQVUsUUFBUyxjQUFjVixNQUFNLENBQUFXLFFBQVMsTUFBTTtVQUExRUYsTUFBMEU7VUFHMUUsSUFBSVQsTUFBTSxDQUFBWSxNQUFPLENBQUFDLE1BQU8sR0FBRyxDQUFDO1lBQzFCSixNQUFBLEdBQUFBLE1BQU0sR0FBSSxHQUFHcEIsT0FBTyxDQUFBeUIsS0FBTSxVQUFVZCxNQUFNLENBQUFZLE1BQU8sQ0FBQUMsTUFBTyxJQUFJaEIsTUFBTSxDQUFDRyxNQUFNLENBQUFZLE1BQU8sQ0FBQUMsTUFBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO1lBQXhHSixNQUF3RztZQUV4R1QsTUFBTSxDQUFBWSxNQUFPLENBQUFHLE9BQVEsQ0FBQ0MsT0FBQTtjQUNwQlAsTUFBQSxHQUFBQSxNQUFNLEdBQUksS0FBS3BCLE9BQU8sQ0FBQTRCLE9BQVEsSUFBSUMsT0FBSyxDQUFBakIsSUFBSyxLQUFLaUIsT0FBSyxDQUFBQyxPQUFRLElBQUk7Y0FBbEVWLE1BQWtFO1lBQUEsQ0FDbkUsQ0FBQztZQUVGQSxNQUFBLEdBQUFBLE1BQU0sR0FBSSxJQUFJO1lBQWRBLE1BQWM7VUFBQTtVQUloQixJQUFJVCxNQUFNLENBQUFvQixRQUFTLENBQUFQLE1BQU8sR0FBRyxDQUFDO1lBQzVCSixNQUFBLEdBQUFBLE1BQU0sR0FBSSxHQUFHcEIsT0FBTyxDQUFBZ0MsT0FBUSxVQUFVckIsTUFBTSxDQUFBb0IsUUFBUyxDQUFBUCxNQUFPLElBQUloQixNQUFNLENBQUNHLE1BQU0sQ0FBQW9CLFFBQVMsQ0FBQVAsTUFBTyxFQUFFLFNBQVMsQ0FBQyxPQUFPO1lBQWhISixNQUFnSDtZQUVoSFQsTUFBTSxDQUFBb0IsUUFBUyxDQUFBTCxPQUFRLENBQUNNLE9BQUE7Y0FDdEJaLE1BQUEsR0FBQUEsTUFBTSxHQUFJLEtBQUtwQixPQUFPLENBQUE0QixPQUFRLElBQUlJLE9BQU8sQ0FBQXBCLElBQUssS0FBS29CLE9BQU8sQ0FBQUYsT0FBUSxJQUFJO2NBQXRFVixNQUFzRTtZQUFBLENBQ3ZFLENBQUM7WUFFRkEsTUFBQSxHQUFBQSxNQUFNLEdBQUksSUFBSTtZQUFkQSxNQUFjO1VBQUE7VUFJaEIsSUFBSVQsTUFBTSxDQUFBc0IsT0FBUTtZQUNoQixJQUFJdEIsTUFBTSxDQUFBb0IsUUFBUyxDQUFBUCxNQUFPLEdBQUcsQ0FBQztjQUM1QkosTUFBQSxHQUFBQSxNQUFNLEdBQUksR0FBR3BCLE9BQU8sQ0FBQWtDLElBQUssb0NBQW9DO2NBQTdEZCxNQUE2RDtZQUFBO2NBRTdEQSxNQUFBLEdBQUFBLE1BQU0sR0FBSSxHQUFHcEIsT0FBTyxDQUFBa0MsSUFBSyxzQkFBc0I7Y0FBL0NkLE1BQStDO1lBQUE7WUFJakRlLE9BQU8sQ0FBQUMsUUFBQSxHQUFZLENBQUg7VUFBQTtZQUVoQmhCLE1BQUEsR0FBQUEsTUFBTSxHQUFJLEdBQUdwQixPQUFPLENBQUF5QixLQUFNLHNCQUFzQjtZQUFoREwsTUFBZ0Q7WUFHaERlLE9BQU8sQ0FBQUMsUUFBQSxHQUFZLENBQUg7VUFBQTtVQUdsQjFCLFVBQVUsQ0FBQ1UsTUFBTSxDQUFDO1FBQUEsU0FBQWlCLEVBQUE7VUFDWFIsS0FBQSxDQUFBQSxLQUFBLENBQUFBLENBQUEsQ0FBQUEsRUFBSztVQUVaTSxPQUFPLENBQUFDLFFBQUEsR0FBWSxDQUFIO1VBRWhCOUIsUUFBUSxDQUFDdUIsS0FBSyxDQUFDO1VBRWZuQixVQUFVLENBQ1IsR0FBR1YsT0FBTyxDQUFBeUIsS0FBTSx3Q0FBd0NwQixZQUFZLENBQUN3QixLQUFLLENBQUMsRUFDN0UsQ0FBQztRQUFBO01BQ0YsQ0FDRjtNQUVJVixhQUFhLENBQUMsQ0FBQztJQUFBLENBQ3JCO0lBQUVELEVBQUEsSUFBQ1IsVUFBVSxFQUFFRSxJQUFJLENBQUM7SUFBQUcsQ0FBQSxNQUFBTCxVQUFBO0lBQUFLLENBQUEsTUFBQUgsSUFBQTtJQUFBRyxDQUFBLE1BQUFFLEVBQUE7SUFBQUYsQ0FBQSxNQUFBRyxFQUFBO0VBQUE7SUFBQUQsRUFBQSxHQUFBRixDQUFBO0lBQUFHLEVBQUEsR0FBQUgsQ0FBQTtFQUFBO0VBaEZyQmIsU0FBUyxDQUFDZSxFQWdGVCxFQUFFQyxFQUFrQixDQUFDO0VBQUEsSUFBQW1CLEVBQUE7RUFBQSxJQUFBdEIsQ0FBQSxRQUFBdUIsTUFBQSxDQUFBQyxHQUFBO0lBR3BCRixFQUFBLElBQUMsR0FBRyxDQUFlLGFBQVEsQ0FBUixRQUFRLENBQ3pCLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUExQixJQUFJLENBQ1AsRUFGQyxHQUFHLENBRUU7SUFBQXRCLENBQUEsTUFBQXNCLEVBQUE7RUFBQTtJQUFBQSxFQUFBLEdBQUF0QixDQUFBO0VBQUE7RUFBQSxPQUZOc0IsRUFFTTtBQUFBIiwiaWdub3JlTGlzdCI6W119
|
src/commands/plugin/index.tsx
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Command } from '../../commands.js';
|
| 2 |
+
const plugin = {
|
| 3 |
+
type: 'local-jsx',
|
| 4 |
+
name: 'plugin',
|
| 5 |
+
aliases: ['plugins', 'marketplace'],
|
| 6 |
+
description: 'Manage Claude Code plugins',
|
| 7 |
+
immediate: true,
|
| 8 |
+
load: () => import('./plugin.js')
|
| 9 |
+
} satisfies Command;
|
| 10 |
+
export default plugin;
|
| 11 |
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDb21tYW5kIiwicGx1Z2luIiwidHlwZSIsIm5hbWUiLCJhbGlhc2VzIiwiZGVzY3JpcHRpb24iLCJpbW1lZGlhdGUiLCJsb2FkIl0sInNvdXJjZXMiOlsiaW5kZXgudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgQ29tbWFuZCB9IGZyb20gJy4uLy4uL2NvbW1hbmRzLmpzJ1xuXG5jb25zdCBwbHVnaW4gPSB7XG4gIHR5cGU6ICdsb2NhbC1qc3gnLFxuICBuYW1lOiAncGx1Z2luJyxcbiAgYWxpYXNlczogWydwbHVnaW5zJywgJ21hcmtldHBsYWNlJ10sXG4gIGRlc2NyaXB0aW9uOiAnTWFuYWdlIENsYXVkZSBDb2RlIHBsdWdpbnMnLFxuICBpbW1lZGlhdGU6IHRydWUsXG4gIGxvYWQ6ICgpID0+IGltcG9ydCgnLi9wbHVnaW4uanMnKSxcbn0gc2F0aXNmaWVzIENvbW1hbmRcblxuZXhwb3J0IGRlZmF1bHQgcGx1Z2luXG4iXSwibWFwcGluZ3MiOiJBQUFBLGNBQWNBLE9BQU8sUUFBUSxtQkFBbUI7QUFFaEQsTUFBTUMsTUFBTSxHQUFHO0VBQ2JDLElBQUksRUFBRSxXQUFXO0VBQ2pCQyxJQUFJLEVBQUUsUUFBUTtFQUNkQyxPQUFPLEVBQUUsQ0FBQyxTQUFTLEVBQUUsYUFBYSxDQUFDO0VBQ25DQyxXQUFXLEVBQUUsNEJBQTRCO0VBQ3pDQyxTQUFTLEVBQUUsSUFBSTtFQUNmQyxJQUFJLEVBQUVBLENBQUEsS0FBTSxNQUFNLENBQUMsYUFBYTtBQUNsQyxDQUFDLFdBQVdQLE9BQU87QUFFbkIsZUFBZUMsTUFBTSIsImlnbm9yZUxpc3QiOltdfQ==
|
src/commands/plugin/parseArgs.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Parse plugin subcommand arguments into structured commands
|
| 2 |
+
export type ParsedCommand =
|
| 3 |
+
| { type: 'menu' }
|
| 4 |
+
| { type: 'help' }
|
| 5 |
+
| { type: 'install'; marketplace?: string; plugin?: string }
|
| 6 |
+
| { type: 'manage' }
|
| 7 |
+
| { type: 'uninstall'; plugin?: string }
|
| 8 |
+
| { type: 'enable'; plugin?: string }
|
| 9 |
+
| { type: 'disable'; plugin?: string }
|
| 10 |
+
| { type: 'validate'; path?: string }
|
| 11 |
+
| {
|
| 12 |
+
type: 'marketplace'
|
| 13 |
+
action?: 'add' | 'remove' | 'update' | 'list'
|
| 14 |
+
target?: string
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
export function parsePluginArgs(args?: string): ParsedCommand {
|
| 18 |
+
if (!args) {
|
| 19 |
+
return { type: 'menu' }
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
const parts = args.trim().split(/\s+/)
|
| 23 |
+
const command = parts[0]?.toLowerCase()
|
| 24 |
+
|
| 25 |
+
switch (command) {
|
| 26 |
+
case 'help':
|
| 27 |
+
case '--help':
|
| 28 |
+
case '-h':
|
| 29 |
+
return { type: 'help' }
|
| 30 |
+
|
| 31 |
+
case 'install':
|
| 32 |
+
case 'i': {
|
| 33 |
+
const target = parts[1]
|
| 34 |
+
if (!target) {
|
| 35 |
+
return { type: 'install' }
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
// Check if it's in format plugin@marketplace
|
| 39 |
+
if (target.includes('@')) {
|
| 40 |
+
const [plugin, marketplace] = target.split('@')
|
| 41 |
+
return { type: 'install', plugin, marketplace }
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
// Check if the target looks like a marketplace (URL or path)
|
| 45 |
+
const isMarketplace =
|
| 46 |
+
target.startsWith('http://') ||
|
| 47 |
+
target.startsWith('https://') ||
|
| 48 |
+
target.startsWith('file://') ||
|
| 49 |
+
target.includes('/') ||
|
| 50 |
+
target.includes('\\')
|
| 51 |
+
|
| 52 |
+
if (isMarketplace) {
|
| 53 |
+
// This is a marketplace URL/path, no plugin specified
|
| 54 |
+
return { type: 'install', marketplace: target }
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
// Otherwise treat it as a plugin name
|
| 58 |
+
return { type: 'install', plugin: target }
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
case 'manage':
|
| 62 |
+
return { type: 'manage' }
|
| 63 |
+
|
| 64 |
+
case 'uninstall':
|
| 65 |
+
return { type: 'uninstall', plugin: parts[1] }
|
| 66 |
+
|
| 67 |
+
case 'enable':
|
| 68 |
+
return { type: 'enable', plugin: parts[1] }
|
| 69 |
+
|
| 70 |
+
case 'disable':
|
| 71 |
+
return { type: 'disable', plugin: parts[1] }
|
| 72 |
+
|
| 73 |
+
case 'validate': {
|
| 74 |
+
const target = parts.slice(1).join(' ').trim()
|
| 75 |
+
return { type: 'validate', path: target || undefined }
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
case 'marketplace':
|
| 79 |
+
case 'market': {
|
| 80 |
+
const action = parts[1]?.toLowerCase()
|
| 81 |
+
const target = parts.slice(2).join(' ')
|
| 82 |
+
|
| 83 |
+
switch (action) {
|
| 84 |
+
case 'add':
|
| 85 |
+
return { type: 'marketplace', action: 'add', target }
|
| 86 |
+
case 'remove':
|
| 87 |
+
case 'rm':
|
| 88 |
+
return { type: 'marketplace', action: 'remove', target }
|
| 89 |
+
case 'update':
|
| 90 |
+
return { type: 'marketplace', action: 'update', target }
|
| 91 |
+
case 'list':
|
| 92 |
+
return { type: 'marketplace', action: 'list' }
|
| 93 |
+
default:
|
| 94 |
+
// No action specified, show marketplace menu
|
| 95 |
+
return { type: 'marketplace' }
|
| 96 |
+
}
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
default:
|
| 100 |
+
// Unknown command, show menu
|
| 101 |
+
return { type: 'menu' }
|
| 102 |
+
}
|
| 103 |
+
}
|