ocx 1.0.13 → 1.0.14
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 +121 -5
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13266,7 +13266,7 @@ Diff for ${res.name}:`));
|
|
|
13266
13266
|
|
|
13267
13267
|
// src/commands/init.ts
|
|
13268
13268
|
import { existsSync as existsSync2 } from "fs";
|
|
13269
|
-
import { writeFile as writeFile2 } from "fs/promises";
|
|
13269
|
+
import { cp, mkdir as mkdir3, readdir, readFile, rm, writeFile as writeFile2 } from "fs/promises";
|
|
13270
13270
|
import { join as join4 } from "path";
|
|
13271
13271
|
|
|
13272
13272
|
// src/constants.ts
|
|
@@ -13274,10 +13274,16 @@ var OCX_DOMAIN = "ocx.kdco.dev";
|
|
|
13274
13274
|
var OCX_SCHEMA_URL = `https://${OCX_DOMAIN}/schema.json`;
|
|
13275
13275
|
|
|
13276
13276
|
// src/commands/init.ts
|
|
13277
|
+
var TEMPLATE_REPO = "kdcokenny/ocx";
|
|
13278
|
+
var TEMPLATE_PATH = "examples/registry-starter";
|
|
13277
13279
|
function registerInitCommand(program2) {
|
|
13278
|
-
program2.command("init").description("Initialize OCX configuration in your project").option("-y, --yes", "Skip prompts and use defaults").option("--cwd <path>", "Working directory", process.cwd()).option("-q, --quiet", "Suppress output").option("-v, --verbose", "Verbose output").option("--json", "Output as JSON").action(async (options2) => {
|
|
13280
|
+
program2.command("init [directory]").description("Initialize OCX configuration in your project").option("-y, --yes", "Skip prompts and use defaults").option("--cwd <path>", "Working directory", process.cwd()).option("-q, --quiet", "Suppress output").option("-v, --verbose", "Verbose output").option("--json", "Output as JSON").option("--registry", "Scaffold a new OCX registry project").option("--namespace <name>", "Registry namespace (e.g., my-org)").option("--author <name>", "Author name for the registry").option("--canary", "Use canary (main branch) instead of latest release").option("--local <path>", "Use local template directory instead of fetching").action(async (directory, options2) => {
|
|
13279
13281
|
try {
|
|
13280
|
-
|
|
13282
|
+
if (options2.registry) {
|
|
13283
|
+
await runInitRegistry(directory, options2);
|
|
13284
|
+
} else {
|
|
13285
|
+
await runInit(options2);
|
|
13286
|
+
}
|
|
13281
13287
|
} catch (error) {
|
|
13282
13288
|
handleError(error, { json: options2.json });
|
|
13283
13289
|
}
|
|
@@ -13322,6 +13328,116 @@ async function runInit(options2) {
|
|
|
13322
13328
|
throw error;
|
|
13323
13329
|
}
|
|
13324
13330
|
}
|
|
13331
|
+
async function runInitRegistry(directory, options2) {
|
|
13332
|
+
const cwd = directory ?? options2.cwd ?? process.cwd();
|
|
13333
|
+
const namespace = options2.namespace ?? "my-registry";
|
|
13334
|
+
const author = options2.author ?? "Your Name";
|
|
13335
|
+
if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(namespace)) {
|
|
13336
|
+
throw new ValidationError("Invalid namespace format: must start with letter/number, use hyphens only between segments (e.g., 'my-registry')");
|
|
13337
|
+
}
|
|
13338
|
+
const existingFiles = await readdir(cwd).catch(() => []);
|
|
13339
|
+
const hasVisibleFiles = existingFiles.some((f) => !f.startsWith("."));
|
|
13340
|
+
if (hasVisibleFiles && !options2.yes) {
|
|
13341
|
+
throw new ConflictError("Directory is not empty. Use --yes to overwrite existing files.");
|
|
13342
|
+
}
|
|
13343
|
+
const spin = options2.quiet ? null : createSpinner({ text: "Scaffolding registry..." });
|
|
13344
|
+
spin?.start();
|
|
13345
|
+
try {
|
|
13346
|
+
if (spin)
|
|
13347
|
+
spin.text = options2.local ? "Copying template..." : "Fetching template...";
|
|
13348
|
+
if (options2.local) {
|
|
13349
|
+
await mkdir3(cwd, { recursive: true });
|
|
13350
|
+
await copyDir(options2.local, cwd);
|
|
13351
|
+
} else {
|
|
13352
|
+
const version = options2.canary ? "main" : await getLatestVersion();
|
|
13353
|
+
await fetchAndExtractTemplate(cwd, version, options2.verbose);
|
|
13354
|
+
}
|
|
13355
|
+
if (spin)
|
|
13356
|
+
spin.text = "Configuring project...";
|
|
13357
|
+
await replacePlaceholders(cwd, { namespace, author });
|
|
13358
|
+
spin?.succeed(`Created registry: ${namespace}`);
|
|
13359
|
+
if (options2.json) {
|
|
13360
|
+
console.log(JSON.stringify({ success: true, namespace, path: cwd }));
|
|
13361
|
+
} else if (!options2.quiet) {
|
|
13362
|
+
logger.info("");
|
|
13363
|
+
logger.info("Next steps:");
|
|
13364
|
+
logger.info(" 1. bun install");
|
|
13365
|
+
logger.info(" 2. Edit registry.json with your components");
|
|
13366
|
+
logger.info(" 3. bun run build");
|
|
13367
|
+
logger.info("");
|
|
13368
|
+
logger.info("Deploy to:");
|
|
13369
|
+
logger.info(" Cloudflare: bunx wrangler deploy");
|
|
13370
|
+
logger.info(" Vercel: vercel");
|
|
13371
|
+
logger.info(" Netlify: netlify deploy");
|
|
13372
|
+
}
|
|
13373
|
+
} catch (error) {
|
|
13374
|
+
spin?.fail("Failed to scaffold registry");
|
|
13375
|
+
throw error;
|
|
13376
|
+
}
|
|
13377
|
+
}
|
|
13378
|
+
async function copyDir(src, dest) {
|
|
13379
|
+
await cp(src, dest, { recursive: true });
|
|
13380
|
+
}
|
|
13381
|
+
async function getLatestVersion() {
|
|
13382
|
+
const pkgPath = new URL("../../package.json", import.meta.url);
|
|
13383
|
+
const pkgContent = await readFile(pkgPath);
|
|
13384
|
+
const pkg = JSON.parse(pkgContent.toString());
|
|
13385
|
+
return `v${pkg.version}`;
|
|
13386
|
+
}
|
|
13387
|
+
async function fetchAndExtractTemplate(destDir, version, verbose) {
|
|
13388
|
+
const ref = version === "main" ? "heads/main" : `tags/${version}`;
|
|
13389
|
+
const tarballUrl = `https://github.com/${TEMPLATE_REPO}/archive/refs/${ref}.tar.gz`;
|
|
13390
|
+
if (verbose) {
|
|
13391
|
+
logger.info(`Fetching ${tarballUrl}`);
|
|
13392
|
+
}
|
|
13393
|
+
const response = await fetch(tarballUrl);
|
|
13394
|
+
if (!response.ok || !response.body) {
|
|
13395
|
+
throw new NetworkError(`Failed to fetch template from ${tarballUrl}: ${response.statusText}`);
|
|
13396
|
+
}
|
|
13397
|
+
const tempDir = join4(destDir, ".ocx-temp");
|
|
13398
|
+
await mkdir3(tempDir, { recursive: true });
|
|
13399
|
+
try {
|
|
13400
|
+
const tarPath = join4(tempDir, "template.tar.gz");
|
|
13401
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
13402
|
+
await writeFile2(tarPath, Buffer.from(arrayBuffer));
|
|
13403
|
+
const proc = Bun.spawn(["tar", "-xzf", tarPath, "-C", tempDir], {
|
|
13404
|
+
stdout: "ignore",
|
|
13405
|
+
stderr: "pipe"
|
|
13406
|
+
});
|
|
13407
|
+
const exitCode = await proc.exited;
|
|
13408
|
+
if (exitCode !== 0) {
|
|
13409
|
+
const stderr = await new Response(proc.stderr).text();
|
|
13410
|
+
throw new Error(`Failed to extract template: ${stderr}`);
|
|
13411
|
+
}
|
|
13412
|
+
const extractedDirs = await readdir(tempDir);
|
|
13413
|
+
const extractedDir = extractedDirs.find((d) => d.startsWith("ocx-"));
|
|
13414
|
+
if (!extractedDir) {
|
|
13415
|
+
throw new Error("Failed to find extracted template directory");
|
|
13416
|
+
}
|
|
13417
|
+
const templateDir = join4(tempDir, extractedDir, TEMPLATE_PATH);
|
|
13418
|
+
await copyDir(templateDir, destDir);
|
|
13419
|
+
} finally {
|
|
13420
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
13421
|
+
}
|
|
13422
|
+
}
|
|
13423
|
+
async function replacePlaceholders(dir, values) {
|
|
13424
|
+
const filesToProcess = [
|
|
13425
|
+
"registry.json",
|
|
13426
|
+
"package.json",
|
|
13427
|
+
"wrangler.jsonc",
|
|
13428
|
+
"README.md",
|
|
13429
|
+
"AGENTS.md"
|
|
13430
|
+
];
|
|
13431
|
+
for (const file of filesToProcess) {
|
|
13432
|
+
const filePath = join4(dir, file);
|
|
13433
|
+
if (!existsSync2(filePath))
|
|
13434
|
+
continue;
|
|
13435
|
+
let content2 = await readFile(filePath).then((b) => b.toString());
|
|
13436
|
+
content2 = content2.replace(/my-registry/g, values.namespace);
|
|
13437
|
+
content2 = content2.replace(/Your Name/g, values.author);
|
|
13438
|
+
await writeFile2(filePath, content2);
|
|
13439
|
+
}
|
|
13440
|
+
}
|
|
13325
13441
|
|
|
13326
13442
|
// src/commands/registry.ts
|
|
13327
13443
|
function registerRegistryCommand(program2) {
|
|
@@ -13520,7 +13636,7 @@ function registerSearchCommand(program2) {
|
|
|
13520
13636
|
});
|
|
13521
13637
|
}
|
|
13522
13638
|
// src/index.ts
|
|
13523
|
-
var version = "1.0.
|
|
13639
|
+
var version = "1.0.14";
|
|
13524
13640
|
async function main2() {
|
|
13525
13641
|
const program2 = new Command().name("ocx").description("OpenCode Extensions - Install agents, skills, plugins, and commands").version(version);
|
|
13526
13642
|
registerInitCommand(program2);
|
|
@@ -13545,4 +13661,4 @@ export {
|
|
|
13545
13661
|
buildRegistry
|
|
13546
13662
|
};
|
|
13547
13663
|
|
|
13548
|
-
//# debugId=
|
|
13664
|
+
//# debugId=8679B4448163A59C64756E2164756E21
|