claudeup 4.18.0 → 4.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/claudeup.js +43 -19
- package/package.json +14 -19
- package/scripts/build-binaries.ts +77 -0
- package/scripts/check-optional-deps.ts +49 -0
- package/scripts/test-isolated.ts +43 -0
- package/src/__tests__/alias-adopt.test.ts +364 -0
- package/src/__tests__/alias-parser.test.ts +92 -0
- package/src/__tests__/alias-shell-writer.test.ts +7 -0
- package/src/__tests__/alias-store.test.ts +77 -0
- package/src/__tests__/cli-router.test.ts +65 -0
- package/src/__tests__/conventions-integration.test.ts +745 -0
- package/src/__tests__/conventions-manager.test.ts +1172 -0
- package/src/__tests__/doctor-bins.test.ts +35 -0
- package/src/__tests__/doctor.test.ts +450 -0
- package/src/__tests__/dual-write-prevention.test.ts +14 -4
- package/src/__tests__/file-locking.test.ts +208 -0
- package/src/__tests__/gitignore-prerun.test.ts +1 -0
- package/src/__tests__/install-command.test.ts +81 -0
- package/src/__tests__/install-plan.test.ts +98 -0
- package/src/__tests__/manifest.test.ts +136 -0
- package/src/__tests__/marketplace-refresh.test.ts +267 -0
- package/src/__tests__/plugin-requires.test.ts +133 -0
- package/src/__tests__/plugin-setup.test.ts +118 -0
- package/src/__tests__/profile-command.test.ts +116 -0
- package/src/__tests__/profile-materializer.test.ts +82 -0
- package/src/__tests__/profile-sync.test.ts +136 -0
- package/src/__tests__/registry-version-resolution.test.ts +74 -0
- package/src/__tests__/resolve-executable.test.ts +42 -0
- package/src/__tests__/resolver.test.ts +218 -0
- package/src/__tests__/symlink-manager.test.ts +99 -0
- package/src/__tests__/toolchain.test.ts +56 -0
- package/src/cli/claude.ts +21 -0
- package/src/cli/doctor.ts +132 -0
- package/src/cli/install.ts +360 -0
- package/src/cli/profile.ts +166 -0
- package/src/cli/router.ts +107 -0
- package/src/cli/update.ts +85 -0
- package/src/data/alias-flags.ts +11 -1
- package/src/data/cli-tools.ts +7 -7
- package/src/data/gitignore-defaults.ts +4 -0
- package/src/data/marketplaces.ts +12 -0
- package/src/data/predefined-profiles.ts +3 -4
- package/src/main.tsx +11 -154
- package/src/prerunner/index.ts +62 -27
- package/src/services/alias-shell-writer.ts +382 -8
- package/src/services/alias-store.ts +60 -0
- package/src/services/claude-cli.ts +19 -22
- package/src/services/claude-settings.ts +99 -26
- package/src/services/conventions-manager.ts +865 -0
- package/src/services/doctor-bins.ts +49 -0
- package/src/services/doctor.ts +509 -0
- package/src/services/install-plan.ts +107 -0
- package/src/services/manifest.ts +166 -0
- package/src/services/marketplace-refresh.ts +173 -0
- package/src/services/plugin-manager.ts +7 -1
- package/src/services/plugin-requires.ts +215 -0
- package/src/services/plugin-setup.ts +61 -4
- package/src/services/plugin-version-check.ts +9 -4
- package/src/services/profile-materializer.ts +61 -0
- package/src/services/profile-sync.ts +150 -0
- package/src/services/resolver.ts +293 -0
- package/src/services/symlink-manager.ts +146 -0
- package/src/services/toolchain.ts +97 -0
- package/src/services/version-check.ts +10 -11
- package/src/types/index.ts +138 -31
- package/src/ui/App.tsx +16 -11
- package/src/ui/components/FlagDetailEditor.tsx +0 -0
- package/src/ui/components/modals/ConfirmModal.tsx +1 -1
- package/src/ui/screens/AliasScreen.tsx +491 -359
- package/src/ui/screens/CliToolsScreen.tsx +11 -3
- package/src/ui/screens/PluginsScreen.tsx +3 -1
- package/src/ui/screens/index.ts +0 -1
- package/src/ui/state/reducer.ts +6 -102
- package/src/ui/state/types.ts +8 -35
- package/src/utils/command-utils.ts +23 -0
- package/src/utils/file-locking.ts +144 -0
- package/src/data/alias-flags.js +0 -196
- package/src/data/cli-tools.js +0 -123
- package/src/data/gitignore-defaults.js +0 -24
- package/src/data/gitignore-reasons.js +0 -97
- package/src/data/gitignore-templates.js +0 -21
- package/src/data/marketplaces.js +0 -138
- package/src/data/mcp-servers.js +0 -509
- package/src/data/predefined-profiles.js +0 -248
- package/src/data/settings-catalog.js +0 -625
- package/src/data/skill-repos.js +0 -160
- package/src/data/statuslines.js +0 -159
- package/src/data/statuslines.ts +0 -188
- package/src/index.js +0 -4
- package/src/index.ts +0 -5
- package/src/main.js +0 -170
- package/src/prerunner/index.js +0 -252
- package/src/services/alias-settings.js +0 -51
- package/src/services/alias-shell-writer.js +0 -764
- package/src/services/alias-store.js +0 -77
- package/src/services/claude-cli.js +0 -189
- package/src/services/claude-runner.js +0 -28
- package/src/services/claude-settings.js +0 -1223
- package/src/services/gitignore-detector.js +0 -155
- package/src/services/gitignore-fixer.js +0 -231
- package/src/services/gitignore-prerun.js +0 -46
- package/src/services/gitignore-resolver.js +0 -143
- package/src/services/gitignore-service.js +0 -117
- package/src/services/local-marketplace.js +0 -339
- package/src/services/marketplace-fetcher.js +0 -96
- package/src/services/marketplace-sync.js +0 -94
- package/src/services/mcp-registry.js +0 -87
- package/src/services/plugin-manager.js +0 -473
- package/src/services/plugin-mcp-config.js +0 -177
- package/src/services/plugin-setup.js +0 -444
- package/src/services/plugin-version-check.js +0 -262
- package/src/services/profiles.js +0 -161
- package/src/services/settings-manager.js +0 -243
- package/src/services/skills-manager.js +0 -393
- package/src/services/skillsmp-client.js +0 -87
- package/src/services/update-cache.js +0 -52
- package/src/services/version-check.js +0 -99
- package/src/types/gitignore.js +0 -6
- package/src/types/index.js +0 -1
- package/src/ui/App.js +0 -346
- package/src/ui/adapters/pluginsAdapter.js +0 -139
- package/src/ui/adapters/settingsAdapter.js +0 -111
- package/src/ui/adapters/skillsAdapter.js +0 -154
- package/src/ui/components/CategoryHeader.js +0 -9
- package/src/ui/components/EmptyFilterState.js +0 -4
- package/src/ui/components/ScopeIndicator.js +0 -30
- package/src/ui/components/ScrollableList.js +0 -36
- package/src/ui/components/SearchInput.js +0 -19
- package/src/ui/components/StyledText.js +0 -39
- package/src/ui/components/TabBar.js +0 -19
- package/src/ui/components/layout/FooterHints.js +0 -29
- package/src/ui/components/layout/Panel.js +0 -6
- package/src/ui/components/layout/ProgressBar.js +0 -14
- package/src/ui/components/layout/ScopeTabs.js +0 -6
- package/src/ui/components/layout/ScreenLayout.js +0 -16
- package/src/ui/components/layout/index.js +0 -5
- package/src/ui/components/modals/ConfirmModal.js +0 -14
- package/src/ui/components/modals/InputModal.js +0 -5
- package/src/ui/components/modals/LoadingModal.js +0 -17
- package/src/ui/components/modals/MessageModal.js +0 -16
- package/src/ui/components/modals/ModalContainer.js +0 -137
- package/src/ui/components/modals/SelectModal.js +0 -18
- package/src/ui/components/modals/VersionMismatchModal.js +0 -36
- package/src/ui/components/modals/index.js +0 -6
- package/src/ui/components/primitives/ActionHints.js +0 -13
- package/src/ui/components/primitives/DetailSection.js +0 -7
- package/src/ui/components/primitives/KeyValueLine.js +0 -8
- package/src/ui/components/primitives/ListCategoryRow.js +0 -8
- package/src/ui/components/primitives/MetaText.js +0 -8
- package/src/ui/components/primitives/ScopeDetail.js +0 -32
- package/src/ui/components/primitives/ScopeSquares.js +0 -11
- package/src/ui/components/primitives/SelectableRow.js +0 -5
- package/src/ui/components/primitives/index.js +0 -8
- package/src/ui/hooks/index.js +0 -4
- package/src/ui/hooks/useAsyncData.js +0 -77
- package/src/ui/hooks/useGitignoreModal.js +0 -74
- package/src/ui/hooks/useKeyboard.js +0 -13
- package/src/ui/hooks/useKeyboardHandler.js +0 -39
- package/src/ui/hooks/useMismatchModal.js +0 -77
- package/src/ui/registry.js +0 -1
- package/src/ui/renderers/cliToolRenderers.js +0 -54
- package/src/ui/renderers/gitignoreRenderers.js +0 -46
- package/src/ui/renderers/mcpRenderers.js +0 -26
- package/src/ui/renderers/pluginRenderers.js +0 -124
- package/src/ui/renderers/profileRenderers.js +0 -177
- package/src/ui/renderers/settingsRenderers.js +0 -73
- package/src/ui/renderers/skillRenderers.js +0 -138
- package/src/ui/screens/AliasScreen.js +0 -1008
- package/src/ui/screens/CliToolsScreen.js +0 -338
- package/src/ui/screens/EnvVarsScreen.js +0 -152
- package/src/ui/screens/GitignoreScreen.js +0 -328
- package/src/ui/screens/McpRegistryScreen.js +0 -238
- package/src/ui/screens/McpScreen.js +0 -176
- package/src/ui/screens/ModelSelectorScreen.js +0 -296
- package/src/ui/screens/ModelSelectorScreen.tsx +0 -444
- package/src/ui/screens/PluginsScreen.js +0 -766
- package/src/ui/screens/ProfilesScreen.js +0 -298
- package/src/ui/screens/SkillsScreen.js +0 -549
- package/src/ui/screens/StatusLineScreen.js +0 -206
- package/src/ui/screens/StatusLineScreen.tsx +0 -416
- package/src/ui/screens/index.js +0 -10
- package/src/ui/state/AnimationContext.js +0 -34
- package/src/ui/state/AppContext.js +0 -162
- package/src/ui/state/DimensionsContext.js +0 -71
- package/src/ui/state/reducer.js +0 -543
- package/src/ui/state/types.js +0 -1
- package/src/ui/theme.js +0 -47
- package/src/utils/clipboard.js +0 -56
- package/src/utils/command-utils.js +0 -19
- package/src/utils/fuzzy-search.js +0 -101
- package/src/utils/string-utils.js +0 -62
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* In-memory types and defaults for the managed `claude` alias.
|
|
3
|
-
*
|
|
4
|
-
* Persistence has moved:
|
|
5
|
-
* - Alias name lives in Claude Code's `settings.json` under `claudeup.aliasName`
|
|
6
|
-
* (read/written via `alias-settings.ts`).
|
|
7
|
-
* - Flag values are read from the user's shell rc file on screen mount
|
|
8
|
-
* (via `parseAliasFromRc` in `alias-shell-writer.ts`). Edits stay in
|
|
9
|
-
* memory until the user presses `w` to write the rc file.
|
|
10
|
-
*
|
|
11
|
-
* This module is filesystem-free so it can be imported by tests and pure
|
|
12
|
-
* logic without dragging in `claude-settings.ts`'s module-level `os.homedir()`
|
|
13
|
-
* constants.
|
|
14
|
-
*/
|
|
15
|
-
import { ALIAS_FLAGS } from "../data/alias-flags.js";
|
|
16
|
-
/** Default alias name. POSIX/fish-safe, short, and not in conflict with `claude`. */
|
|
17
|
-
export const DEFAULT_ALIAS_NAME = "c";
|
|
18
|
-
/**
|
|
19
|
-
* Validate a candidate alias name. Returns null when valid, or a human
|
|
20
|
-
* reason when invalid.
|
|
21
|
-
*
|
|
22
|
-
* We refuse anything that isn't `[A-Za-z_][A-Za-z0-9_-]*` — that's the
|
|
23
|
-
* intersection of POSIX `name` rules and fish's `alias NAME …` accepting
|
|
24
|
-
* set, and avoids the need to quote the name on either side of the `=`.
|
|
25
|
-
*/
|
|
26
|
-
export function validateAliasName(name) {
|
|
27
|
-
if (name.length === 0)
|
|
28
|
-
return "Alias name cannot be empty.";
|
|
29
|
-
if (name.length > 32)
|
|
30
|
-
return "Alias name is unreasonably long (>32 chars).";
|
|
31
|
-
if (!/^[A-Za-z_][A-Za-z0-9_-]*$/.test(name)) {
|
|
32
|
-
return "Alias name must start with a letter or underscore and contain only letters, digits, _ or -.";
|
|
33
|
-
}
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Build the default in-memory config. Used when no managed block exists in
|
|
38
|
-
* the rc file (every flag disabled, default alias name).
|
|
39
|
-
*/
|
|
40
|
-
export function defaultAliasConfig() {
|
|
41
|
-
const flags = {};
|
|
42
|
-
for (const flag of ALIAS_FLAGS) {
|
|
43
|
-
flags[flag.id] = defaultValueFor(flag);
|
|
44
|
-
}
|
|
45
|
-
return { aliasName: DEFAULT_ALIAS_NAME, flags };
|
|
46
|
-
}
|
|
47
|
-
export function defaultValueFor(flag) {
|
|
48
|
-
switch (flag.kind) {
|
|
49
|
-
case "boolean":
|
|
50
|
-
return { kind: "boolean", enabled: false };
|
|
51
|
-
case "tri-state":
|
|
52
|
-
return { kind: "tri-state", state: "unset" };
|
|
53
|
-
case "select":
|
|
54
|
-
return {
|
|
55
|
-
kind: "select",
|
|
56
|
-
enabled: false,
|
|
57
|
-
value: flag.options?.[0]?.value ?? "",
|
|
58
|
-
};
|
|
59
|
-
case "text":
|
|
60
|
-
return { kind: "text", enabled: false, value: "" };
|
|
61
|
-
case "optional-text":
|
|
62
|
-
return { kind: "optional-text", enabled: false, value: "" };
|
|
63
|
-
case "text-list":
|
|
64
|
-
return {
|
|
65
|
-
kind: "text-list",
|
|
66
|
-
enabled: false,
|
|
67
|
-
values: [...(flag.defaultValues ?? [])],
|
|
68
|
-
};
|
|
69
|
-
case "multi-with-custom":
|
|
70
|
-
return {
|
|
71
|
-
kind: "multi-with-custom",
|
|
72
|
-
enabled: false,
|
|
73
|
-
picked: [],
|
|
74
|
-
custom: [...(flag.defaultValues ?? [])],
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Claude CLI wrapper service
|
|
3
|
-
*
|
|
4
|
-
* Delegates plugin and marketplace management to the `claude` CLI
|
|
5
|
-
* instead of manipulating settings JSON files directly.
|
|
6
|
-
*
|
|
7
|
-
* CLI commands used:
|
|
8
|
-
* - claude plugin install/uninstall/enable/disable/update
|
|
9
|
-
* - claude marketplace add
|
|
10
|
-
*/
|
|
11
|
-
import { execFile } from "node:child_process";
|
|
12
|
-
import { promisify } from "node:util";
|
|
13
|
-
import { which } from "../utils/command-utils.js";
|
|
14
|
-
import { isMarketplaceRegistered, removeGlobalInstalledPluginVersion, removeLocalInstalledPluginVersion, } from "./claude-settings.js";
|
|
15
|
-
import { removeInstalledPluginVersion } from "./plugin-manager.js";
|
|
16
|
-
import { defaultMarketplaces } from "../data/marketplaces.js";
|
|
17
|
-
const execFileAsync = promisify(execFile);
|
|
18
|
-
/**
|
|
19
|
-
* Get the path to the claude CLI binary
|
|
20
|
-
* @throws Error if claude CLI is not found in PATH
|
|
21
|
-
*/
|
|
22
|
-
async function getClaudePath() {
|
|
23
|
-
const claudePath = await which("claude");
|
|
24
|
-
if (!claudePath) {
|
|
25
|
-
throw new Error("claude CLI not found in PATH. Install with: npm install -g @anthropic-ai/claude-code");
|
|
26
|
-
}
|
|
27
|
-
return claudePath;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Execute a claude CLI command and return stdout
|
|
31
|
-
* @param args - Arguments to pass to claude
|
|
32
|
-
* @param timeoutMs - Timeout in milliseconds (default: 30s)
|
|
33
|
-
* @returns stdout from the command
|
|
34
|
-
*/
|
|
35
|
-
async function execClaude(args, timeoutMs = 30000) {
|
|
36
|
-
const claudePath = await getClaudePath();
|
|
37
|
-
try {
|
|
38
|
-
const { stdout } = await execFileAsync(claudePath, args, {
|
|
39
|
-
timeout: timeoutMs,
|
|
40
|
-
});
|
|
41
|
-
return stdout.trim();
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
const execError = error;
|
|
45
|
-
const msg = execError.stderr?.trim() ||
|
|
46
|
-
execError.stdout?.trim() ||
|
|
47
|
-
execError.message ||
|
|
48
|
-
"claude command failed";
|
|
49
|
-
throw new Error(msg);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Recover from a "not found in marketplace" error.
|
|
54
|
-
*
|
|
55
|
-
* Two distinct failure modes land in the same error string:
|
|
56
|
-
* 1. Marketplace is registered locally but stale (or uses the old
|
|
57
|
-
* "directory" source) — fix the registry and refresh the clone.
|
|
58
|
-
* 2. Marketplace is not registered at all — look up its repo in
|
|
59
|
-
* defaultMarketplaces and add it. This is the "new employee clones
|
|
60
|
-
* a project whose .claude/settings.json enables @magus plugins but
|
|
61
|
-
* magus was never registered on this machine" case.
|
|
62
|
-
*
|
|
63
|
-
* Returns true if recovery was attempted and a retry is worth trying.
|
|
64
|
-
*/
|
|
65
|
-
async function recoverMissingMarketplace(marketplace) {
|
|
66
|
-
if (await isMarketplaceRegistered(marketplace)) {
|
|
67
|
-
// Registered but stale — existing recovery path.
|
|
68
|
-
const { recoverMarketplaceSettings } = await import("./claude-settings.js");
|
|
69
|
-
await recoverMarketplaceSettings();
|
|
70
|
-
await updateMarketplace(marketplace);
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
const defaultMp = defaultMarketplaces.find((m) => m.name === marketplace);
|
|
74
|
-
if (!defaultMp?.source.repo)
|
|
75
|
-
return false;
|
|
76
|
-
await addMarketplace(defaultMp.source.repo);
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Install a plugin using claude CLI
|
|
81
|
-
* Handles enabling + version tracking + cache copy in one shot.
|
|
82
|
-
*
|
|
83
|
-
* If the install fails because the plugin is "not found in marketplace",
|
|
84
|
-
* attempts to recover (add the marketplace if missing, or refresh it if
|
|
85
|
-
* stale) and retries once.
|
|
86
|
-
*/
|
|
87
|
-
export async function installPlugin(pluginId, scope = "user") {
|
|
88
|
-
try {
|
|
89
|
-
await execClaude(["plugin", "install", pluginId, "--scope", scope]);
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
93
|
-
if (msg.includes("not found in marketplace")) {
|
|
94
|
-
const marketplace = pluginId.split("@")[1];
|
|
95
|
-
if (marketplace && (await recoverMissingMarketplace(marketplace))) {
|
|
96
|
-
await execClaude([
|
|
97
|
-
"plugin",
|
|
98
|
-
"install",
|
|
99
|
-
pluginId,
|
|
100
|
-
"--scope",
|
|
101
|
-
scope,
|
|
102
|
-
]);
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
throw error;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Uninstall a plugin using claude CLI.
|
|
111
|
-
* Falls back to direct settings removal if CLI uninstall fails
|
|
112
|
-
* (e.g., for plugins installed via old JSON method).
|
|
113
|
-
* @param projectPath - Required for project/local scope fallback
|
|
114
|
-
*/
|
|
115
|
-
export async function uninstallPlugin(pluginId, scope = "user", projectPath) {
|
|
116
|
-
try {
|
|
117
|
-
await execClaude(["plugin", "uninstall", pluginId, "--scope", scope]);
|
|
118
|
-
}
|
|
119
|
-
catch {
|
|
120
|
-
// Fallback: directly remove from settings JSON
|
|
121
|
-
if (scope === "user") {
|
|
122
|
-
await removeGlobalInstalledPluginVersion(pluginId);
|
|
123
|
-
}
|
|
124
|
-
else if (scope === "local" && projectPath) {
|
|
125
|
-
await removeLocalInstalledPluginVersion(pluginId, projectPath);
|
|
126
|
-
}
|
|
127
|
-
else if (projectPath) {
|
|
128
|
-
await removeInstalledPluginVersion(pluginId, projectPath);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Enable a previously disabled plugin
|
|
134
|
-
*/
|
|
135
|
-
export async function enablePlugin(pluginId, scope = "user") {
|
|
136
|
-
await execClaude(["plugin", "enable", pluginId, "--scope", scope]);
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Disable a plugin without uninstalling it
|
|
140
|
-
*/
|
|
141
|
-
export async function disablePlugin(pluginId, scope = "user") {
|
|
142
|
-
await execClaude(["plugin", "disable", pluginId, "--scope", scope]);
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Update a plugin to the latest version.
|
|
146
|
-
* Uses `install` as primary method since `update` only works for plugins
|
|
147
|
-
* originally installed via the CLI. `install` handles both fresh installs
|
|
148
|
-
* and re-installs (upgrades) of existing plugins regardless of how they
|
|
149
|
-
* were originally added.
|
|
150
|
-
*
|
|
151
|
-
* Retries with marketplace update on "not found" errors (same as installPlugin).
|
|
152
|
-
*/
|
|
153
|
-
export async function updatePlugin(pluginId, scope = "user") {
|
|
154
|
-
try {
|
|
155
|
-
await execClaude(["plugin", "install", pluginId, "--scope", scope], 60000);
|
|
156
|
-
}
|
|
157
|
-
catch (error) {
|
|
158
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
159
|
-
if (msg.includes("not found in marketplace")) {
|
|
160
|
-
const marketplace = pluginId.split("@")[1];
|
|
161
|
-
if (marketplace && (await recoverMissingMarketplace(marketplace))) {
|
|
162
|
-
await execClaude(["plugin", "install", pluginId, "--scope", scope], 60000);
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
throw error;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Add a marketplace by GitHub repo (e.g., "MadAppGang/magus")
|
|
171
|
-
* Uses longer timeout since this involves cloning a git repo
|
|
172
|
-
*/
|
|
173
|
-
export async function addMarketplace(repo) {
|
|
174
|
-
await execClaude(["plugin", "marketplace", "add", repo], 60000);
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Update marketplace cache by running git pull via Claude CLI
|
|
178
|
-
* Uses longer timeout since this involves git network operations
|
|
179
|
-
*/
|
|
180
|
-
export async function updateMarketplace(name) {
|
|
181
|
-
await execClaude(["plugin", "marketplace", "update", name], 60000);
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Check if the claude CLI is available
|
|
185
|
-
* @returns true if claude CLI is found in PATH
|
|
186
|
-
*/
|
|
187
|
-
export async function isClaudeAvailable() {
|
|
188
|
-
return (await which("claude")) !== null;
|
|
189
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { which } from "../utils/command-utils.js";
|
|
3
|
-
/**
|
|
4
|
-
* Execute claude CLI with provided arguments
|
|
5
|
-
* @param args - Arguments to pass to claude
|
|
6
|
-
* @returns Exit code from claude process
|
|
7
|
-
*/
|
|
8
|
-
export async function runClaude(args) {
|
|
9
|
-
// Check if claude exists
|
|
10
|
-
const claudePath = await which("claude");
|
|
11
|
-
if (!claudePath) {
|
|
12
|
-
console.error("Error: claude CLI not found in PATH");
|
|
13
|
-
console.error("Install with: npm install -g @anthropic-ai/claude-code");
|
|
14
|
-
return 1;
|
|
15
|
-
}
|
|
16
|
-
// Spawn claude with full TTY inheritance using the resolved path
|
|
17
|
-
return new Promise((resolve) => {
|
|
18
|
-
const proc = spawn(claudePath, args, {
|
|
19
|
-
stdio: "inherit", // Pass through stdin, stdout, stderr
|
|
20
|
-
shell: false, // Use full path, no shell needed (fixes DEP0190)
|
|
21
|
-
});
|
|
22
|
-
proc.on("exit", (code) => resolve(code || 0));
|
|
23
|
-
proc.on("error", (err) => {
|
|
24
|
-
console.error("Failed to run claude:", err.message);
|
|
25
|
-
resolve(1);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
}
|