ocx 1.1.0 → 1.1.1

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
@@ -10432,7 +10432,7 @@ class GhostConfigProvider {
10432
10432
  // package.json
10433
10433
  var package_default = {
10434
10434
  name: "ocx",
10435
- version: "1.1.0",
10435
+ version: "1.1.1",
10436
10436
  description: "OCX CLI - ShadCN-style registry for OpenCode extensions. Install agents, plugins, skills, and MCP servers.",
10437
10437
  author: "kdcokenny",
10438
10438
  license: "MIT",
@@ -14184,12 +14184,9 @@ var DEFAULT_GHOST_CONFIG = `{
14184
14184
  // This config is used when running commands with \`ocx ghost\` or \`ocx g\`
14185
14185
  // Note: OpenCode settings go in ~/.config/ocx/opencode.jsonc (see: ocx ghost opencode --edit)
14186
14186
 
14187
- // Component registries to use
14188
- "registries": {
14189
- "default": {
14190
- "url": "https://registry.opencode.ai"
14191
- }
14192
- },
14187
+ // Component registries - add your registries here
14188
+ // Example: "myregistry": { "url": "https://example.com/registry" }
14189
+ "registries": {},
14193
14190
 
14194
14191
  // Where to install components (relative to project root)
14195
14192
  "componentPath": "src/components"
@@ -14332,9 +14329,9 @@ function filterExcludedPaths(excludedPaths, includePatterns, excludePatterns) {
14332
14329
 
14333
14330
  // src/utils/symlink-farm.ts
14334
14331
  import { randomBytes } from "crypto";
14335
- import { readdir, rename, rm, stat, symlink } from "fs/promises";
14332
+ import { mkdir as mkdir5, readdir, rename, rm, stat, symlink } from "fs/promises";
14336
14333
  import { tmpdir } from "os";
14337
- import { isAbsolute, join as join6 } from "path";
14334
+ import { dirname as dirname5, isAbsolute, join as join6, relative as relative2 } from "path";
14338
14335
  var STALE_SESSION_THRESHOLD_MS = 24 * 60 * 60 * 1000;
14339
14336
  var REMOVING_THRESHOLD_MS = 60 * 60 * 1000;
14340
14337
  var GHOST_DIR_PREFIX = "ocx-ghost-";
@@ -14362,6 +14359,32 @@ async function createSymlinkFarm(sourceDir, excludePaths) {
14362
14359
  throw error;
14363
14360
  }
14364
14361
  }
14362
+ async function injectGhostFiles(tempDir, sourceDir, injectPaths) {
14363
+ if (!isAbsolute(tempDir)) {
14364
+ throw new Error(`tempDir must be an absolute path, got: ${tempDir}`);
14365
+ }
14366
+ if (!isAbsolute(sourceDir)) {
14367
+ throw new Error(`sourceDir must be an absolute path, got: ${sourceDir}`);
14368
+ }
14369
+ for (const injectPath of injectPaths) {
14370
+ const relativePath = relative2(sourceDir, injectPath);
14371
+ if (relativePath.startsWith("..") || isAbsolute(relativePath)) {
14372
+ throw new Error(`injectPath must be within sourceDir: ${injectPath}`);
14373
+ }
14374
+ const targetPath = join6(tempDir, relativePath);
14375
+ const parentDir = dirname5(targetPath);
14376
+ if (parentDir !== tempDir) {
14377
+ await mkdir5(parentDir, { recursive: true });
14378
+ }
14379
+ try {
14380
+ await symlink(injectPath, targetPath);
14381
+ } catch (err) {
14382
+ if (err.code !== "EEXIST") {
14383
+ throw new Error(`Failed to inject ${injectPath} \u2192 ${targetPath}: ${err.message}`);
14384
+ }
14385
+ }
14386
+ }
14387
+ }
14365
14388
  async function cleanupSymlinkFarm(tempDir) {
14366
14389
  const removingPath = `${tempDir}${REMOVING_SUFFIX}`;
14367
14390
  try {
@@ -14442,6 +14465,8 @@ async function runGhostOpenCode(args, options2) {
14442
14465
  const ghostConfig = await loadGhostConfig();
14443
14466
  const excludePaths = filterExcludedPaths(discoveredPaths, ghostConfig.include, ghostConfig.exclude);
14444
14467
  const tempDir = await createSymlinkFarm(cwd, excludePaths);
14468
+ const ghostFiles = await discoverProjectFiles(ghostConfigDir, ghostConfigDir);
14469
+ await injectGhostFiles(tempDir, ghostConfigDir, ghostFiles);
14445
14470
  let cleanupDone = false;
14446
14471
  const performCleanup = async () => {
14447
14472
  if (cleanupDone)
@@ -14859,7 +14884,7 @@ function registerGhostCommand(program2) {
14859
14884
 
14860
14885
  // src/commands/init.ts
14861
14886
  import { existsSync as existsSync2 } from "fs";
14862
- import { cp, mkdir as mkdir5, readdir as readdir2, readFile, rm as rm2, writeFile as writeFile3 } from "fs/promises";
14887
+ import { cp, mkdir as mkdir6, readdir as readdir2, readFile, rm as rm2, writeFile as writeFile3 } from "fs/promises";
14863
14888
  import { join as join7 } from "path";
14864
14889
  var TEMPLATE_REPO = "kdcokenny/ocx";
14865
14890
  var TEMPLATE_PATH = "examples/registry-starter";
@@ -14937,7 +14962,7 @@ async function runInitRegistry(directory, options2) {
14937
14962
  if (spin)
14938
14963
  spin.text = options2.local ? "Copying template..." : "Fetching template...";
14939
14964
  if (options2.local) {
14940
- await mkdir5(cwd, { recursive: true });
14965
+ await mkdir6(cwd, { recursive: true });
14941
14966
  await copyDir(options2.local, cwd);
14942
14967
  } else {
14943
14968
  const version = options2.canary ? "main" : await getLatestVersion();
@@ -14986,7 +15011,7 @@ async function fetchAndExtractTemplate(destDir, version, verbose) {
14986
15011
  throw new NetworkError(`Failed to fetch template from ${tarballUrl}: ${response.statusText}`);
14987
15012
  }
14988
15013
  const tempDir = join7(destDir, ".ocx-temp");
14989
- await mkdir5(tempDir, { recursive: true });
15014
+ await mkdir6(tempDir, { recursive: true });
14990
15015
  try {
14991
15016
  const tarPath = join7(tempDir, "template.tar.gz");
14992
15017
  const arrayBuffer = await response.arrayBuffer();
@@ -15033,8 +15058,8 @@ async function replacePlaceholders(dir, values) {
15033
15058
  // src/commands/update.ts
15034
15059
  import { createHash as createHash2 } from "crypto";
15035
15060
  import { existsSync as existsSync3 } from "fs";
15036
- import { mkdir as mkdir6, writeFile as writeFile4 } from "fs/promises";
15037
- import { dirname as dirname5, join as join8 } from "path";
15061
+ import { mkdir as mkdir7, writeFile as writeFile4 } from "fs/promises";
15062
+ import { dirname as dirname6, join as join8 } from "path";
15038
15063
  function registerUpdateCommand(program2) {
15039
15064
  program2.command("update [components...]").description("Update installed components (use @version suffix to pin, e.g., kdco/agents@1.2.0)").option("--all", "Update all installed components").option("--registry <name>", "Update all components from a specific registry").option("--dry-run", "Preview changes without applying").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) => {
15040
15065
  try {
@@ -15172,9 +15197,9 @@ Version cannot be empty. Use 'kdco/agents@1.2.0' or omit the version for latest.
15172
15197
  if (!fileObj)
15173
15198
  continue;
15174
15199
  const targetPath = join8(cwd, fileObj.target);
15175
- const targetDir = dirname5(targetPath);
15200
+ const targetDir = dirname6(targetPath);
15176
15201
  if (!existsSync3(targetDir)) {
15177
- await mkdir6(targetDir, { recursive: true });
15202
+ await mkdir7(targetDir, { recursive: true });
15178
15203
  }
15179
15204
  await writeFile4(targetPath, file.content);
15180
15205
  if (options2.verbose) {
@@ -15309,7 +15334,7 @@ async function hashBundle2(files) {
15309
15334
  `));
15310
15335
  }
15311
15336
  // src/index.ts
15312
- var version = "1.1.0";
15337
+ var version = "1.1.1";
15313
15338
  async function main2() {
15314
15339
  const program2 = new Command().name("ocx").description("OpenCode Extensions - Install agents, skills, plugins, and commands").version(version);
15315
15340
  registerInitCommand(program2);
@@ -15336,4 +15361,4 @@ export {
15336
15361
  buildRegistry
15337
15362
  };
15338
15363
 
15339
- //# debugId=46A2A0DCEF36C6A464756E2164756E21
15364
+ //# debugId=66554E2EE245482F64756E2164756E21