ocx 1.0.16 → 1.0.18

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 CHANGED
@@ -4512,6 +4512,77 @@ import { createHash } from "crypto";
4512
4512
  import { existsSync } from "fs";
4513
4513
  import { mkdir, writeFile } from "fs/promises";
4514
4514
  import { dirname, join } from "path";
4515
+ // package.json
4516
+ var package_default = {
4517
+ name: "ocx",
4518
+ version: "1.0.18",
4519
+ description: "OCX CLI - ShadCN-style registry for OpenCode extensions. Install agents, plugins, skills, and MCP servers.",
4520
+ author: "kdcokenny",
4521
+ license: "MIT",
4522
+ type: "module",
4523
+ main: "./dist/index.js",
4524
+ bin: {
4525
+ ocx: "./dist/index.js"
4526
+ },
4527
+ files: [
4528
+ "dist/index.js",
4529
+ "dist/index.js.map"
4530
+ ],
4531
+ publishConfig: {
4532
+ access: "public"
4533
+ },
4534
+ repository: {
4535
+ type: "git",
4536
+ url: "https://github.com/kdcokenny/ocx.git"
4537
+ },
4538
+ homepage: "https://github.com/kdcokenny/ocx#readme",
4539
+ bugs: {
4540
+ url: "https://github.com/kdcokenny/ocx/issues"
4541
+ },
4542
+ keywords: [
4543
+ "opencode",
4544
+ "cli",
4545
+ "extensions",
4546
+ "agents",
4547
+ "plugins",
4548
+ "mcp",
4549
+ "shadcn",
4550
+ "registry"
4551
+ ],
4552
+ engines: {
4553
+ node: ">=18"
4554
+ },
4555
+ scripts: {
4556
+ build: "bun run scripts/build.ts",
4557
+ "build:binary": "bun run scripts/build-binary.ts",
4558
+ check: "bun check:biome && bun check:types",
4559
+ "check:biome": "biome check .",
4560
+ "check:types": "tsc --noEmit",
4561
+ dev: "bun run src/index.ts",
4562
+ prepublishOnly: "bun run build",
4563
+ test: "bun test"
4564
+ },
4565
+ dependencies: {
4566
+ commander: "^14.0.0",
4567
+ diff: "^8.0.0",
4568
+ fuzzysort: "^3.1.0",
4569
+ "jsonc-parser": "3.3.1",
4570
+ kleur: "^4.1.5",
4571
+ ora: "^8.2.0",
4572
+ remeda: "^2.33.0",
4573
+ zod: "^3.24.0"
4574
+ },
4575
+ devDependencies: {
4576
+ "@types/bun": "latest",
4577
+ "@types/diff": "^8.0.0"
4578
+ }
4579
+ };
4580
+
4581
+ // src/constants.ts
4582
+ var OCX_DOMAIN = "ocx.kdco.dev";
4583
+ var GITHUB_REPO = "kdcokenny/ocx";
4584
+ var OCX_SCHEMA_URL = `https://${OCX_DOMAIN}/schema.json`;
4585
+ var CLI_VERSION = package_default.version;
4515
4586
 
4516
4587
  // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
4517
4588
  var exports_external = {};
@@ -8700,6 +8771,12 @@ var registrySchema = exports_external.object({
8700
8771
  message: "Version must be valid semver (e.g., '1.0.0', '2.1.0-beta.1')"
8701
8772
  }),
8702
8773
  author: exports_external.string().min(1, "Author cannot be empty"),
8774
+ opencode: exports_external.string().regex(semverRegex, {
8775
+ message: "OpenCode version must be valid semver"
8776
+ }).optional(),
8777
+ ocx: exports_external.string().regex(semverRegex, {
8778
+ message: "OCX version must be valid semver"
8779
+ }).optional(),
8703
8780
  components: exports_external.array(componentManifestSchema)
8704
8781
  }).refine((data) => {
8705
8782
  const componentNames = new Set(data.components.map((c) => c.name));
@@ -8726,6 +8803,12 @@ var registryIndexSchema = exports_external.object({
8726
8803
  namespace: namespaceSchema,
8727
8804
  version: exports_external.string(),
8728
8805
  author: exports_external.string(),
8806
+ opencode: exports_external.string().regex(semverRegex, {
8807
+ message: "OpenCode version must be valid semver"
8808
+ }).optional(),
8809
+ ocx: exports_external.string().regex(semverRegex, {
8810
+ message: "OCX version must be valid semver"
8811
+ }).optional(),
8729
8812
  components: exports_external.array(exports_external.object({
8730
8813
  name: openCodeNameSchema,
8731
8814
  type: componentTypeSchema,
@@ -10335,7 +10418,8 @@ var registryConfigSchema = exports_external.object({
10335
10418
  var ocxConfigSchema = exports_external.object({
10336
10419
  $schema: exports_external.string().optional(),
10337
10420
  registries: exports_external.record(registryConfigSchema).default({}),
10338
- lockRegistries: exports_external.boolean().default(false)
10421
+ lockRegistries: exports_external.boolean().default(false),
10422
+ skipCompatCheck: exports_external.boolean().default(false)
10339
10423
  });
10340
10424
  var installedComponentSchema = exports_external.object({
10341
10425
  registry: exports_external.string(),
@@ -12006,9 +12090,86 @@ function createSpinner(options2) {
12006
12090
  });
12007
12091
  return spinner;
12008
12092
  }
12093
+ // src/utils/version-compat.ts
12094
+ function parseVersion(v) {
12095
+ const [main2 = ""] = v.split("-");
12096
+ const parts = main2.split(".");
12097
+ const major = parseInt(parts[0] ?? "", 10);
12098
+ const minor = parseInt(parts[1] ?? "", 10);
12099
+ const patch = parseInt(parts[2] ?? "", 10);
12100
+ if (Number.isNaN(major) || Number.isNaN(minor) || Number.isNaN(patch)) {
12101
+ return null;
12102
+ }
12103
+ return { major, minor, patch };
12104
+ }
12105
+ function compareSemver(a, b) {
12106
+ const vA = parseVersion(a);
12107
+ const vB = parseVersion(b);
12108
+ if (!vA || !vB) {
12109
+ return null;
12110
+ }
12111
+ if (vA.major !== vB.major)
12112
+ return vA.major - vB.major;
12113
+ if (vA.minor !== vB.minor)
12114
+ return vA.minor - vB.minor;
12115
+ return vA.patch - vB.patch;
12116
+ }
12117
+ function checkCompatibility(requiredVersion, installedVersion, type) {
12118
+ if (!requiredVersion) {
12119
+ return { compatible: true };
12120
+ }
12121
+ const cmp = compareSemver(installedVersion, requiredVersion);
12122
+ if (cmp === null) {
12123
+ return { compatible: true };
12124
+ }
12125
+ if (cmp >= 0) {
12126
+ return { compatible: true };
12127
+ }
12128
+ return {
12129
+ compatible: false,
12130
+ required: requiredVersion,
12131
+ installed: installedVersion,
12132
+ type
12133
+ };
12134
+ }
12135
+ function formatCompatWarning(registryName, result) {
12136
+ const typeLabel = result.type === "opencode" ? "OpenCode" : "OCX CLI";
12137
+ const updateCmd = result.type === "opencode" ? "Update OpenCode to the latest version" : "bun update -g ocx";
12138
+ return `
12139
+ ${kleur_default.yellow().bold("\u26A0 WARN")} ${kleur_default.yellow("Version compatibility notice")}
12140
+
12141
+ Registry ${kleur_default.cyan(`"${registryName}"`)} requires ${typeLabel} ${kleur_default.green(result.required)}
12142
+ You are running ${typeLabel} ${kleur_default.red(result.installed)}
12143
+
12144
+ This may work fine, but if you encounter issues,
12145
+ consider updating: ${kleur_default.dim(updateCmd)}
12146
+
12147
+ To silence: ${kleur_default.dim("--skip-compat-check")} or set ${kleur_default.dim('"skipCompatCheck": true')} in ocx.jsonc
12148
+ `;
12149
+ }
12150
+ function collectCompatIssues(options2) {
12151
+ const { registry, ocxVersion, opencodeVersion } = options2;
12152
+ const issues = [];
12153
+ const ocxResult = checkCompatibility(registry.ocx, ocxVersion, "ocx");
12154
+ if (!ocxResult.compatible) {
12155
+ issues.push(ocxResult);
12156
+ }
12157
+ if (opencodeVersion) {
12158
+ const opencodeResult = checkCompatibility(registry.opencode, opencodeVersion, "opencode");
12159
+ if (!opencodeResult.compatible) {
12160
+ issues.push(opencodeResult);
12161
+ }
12162
+ }
12163
+ return issues;
12164
+ }
12165
+ function warnCompatIssues(registryName, issues) {
12166
+ for (const issue of issues) {
12167
+ logger.log(formatCompatWarning(registryName, issue));
12168
+ }
12169
+ }
12009
12170
  // src/commands/add.ts
12010
12171
  function registerAddCommand(program2) {
12011
- program2.command("add").description("Add components to your project").argument("<components...>", "Components to install").option("-y, --yes", "Skip prompts").option("--dry-run", "Show what would be installed without making changes").option("--cwd <path>", "Working directory", process.cwd()).option("-q, --quiet", "Suppress output").option("-v, --verbose", "Verbose output").option("--json", "Output as JSON").action(async (components, options2) => {
12172
+ program2.command("add").description("Add components to your project").argument("<components...>", "Components to install").option("-y, --yes", "Skip prompts").option("--dry-run", "Show what would be installed without making changes").option("--cwd <path>", "Working directory", process.cwd()).option("-q, --quiet", "Suppress output").option("-v, --verbose", "Verbose output").option("--json", "Output as JSON").option("--skip-compat-check", "Skip version compatibility checks").action(async (components, options2) => {
12012
12173
  try {
12013
12174
  await runAdd(components, options2);
12014
12175
  } catch (error) {
@@ -12032,13 +12193,34 @@ async function runAdd(componentNames, options2) {
12032
12193
  spin?.start();
12033
12194
  try {
12034
12195
  const resolved = await resolveDependencies(config.registries, componentNames);
12035
- spin?.succeed(`Resolved ${resolved.components.length} components`);
12036
12196
  if (options2.verbose) {
12037
12197
  logger.info("Install order:");
12038
12198
  for (const name of resolved.installOrder) {
12039
12199
  logger.info(` - ${name}`);
12040
12200
  }
12041
12201
  }
12202
+ const registryIndexes = new Map;
12203
+ const uniqueBaseUrls = new Map;
12204
+ for (const component of resolved.components) {
12205
+ if (!uniqueBaseUrls.has(component.registryName)) {
12206
+ uniqueBaseUrls.set(component.registryName, component.baseUrl);
12207
+ }
12208
+ }
12209
+ for (const [namespace, baseUrl] of uniqueBaseUrls) {
12210
+ const index = await fetchRegistryIndex(baseUrl);
12211
+ registryIndexes.set(namespace, index);
12212
+ }
12213
+ spin?.succeed(`Resolved ${resolved.components.length} components from ${registryIndexes.size} registries`);
12214
+ const skipCompat = options2.skipCompatCheck || config.skipCompatCheck;
12215
+ if (!skipCompat) {
12216
+ for (const [namespace, index] of registryIndexes) {
12217
+ const issues = collectCompatIssues({
12218
+ registry: { opencode: index.opencode, ocx: index.ocx },
12219
+ ocxVersion: CLI_VERSION
12220
+ });
12221
+ warnCompatIssues(namespace, issues);
12222
+ }
12223
+ }
12042
12224
  if (options2.dryRun) {
12043
12225
  logger.info("");
12044
12226
  logger.info("Dry run - no changes made");
@@ -12123,7 +12305,10 @@ async function runAdd(componentNames, options2) {
12123
12305
  logger.info(` \u2713 Wrote ${f}`);
12124
12306
  }
12125
12307
  }
12126
- const index = await fetchRegistryIndex(component.baseUrl);
12308
+ const index = registryIndexes.get(component.registryName);
12309
+ if (!index) {
12310
+ throw new ValidationError(`Registry index not found for "${component.registryName}". ` + `This is an internal error - please report it at https://github.com/${GITHUB_REPO}/issues`);
12311
+ }
12127
12312
  lock.installed[component.qualifiedName] = {
12128
12313
  registry: component.registryName,
12129
12314
  version: index.version,
@@ -12393,6 +12578,8 @@ async function buildRegistry(options2) {
12393
12578
  namespace: registry.namespace,
12394
12579
  version: registry.version,
12395
12580
  author: registry.author,
12581
+ ...registry.opencode && { opencode: registry.opencode },
12582
+ ...registry.ocx && { ocx: registry.ocx },
12396
12583
  components: registry.components.map((c) => ({
12397
12584
  name: c.name,
12398
12585
  type: c.type,
@@ -13356,12 +13543,6 @@ Diff for ${res.name}:`));
13356
13543
  import { existsSync as existsSync2 } from "fs";
13357
13544
  import { cp, mkdir as mkdir3, readdir, readFile, rm, writeFile as writeFile2 } from "fs/promises";
13358
13545
  import { join as join4 } from "path";
13359
-
13360
- // src/constants.ts
13361
- var OCX_DOMAIN = "ocx.kdco.dev";
13362
- var OCX_SCHEMA_URL = `https://${OCX_DOMAIN}/schema.json`;
13363
-
13364
- // src/commands/init.ts
13365
13546
  var TEMPLATE_REPO = "kdcokenny/ocx";
13366
13547
  var TEMPLATE_PATH = "examples/registry-starter";
13367
13548
  function registerInitCommand(program2) {
@@ -14003,7 +14184,7 @@ async function hashBundle2(files) {
14003
14184
  `));
14004
14185
  }
14005
14186
  // src/index.ts
14006
- var version = "1.0.16";
14187
+ var version = "1.0.18";
14007
14188
  async function main2() {
14008
14189
  const program2 = new Command().name("ocx").description("OpenCode Extensions - Install agents, skills, plugins, and commands").version(version);
14009
14190
  registerInitCommand(program2);
@@ -14029,4 +14210,4 @@ export {
14029
14210
  buildRegistry
14030
14211
  };
14031
14212
 
14032
- //# debugId=2706150244B1090964756E2164756E21
14213
+ //# debugId=EB704B787D95653F64756E2164756E21