ocx 1.2.0 → 1.2.2
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 +272 -59
- package/dist/index.js.map +9 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10528,7 +10528,7 @@ class GhostConfigProvider {
|
|
|
10528
10528
|
// package.json
|
|
10529
10529
|
var package_default = {
|
|
10530
10530
|
name: "ocx",
|
|
10531
|
-
version: "1.2.
|
|
10531
|
+
version: "1.2.2",
|
|
10532
10532
|
description: "OCX CLI - ShadCN-style registry for OpenCode extensions. Install agents, plugins, skills, and MCP servers.",
|
|
10533
10533
|
author: "kdcokenny",
|
|
10534
10534
|
license: "MIT",
|
|
@@ -10921,14 +10921,15 @@ var isCI = Boolean(process.env.CI || process.env.GITHUB_ACTIONS || process.env.G
|
|
|
10921
10921
|
var isTTY = Boolean(process.stdout.isTTY && !isCI);
|
|
10922
10922
|
var supportsColor = Boolean(isTTY && process.env.FORCE_COLOR !== "0" && process.env.NO_COLOR === undefined);
|
|
10923
10923
|
// src/utils/git-context.ts
|
|
10924
|
-
import { resolve } from "path";
|
|
10924
|
+
import { basename, resolve } from "path";
|
|
10925
|
+
function getGitEnv() {
|
|
10926
|
+
const { GIT_DIR: _, GIT_WORK_TREE: __, ...cleanEnv } = process.env;
|
|
10927
|
+
return cleanEnv;
|
|
10928
|
+
}
|
|
10925
10929
|
async function detectGitRepo(cwd) {
|
|
10926
|
-
const cleanEnv = { ...process.env };
|
|
10927
|
-
delete cleanEnv.GIT_DIR;
|
|
10928
|
-
delete cleanEnv.GIT_WORK_TREE;
|
|
10929
10930
|
const gitDirProc = Bun.spawn(["git", "rev-parse", "--git-dir"], {
|
|
10930
10931
|
cwd,
|
|
10931
|
-
env:
|
|
10932
|
+
env: getGitEnv(),
|
|
10932
10933
|
stdout: "pipe",
|
|
10933
10934
|
stderr: "pipe"
|
|
10934
10935
|
});
|
|
@@ -10943,7 +10944,7 @@ async function detectGitRepo(cwd) {
|
|
|
10943
10944
|
}
|
|
10944
10945
|
const workTreeProc = Bun.spawn(["git", "rev-parse", "--show-toplevel"], {
|
|
10945
10946
|
cwd,
|
|
10946
|
-
env:
|
|
10947
|
+
env: getGitEnv(),
|
|
10947
10948
|
stdout: "pipe",
|
|
10948
10949
|
stderr: "pipe"
|
|
10949
10950
|
});
|
|
@@ -10959,6 +10960,73 @@ async function detectGitRepo(cwd) {
|
|
|
10959
10960
|
const gitDir = resolve(cwd, gitDirRaw);
|
|
10960
10961
|
return { gitDir, workTree };
|
|
10961
10962
|
}
|
|
10963
|
+
async function getBranch(cwd) {
|
|
10964
|
+
const symbolicProc = Bun.spawn(["git", "symbolic-ref", "--short", "HEAD"], {
|
|
10965
|
+
cwd,
|
|
10966
|
+
env: getGitEnv(),
|
|
10967
|
+
stdout: "pipe",
|
|
10968
|
+
stderr: "pipe"
|
|
10969
|
+
});
|
|
10970
|
+
const symbolicExitCode = await symbolicProc.exited;
|
|
10971
|
+
if (symbolicExitCode === 0) {
|
|
10972
|
+
const output = await new Response(symbolicProc.stdout).text();
|
|
10973
|
+
const branch = output.trim();
|
|
10974
|
+
if (branch) {
|
|
10975
|
+
return branch;
|
|
10976
|
+
}
|
|
10977
|
+
}
|
|
10978
|
+
const tagProc = Bun.spawn(["git", "describe", "--tags", "--exact-match", "HEAD"], {
|
|
10979
|
+
cwd,
|
|
10980
|
+
env: getGitEnv(),
|
|
10981
|
+
stdout: "pipe",
|
|
10982
|
+
stderr: "pipe"
|
|
10983
|
+
});
|
|
10984
|
+
const tagExitCode = await tagProc.exited;
|
|
10985
|
+
if (tagExitCode === 0) {
|
|
10986
|
+
const output = await new Response(tagProc.stdout).text();
|
|
10987
|
+
const tag = output.trim();
|
|
10988
|
+
if (tag) {
|
|
10989
|
+
return tag;
|
|
10990
|
+
}
|
|
10991
|
+
}
|
|
10992
|
+
const hashProc = Bun.spawn(["git", "rev-parse", "--short", "HEAD"], {
|
|
10993
|
+
cwd,
|
|
10994
|
+
env: getGitEnv(),
|
|
10995
|
+
stdout: "pipe",
|
|
10996
|
+
stderr: "pipe"
|
|
10997
|
+
});
|
|
10998
|
+
const hashExitCode = await hashProc.exited;
|
|
10999
|
+
if (hashExitCode === 0) {
|
|
11000
|
+
const output = await new Response(hashProc.stdout).text();
|
|
11001
|
+
const hash = output.trim();
|
|
11002
|
+
if (hash) {
|
|
11003
|
+
return hash;
|
|
11004
|
+
}
|
|
11005
|
+
}
|
|
11006
|
+
return null;
|
|
11007
|
+
}
|
|
11008
|
+
async function getRepoName(cwd) {
|
|
11009
|
+
const proc = Bun.spawn(["git", "rev-parse", "--show-toplevel"], {
|
|
11010
|
+
cwd,
|
|
11011
|
+
env: getGitEnv(),
|
|
11012
|
+
stdout: "pipe",
|
|
11013
|
+
stderr: "pipe"
|
|
11014
|
+
});
|
|
11015
|
+
const exitCode = await proc.exited;
|
|
11016
|
+
if (exitCode !== 0) {
|
|
11017
|
+
return null;
|
|
11018
|
+
}
|
|
11019
|
+
const output = await new Response(proc.stdout).text();
|
|
11020
|
+
const rootPath = output.trim();
|
|
11021
|
+
if (!rootPath) {
|
|
11022
|
+
return null;
|
|
11023
|
+
}
|
|
11024
|
+
return basename(rootPath);
|
|
11025
|
+
}
|
|
11026
|
+
async function getGitInfo(cwd) {
|
|
11027
|
+
const [repoName, branch] = await Promise.all([getRepoName(cwd), getBranch(cwd)]);
|
|
11028
|
+
return { repoName, branch };
|
|
11029
|
+
}
|
|
10962
11030
|
// ../../node_modules/.bun/kleur@4.1.5/node_modules/kleur/index.mjs
|
|
10963
11031
|
var FORCE_COLOR;
|
|
10964
11032
|
var NODE_DISABLE_COLORS;
|
|
@@ -14454,7 +14522,7 @@ Profile location:`);
|
|
|
14454
14522
|
// src/commands/ghost/opencode.ts
|
|
14455
14523
|
import { renameSync, rmSync } from "fs";
|
|
14456
14524
|
import { copyFile as copyFilePromise } from "fs/promises";
|
|
14457
|
-
import
|
|
14525
|
+
import path8 from "path";
|
|
14458
14526
|
|
|
14459
14527
|
// src/utils/opencode-discovery.ts
|
|
14460
14528
|
import { exists } from "fs/promises";
|
|
@@ -14517,40 +14585,73 @@ async function discoverProjectFiles(start, stop) {
|
|
|
14517
14585
|
return excluded;
|
|
14518
14586
|
}
|
|
14519
14587
|
|
|
14588
|
+
// src/utils/symlink-farm.ts
|
|
14589
|
+
import { randomBytes } from "crypto";
|
|
14590
|
+
import { mkdir as mkdir4, readdir as readdir3, rename as rename3, rm as rm2, stat as stat3, symlink as symlink2 } from "fs/promises";
|
|
14591
|
+
import { tmpdir } from "os";
|
|
14592
|
+
import { dirname as dirname4, isAbsolute, join as join5, relative as relative2 } from "path";
|
|
14593
|
+
|
|
14520
14594
|
// src/utils/pattern-filter.ts
|
|
14595
|
+
import path6 from "path";
|
|
14521
14596
|
var {Glob: Glob2 } = globalThis.Bun;
|
|
14522
|
-
function
|
|
14523
|
-
|
|
14524
|
-
|
|
14525
|
-
|
|
14526
|
-
|
|
14527
|
-
|
|
14528
|
-
|
|
14529
|
-
|
|
14530
|
-
|
|
14531
|
-
|
|
14532
|
-
|
|
14533
|
-
|
|
14534
|
-
|
|
14535
|
-
|
|
14536
|
-
|
|
14597
|
+
function normalizeForMatching(absolutePath, projectRoot) {
|
|
14598
|
+
const relativePath = path6.relative(projectRoot, absolutePath);
|
|
14599
|
+
return relativePath.split(path6.sep).join("/").replace(/^\.\//, "");
|
|
14600
|
+
}
|
|
14601
|
+
class PathMatcher {
|
|
14602
|
+
includeGlobs;
|
|
14603
|
+
excludeGlobs;
|
|
14604
|
+
includePatterns;
|
|
14605
|
+
constructor(includePatterns = [], excludePatterns = []) {
|
|
14606
|
+
this.includePatterns = includePatterns;
|
|
14607
|
+
this.includeGlobs = includePatterns.map((p) => ({ pattern: p, glob: new Glob2(p) }));
|
|
14608
|
+
this.excludeGlobs = excludePatterns.map((p) => ({ pattern: p, glob: new Glob2(p) }));
|
|
14609
|
+
}
|
|
14610
|
+
getDisposition(relativePath) {
|
|
14611
|
+
if (this.excludeGlobs.some((g) => g.glob.match(relativePath))) {
|
|
14612
|
+
return { type: "excluded" };
|
|
14613
|
+
}
|
|
14614
|
+
if (this.includeGlobs.some((g) => g.glob.match(relativePath))) {
|
|
14615
|
+
return { type: "included" };
|
|
14616
|
+
}
|
|
14617
|
+
const patternsInsideDir = this.includePatterns.filter((pattern) => {
|
|
14618
|
+
if (pattern.startsWith(`${relativePath}/`))
|
|
14619
|
+
return true;
|
|
14620
|
+
if (pattern.startsWith("**/"))
|
|
14621
|
+
return true;
|
|
14622
|
+
return false;
|
|
14623
|
+
});
|
|
14624
|
+
if (patternsInsideDir.length > 0) {
|
|
14625
|
+
return { type: "partial", patterns: patternsInsideDir };
|
|
14537
14626
|
}
|
|
14538
|
-
|
|
14627
|
+
if (this.includePatterns.length > 0) {
|
|
14628
|
+
return { type: "excluded" };
|
|
14629
|
+
}
|
|
14630
|
+
return { type: "included" };
|
|
14631
|
+
}
|
|
14632
|
+
targetsInside(dirPath) {
|
|
14633
|
+
const normalizedDir = dirPath.endsWith("/") ? dirPath : `${dirPath}/`;
|
|
14634
|
+
return this.includePatterns.some((p) => p.startsWith(normalizedDir));
|
|
14635
|
+
}
|
|
14636
|
+
getInnerPatterns(dirPath) {
|
|
14637
|
+
const normalizedDir = dirPath.endsWith("/") ? dirPath : `${dirPath}/`;
|
|
14638
|
+
return this.includePatterns.filter((p) => p.startsWith(normalizedDir));
|
|
14539
14639
|
}
|
|
14540
|
-
|
|
14640
|
+
hasIncludePatterns() {
|
|
14641
|
+
return this.includePatterns.length > 0;
|
|
14642
|
+
}
|
|
14643
|
+
}
|
|
14644
|
+
function createPathMatcher(includePatterns = [], excludePatterns = []) {
|
|
14645
|
+
return new PathMatcher(includePatterns, excludePatterns);
|
|
14541
14646
|
}
|
|
14542
14647
|
|
|
14543
14648
|
// src/utils/symlink-farm.ts
|
|
14544
|
-
import { randomBytes } from "crypto";
|
|
14545
|
-
import { mkdir as mkdir4, readdir as readdir3, rename as rename3, rm as rm2, stat as stat3, symlink as symlink2 } from "fs/promises";
|
|
14546
|
-
import { tmpdir } from "os";
|
|
14547
|
-
import { dirname as dirname4, isAbsolute, join as join5, relative as relative2 } from "path";
|
|
14548
14649
|
var STALE_SESSION_THRESHOLD_MS = 24 * 60 * 60 * 1000;
|
|
14549
14650
|
var REMOVING_THRESHOLD_MS = 60 * 60 * 1000;
|
|
14550
14651
|
var GHOST_DIR_PREFIX = "ocx-ghost-";
|
|
14551
14652
|
var REMOVING_SUFFIX = "-removing";
|
|
14552
14653
|
var GHOST_MARKER_FILE = ".ocx-ghost-marker";
|
|
14553
|
-
async function createSymlinkFarm(sourceDir, excludePaths) {
|
|
14654
|
+
async function createSymlinkFarm(sourceDir, excludePaths, options2) {
|
|
14554
14655
|
if (!isAbsolute(sourceDir)) {
|
|
14555
14656
|
throw new Error(`sourceDir must be an absolute path, got: ${sourceDir}`);
|
|
14556
14657
|
}
|
|
@@ -14558,14 +14659,9 @@ async function createSymlinkFarm(sourceDir, excludePaths) {
|
|
|
14558
14659
|
const tempDir = join5(tmpdir(), `${GHOST_DIR_PREFIX}${suffix}`);
|
|
14559
14660
|
await Bun.write(join5(tempDir, GHOST_MARKER_FILE), "");
|
|
14560
14661
|
try {
|
|
14561
|
-
const
|
|
14562
|
-
|
|
14563
|
-
|
|
14564
|
-
if (excludePaths.has(sourcePath))
|
|
14565
|
-
continue;
|
|
14566
|
-
const targetPath = join5(tempDir, entry.name);
|
|
14567
|
-
await symlink2(sourcePath, targetPath);
|
|
14568
|
-
}
|
|
14662
|
+
const matcher = createPathMatcher(options2?.includePatterns ?? [], options2?.excludePatterns ?? []);
|
|
14663
|
+
const plan = await computeSymlinkPlan(sourceDir, sourceDir, excludePaths, matcher);
|
|
14664
|
+
await executeSymlinkPlan(plan, sourceDir, tempDir);
|
|
14569
14665
|
return tempDir;
|
|
14570
14666
|
} catch (error) {
|
|
14571
14667
|
await rm2(tempDir, { recursive: true, force: true }).catch(() => {});
|
|
@@ -14649,6 +14745,133 @@ async function cleanupOrphanedGhostDirs(tempBase = tmpdir()) {
|
|
|
14649
14745
|
}
|
|
14650
14746
|
return cleanedCount;
|
|
14651
14747
|
}
|
|
14748
|
+
async function handleExcludedEntry(isDirectory, disposition, computeNestedPlan) {
|
|
14749
|
+
if (disposition.type === "excluded") {
|
|
14750
|
+
return { action: "skip" };
|
|
14751
|
+
}
|
|
14752
|
+
if (disposition.type === "included") {
|
|
14753
|
+
return { action: "includeWhole" };
|
|
14754
|
+
}
|
|
14755
|
+
if (isDirectory) {
|
|
14756
|
+
const nestedPlan = await computeNestedPlan();
|
|
14757
|
+
return { action: "partial", nestedPlan };
|
|
14758
|
+
}
|
|
14759
|
+
return { action: "skip" };
|
|
14760
|
+
}
|
|
14761
|
+
async function computeSymlinkPlan(sourceDir, projectRoot, excludedPaths, matcher, insideExcludedTree = false) {
|
|
14762
|
+
if (!isAbsolute(sourceDir)) {
|
|
14763
|
+
throw new Error(`sourceDir must be an absolute path, got: ${sourceDir}`);
|
|
14764
|
+
}
|
|
14765
|
+
const plan = {
|
|
14766
|
+
wholeDirs: [],
|
|
14767
|
+
files: [],
|
|
14768
|
+
partialDirs: new Map
|
|
14769
|
+
};
|
|
14770
|
+
const entries = await readdir3(sourceDir, { withFileTypes: true });
|
|
14771
|
+
for (const entry of entries) {
|
|
14772
|
+
const sourcePath = join5(sourceDir, entry.name);
|
|
14773
|
+
const relativePath = normalizeForMatching(sourcePath, projectRoot);
|
|
14774
|
+
if (insideExcludedTree) {
|
|
14775
|
+
const disposition = matcher.getDisposition(relativePath);
|
|
14776
|
+
const result = await handleExcludedEntry(entry.isDirectory(), disposition, () => computeSymlinkPlan(sourcePath, projectRoot, excludedPaths, matcher, true));
|
|
14777
|
+
if (result.action === "skip") {
|
|
14778
|
+
continue;
|
|
14779
|
+
}
|
|
14780
|
+
if (result.action === "includeWhole") {
|
|
14781
|
+
if (entry.isDirectory()) {
|
|
14782
|
+
plan.wholeDirs.push(entry.name);
|
|
14783
|
+
} else {
|
|
14784
|
+
plan.files.push(entry.name);
|
|
14785
|
+
}
|
|
14786
|
+
continue;
|
|
14787
|
+
}
|
|
14788
|
+
plan.partialDirs.set(entry.name, result.nestedPlan);
|
|
14789
|
+
continue;
|
|
14790
|
+
}
|
|
14791
|
+
if (excludedPaths.has(sourcePath)) {
|
|
14792
|
+
if (!matcher.hasIncludePatterns()) {
|
|
14793
|
+
continue;
|
|
14794
|
+
}
|
|
14795
|
+
const disposition = matcher.getDisposition(relativePath);
|
|
14796
|
+
const result = await handleExcludedEntry(entry.isDirectory(), disposition, () => computeSymlinkPlan(sourcePath, projectRoot, excludedPaths, matcher, true));
|
|
14797
|
+
if (result.action === "skip") {
|
|
14798
|
+
continue;
|
|
14799
|
+
}
|
|
14800
|
+
if (result.action === "includeWhole") {
|
|
14801
|
+
if (entry.isDirectory()) {
|
|
14802
|
+
plan.wholeDirs.push(entry.name);
|
|
14803
|
+
} else {
|
|
14804
|
+
plan.files.push(entry.name);
|
|
14805
|
+
}
|
|
14806
|
+
continue;
|
|
14807
|
+
}
|
|
14808
|
+
plan.partialDirs.set(entry.name, result.nestedPlan);
|
|
14809
|
+
continue;
|
|
14810
|
+
}
|
|
14811
|
+
if (entry.isDirectory()) {
|
|
14812
|
+
plan.wholeDirs.push(entry.name);
|
|
14813
|
+
} else {
|
|
14814
|
+
plan.files.push(entry.name);
|
|
14815
|
+
}
|
|
14816
|
+
}
|
|
14817
|
+
return plan;
|
|
14818
|
+
}
|
|
14819
|
+
async function executeSymlinkPlan(plan, sourceRoot, targetRoot) {
|
|
14820
|
+
if (!isAbsolute(sourceRoot)) {
|
|
14821
|
+
throw new Error(`sourceRoot must be an absolute path, got: ${sourceRoot}`);
|
|
14822
|
+
}
|
|
14823
|
+
if (!isAbsolute(targetRoot)) {
|
|
14824
|
+
throw new Error(`targetRoot must be an absolute path, got: ${targetRoot}`);
|
|
14825
|
+
}
|
|
14826
|
+
for (const dirName of plan.wholeDirs) {
|
|
14827
|
+
const sourcePath = join5(sourceRoot, dirName);
|
|
14828
|
+
const targetPath = join5(targetRoot, dirName);
|
|
14829
|
+
await symlink2(sourcePath, targetPath);
|
|
14830
|
+
}
|
|
14831
|
+
for (const fileName of plan.files) {
|
|
14832
|
+
const sourcePath = join5(sourceRoot, fileName);
|
|
14833
|
+
const targetPath = join5(targetRoot, fileName);
|
|
14834
|
+
await symlink2(sourcePath, targetPath);
|
|
14835
|
+
}
|
|
14836
|
+
for (const [dirName, nestedPlan] of plan.partialDirs) {
|
|
14837
|
+
const sourcePath = join5(sourceRoot, dirName);
|
|
14838
|
+
const targetPath = join5(targetRoot, dirName);
|
|
14839
|
+
await mkdir4(targetPath, { recursive: true });
|
|
14840
|
+
await executeSymlinkPlan(nestedPlan, sourcePath, targetPath);
|
|
14841
|
+
}
|
|
14842
|
+
}
|
|
14843
|
+
|
|
14844
|
+
// src/utils/terminal-title.ts
|
|
14845
|
+
import path7 from "path";
|
|
14846
|
+
var MAX_BRANCH_LENGTH = 20;
|
|
14847
|
+
function isInsideTmux() {
|
|
14848
|
+
return Boolean(process.env.TMUX);
|
|
14849
|
+
}
|
|
14850
|
+
function setTmuxWindowName(name) {
|
|
14851
|
+
if (!isInsideTmux()) {
|
|
14852
|
+
return;
|
|
14853
|
+
}
|
|
14854
|
+
Bun.spawnSync(["tmux", "rename-window", name]);
|
|
14855
|
+
Bun.spawnSync(["tmux", "set-window-option", "automatic-rename", "off"]);
|
|
14856
|
+
}
|
|
14857
|
+
function setTerminalTitle(title) {
|
|
14858
|
+
if (!isTTY) {
|
|
14859
|
+
return;
|
|
14860
|
+
}
|
|
14861
|
+
process.stdout.write(`\x1B]0;${title}\x07`);
|
|
14862
|
+
}
|
|
14863
|
+
function setTerminalName(name) {
|
|
14864
|
+
setTmuxWindowName(name);
|
|
14865
|
+
setTerminalTitle(name);
|
|
14866
|
+
}
|
|
14867
|
+
function formatTerminalName(cwd, profileName, gitInfo) {
|
|
14868
|
+
const repoName = gitInfo.repoName ?? path7.basename(cwd);
|
|
14869
|
+
if (!gitInfo.branch) {
|
|
14870
|
+
return `ghost[${profileName}]:${repoName}`;
|
|
14871
|
+
}
|
|
14872
|
+
const branch = gitInfo.branch.length > MAX_BRANCH_LENGTH ? `${gitInfo.branch.slice(0, MAX_BRANCH_LENGTH - 3)}...` : gitInfo.branch;
|
|
14873
|
+
return `ghost[${profileName}]:${repoName}/${branch}`;
|
|
14874
|
+
}
|
|
14652
14875
|
|
|
14653
14876
|
// src/commands/ghost/opencode.ts
|
|
14654
14877
|
function registerGhostOpenCodeCommand(parent) {
|
|
@@ -14686,13 +14909,15 @@ async function runGhostOpenCode(args, options2) {
|
|
|
14686
14909
|
const gitRoot = gitContext?.workTree ?? cwd;
|
|
14687
14910
|
const discoveredPaths = await discoverProjectFiles(cwd, gitRoot);
|
|
14688
14911
|
const ghostConfig = profile.ghost;
|
|
14689
|
-
const
|
|
14690
|
-
|
|
14912
|
+
const tempDir = await createSymlinkFarm(cwd, discoveredPaths, {
|
|
14913
|
+
includePatterns: ghostConfig.include,
|
|
14914
|
+
excludePatterns: ghostConfig.exclude
|
|
14915
|
+
});
|
|
14691
14916
|
const ghostFiles = await discoverProjectFiles(profileDir, profileDir);
|
|
14692
14917
|
await injectGhostFiles(tempDir, profileDir, ghostFiles);
|
|
14693
14918
|
if (profile.hasAgents) {
|
|
14694
14919
|
const agentsPath = getProfileAgents(profileName);
|
|
14695
|
-
const destAgentsPath =
|
|
14920
|
+
const destAgentsPath = path8.join(tempDir, "AGENTS.md");
|
|
14696
14921
|
await copyFilePromise(agentsPath, destAgentsPath);
|
|
14697
14922
|
}
|
|
14698
14923
|
let cleanupDone = false;
|
|
@@ -14717,6 +14942,8 @@ async function runGhostOpenCode(args, options2) {
|
|
|
14717
14942
|
const sigtermHandler = () => proc?.kill("SIGTERM");
|
|
14718
14943
|
process.on("SIGINT", sigintHandler);
|
|
14719
14944
|
process.on("SIGTERM", sigtermHandler);
|
|
14945
|
+
const gitInfo = await getGitInfo(cwd);
|
|
14946
|
+
setTerminalName(formatTerminalName(cwd, profileName, gitInfo));
|
|
14720
14947
|
proc = Bun.spawn({
|
|
14721
14948
|
cmd: ["opencode", ...args],
|
|
14722
14949
|
cwd: tempDir,
|
|
@@ -14833,7 +15060,7 @@ async function runProfileList(options2) {
|
|
|
14833
15060
|
|
|
14834
15061
|
// src/commands/ghost/profile/remove.ts
|
|
14835
15062
|
function registerProfileRemoveCommand(parent) {
|
|
14836
|
-
parent.command("remove <name>").alias("rm").description("Delete a ghost profile").option("-f, --force", "
|
|
15063
|
+
parent.command("remove <name>").alias("rm").description("Delete a ghost profile").option("-f, --force", "Allow deleting current profile").action(async (name, options2) => {
|
|
14837
15064
|
try {
|
|
14838
15065
|
await runProfileRemove(name, options2);
|
|
14839
15066
|
} catch (error) {
|
|
@@ -14846,23 +15073,9 @@ async function runProfileRemove(name, options2) {
|
|
|
14846
15073
|
if (!await manager.exists(name)) {
|
|
14847
15074
|
throw new ProfileNotFoundError(name);
|
|
14848
15075
|
}
|
|
14849
|
-
|
|
14850
|
-
if (!isTTY) {
|
|
14851
|
-
throw new ValidationError("Cannot confirm deletion in non-interactive mode. Use --force to delete without confirmation.");
|
|
14852
|
-
}
|
|
14853
|
-
const confirmed = confirmDeletion(name);
|
|
14854
|
-
if (!confirmed) {
|
|
14855
|
-
console.log("Aborted.");
|
|
14856
|
-
return;
|
|
14857
|
-
}
|
|
14858
|
-
}
|
|
14859
|
-
await manager.remove(name, options2.force);
|
|
15076
|
+
await manager.remove(name, options2.force ?? false);
|
|
14860
15077
|
logger.success(`Deleted profile "${name}"`);
|
|
14861
15078
|
}
|
|
14862
|
-
function confirmDeletion(name) {
|
|
14863
|
-
const answer = prompt(`Delete profile "${name}"? This cannot be undone. [y/N]`);
|
|
14864
|
-
return answer?.toLowerCase() === "y";
|
|
14865
|
-
}
|
|
14866
15079
|
|
|
14867
15080
|
// src/commands/ghost/profile/show.ts
|
|
14868
15081
|
function registerProfileShowCommand(parent) {
|
|
@@ -15748,7 +15961,7 @@ async function hashBundle2(files) {
|
|
|
15748
15961
|
`));
|
|
15749
15962
|
}
|
|
15750
15963
|
// src/index.ts
|
|
15751
|
-
var version = "1.2.
|
|
15964
|
+
var version = "1.2.2";
|
|
15752
15965
|
async function main2() {
|
|
15753
15966
|
const program2 = new Command().name("ocx").description("OpenCode Extensions - Install agents, skills, plugins, and commands").version(version);
|
|
15754
15967
|
registerInitCommand(program2);
|
|
@@ -15775,4 +15988,4 @@ export {
|
|
|
15775
15988
|
buildRegistry
|
|
15776
15989
|
};
|
|
15777
15990
|
|
|
15778
|
-
//# debugId=
|
|
15991
|
+
//# debugId=DCBED805AED28C6C64756E2164756E21
|