ocx 1.0.21 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +270 -17
- package/dist/index.js.map +8 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9864,6 +9864,18 @@ function isAbsolutePath(p) {
|
|
|
9864
9864
|
var safeRelativePathSchema = exports_external.string().refine((val) => !val.includes("\x00"), "Path cannot contain null bytes").refine((val) => !val.split(/[/\\]/).some((seg) => seg === ".."), "Path cannot contain '..'").refine((val) => !isAbsolutePath(val), "Path must be relative, not absolute");
|
|
9865
9865
|
|
|
9866
9866
|
// src/schemas/registry.ts
|
|
9867
|
+
var npmSpecifierSchema = exports_external.string().refine((val) => val.startsWith("npm:"), {
|
|
9868
|
+
message: 'npm specifier must start with "npm:" prefix'
|
|
9869
|
+
}).refine((val) => {
|
|
9870
|
+
const remainder = val.slice(4);
|
|
9871
|
+
if (!remainder)
|
|
9872
|
+
return false;
|
|
9873
|
+
if (remainder.includes("..") || remainder.includes("/./"))
|
|
9874
|
+
return false;
|
|
9875
|
+
return true;
|
|
9876
|
+
}, {
|
|
9877
|
+
message: "Invalid npm specifier format"
|
|
9878
|
+
});
|
|
9867
9879
|
var openCodeNameSchema = exports_external.string().min(1, "Name cannot be empty").max(64, "Name cannot exceed 64 characters").regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, {
|
|
9868
9880
|
message: "Must be lowercase alphanumeric with single hyphen separators (e.g., 'my-component', 'my-plugin'). Cannot start/end with hyphen or have consecutive hyphens."
|
|
9869
9881
|
});
|
|
@@ -10420,7 +10432,7 @@ class GhostConfigProvider {
|
|
|
10420
10432
|
// package.json
|
|
10421
10433
|
var package_default = {
|
|
10422
10434
|
name: "ocx",
|
|
10423
|
-
version: "1.0
|
|
10435
|
+
version: "1.1.0",
|
|
10424
10436
|
description: "OCX CLI - ShadCN-style registry for OpenCode extensions. Install agents, plugins, skills, and MCP servers.",
|
|
10425
10437
|
author: "kdcokenny",
|
|
10426
10438
|
license: "MIT",
|
|
@@ -11082,14 +11094,14 @@ var sharedOptions = {
|
|
|
11082
11094
|
cwd: () => new Option("--cwd <path>", "Working directory").default(process.cwd()),
|
|
11083
11095
|
quiet: () => new Option("-q, --quiet", "Suppress output"),
|
|
11084
11096
|
json: () => new Option("--json", "Output as JSON"),
|
|
11085
|
-
|
|
11097
|
+
force: () => new Option("-f, --force", "Skip confirmation prompts"),
|
|
11086
11098
|
verbose: () => new Option("-v, --verbose", "Verbose output")
|
|
11087
11099
|
};
|
|
11088
11100
|
function addCommonOptions(cmd) {
|
|
11089
11101
|
return cmd.addOption(sharedOptions.cwd()).addOption(sharedOptions.quiet()).addOption(sharedOptions.json());
|
|
11090
11102
|
}
|
|
11091
|
-
function
|
|
11092
|
-
return cmd.addOption(sharedOptions.
|
|
11103
|
+
function addForceOption(cmd) {
|
|
11104
|
+
return cmd.addOption(sharedOptions.force());
|
|
11093
11105
|
}
|
|
11094
11106
|
function addVerboseOption(cmd) {
|
|
11095
11107
|
return cmd.addOption(sharedOptions.verbose());
|
|
@@ -12486,11 +12498,154 @@ function warnCompatIssues(registryName, issues) {
|
|
|
12486
12498
|
logger.log(formatCompatWarning(registryName, issue));
|
|
12487
12499
|
}
|
|
12488
12500
|
}
|
|
12501
|
+
// src/utils/npm-registry.ts
|
|
12502
|
+
var NPM_REGISTRY_BASE = "https://registry.npmjs.org";
|
|
12503
|
+
var NPM_FETCH_TIMEOUT_MS = 30000;
|
|
12504
|
+
var NPM_NAME_REGEX = /^(?:@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*$/;
|
|
12505
|
+
var MAX_NAME_LENGTH = 214;
|
|
12506
|
+
function validateNpmPackageName(name) {
|
|
12507
|
+
if (!name) {
|
|
12508
|
+
throw new ValidationError("npm package name cannot be empty");
|
|
12509
|
+
}
|
|
12510
|
+
if (name.length > MAX_NAME_LENGTH) {
|
|
12511
|
+
throw new ValidationError(`npm package name exceeds maximum length of ${MAX_NAME_LENGTH} characters: \`${name}\``);
|
|
12512
|
+
}
|
|
12513
|
+
if (name.includes("..") || name.includes("/./") || name.startsWith("./")) {
|
|
12514
|
+
throw new ValidationError(`Invalid npm package name - path traversal detected: \`${name}\``);
|
|
12515
|
+
}
|
|
12516
|
+
if (!NPM_NAME_REGEX.test(name)) {
|
|
12517
|
+
throw new ValidationError(`Invalid npm package name: \`${name}\`. ` + "Must be lowercase, start with alphanumeric, and contain only letters, numbers, hyphens, dots, or underscores.");
|
|
12518
|
+
}
|
|
12519
|
+
}
|
|
12520
|
+
function parseNpmSpecifier(specifier) {
|
|
12521
|
+
if (!specifier?.trim()) {
|
|
12522
|
+
throw new ValidationError("npm specifier cannot be empty");
|
|
12523
|
+
}
|
|
12524
|
+
const trimmed = specifier.trim();
|
|
12525
|
+
if (!trimmed.startsWith("npm:")) {
|
|
12526
|
+
throw new ValidationError(`Invalid npm specifier: \`${specifier}\`. Must start with \`npm:\` prefix.`);
|
|
12527
|
+
}
|
|
12528
|
+
const remainder = trimmed.slice(4);
|
|
12529
|
+
if (!remainder) {
|
|
12530
|
+
throw new ValidationError(`Invalid npm specifier: \`${specifier}\`. Package name is required.`);
|
|
12531
|
+
}
|
|
12532
|
+
const lastAt = remainder.lastIndexOf("@");
|
|
12533
|
+
let name;
|
|
12534
|
+
let version;
|
|
12535
|
+
if (lastAt > 0) {
|
|
12536
|
+
const beforeAt = remainder.slice(0, lastAt);
|
|
12537
|
+
const afterAt = remainder.slice(lastAt + 1);
|
|
12538
|
+
if (beforeAt.includes("/") || !beforeAt.startsWith("@")) {
|
|
12539
|
+
name = beforeAt;
|
|
12540
|
+
version = afterAt || undefined;
|
|
12541
|
+
} else {
|
|
12542
|
+
throw new ValidationError(`Invalid npm specifier: \`${specifier}\`. Scoped packages must have format @scope/pkg.`);
|
|
12543
|
+
}
|
|
12544
|
+
} else {
|
|
12545
|
+
name = remainder;
|
|
12546
|
+
}
|
|
12547
|
+
validateNpmPackageName(name);
|
|
12548
|
+
return { type: "npm", name, version };
|
|
12549
|
+
}
|
|
12550
|
+
function isNpmSpecifier(input) {
|
|
12551
|
+
return input.trim().startsWith("npm:");
|
|
12552
|
+
}
|
|
12553
|
+
async function validateNpmPackage(packageName) {
|
|
12554
|
+
validateNpmPackageName(packageName);
|
|
12555
|
+
const encodedName = packageName.startsWith("@") ? `@${encodeURIComponent(packageName.slice(1))}` : encodeURIComponent(packageName);
|
|
12556
|
+
const url = `${NPM_REGISTRY_BASE}/${encodedName}`;
|
|
12557
|
+
try {
|
|
12558
|
+
const controller = new AbortController;
|
|
12559
|
+
const timeoutId = setTimeout(() => controller.abort(), NPM_FETCH_TIMEOUT_MS);
|
|
12560
|
+
const response = await fetch(url, {
|
|
12561
|
+
signal: controller.signal,
|
|
12562
|
+
headers: {
|
|
12563
|
+
Accept: "application/json"
|
|
12564
|
+
}
|
|
12565
|
+
});
|
|
12566
|
+
clearTimeout(timeoutId);
|
|
12567
|
+
if (response.status === 404) {
|
|
12568
|
+
throw new NotFoundError(`npm package \`${packageName}\` not found on registry`);
|
|
12569
|
+
}
|
|
12570
|
+
if (!response.ok) {
|
|
12571
|
+
throw new NetworkError(`Failed to fetch npm package \`${packageName}\`: HTTP ${response.status} ${response.statusText}`);
|
|
12572
|
+
}
|
|
12573
|
+
const data = await response.json();
|
|
12574
|
+
return data;
|
|
12575
|
+
} catch (error) {
|
|
12576
|
+
if (error instanceof NotFoundError || error instanceof NetworkError) {
|
|
12577
|
+
throw error;
|
|
12578
|
+
}
|
|
12579
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
12580
|
+
throw new NetworkError(`Request to npm registry timed out after ${NPM_FETCH_TIMEOUT_MS / 1000}s for package \`${packageName}\``);
|
|
12581
|
+
}
|
|
12582
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
12583
|
+
throw new NetworkError(`Failed to fetch npm package \`${packageName}\`: ${message}`);
|
|
12584
|
+
}
|
|
12585
|
+
}
|
|
12586
|
+
function formatPluginEntry(name, version) {
|
|
12587
|
+
return version ? `${name}@${version}` : name;
|
|
12588
|
+
}
|
|
12589
|
+
function validateOpenCodePlugin(packageJson) {
|
|
12590
|
+
const warnings = [];
|
|
12591
|
+
if (packageJson.type !== "module") {
|
|
12592
|
+
throw new ValidationError(`Package \`${packageJson.name}\` is not an ESM module (missing "type": "module" in package.json)`);
|
|
12593
|
+
}
|
|
12594
|
+
const hasMain = Boolean(packageJson.main);
|
|
12595
|
+
const hasExports = packageJson.exports !== undefined;
|
|
12596
|
+
if (!hasMain && !hasExports) {
|
|
12597
|
+
throw new ValidationError(`Package \`${packageJson.name}\` has no entry point (missing "main" or "exports")`);
|
|
12598
|
+
}
|
|
12599
|
+
if (!packageJson.name.includes("opencode")) {
|
|
12600
|
+
warnings.push(`Package name \`${packageJson.name}\` doesn't contain "opencode" - this may not be an OpenCode plugin`);
|
|
12601
|
+
}
|
|
12602
|
+
return { valid: true, warnings };
|
|
12603
|
+
}
|
|
12604
|
+
async function fetchPackageVersion(packageName, version) {
|
|
12605
|
+
const metadata = await validateNpmPackage(packageName);
|
|
12606
|
+
const resolvedVersion = version ?? metadata["dist-tags"].latest;
|
|
12607
|
+
const versionData = metadata.versions[resolvedVersion];
|
|
12608
|
+
if (!versionData) {
|
|
12609
|
+
throw new NotFoundError(`Version \`${resolvedVersion}\` not found for npm package \`${packageName}\``);
|
|
12610
|
+
}
|
|
12611
|
+
return versionData;
|
|
12612
|
+
}
|
|
12613
|
+
function extractPackageName(pluginEntry) {
|
|
12614
|
+
const trimmed = pluginEntry.trim();
|
|
12615
|
+
const lastAt = trimmed.lastIndexOf("@");
|
|
12616
|
+
if (lastAt <= 0) {
|
|
12617
|
+
return trimmed;
|
|
12618
|
+
}
|
|
12619
|
+
const beforeAt = trimmed.slice(0, lastAt);
|
|
12620
|
+
if (beforeAt.includes("/") || !beforeAt.startsWith("@")) {
|
|
12621
|
+
return beforeAt;
|
|
12622
|
+
}
|
|
12623
|
+
return trimmed;
|
|
12624
|
+
}
|
|
12625
|
+
|
|
12489
12626
|
// src/commands/add.ts
|
|
12627
|
+
function parseAddInput(input) {
|
|
12628
|
+
if (!input?.trim()) {
|
|
12629
|
+
throw new ValidationError("Component name cannot be empty");
|
|
12630
|
+
}
|
|
12631
|
+
const trimmed = input.trim();
|
|
12632
|
+
if (isNpmSpecifier(trimmed)) {
|
|
12633
|
+
const parsed = parseNpmSpecifier(trimmed);
|
|
12634
|
+
return { type: "npm", name: parsed.name, version: parsed.version };
|
|
12635
|
+
}
|
|
12636
|
+
if (trimmed.includes("/")) {
|
|
12637
|
+
const { namespace, component } = parseQualifiedComponent(trimmed);
|
|
12638
|
+
return { type: "registry", namespace, component };
|
|
12639
|
+
}
|
|
12640
|
+
return { type: "registry", namespace: "", component: trimmed };
|
|
12641
|
+
}
|
|
12490
12642
|
function registerAddCommand(program2) {
|
|
12491
|
-
const cmd = program2.command("add").description(
|
|
12643
|
+
const cmd = program2.command("add").description(`Add components or npm plugins to your project.
|
|
12644
|
+
|
|
12645
|
+
` + ` Registry components: ocx add namespace/component
|
|
12646
|
+
` + " npm plugins: ocx add npm:package-name[@version]").argument("<components...>", "Components to install (namespace/component or npm:package[@version])").option("--dry-run", "Show what would be installed without making changes").option("--skip-compat-check", "Skip version compatibility checks").option("--trust", "Skip npm plugin validation (for packages that don't follow conventions)");
|
|
12492
12647
|
addCommonOptions(cmd);
|
|
12493
|
-
|
|
12648
|
+
addForceOption(cmd);
|
|
12494
12649
|
addVerboseOption(cmd);
|
|
12495
12650
|
cmd.action(async (components, options2) => {
|
|
12496
12651
|
try {
|
|
@@ -12502,6 +12657,104 @@ function registerAddCommand(program2) {
|
|
|
12502
12657
|
});
|
|
12503
12658
|
}
|
|
12504
12659
|
async function runAddCore(componentNames, options2, provider) {
|
|
12660
|
+
const cwd = provider.cwd;
|
|
12661
|
+
const parsedInputs = componentNames.map(parseAddInput);
|
|
12662
|
+
const npmInputs = parsedInputs.filter((i) => i.type === "npm");
|
|
12663
|
+
const registryInputs = parsedInputs.filter((i) => i.type === "registry");
|
|
12664
|
+
if (npmInputs.length > 0) {
|
|
12665
|
+
await handleNpmPlugins(npmInputs, options2, cwd);
|
|
12666
|
+
}
|
|
12667
|
+
if (registryInputs.length > 0) {
|
|
12668
|
+
const registryComponentNames = registryInputs.map((i) => i.namespace ? `${i.namespace}/${i.component}` : i.component);
|
|
12669
|
+
await runRegistryAddCore(registryComponentNames, options2, provider);
|
|
12670
|
+
}
|
|
12671
|
+
}
|
|
12672
|
+
async function handleNpmPlugins(inputs, options2, cwd) {
|
|
12673
|
+
const spin = options2.quiet ? null : createSpinner({ text: "Validating npm packages..." });
|
|
12674
|
+
spin?.start();
|
|
12675
|
+
try {
|
|
12676
|
+
const allWarnings = [];
|
|
12677
|
+
for (const input of inputs) {
|
|
12678
|
+
await validateNpmPackage(input.name);
|
|
12679
|
+
if (!options2.trust) {
|
|
12680
|
+
try {
|
|
12681
|
+
const versionData = await fetchPackageVersion(input.name, input.version);
|
|
12682
|
+
const result = validateOpenCodePlugin(versionData);
|
|
12683
|
+
allWarnings.push(...result.warnings);
|
|
12684
|
+
} catch (error) {
|
|
12685
|
+
if (error instanceof ValidationError) {
|
|
12686
|
+
spin?.fail("Plugin validation failed");
|
|
12687
|
+
throw new ValidationError(`${error.message}
|
|
12688
|
+
` + `hint OpenCode plugins must be ESM modules with an entry point
|
|
12689
|
+
` + `hint Use \`--trust\` to add anyway`);
|
|
12690
|
+
}
|
|
12691
|
+
throw error;
|
|
12692
|
+
}
|
|
12693
|
+
}
|
|
12694
|
+
}
|
|
12695
|
+
spin?.succeed(`Validated ${inputs.length} npm package(s)`);
|
|
12696
|
+
if (allWarnings.length > 0 && !options2.quiet) {
|
|
12697
|
+
logger.info("");
|
|
12698
|
+
for (const warning of allWarnings) {
|
|
12699
|
+
logger.warn(warning);
|
|
12700
|
+
}
|
|
12701
|
+
}
|
|
12702
|
+
const existingConfig = await readOpencodeJsonConfig(cwd);
|
|
12703
|
+
const existingPlugins = existingConfig?.config.plugin ?? [];
|
|
12704
|
+
const existingPluginMap = new Map;
|
|
12705
|
+
for (const plugin of existingPlugins) {
|
|
12706
|
+
const name = extractPackageName(plugin);
|
|
12707
|
+
existingPluginMap.set(name, plugin);
|
|
12708
|
+
}
|
|
12709
|
+
const pluginsToAdd = [];
|
|
12710
|
+
const conflicts = [];
|
|
12711
|
+
for (const input of inputs) {
|
|
12712
|
+
const existingEntry = existingPluginMap.get(input.name);
|
|
12713
|
+
if (existingEntry) {
|
|
12714
|
+
if (!options2.force) {
|
|
12715
|
+
conflicts.push(input.name);
|
|
12716
|
+
} else {
|
|
12717
|
+
existingPluginMap.set(input.name, formatPluginEntry(input.name, input.version));
|
|
12718
|
+
}
|
|
12719
|
+
} else {
|
|
12720
|
+
pluginsToAdd.push(formatPluginEntry(input.name, input.version));
|
|
12721
|
+
}
|
|
12722
|
+
}
|
|
12723
|
+
if (conflicts.length > 0) {
|
|
12724
|
+
throw new ConflictError(`Plugin(s) already exist in opencode.json: ${conflicts.join(", ")}.
|
|
12725
|
+
` + "Use --force to replace existing entries.");
|
|
12726
|
+
}
|
|
12727
|
+
const finalPlugins = [...existingPluginMap.values(), ...pluginsToAdd];
|
|
12728
|
+
if (options2.dryRun) {
|
|
12729
|
+
logger.info("");
|
|
12730
|
+
logger.info("Dry run - no changes made");
|
|
12731
|
+
logger.info("");
|
|
12732
|
+
logger.info("Would add npm plugins:");
|
|
12733
|
+
for (const input of inputs) {
|
|
12734
|
+
logger.info(` ${formatPluginEntry(input.name, input.version)}`);
|
|
12735
|
+
}
|
|
12736
|
+
return;
|
|
12737
|
+
}
|
|
12738
|
+
await updateOpencodeJsonConfig(cwd, { plugin: finalPlugins });
|
|
12739
|
+
if (!options2.quiet) {
|
|
12740
|
+
logger.info("");
|
|
12741
|
+
logger.success(`Added ${inputs.length} npm plugin(s) to opencode.json`);
|
|
12742
|
+
for (const input of inputs) {
|
|
12743
|
+
logger.info(` \u2713 ${formatPluginEntry(input.name, input.version)}`);
|
|
12744
|
+
}
|
|
12745
|
+
}
|
|
12746
|
+
if (options2.json) {
|
|
12747
|
+
console.log(JSON.stringify({
|
|
12748
|
+
success: true,
|
|
12749
|
+
plugins: inputs.map((i) => formatPluginEntry(i.name, i.version))
|
|
12750
|
+
}, null, 2));
|
|
12751
|
+
}
|
|
12752
|
+
} catch (error) {
|
|
12753
|
+
spin?.fail("Failed to add npm plugins");
|
|
12754
|
+
throw error;
|
|
12755
|
+
}
|
|
12756
|
+
}
|
|
12757
|
+
async function runRegistryAddCore(componentNames, options2, provider) {
|
|
12505
12758
|
const cwd = provider.cwd;
|
|
12506
12759
|
const lockPath = join2(cwd, "ocx.lock");
|
|
12507
12760
|
const registries = provider.getRegistries();
|
|
@@ -12595,7 +12848,7 @@ async function runAddCore(componentNames, options2, provider) {
|
|
|
12595
12848
|
if (existsSync(targetPath)) {
|
|
12596
12849
|
const existingContent = await Bun.file(targetPath).text();
|
|
12597
12850
|
const incomingContent = file.content.toString("utf-8");
|
|
12598
|
-
if (!isContentIdentical(existingContent, incomingContent) && !options2.
|
|
12851
|
+
if (!isContentIdentical(existingContent, incomingContent) && !options2.force) {
|
|
12599
12852
|
allConflicts.push(componentFile.target);
|
|
12600
12853
|
}
|
|
12601
12854
|
}
|
|
@@ -12609,14 +12862,14 @@ async function runAddCore(componentNames, options2, provider) {
|
|
|
12609
12862
|
}
|
|
12610
12863
|
logger.error("");
|
|
12611
12864
|
logger.error("These files have been modified since installation.");
|
|
12612
|
-
logger.error("Use --
|
|
12613
|
-
throw new ConflictError(`${allConflicts.length} file(s) have conflicts. Use --
|
|
12865
|
+
logger.error("Use --force to overwrite, or review the changes first.");
|
|
12866
|
+
throw new ConflictError(`${allConflicts.length} file(s) have conflicts. Use --force to overwrite.`);
|
|
12614
12867
|
}
|
|
12615
12868
|
const installSpin = options2.quiet ? null : createSpinner({ text: "Installing components..." });
|
|
12616
12869
|
installSpin?.start();
|
|
12617
12870
|
for (const { component, files, computedHash } of componentBundles) {
|
|
12618
12871
|
const installResult = await installComponent(component, files, cwd, {
|
|
12619
|
-
|
|
12872
|
+
force: options2.force,
|
|
12620
12873
|
verbose: options2.verbose
|
|
12621
12874
|
});
|
|
12622
12875
|
if (options2.verbose) {
|
|
@@ -13871,9 +14124,9 @@ Diff for ${res.name}:`));
|
|
|
13871
14124
|
|
|
13872
14125
|
// src/commands/ghost/add.ts
|
|
13873
14126
|
function registerGhostAddCommand(parent) {
|
|
13874
|
-
const cmd = parent.command("add").description("Add components using ghost mode registries").argument("<components...>", "Components to install").option("--dry-run", "Show what would be installed without making changes").option("--skip-compat-check", "Skip version compatibility checks");
|
|
14127
|
+
const cmd = parent.command("add").description("Add components using ghost mode registries").argument("<components...>", "Components to install").option("--dry-run", "Show what would be installed without making changes").option("--skip-compat-check", "Skip version compatibility checks").option("--trust", "Skip npm plugin validation");
|
|
13875
14128
|
addCommonOptions(cmd);
|
|
13876
|
-
|
|
14129
|
+
addForceOption(cmd);
|
|
13877
14130
|
addVerboseOption(cmd);
|
|
13878
14131
|
cmd.action(async (components, options2) => {
|
|
13879
14132
|
try {
|
|
@@ -14239,7 +14492,7 @@ async function runGhostOpenCode(args, options2) {
|
|
|
14239
14492
|
}
|
|
14240
14493
|
|
|
14241
14494
|
// src/commands/registry.ts
|
|
14242
|
-
async function
|
|
14495
|
+
async function runRegistryAddCore2(url, options2, callbacks) {
|
|
14243
14496
|
if (callbacks.isLocked?.()) {
|
|
14244
14497
|
throw new Error("Registries are locked. Cannot add.");
|
|
14245
14498
|
}
|
|
@@ -14285,7 +14538,7 @@ function registerRegistryCommand(program2) {
|
|
|
14285
14538
|
logger.error("No ocx.jsonc found. Run 'ocx init' first.");
|
|
14286
14539
|
process.exit(1);
|
|
14287
14540
|
}
|
|
14288
|
-
const result = await
|
|
14541
|
+
const result = await runRegistryAddCore2(url, options2, {
|
|
14289
14542
|
getRegistries: () => config.registries,
|
|
14290
14543
|
isLocked: () => config.lockRegistries ?? false,
|
|
14291
14544
|
setRegistry: async (name, regConfig) => {
|
|
@@ -14380,7 +14633,7 @@ function registerGhostRegistryCommand(parent) {
|
|
|
14380
14633
|
try {
|
|
14381
14634
|
await ensureGhostInitialized();
|
|
14382
14635
|
const config = await loadGhostConfig();
|
|
14383
|
-
const result = await
|
|
14636
|
+
const result = await runRegistryAddCore2(url, options2, {
|
|
14384
14637
|
getRegistries: () => config.registries,
|
|
14385
14638
|
setRegistry: async (name, regConfig) => {
|
|
14386
14639
|
config.registries[name] = regConfig;
|
|
@@ -15056,7 +15309,7 @@ async function hashBundle2(files) {
|
|
|
15056
15309
|
`));
|
|
15057
15310
|
}
|
|
15058
15311
|
// src/index.ts
|
|
15059
|
-
var version = "1.0
|
|
15312
|
+
var version = "1.1.0";
|
|
15060
15313
|
async function main2() {
|
|
15061
15314
|
const program2 = new Command().name("ocx").description("OpenCode Extensions - Install agents, skills, plugins, and commands").version(version);
|
|
15062
15315
|
registerInitCommand(program2);
|
|
@@ -15083,4 +15336,4 @@ export {
|
|
|
15083
15336
|
buildRegistry
|
|
15084
15337
|
};
|
|
15085
15338
|
|
|
15086
|
-
//# debugId=
|
|
15339
|
+
//# debugId=46A2A0DCEF36C6A464756E2164756E21
|