refactor: rename remaining oh-my-opencode string literals
This commit is contained in:
@@ -32,7 +32,7 @@ function supportsAvx2() {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.OH_MY_OPENCODE_FORCE_BASELINE === "1") {
|
if (process.env.OH_MY_OPENAGENT_FORCE_BASELINE === "1" || process.env.OH_MY_OPENCODE_FORCE_BASELINE === "1") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ function main() {
|
|||||||
preferBaseline: avx2Supported === false,
|
preferBaseline: avx2Supported === false,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`\noh-my-opencode: ${error.message}\n`);
|
console.error(`\noh-my-openagent: ${error.message}\n`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ function main() {
|
|||||||
.filter((entry) => entry !== null);
|
.filter((entry) => entry !== null);
|
||||||
|
|
||||||
if (resolvedBinaries.length === 0) {
|
if (resolvedBinaries.length === 0) {
|
||||||
console.error(`\noh-my-opencode: Platform binary not installed.`);
|
console.error(`\noh-my-openagent: Platform binary not installed.`);
|
||||||
console.error(`\nYour platform: ${platform}-${arch}${libcFamily === "musl" ? "-musl" : ""}`);
|
console.error(`\nYour platform: ${platform}-${arch}${libcFamily === "musl" ? "-musl" : ""}`);
|
||||||
console.error(`Expected packages (in order): ${packageCandidates.join(", ")}`);
|
console.error(`Expected packages (in order): ${packageCandidates.join(", ")}`);
|
||||||
console.error(`\nTo fix, run:`);
|
console.error(`\nTo fix, run:`);
|
||||||
@@ -120,7 +120,7 @@ function main() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error(`\noh-my-opencode: Failed to execute binary.`);
|
console.error(`\noh-my-openagent: Failed to execute binary.`);
|
||||||
console.error(`Error: ${result.error.message}\n`);
|
console.error(`Error: ${result.error.message}\n`);
|
||||||
process.exit(2);
|
process.exit(2);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -48,9 +48,9 @@ function main() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`✓ oh-my-opencode binary installed for ${platform}-${arch} (${resolvedPackage})`);
|
console.log(`✓ oh-my-openagent binary installed for ${platform}-${arch} (${resolvedPackage})`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`⚠ oh-my-opencode: ${error.message}`);
|
console.warn(`⚠ oh-my-openagent: ${error.message}`)
|
||||||
console.warn(` The CLI may not work on this platform.`);
|
console.warn(` The CLI may not work on this platform.`);
|
||||||
// Don't fail installation - let user try anyway
|
// Don't fail installation - let user try anyway
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
exports[`generateModelConfig no providers available returns ULTIMATE_FALLBACK for all agents and categories when no providers 1`] = `
|
exports[`generateModelConfig no providers available returns ULTIMATE_FALLBACK for all agents and categories when no providers 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "opencode/gpt-5-nano",
|
"model": "opencode/gpt-5-nano",
|
||||||
@@ -66,7 +66,7 @@ exports[`generateModelConfig no providers available returns ULTIMATE_FALLBACK fo
|
|||||||
|
|
||||||
exports[`generateModelConfig single native provider uses Claude models when only Claude is available 1`] = `
|
exports[`generateModelConfig single native provider uses Claude models when only Claude is available 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "anthropic/claude-sonnet-4-6",
|
"model": "anthropic/claude-sonnet-4-6",
|
||||||
@@ -128,7 +128,7 @@ exports[`generateModelConfig single native provider uses Claude models when only
|
|||||||
|
|
||||||
exports[`generateModelConfig single native provider uses Claude models with isMax20 flag 1`] = `
|
exports[`generateModelConfig single native provider uses Claude models with isMax20 flag 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "anthropic/claude-sonnet-4-6",
|
"model": "anthropic/claude-sonnet-4-6",
|
||||||
@@ -191,7 +191,7 @@ exports[`generateModelConfig single native provider uses Claude models with isMa
|
|||||||
|
|
||||||
exports[`generateModelConfig single native provider uses OpenAI models when only OpenAI is available 1`] = `
|
exports[`generateModelConfig single native provider uses OpenAI models when only OpenAI is available 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "openai/gpt-5.4",
|
"model": "openai/gpt-5.4",
|
||||||
@@ -277,7 +277,7 @@ exports[`generateModelConfig single native provider uses OpenAI models when only
|
|||||||
|
|
||||||
exports[`generateModelConfig single native provider uses OpenAI models with isMax20 flag 1`] = `
|
exports[`generateModelConfig single native provider uses OpenAI models with isMax20 flag 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "openai/gpt-5.4",
|
"model": "openai/gpt-5.4",
|
||||||
@@ -363,7 +363,7 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa
|
|||||||
|
|
||||||
exports[`generateModelConfig single native provider uses Gemini models when only Gemini is available 1`] = `
|
exports[`generateModelConfig single native provider uses Gemini models when only Gemini is available 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "opencode/gpt-5-nano",
|
"model": "opencode/gpt-5-nano",
|
||||||
@@ -423,7 +423,7 @@ exports[`generateModelConfig single native provider uses Gemini models when only
|
|||||||
|
|
||||||
exports[`generateModelConfig single native provider uses Gemini models with isMax20 flag 1`] = `
|
exports[`generateModelConfig single native provider uses Gemini models with isMax20 flag 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "opencode/gpt-5-nano",
|
"model": "opencode/gpt-5-nano",
|
||||||
@@ -483,7 +483,7 @@ exports[`generateModelConfig single native provider uses Gemini models with isMa
|
|||||||
|
|
||||||
exports[`generateModelConfig all native providers uses preferred models from fallback chains when all natives available 1`] = `
|
exports[`generateModelConfig all native providers uses preferred models from fallback chains when all natives available 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "anthropic/claude-sonnet-4-6",
|
"model": "anthropic/claude-sonnet-4-6",
|
||||||
@@ -558,7 +558,7 @@ exports[`generateModelConfig all native providers uses preferred models from fal
|
|||||||
|
|
||||||
exports[`generateModelConfig all native providers uses preferred models with isMax20 flag when all natives available 1`] = `
|
exports[`generateModelConfig all native providers uses preferred models with isMax20 flag when all natives available 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "anthropic/claude-sonnet-4-6",
|
"model": "anthropic/claude-sonnet-4-6",
|
||||||
@@ -634,7 +634,7 @@ exports[`generateModelConfig all native providers uses preferred models with isM
|
|||||||
|
|
||||||
exports[`generateModelConfig fallback providers uses OpenCode Zen models when only OpenCode Zen is available 1`] = `
|
exports[`generateModelConfig fallback providers uses OpenCode Zen models when only OpenCode Zen is available 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "opencode/claude-sonnet-4-6",
|
"model": "opencode/claude-sonnet-4-6",
|
||||||
@@ -709,7 +709,7 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models when on
|
|||||||
|
|
||||||
exports[`generateModelConfig fallback providers uses OpenCode Zen models with isMax20 flag 1`] = `
|
exports[`generateModelConfig fallback providers uses OpenCode Zen models with isMax20 flag 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "opencode/claude-sonnet-4-6",
|
"model": "opencode/claude-sonnet-4-6",
|
||||||
@@ -785,7 +785,7 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models with is
|
|||||||
|
|
||||||
exports[`generateModelConfig fallback providers uses GitHub Copilot models when only Copilot is available 1`] = `
|
exports[`generateModelConfig fallback providers uses GitHub Copilot models when only Copilot is available 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "github-copilot/claude-sonnet-4.6",
|
"model": "github-copilot/claude-sonnet-4.6",
|
||||||
@@ -855,7 +855,7 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models when
|
|||||||
|
|
||||||
exports[`generateModelConfig fallback providers uses GitHub Copilot models with isMax20 flag 1`] = `
|
exports[`generateModelConfig fallback providers uses GitHub Copilot models with isMax20 flag 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "github-copilot/claude-sonnet-4.6",
|
"model": "github-copilot/claude-sonnet-4.6",
|
||||||
@@ -926,7 +926,7 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models with
|
|||||||
|
|
||||||
exports[`generateModelConfig fallback providers uses ZAI model for librarian when only ZAI is available 1`] = `
|
exports[`generateModelConfig fallback providers uses ZAI model for librarian when only ZAI is available 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "opencode/gpt-5-nano",
|
"model": "opencode/gpt-5-nano",
|
||||||
@@ -984,7 +984,7 @@ exports[`generateModelConfig fallback providers uses ZAI model for librarian whe
|
|||||||
|
|
||||||
exports[`generateModelConfig fallback providers uses ZAI model for librarian with isMax20 flag 1`] = `
|
exports[`generateModelConfig fallback providers uses ZAI model for librarian with isMax20 flag 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "opencode/gpt-5-nano",
|
"model": "opencode/gpt-5-nano",
|
||||||
@@ -1042,7 +1042,7 @@ exports[`generateModelConfig fallback providers uses ZAI model for librarian wit
|
|||||||
|
|
||||||
exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen combination 1`] = `
|
exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen combination 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "anthropic/claude-sonnet-4-6",
|
"model": "anthropic/claude-sonnet-4-6",
|
||||||
@@ -1117,7 +1117,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
|
|||||||
|
|
||||||
exports[`generateModelConfig mixed provider scenarios uses OpenAI + Copilot combination 1`] = `
|
exports[`generateModelConfig mixed provider scenarios uses OpenAI + Copilot combination 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "github-copilot/claude-sonnet-4.6",
|
"model": "github-copilot/claude-sonnet-4.6",
|
||||||
@@ -1192,7 +1192,7 @@ exports[`generateModelConfig mixed provider scenarios uses OpenAI + Copilot comb
|
|||||||
|
|
||||||
exports[`generateModelConfig mixed provider scenarios uses Claude + ZAI combination (librarian uses ZAI) 1`] = `
|
exports[`generateModelConfig mixed provider scenarios uses Claude + ZAI combination (librarian uses ZAI) 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "anthropic/claude-sonnet-4-6",
|
"model": "anthropic/claude-sonnet-4-6",
|
||||||
@@ -1256,7 +1256,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + ZAI combinat
|
|||||||
|
|
||||||
exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combination (explore uses Gemini) 1`] = `
|
exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combination (explore uses Gemini) 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "anthropic/claude-sonnet-4-6",
|
"model": "anthropic/claude-sonnet-4-6",
|
||||||
@@ -1322,7 +1322,7 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
|
|||||||
|
|
||||||
exports[`generateModelConfig mixed provider scenarios uses all fallback providers together 1`] = `
|
exports[`generateModelConfig mixed provider scenarios uses all fallback providers together 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "github-copilot/claude-sonnet-4.6",
|
"model": "github-copilot/claude-sonnet-4.6",
|
||||||
@@ -1400,7 +1400,7 @@ exports[`generateModelConfig mixed provider scenarios uses all fallback provider
|
|||||||
|
|
||||||
exports[`generateModelConfig mixed provider scenarios uses all providers together 1`] = `
|
exports[`generateModelConfig mixed provider scenarios uses all providers together 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "anthropic/claude-sonnet-4-6",
|
"model": "anthropic/claude-sonnet-4-6",
|
||||||
@@ -1478,7 +1478,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
|
|||||||
|
|
||||||
exports[`generateModelConfig mixed provider scenarios uses all providers with isMax20 flag 1`] = `
|
exports[`generateModelConfig mixed provider scenarios uses all providers with isMax20 flag 1`] = `
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json",
|
||||||
"agents": {
|
"agents": {
|
||||||
"atlas": {
|
"atlas": {
|
||||||
"model": "anthropic/claude-sonnet-4-6",
|
"model": "anthropic/claude-sonnet-4-6",
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ describe("runCliInstaller", () => {
|
|||||||
}),
|
}),
|
||||||
spyOn(configManager, "writeOmoConfig").mockReturnValue({
|
spyOn(configManager, "writeOmoConfig").mockReturnValue({
|
||||||
success: true,
|
success: true,
|
||||||
configPath: "/tmp/oh-my-opencode.jsonc",
|
configPath: "/tmp/oh-my-openagent.jsonc"
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export async function runCliInstaller(args: InstallArgs, version: string): Promi
|
|||||||
}
|
}
|
||||||
console.log()
|
console.log()
|
||||||
printInfo(
|
printInfo(
|
||||||
"Usage: bunx oh-my-opencode install --no-tui --claude=<no|yes|max20> --gemini=<no|yes> --copilot=<no|yes>",
|
"Usage: bunx oh-my-openagent install --no-tui --claude=<no|yes|max20> --gemini=<no|yes> --copilot=<no|yes>"
|
||||||
)
|
)
|
||||||
console.log()
|
console.log()
|
||||||
return 1
|
return 1
|
||||||
@@ -65,7 +65,7 @@ export async function runCliInstaller(args: InstallArgs, version: string): Promi
|
|||||||
|
|
||||||
const config = argsToConfig(args)
|
const config = argsToConfig(args)
|
||||||
|
|
||||||
printStep(step++, totalSteps, "Adding oh-my-opencode plugin...")
|
printStep(step++, totalSteps, "Adding oh-my-openagent plugin...")
|
||||||
const pluginResult = await addPluginToOpenCodeConfig(version)
|
const pluginResult = await addPluginToOpenCodeConfig(version)
|
||||||
if (!pluginResult.success) {
|
if (!pluginResult.success) {
|
||||||
printError(`Failed: ${pluginResult.error}`)
|
printError(`Failed: ${pluginResult.error}`)
|
||||||
@@ -75,7 +75,7 @@ export async function runCliInstaller(args: InstallArgs, version: string): Promi
|
|||||||
`Plugin ${isUpdate ? "verified" : "added"} ${SYMBOLS.arrow} ${color.dim(pluginResult.configPath)}`,
|
`Plugin ${isUpdate ? "verified" : "added"} ${SYMBOLS.arrow} ${color.dim(pluginResult.configPath)}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
printStep(step++, totalSteps, "Writing oh-my-opencode configuration...")
|
printStep(step++, totalSteps, "Writing oh-my-openagent configuration...")
|
||||||
const omoResult = writeOmoConfig(config)
|
const omoResult = writeOmoConfig(config)
|
||||||
if (!omoResult.success) {
|
if (!omoResult.success) {
|
||||||
printError(`Failed: ${omoResult.error}`)
|
printError(`Failed: ${omoResult.error}`)
|
||||||
|
|||||||
+24
-24
@@ -15,14 +15,14 @@ const VERSION = packageJson.version
|
|||||||
const program = new Command()
|
const program = new Command()
|
||||||
|
|
||||||
program
|
program
|
||||||
.name("oh-my-opencode")
|
.name("oh-my-openagent")
|
||||||
.description("The ultimate OpenCode plugin - multi-model orchestration, LSP tools, and more")
|
.description("The ultimate OpenCode plugin - multi-model orchestration, LSP tools, and more")
|
||||||
.version(VERSION, "-v, --version", "Show version number")
|
.version(VERSION, "-v, --version", "Show version number")
|
||||||
.enablePositionalOptions()
|
.enablePositionalOptions()
|
||||||
|
|
||||||
program
|
program
|
||||||
.command("install")
|
.command("install")
|
||||||
.description("Install and configure oh-my-opencode with interactive setup")
|
.description("Install and configure oh-my-openagent with interactive setup")
|
||||||
.option("--no-tui", "Run in non-interactive mode (requires all options)")
|
.option("--no-tui", "Run in non-interactive mode (requires all options)")
|
||||||
.option("--claude <value>", "Claude subscription: no, yes, max20")
|
.option("--claude <value>", "Claude subscription: no, yes, max20")
|
||||||
.option("--openai <value>", "OpenAI/ChatGPT subscription: no, yes (default: no)")
|
.option("--openai <value>", "OpenAI/ChatGPT subscription: no, yes (default: no)")
|
||||||
@@ -35,9 +35,9 @@ program
|
|||||||
.option("--skip-auth", "Skip authentication setup hints")
|
.option("--skip-auth", "Skip authentication setup hints")
|
||||||
.addHelpText("after", `
|
.addHelpText("after", `
|
||||||
Examples:
|
Examples:
|
||||||
$ bunx oh-my-opencode install
|
$ bunx oh-my-openagent install
|
||||||
$ bunx oh-my-opencode install --no-tui --claude=max20 --openai=yes --gemini=yes --copilot=no
|
$ bunx oh-my-openagent install --no-tui --claude=max20 --openai=yes --gemini=yes --copilot=no
|
||||||
$ bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=yes --opencode-zen=yes
|
$ bunx oh-my-openagent install --no-tui --claude=no --gemini=no --copilot=yes --opencode-zen=yes
|
||||||
|
|
||||||
Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi):
|
Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi):
|
||||||
Claude Native anthropic/ models (Opus, Sonnet, Haiku)
|
Claude Native anthropic/ models (Opus, Sonnet, Haiku)
|
||||||
@@ -82,20 +82,20 @@ program
|
|||||||
.option("--session-id <id>", "Resume existing session instead of creating new one")
|
.option("--session-id <id>", "Resume existing session instead of creating new one")
|
||||||
.addHelpText("after", `
|
.addHelpText("after", `
|
||||||
Examples:
|
Examples:
|
||||||
$ bunx oh-my-opencode run "Fix the bug in index.ts"
|
$ bunx oh-my-openagent run "Fix the bug in index.ts"
|
||||||
$ bunx oh-my-opencode run --agent Sisyphus "Implement feature X"
|
$ bunx oh-my-openagent run --agent Sisyphus "Implement feature X"
|
||||||
$ bunx oh-my-opencode run --port 4321 "Fix the bug"
|
$ bunx oh-my-openagent run --port 4321 "Fix the bug"
|
||||||
$ bunx oh-my-opencode run --attach http://127.0.0.1:4321 "Fix the bug"
|
$ bunx oh-my-openagent run --attach http://127.0.0.1:4321 "Fix the bug"
|
||||||
$ bunx oh-my-opencode run --json "Fix the bug" | jq .sessionId
|
$ bunx oh-my-openagent run --json "Fix the bug" | jq .sessionId
|
||||||
$ bunx oh-my-opencode run --on-complete "notify-send Done" "Fix the bug"
|
$ bunx oh-my-openagent run --on-complete "notify-send Done" "Fix the bug"
|
||||||
$ bunx oh-my-opencode run --session-id ses_abc123 "Continue the work"
|
$ bunx oh-my-openagent run --session-id ses_abc123 "Continue the work"
|
||||||
$ bunx oh-my-opencode run --model anthropic/claude-sonnet-4 "Fix the bug"
|
$ bunx oh-my-openagent run --model anthropic/claude-sonnet-4 "Fix the bug"
|
||||||
$ bunx oh-my-opencode run --agent Sisyphus --model openai/gpt-5.4 "Implement feature X"
|
$ bunx oh-my-openagent run --agent Sisyphus --model openai/gpt-5.4 "Implement feature X"
|
||||||
|
|
||||||
Agent resolution order:
|
Agent resolution order:
|
||||||
1) --agent flag
|
1) --agent flag
|
||||||
2) OPENCODE_DEFAULT_AGENT
|
2) OPENCODE_DEFAULT_AGENT
|
||||||
3) oh-my-opencode.json "default_run_agent"
|
3) oh-my-openagent.json "default_run_agent"
|
||||||
4) Sisyphus (fallback)
|
4) Sisyphus (fallback)
|
||||||
|
|
||||||
Available core agents:
|
Available core agents:
|
||||||
@@ -134,9 +134,9 @@ program
|
|||||||
.option("--json", "Output in JSON format for scripting")
|
.option("--json", "Output in JSON format for scripting")
|
||||||
.addHelpText("after", `
|
.addHelpText("after", `
|
||||||
Examples:
|
Examples:
|
||||||
$ bunx oh-my-opencode get-local-version
|
$ bunx oh-my-openagent get-local-version
|
||||||
$ bunx oh-my-opencode get-local-version --json
|
$ bunx oh-my-openagent get-local-version --json
|
||||||
$ bunx oh-my-opencode get-local-version --directory /path/to/project
|
$ bunx oh-my-openagent get-local-version --directory /path/to/project
|
||||||
|
|
||||||
This command shows:
|
This command shows:
|
||||||
- Current installed version
|
- Current installed version
|
||||||
@@ -155,16 +155,16 @@ This command shows:
|
|||||||
|
|
||||||
program
|
program
|
||||||
.command("doctor")
|
.command("doctor")
|
||||||
.description("Check oh-my-opencode installation health and diagnose issues")
|
.description("Check oh-my-openagent installation health and diagnose issues")
|
||||||
.option("--status", "Show compact system dashboard")
|
.option("--status", "Show compact system dashboard")
|
||||||
.option("--verbose", "Show detailed diagnostic information")
|
.option("--verbose", "Show detailed diagnostic information")
|
||||||
.option("--json", "Output results in JSON format")
|
.option("--json", "Output results in JSON format")
|
||||||
.addHelpText("after", `
|
.addHelpText("after", `
|
||||||
Examples:
|
Examples:
|
||||||
$ bunx oh-my-opencode doctor # Show problems only
|
$ bunx oh-my-openagent doctor # Show problems only
|
||||||
$ bunx oh-my-opencode doctor --status # Compact dashboard
|
$ bunx oh-my-openagent doctor --status # Compact dashboard
|
||||||
$ bunx oh-my-opencode doctor --verbose # Deep diagnostics
|
$ bunx oh-my-openagent doctor --verbose # Deep diagnostics
|
||||||
$ bunx oh-my-opencode doctor --json # JSON output
|
$ bunx oh-my-openagent doctor --json # JSON output
|
||||||
`)
|
`)
|
||||||
.action(async (options) => {
|
.action(async (options) => {
|
||||||
const mode = options.status ? "status" : options.verbose ? "verbose" : "default"
|
const mode = options.status ? "status" : options.verbose ? "verbose" : "default"
|
||||||
@@ -180,7 +180,7 @@ program
|
|||||||
.command("version")
|
.command("version")
|
||||||
.description("Show version information")
|
.description("Show version information")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
console.log(`oh-my-opencode v${VERSION}`)
|
console.log(`oh-my-openagent v${VERSION}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
program.addCommand(createMcpOAuthCommand())
|
program.addCommand(createMcpOAuthCommand())
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ describe("getPluginNameWithVersion", () => {
|
|||||||
const result = await getPluginNameWithVersion("2.14.0")
|
const result = await getPluginNameWithVersion("2.14.0")
|
||||||
|
|
||||||
// #then should use @latest tag
|
// #then should use @latest tag
|
||||||
expect(result).toBe("oh-my-opencode@latest")
|
expect(result).toBe("oh-my-openagent@latest")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("returns @beta when current version matches beta tag", async () => {
|
test("returns @beta when current version matches beta tag", async () => {
|
||||||
@@ -39,7 +39,7 @@ describe("getPluginNameWithVersion", () => {
|
|||||||
const result = await getPluginNameWithVersion("3.0.0-beta.3")
|
const result = await getPluginNameWithVersion("3.0.0-beta.3")
|
||||||
|
|
||||||
// #then should use @beta tag
|
// #then should use @beta tag
|
||||||
expect(result).toBe("oh-my-opencode@beta")
|
expect(result).toBe("oh-my-openagent@beta")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("returns @next when current version matches next tag", async () => {
|
test("returns @next when current version matches next tag", async () => {
|
||||||
@@ -55,7 +55,7 @@ describe("getPluginNameWithVersion", () => {
|
|||||||
const result = await getPluginNameWithVersion("3.1.0-next.1")
|
const result = await getPluginNameWithVersion("3.1.0-next.1")
|
||||||
|
|
||||||
// #then should use @next tag
|
// #then should use @next tag
|
||||||
expect(result).toBe("oh-my-opencode@next")
|
expect(result).toBe("oh-my-openagent@next")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("returns prerelease channel tag when no dist-tag matches prerelease version", async () => {
|
test("returns prerelease channel tag when no dist-tag matches prerelease version", async () => {
|
||||||
@@ -71,7 +71,7 @@ describe("getPluginNameWithVersion", () => {
|
|||||||
const result = await getPluginNameWithVersion("3.0.0-beta.2")
|
const result = await getPluginNameWithVersion("3.0.0-beta.2")
|
||||||
|
|
||||||
// #then should preserve prerelease channel
|
// #then should preserve prerelease channel
|
||||||
expect(result).toBe("oh-my-opencode@beta")
|
expect(result).toBe("oh-my-openagent@beta")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("returns prerelease channel tag when fetch fails", async () => {
|
test("returns prerelease channel tag when fetch fails", async () => {
|
||||||
@@ -82,7 +82,7 @@ describe("getPluginNameWithVersion", () => {
|
|||||||
const result = await getPluginNameWithVersion("3.0.0-beta.3")
|
const result = await getPluginNameWithVersion("3.0.0-beta.3")
|
||||||
|
|
||||||
// #then should preserve prerelease channel
|
// #then should preserve prerelease channel
|
||||||
expect(result).toBe("oh-my-opencode@beta")
|
expect(result).toBe("oh-my-openagent@beta")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("returns bare package name when npm returns non-ok response for stable version", async () => {
|
test("returns bare package name when npm returns non-ok response for stable version", async () => {
|
||||||
@@ -98,7 +98,7 @@ describe("getPluginNameWithVersion", () => {
|
|||||||
const result = await getPluginNameWithVersion("2.14.0")
|
const result = await getPluginNameWithVersion("2.14.0")
|
||||||
|
|
||||||
// #then should fall back to bare package entry
|
// #then should fall back to bare package entry
|
||||||
expect(result).toBe("oh-my-opencode")
|
expect(result).toBe("oh-my-openagent")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("prioritizes latest over other tags when version matches multiple", async () => {
|
test("prioritizes latest over other tags when version matches multiple", async () => {
|
||||||
@@ -114,7 +114,7 @@ describe("getPluginNameWithVersion", () => {
|
|||||||
const result = await getPluginNameWithVersion("3.0.0")
|
const result = await getPluginNameWithVersion("3.0.0")
|
||||||
|
|
||||||
// #then should prioritize @latest
|
// #then should prioritize @latest
|
||||||
expect(result).toBe("oh-my-opencode@latest")
|
expect(result).toBe("oh-my-openagent@latest")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ describe("generateOmoConfig - model fallback system", () => {
|
|||||||
const result = generateOmoConfig(config)
|
const result = generateOmoConfig(config)
|
||||||
|
|
||||||
// #then Sisyphus is omitted (requires all fallback providers)
|
// #then Sisyphus is omitted (requires all fallback providers)
|
||||||
expect(result.$schema).toBe("https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json")
|
expect(result.$schema).toBe("https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json")
|
||||||
expect((result.agents as Record<string, { model: string }>).sisyphus).toBeUndefined()
|
expect((result.agents as Record<string, { model: string }>).sisyphus).toBeUndefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ describe("writeOmoConfig", () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
testConfigDir = join(tmpdir(), `omo-write-config-${Date.now()}-${Math.random().toString(36).slice(2)}`)
|
testConfigDir = join(tmpdir(), `omo-write-config-${Date.now()}-${Math.random().toString(36).slice(2)}`)
|
||||||
testConfigPath = join(testConfigDir, "oh-my-opencode.json")
|
testConfigPath = join(testConfigDir, "oh-my-openagent.json")
|
||||||
|
|
||||||
mkdirSync(testConfigDir, { recursive: true })
|
mkdirSync(testConfigDir, { recursive: true })
|
||||||
process.env.OPENCODE_CONFIG_DIR = testConfigDir
|
process.env.OPENCODE_CONFIG_DIR = testConfigDir
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export function writeOmoConfig(installConfig: InstallConfig): ConfigMergeResult
|
|||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
configPath: omoConfigPath,
|
configPath: omoConfigPath,
|
||||||
error: formatErrorWithSuggestion(err, "write oh-my-opencode config"),
|
error: formatErrorWithSuggestion(err, "write oh-my-openagent config")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ describe("model-resolution check", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("getModelResolutionInfoWithOverrides", () => {
|
describe("getModelResolutionInfoWithOverrides", () => {
|
||||||
// given: User has overrides in oh-my-opencode.json
|
// given: User has overrides in oh-my-openagent.json
|
||||||
// when: Getting resolution info with config
|
// when: Getting resolution info with config
|
||||||
// then: Shows user override in Step 1 position
|
// then: Shows user override in Step 1 position
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const mockGetOpenCodeVersion = mock(async () => "1.0.200")
|
|||||||
const mockCompareVersions = mock(() => true)
|
const mockCompareVersions = mock(() => true)
|
||||||
const mockGetPluginInfo = mock(() => ({
|
const mockGetPluginInfo = mock(() => ({
|
||||||
registered: true,
|
registered: true,
|
||||||
entry: "oh-my-opencode",
|
entry: "oh-my-openagent",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: null,
|
pinnedVersion: null,
|
||||||
configPath: null,
|
configPath: null,
|
||||||
@@ -14,7 +14,7 @@ const mockGetPluginInfo = mock(() => ({
|
|||||||
const mockGetLoadedPluginVersion = mock(() => ({
|
const mockGetLoadedPluginVersion = mock(() => ({
|
||||||
cacheDir: "/Users/test/Library/Caches/opencode with spaces",
|
cacheDir: "/Users/test/Library/Caches/opencode with spaces",
|
||||||
cachePackagePath: "/tmp/package.json",
|
cachePackagePath: "/tmp/package.json",
|
||||||
installedPackagePath: "/tmp/node_modules/oh-my-opencode/package.json",
|
installedPackagePath: "/tmp/node_modules/oh-my-openagent/package.json",
|
||||||
expectedVersion: "3.0.0",
|
expectedVersion: "3.0.0",
|
||||||
loadedVersion: "3.1.0",
|
loadedVersion: "3.1.0",
|
||||||
}))
|
}))
|
||||||
@@ -51,7 +51,7 @@ describe("system check", () => {
|
|||||||
mockCompareVersions.mockReturnValue(true)
|
mockCompareVersions.mockReturnValue(true)
|
||||||
mockGetPluginInfo.mockReturnValue({
|
mockGetPluginInfo.mockReturnValue({
|
||||||
registered: true,
|
registered: true,
|
||||||
entry: "oh-my-opencode",
|
entry: "oh-my-openagent",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: null,
|
pinnedVersion: null,
|
||||||
configPath: null,
|
configPath: null,
|
||||||
@@ -60,7 +60,7 @@ describe("system check", () => {
|
|||||||
mockGetLoadedPluginVersion.mockReturnValue({
|
mockGetLoadedPluginVersion.mockReturnValue({
|
||||||
cacheDir: "/Users/test/Library/Caches/opencode with spaces",
|
cacheDir: "/Users/test/Library/Caches/opencode with spaces",
|
||||||
cachePackagePath: "/tmp/package.json",
|
cachePackagePath: "/tmp/package.json",
|
||||||
installedPackagePath: "/tmp/node_modules/oh-my-opencode/package.json",
|
installedPackagePath: "/tmp/node_modules/oh-my-openagent/package.json",
|
||||||
expectedVersion: "3.0.0",
|
expectedVersion: "3.0.0",
|
||||||
loadedVersion: "3.1.0",
|
loadedVersion: "3.1.0",
|
||||||
})
|
})
|
||||||
@@ -82,7 +82,7 @@ describe("system check", () => {
|
|||||||
mockGetLoadedPluginVersion.mockReturnValue({
|
mockGetLoadedPluginVersion.mockReturnValue({
|
||||||
cacheDir: "/Users/test/Library/Caches/opencode with spaces",
|
cacheDir: "/Users/test/Library/Caches/opencode with spaces",
|
||||||
cachePackagePath: "/tmp/package.json",
|
cachePackagePath: "/tmp/package.json",
|
||||||
installedPackagePath: "/tmp/node_modules/oh-my-opencode/package.json",
|
installedPackagePath: "/tmp/node_modules/oh-my-openagent/package.json",
|
||||||
expectedVersion: "3.0.0-canary.1",
|
expectedVersion: "3.0.0-canary.1",
|
||||||
loadedVersion: "3.0.0-canary.1",
|
loadedVersion: "3.0.0-canary.1",
|
||||||
})
|
})
|
||||||
@@ -97,7 +97,7 @@ describe("system check", () => {
|
|||||||
//#then
|
//#then
|
||||||
const outdatedIssue = result.issues.find((issue) => issue.title === "Loaded plugin is outdated")
|
const outdatedIssue = result.issues.find((issue) => issue.title === "Loaded plugin is outdated")
|
||||||
expect(outdatedIssue?.fix).toBe(
|
expect(outdatedIssue?.fix).toBe(
|
||||||
'Update: cd "/Users/test/Library/Caches/opencode with spaces" && bun add oh-my-opencode@canary'
|
'Update: cd "/Users/test/Library/Caches/opencode with spaces" && bun add oh-my-openagent@canary'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -82,9 +82,9 @@ export async function checkSystem(): Promise<CheckResult> {
|
|||||||
|
|
||||||
if (!pluginInfo.registered) {
|
if (!pluginInfo.registered) {
|
||||||
issues.push({
|
issues.push({
|
||||||
title: "oh-my-opencode is not registered",
|
title: "oh-my-openagent is not registered",
|
||||||
description: "Plugin entry is missing from OpenCode configuration.",
|
description: "Plugin entry is missing from OpenCode configuration.",
|
||||||
fix: "Run: bunx oh-my-opencode install",
|
fix: "Run: bunx oh-my-openagent install",
|
||||||
severity: "error",
|
severity: "error",
|
||||||
affects: ["all agents"],
|
affects: ["all agents"],
|
||||||
})
|
})
|
||||||
@@ -108,7 +108,7 @@ export async function checkSystem(): Promise<CheckResult> {
|
|||||||
issues.push({
|
issues.push({
|
||||||
title: "Loaded plugin is outdated",
|
title: "Loaded plugin is outdated",
|
||||||
description: `Loaded ${systemInfo.loadedVersion}, latest ${latestVersion}.`,
|
description: `Loaded ${systemInfo.loadedVersion}, latest ${latestVersion}.`,
|
||||||
fix: `Update: cd "${loadedInfo.cacheDir}" && bun add oh-my-opencode@${installTag}`,
|
fix: `Update: cd "${loadedInfo.cacheDir}" && bun add oh-my-openagent@${installTag}`,
|
||||||
severity: "warning",
|
severity: "warning",
|
||||||
affects: ["plugin features"],
|
affects: ["plugin features"],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export function formatDefault(result: DoctorResult): string {
|
|||||||
const pluginVer = result.systemInfo.pluginVersion ?? "unknown"
|
const pluginVer = result.systemInfo.pluginVersion ?? "unknown"
|
||||||
lines.push(
|
lines.push(
|
||||||
` ${color.green(SYMBOLS.check)} ${color.green(
|
` ${color.green(SYMBOLS.check)} ${color.green(
|
||||||
`System OK (opencode ${opencodeVer} · oh-my-opencode ${pluginVer})`
|
`System OK (opencode ${opencodeVer} · oh-my-openagent ${pluginVer})`
|
||||||
)}`
|
)}`
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export function formatVerbose(result: DoctorResult): string {
|
|||||||
lines.push(`${color.bold("System Information")}`)
|
lines.push(`${color.bold("System Information")}`)
|
||||||
lines.push(`${color.dim("\u2500".repeat(40))}`)
|
lines.push(`${color.dim("\u2500".repeat(40))}`)
|
||||||
lines.push(` ${formatStatusSymbol("pass")} opencode ${systemInfo.opencodeVersion ?? "unknown"}`)
|
lines.push(` ${formatStatusSymbol("pass")} opencode ${systemInfo.opencodeVersion ?? "unknown"}`)
|
||||||
lines.push(` ${formatStatusSymbol("pass")} oh-my-opencode ${systemInfo.pluginVersion ?? "unknown"}`)
|
lines.push(` ${formatStatusSymbol("pass")} oh-my-openagent ${systemInfo.pluginVersion ?? "unknown"}`)
|
||||||
if (systemInfo.loadedVersion) {
|
if (systemInfo.loadedVersion) {
|
||||||
lines.push(` ${formatStatusSymbol("pass")} loaded ${systemInfo.loadedVersion}`)
|
lines.push(` ${formatStatusSymbol("pass")} loaded ${systemInfo.loadedVersion}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ describe("formatDoctorOutput", () => {
|
|||||||
const output = stripAnsi(formatDoctorOutput(result, "default"))
|
const output = stripAnsi(formatDoctorOutput(result, "default"))
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(output).toContain("System OK (opencode 1.0.200 · oh-my-opencode 3.4.0)")
|
expect(output).toContain("System OK (opencode 1.0.200 · oh-my-openagent 3.4.0)")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("shows issue count and details when issues exist", async () => {
|
it("shows issue count and details when issues exist", async () => {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export function formatVersionOutput(info: VersionInfo): string {
|
|||||||
const lines: string[] = []
|
const lines: string[] = []
|
||||||
|
|
||||||
lines.push("")
|
lines.push("")
|
||||||
lines.push(color.bold(color.white("oh-my-opencode Version Information")))
|
lines.push(color.bold(color.white("oh-my-openagent Version Information")))
|
||||||
lines.push(color.dim("─".repeat(50)))
|
lines.push(color.dim("─".repeat(50)))
|
||||||
lines.push("")
|
lines.push("")
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ export function formatVersionOutput(info: VersionInfo): string {
|
|||||||
break
|
break
|
||||||
case "outdated":
|
case "outdated":
|
||||||
lines.push(` ${SYMBOLS.warn} ${color.yellow("Update available")}`)
|
lines.push(` ${SYMBOLS.warn} ${color.yellow("Update available")}`)
|
||||||
lines.push(` ${color.dim("Run:")} ${color.cyan("cd ~/.config/opencode && bun update oh-my-opencode")}`)
|
lines.push(` ${color.dim("Run:")} ${color.cyan("cd ~/.config/opencode && bun update oh-my-openagent")}`)
|
||||||
break
|
break
|
||||||
case "local-dev":
|
case "local-dev":
|
||||||
lines.push(` ${SYMBOLS.dev} ${color.cyan("Running in local development mode")}`)
|
lines.push(` ${SYMBOLS.dev} ${color.cyan("Running in local development mode")}`)
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ describe("install CLI - binary check behavior", () => {
|
|||||||
// then opencode.json should have plugin entry
|
// then opencode.json should have plugin entry
|
||||||
const config = JSON.parse(readFileSync(configPath, "utf-8"))
|
const config = JSON.parse(readFileSync(configPath, "utf-8"))
|
||||||
expect(config.plugin).toBeDefined()
|
expect(config.plugin).toBeDefined()
|
||||||
expect(config.plugin.some((p: string) => p.includes("oh-my-opencode"))).toBe(true)
|
expect(config.plugin.some((p: string) => p.includes("oh-my-openagent"))).toBe(true)
|
||||||
|
|
||||||
// then exit code should be 0 (success)
|
// then exit code should be 0 (success)
|
||||||
expect(exitCode).toBe(0)
|
expect(exitCode).toBe(0)
|
||||||
|
|||||||
@@ -559,7 +559,7 @@ describe("generateModelConfig", () => {
|
|||||||
|
|
||||||
// #then should include correct schema URL
|
// #then should include correct schema URL
|
||||||
expect(result.$schema).toBe(
|
expect(result.$schema).toBe(
|
||||||
"https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json"
|
"https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json"
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export type { GeneratedOmoConfig } from "./model-fallback-types"
|
|||||||
const ZAI_MODEL = "zai-coding-plan/glm-4.7"
|
const ZAI_MODEL = "zai-coding-plan/glm-4.7"
|
||||||
|
|
||||||
const ULTIMATE_FALLBACK = "opencode/gpt-5-nano"
|
const ULTIMATE_FALLBACK = "opencode/gpt-5-nano"
|
||||||
const SCHEMA_URL = "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json"
|
const SCHEMA_URL = "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ describe("resolveSession", () => {
|
|||||||
expect(result).toBe("new-session-id")
|
expect(result).toBe("new-session-id")
|
||||||
expect(mockClient.session.create).toHaveBeenCalledWith({
|
expect(mockClient.session.create).toHaveBeenCalledWith({
|
||||||
body: {
|
body: {
|
||||||
title: "oh-my-opencode run",
|
title: "oh-my-openagent run",
|
||||||
permission: [
|
permission: [
|
||||||
{ permission: "question", action: "deny", pattern: "*" },
|
{ permission: "question", action: "deny", pattern: "*" },
|
||||||
],
|
],
|
||||||
@@ -113,7 +113,7 @@ describe("resolveSession", () => {
|
|||||||
expect(mockClient.session.create).toHaveBeenCalledTimes(2)
|
expect(mockClient.session.create).toHaveBeenCalledTimes(2)
|
||||||
expect(mockClient.session.create).toHaveBeenCalledWith({
|
expect(mockClient.session.create).toHaveBeenCalledWith({
|
||||||
body: {
|
body: {
|
||||||
title: "oh-my-opencode run",
|
title: "oh-my-openagent run",
|
||||||
permission: [
|
permission: [
|
||||||
{ permission: "question", action: "deny", pattern: "*" },
|
{ permission: "question", action: "deny", pattern: "*" },
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export async function resolveSession(options: {
|
|||||||
for (let attempt = 1; attempt <= SESSION_CREATE_MAX_RETRIES; attempt++) {
|
for (let attempt = 1; attempt <= SESSION_CREATE_MAX_RETRIES; attempt++) {
|
||||||
const res = await client.session.create({
|
const res = await client.session.create({
|
||||||
body: {
|
body: {
|
||||||
title: "oh-my-opencode run",
|
title: "oh-my-openagent run",
|
||||||
// In CLI run mode there's no TUI to answer questions.
|
// In CLI run mode there's no TUI to answer questions.
|
||||||
permission: [
|
permission: [
|
||||||
{ permission: "question", action: "deny" as const, pattern: "*" },
|
{ permission: "question", action: "deny" as const, pattern: "*" },
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export async function runTuiInstaller(args: InstallArgs, version: string): Promi
|
|||||||
const config = await promptInstallConfig(detected)
|
const config = await promptInstallConfig(detected)
|
||||||
if (!config) return 1
|
if (!config) return 1
|
||||||
|
|
||||||
spinner.start("Adding oh-my-opencode to OpenCode config")
|
spinner.start("Adding oh-my-openagent to OpenCode config")
|
||||||
const pluginResult = await addPluginToOpenCodeConfig(version)
|
const pluginResult = await addPluginToOpenCodeConfig(version)
|
||||||
if (!pluginResult.success) {
|
if (!pluginResult.success) {
|
||||||
spinner.stop(`Failed to add plugin: ${pluginResult.error}`)
|
spinner.stop(`Failed to add plugin: ${pluginResult.error}`)
|
||||||
@@ -52,7 +52,7 @@ export async function runTuiInstaller(args: InstallArgs, version: string): Promi
|
|||||||
}
|
}
|
||||||
spinner.stop(`Plugin added to ${color.cyan(pluginResult.configPath)}`)
|
spinner.stop(`Plugin added to ${color.cyan(pluginResult.configPath)}`)
|
||||||
|
|
||||||
spinner.start("Writing oh-my-opencode configuration")
|
spinner.start("Writing oh-my-openagent configuration")
|
||||||
const omoResult = writeOmoConfig(config)
|
const omoResult = writeOmoConfig(config)
|
||||||
if (!omoResult.success) {
|
if (!omoResult.success) {
|
||||||
spinner.stop(`Failed to write config: ${omoResult.error}`)
|
spinner.stop(`Failed to write config: ${omoResult.error}`)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const OhMyOpenAgentConfigSchema = z.object({
|
|||||||
$schema: z.string().optional(),
|
$schema: z.string().optional(),
|
||||||
/** Enable new task system (default: false) */
|
/** Enable new task system (default: false) */
|
||||||
new_task_system_enabled: z.boolean().optional(),
|
new_task_system_enabled: z.boolean().optional(),
|
||||||
/** Default agent name for `oh-my-opencode run` (env: OPENCODE_DEFAULT_AGENT) */
|
/** Default agent name for `oh-my-openagent run` (env: OPENCODE_DEFAULT_AGENT) */
|
||||||
default_run_agent: z.string().optional(),
|
default_run_agent: z.string().optional(),
|
||||||
disabled_mcps: z.array(AnyMcpNameSchema).optional(),
|
disabled_mcps: z.array(AnyMcpNameSchema).optional(),
|
||||||
disabled_agents: z.array(z.string()).optional(),
|
disabled_agents: z.array(z.string()).optional(),
|
||||||
|
|||||||
@@ -222,11 +222,12 @@ export interface ClaudeSettings {
|
|||||||
*/
|
*/
|
||||||
export interface PluginLoaderOptions {
|
export interface PluginLoaderOptions {
|
||||||
/**
|
/**
|
||||||
* Override enabled plugins from oh-my-opencode config.
|
* Override enabled plugins from oh-my-openagent config.
|
||||||
* Key format: "pluginName@marketplace" (e.g., "shell-scripting@claude-code-workflows")
|
* Key format: "pluginName@marketplace" (e.g., "shell-scripting@claude-code-workflows")
|
||||||
* Value: true = enabled, false = disabled
|
* Value: true = enabled, false = disabled
|
||||||
*
|
*
|
||||||
* This takes precedence over ~/.claude/settings.json enabledPlugins
|
* This takes precedence over ~/.claude/settings.json enabledPlugins
|
||||||
*/
|
*/
|
||||||
enabledPluginsOverride?: Record<string, boolean>
|
enabledPluginsOverride?: Record<string, boolean>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const TEST_USER_CONFIG_DIR = "/tmp/opencode-config"
|
|||||||
mock.module("./constants", () => ({
|
mock.module("./constants", () => ({
|
||||||
CACHE_DIR: TEST_OPENCODE_CACHE_DIR,
|
CACHE_DIR: TEST_OPENCODE_CACHE_DIR,
|
||||||
USER_CONFIG_DIR: TEST_USER_CONFIG_DIR,
|
USER_CONFIG_DIR: TEST_USER_CONFIG_DIR,
|
||||||
PACKAGE_NAME: "oh-my-opencode",
|
PACKAGE_NAME: "oh-my-openagent",
|
||||||
}))
|
}))
|
||||||
|
|
||||||
mock.module("../../shared/logger", () => ({
|
mock.module("../../shared/logger", () => ({
|
||||||
@@ -21,10 +21,10 @@ function resetTestCache(): void {
|
|||||||
rmSync(TEST_CACHE_DIR, { recursive: true, force: true })
|
rmSync(TEST_CACHE_DIR, { recursive: true, force: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
mkdirSync(join(TEST_OPENCODE_CACHE_DIR, "node_modules", "oh-my-opencode"), { recursive: true })
|
mkdirSync(join(TEST_OPENCODE_CACHE_DIR, "node_modules", "oh-my-openagent"), { recursive: true })
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
join(TEST_OPENCODE_CACHE_DIR, "package.json"),
|
join(TEST_OPENCODE_CACHE_DIR, "package.json"),
|
||||||
JSON.stringify({ dependencies: { "oh-my-opencode": "latest", other: "1.0.0" } }, null, 2)
|
JSON.stringify({ dependencies: { "oh-my-openagent": "latest", other: "1.0.0" } }, null, 2)
|
||||||
)
|
)
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
join(TEST_OPENCODE_CACHE_DIR, "bun.lock"),
|
join(TEST_OPENCODE_CACHE_DIR, "bun.lock"),
|
||||||
@@ -32,11 +32,11 @@ function resetTestCache(): void {
|
|||||||
{
|
{
|
||||||
workspaces: {
|
workspaces: {
|
||||||
"": {
|
"": {
|
||||||
dependencies: { "oh-my-opencode": "latest", other: "1.0.0" },
|
dependencies: { "oh-my-openagent": "latest", other: "1.0.0" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
packages: {
|
packages: {
|
||||||
"oh-my-opencode": {},
|
"oh-my-openagent": {},
|
||||||
other: {},
|
other: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -45,8 +45,8 @@ function resetTestCache(): void {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
join(TEST_OPENCODE_CACHE_DIR, "node_modules", "oh-my-opencode", "package.json"),
|
join(TEST_OPENCODE_CACHE_DIR, "node_modules", "oh-my-openagent", "package.json"),
|
||||||
'{"name":"oh-my-opencode"}'
|
'{"name":"oh-my-openagent"}'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,21 +67,21 @@ describe("invalidatePackage", () => {
|
|||||||
const result = invalidatePackage()
|
const result = invalidatePackage()
|
||||||
|
|
||||||
expect(result).toBe(true)
|
expect(result).toBe(true)
|
||||||
expect(existsSync(join(TEST_OPENCODE_CACHE_DIR, "node_modules", "oh-my-opencode"))).toBe(false)
|
expect(existsSync(join(TEST_OPENCODE_CACHE_DIR, "node_modules", "oh-my-openagent"))).toBe(false)
|
||||||
|
|
||||||
const packageJson = JSON.parse(readFileSync(join(TEST_OPENCODE_CACHE_DIR, "package.json"), "utf-8")) as {
|
const packageJson = JSON.parse(readFileSync(join(TEST_OPENCODE_CACHE_DIR, "package.json"), "utf-8")) as {
|
||||||
dependencies?: Record<string, string>
|
dependencies?: Record<string, string>
|
||||||
}
|
}
|
||||||
expect(packageJson.dependencies?.["oh-my-opencode"]).toBe("latest")
|
expect(packageJson.dependencies?.["oh-my-openagent"]).toBe("latest")
|
||||||
expect(packageJson.dependencies?.other).toBe("1.0.0")
|
expect(packageJson.dependencies?.other).toBe("1.0.0")
|
||||||
|
|
||||||
const bunLock = JSON.parse(readFileSync(join(TEST_OPENCODE_CACHE_DIR, "bun.lock"), "utf-8")) as {
|
const bunLock = JSON.parse(readFileSync(join(TEST_OPENCODE_CACHE_DIR, "bun.lock"), "utf-8")) as {
|
||||||
workspaces?: { ""?: { dependencies?: Record<string, string> } }
|
workspaces?: { ""?: { dependencies?: Record<string, string> } }
|
||||||
packages?: Record<string, unknown>
|
packages?: Record<string, unknown>
|
||||||
}
|
}
|
||||||
expect(bunLock.workspaces?.[""]?.dependencies?.["oh-my-opencode"]).toBe("latest")
|
expect(bunLock.workspaces?.[""]?.dependencies?.["oh-my-openagent"]).toBe("latest")
|
||||||
expect(bunLock.workspaces?.[""]?.dependencies?.other).toBe("1.0.0")
|
expect(bunLock.workspaces?.[""]?.dependencies?.other).toBe("1.0.0")
|
||||||
expect(bunLock.packages?.["oh-my-opencode"]).toBeUndefined()
|
expect(bunLock.packages?.["oh-my-openagent"]).toBeUndefined()
|
||||||
expect(bunLock.packages?.other).toEqual({})
|
expect(bunLock.packages?.other).toEqual({})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,18 +21,18 @@ describe("pinned-version-updater", () => {
|
|||||||
test("updates pinned version in config", () => {
|
test("updates pinned version in config", () => {
|
||||||
//#given
|
//#given
|
||||||
const config = JSON.stringify({
|
const config = JSON.stringify({
|
||||||
plugin: ["oh-my-opencode@3.1.8"],
|
plugin: ["oh-my-openagent@3.1.8"],
|
||||||
})
|
})
|
||||||
fs.writeFileSync(configPath, config)
|
fs.writeFileSync(configPath, config)
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const result = updatePinnedVersion(configPath, "oh-my-opencode@3.1.8", "3.4.0")
|
const result = updatePinnedVersion(configPath, "oh-my-openagent@3.1.8", "3.4.0")
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(result).toBe(true)
|
expect(result).toBe(true)
|
||||||
const updated = fs.readFileSync(configPath, "utf-8")
|
const updated = fs.readFileSync(configPath, "utf-8")
|
||||||
expect(updated).toContain("oh-my-opencode@3.4.0")
|
expect(updated).toContain("oh-my-openagent@3.4.0")
|
||||||
expect(updated).not.toContain("oh-my-opencode@3.1.8")
|
expect(updated).not.toContain("oh-my-openagent@3.1.8")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("returns false when entry not found", () => {
|
test("returns false when entry not found", () => {
|
||||||
@@ -43,7 +43,7 @@ describe("pinned-version-updater", () => {
|
|||||||
fs.writeFileSync(configPath, config)
|
fs.writeFileSync(configPath, config)
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const result = updatePinnedVersion(configPath, "oh-my-opencode@3.1.8", "3.4.0")
|
const result = updatePinnedVersion(configPath, "oh-my-openagent@3.1.8", "3.4.0")
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(result).toBe(false)
|
expect(result).toBe(false)
|
||||||
@@ -55,7 +55,7 @@ describe("pinned-version-updater", () => {
|
|||||||
fs.writeFileSync(configPath, config)
|
fs.writeFileSync(configPath, config)
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const result = updatePinnedVersion(configPath, "oh-my-opencode@3.1.8", "3.4.0")
|
const result = updatePinnedVersion(configPath, "oh-my-openagent@3.1.8", "3.4.0")
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(result).toBe(false)
|
expect(result).toBe(false)
|
||||||
@@ -66,46 +66,46 @@ describe("pinned-version-updater", () => {
|
|||||||
test("reverts from failed version back to original entry", () => {
|
test("reverts from failed version back to original entry", () => {
|
||||||
//#given
|
//#given
|
||||||
const config = JSON.stringify({
|
const config = JSON.stringify({
|
||||||
plugin: ["oh-my-opencode@3.4.0"],
|
plugin: ["oh-my-openagent@3.4.0"],
|
||||||
})
|
})
|
||||||
fs.writeFileSync(configPath, config)
|
fs.writeFileSync(configPath, config)
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const result = revertPinnedVersion(configPath, "3.4.0", "oh-my-opencode@3.1.8")
|
const result = revertPinnedVersion(configPath, "3.4.0", "oh-my-openagent@3.1.8")
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(result).toBe(true)
|
expect(result).toBe(true)
|
||||||
const reverted = fs.readFileSync(configPath, "utf-8")
|
const reverted = fs.readFileSync(configPath, "utf-8")
|
||||||
expect(reverted).toContain("oh-my-opencode@3.1.8")
|
expect(reverted).toContain("oh-my-openagent@3.1.8")
|
||||||
expect(reverted).not.toContain("oh-my-opencode@3.4.0")
|
expect(reverted).not.toContain("oh-my-openagent@3.4.0")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("reverts to unpinned entry", () => {
|
test("reverts to unpinned entry", () => {
|
||||||
//#given
|
//#given
|
||||||
const config = JSON.stringify({
|
const config = JSON.stringify({
|
||||||
plugin: ["oh-my-opencode@3.4.0"],
|
plugin: ["oh-my-openagent@3.4.0"],
|
||||||
})
|
})
|
||||||
fs.writeFileSync(configPath, config)
|
fs.writeFileSync(configPath, config)
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const result = revertPinnedVersion(configPath, "3.4.0", "oh-my-opencode")
|
const result = revertPinnedVersion(configPath, "3.4.0", "oh-my-openagent")
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(result).toBe(true)
|
expect(result).toBe(true)
|
||||||
const reverted = fs.readFileSync(configPath, "utf-8")
|
const reverted = fs.readFileSync(configPath, "utf-8")
|
||||||
expect(reverted).toContain('"oh-my-opencode"')
|
expect(reverted).toContain('"oh-my-openagent"')
|
||||||
expect(reverted).not.toContain("oh-my-opencode@3.4.0")
|
expect(reverted).not.toContain("oh-my-openagent@3.4.0")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("returns false when failed version not found", () => {
|
test("returns false when failed version not found", () => {
|
||||||
//#given
|
//#given
|
||||||
const config = JSON.stringify({
|
const config = JSON.stringify({
|
||||||
plugin: ["oh-my-opencode@3.1.8"],
|
plugin: ["oh-my-openagent@3.1.8"],
|
||||||
})
|
})
|
||||||
fs.writeFileSync(configPath, config)
|
fs.writeFileSync(configPath, config)
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const result = revertPinnedVersion(configPath, "3.4.0", "oh-my-opencode@3.1.8")
|
const result = revertPinnedVersion(configPath, "3.4.0", "oh-my-openagent@3.1.8")
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(result).toBe(false)
|
expect(result).toBe(false)
|
||||||
@@ -116,18 +116,18 @@ describe("pinned-version-updater", () => {
|
|||||||
test("config returns to original state after update + revert", () => {
|
test("config returns to original state after update + revert", () => {
|
||||||
//#given
|
//#given
|
||||||
const originalConfig = JSON.stringify({
|
const originalConfig = JSON.stringify({
|
||||||
plugin: ["oh-my-opencode@3.1.8"],
|
plugin: ["oh-my-openagent@3.1.8"],
|
||||||
})
|
})
|
||||||
fs.writeFileSync(configPath, originalConfig)
|
fs.writeFileSync(configPath, originalConfig)
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
updatePinnedVersion(configPath, "oh-my-opencode@3.1.8", "3.4.0")
|
updatePinnedVersion(configPath, "oh-my-openagent@3.1.8", "3.4.0")
|
||||||
revertPinnedVersion(configPath, "3.4.0", "oh-my-opencode@3.1.8")
|
revertPinnedVersion(configPath, "3.4.0", "oh-my-openagent@3.1.8")
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
const finalConfig = fs.readFileSync(configPath, "utf-8")
|
const finalConfig = fs.readFileSync(configPath, "utf-8")
|
||||||
expect(finalConfig).toContain("oh-my-opencode@3.1.8")
|
expect(finalConfig).toContain("oh-my-openagent@3.1.8")
|
||||||
expect(finalConfig).not.toContain("oh-my-opencode@3.4.0")
|
expect(finalConfig).not.toContain("oh-my-openagent@3.4.0")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ describe("findPluginEntry", () => {
|
|||||||
|
|
||||||
test("returns unpinned for bare package name", () => {
|
test("returns unpinned for bare package name", () => {
|
||||||
// #given plugin is configured without a tag
|
// #given plugin is configured without a tag
|
||||||
fs.writeFileSync(configPath, JSON.stringify({ plugin: ["oh-my-opencode"] }))
|
fs.writeFileSync(configPath, JSON.stringify({ plugin: ["oh-my-openagent"] }))
|
||||||
|
|
||||||
// #when plugin entry is detected
|
// #when plugin entry is detected
|
||||||
const pluginInfo = findPluginEntry(temporaryDirectory)
|
const pluginInfo = findPluginEntry(temporaryDirectory)
|
||||||
@@ -34,7 +34,7 @@ describe("findPluginEntry", () => {
|
|||||||
|
|
||||||
test("returns unpinned for latest dist-tag", () => {
|
test("returns unpinned for latest dist-tag", () => {
|
||||||
// #given plugin is configured with latest dist-tag
|
// #given plugin is configured with latest dist-tag
|
||||||
fs.writeFileSync(configPath, JSON.stringify({ plugin: ["oh-my-opencode@latest"] }))
|
fs.writeFileSync(configPath, JSON.stringify({ plugin: ["oh-my-openagent@latest"] }))
|
||||||
|
|
||||||
// #when plugin entry is detected
|
// #when plugin entry is detected
|
||||||
const pluginInfo = findPluginEntry(temporaryDirectory)
|
const pluginInfo = findPluginEntry(temporaryDirectory)
|
||||||
@@ -47,7 +47,7 @@ describe("findPluginEntry", () => {
|
|||||||
|
|
||||||
test("returns unpinned for beta dist-tag", () => {
|
test("returns unpinned for beta dist-tag", () => {
|
||||||
// #given plugin is configured with beta dist-tag
|
// #given plugin is configured with beta dist-tag
|
||||||
fs.writeFileSync(configPath, JSON.stringify({ plugin: ["oh-my-opencode@beta"] }))
|
fs.writeFileSync(configPath, JSON.stringify({ plugin: ["oh-my-openagent@beta"] }))
|
||||||
|
|
||||||
// #when plugin entry is detected
|
// #when plugin entry is detected
|
||||||
const pluginInfo = findPluginEntry(temporaryDirectory)
|
const pluginInfo = findPluginEntry(temporaryDirectory)
|
||||||
@@ -60,7 +60,7 @@ describe("findPluginEntry", () => {
|
|||||||
|
|
||||||
test("returns pinned for explicit semver", () => {
|
test("returns pinned for explicit semver", () => {
|
||||||
// #given plugin is configured with explicit version
|
// #given plugin is configured with explicit version
|
||||||
fs.writeFileSync(configPath, JSON.stringify({ plugin: ["oh-my-opencode@3.5.2"] }))
|
fs.writeFileSync(configPath, JSON.stringify({ plugin: ["oh-my-openagent@3.5.2"] }))
|
||||||
|
|
||||||
// #when plugin entry is detected
|
// #when plugin entry is detected
|
||||||
const pluginInfo = findPluginEntry(temporaryDirectory)
|
const pluginInfo = findPluginEntry(temporaryDirectory)
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ const TEST_CACHE_DIR = join(import.meta.dir, "__test-sync-cache__")
|
|||||||
|
|
||||||
mock.module("../constants", () => ({
|
mock.module("../constants", () => ({
|
||||||
CACHE_DIR: TEST_CACHE_DIR,
|
CACHE_DIR: TEST_CACHE_DIR,
|
||||||
PACKAGE_NAME: "oh-my-opencode",
|
PACKAGE_NAME: "oh-my-openagent",
|
||||||
NPM_REGISTRY_URL: "https://registry.npmjs.org/-/package/oh-my-opencode/dist-tags",
|
NPM_REGISTRY_URL: "https://registry.npmjs.org/-/package/oh-my-openagent/dist-tags",
|
||||||
NPM_FETCH_TIMEOUT: 5000,
|
NPM_FETCH_TIMEOUT: 5000,
|
||||||
VERSION_FILE: join(TEST_CACHE_DIR, "version"),
|
VERSION_FILE: join(TEST_CACHE_DIR, "version"),
|
||||||
USER_CONFIG_DIR: "/tmp/opencode-config",
|
USER_CONFIG_DIR: "/tmp/opencode-config",
|
||||||
USER_OPENCODE_CONFIG: "/tmp/opencode-config/opencode.json",
|
USER_OPENCODE_CONFIG: "/tmp/opencode-config/opencode.json",
|
||||||
USER_OPENCODE_CONFIG_JSONC: "/tmp/opencode-config/opencode.jsonc",
|
USER_OPENCODE_CONFIG_JSONC: "/tmp/opencode-config/opencode.jsonc",
|
||||||
INSTALLED_PACKAGE_JSON: join(TEST_CACHE_DIR, "node_modules", "oh-my-opencode", "package.json"),
|
INSTALLED_PACKAGE_JSON: join(TEST_CACHE_DIR, "node_modules", "oh-my-openagent", "package.json"),
|
||||||
getWindowsAppdataDir: () => null,
|
getWindowsAppdataDir: () => null,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ function resetTestCache(currentVersion = "3.10.0"): void {
|
|||||||
mkdirSync(TEST_CACHE_DIR, { recursive: true })
|
mkdirSync(TEST_CACHE_DIR, { recursive: true })
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
join(TEST_CACHE_DIR, "package.json"),
|
join(TEST_CACHE_DIR, "package.json"),
|
||||||
JSON.stringify({ dependencies: { "oh-my-opencode": currentVersion, other: "1.0.0" } }, null, 2)
|
JSON.stringify({ dependencies: { "oh-my-openagent": currentVersion, other: "1.0.0" } }, null, 2)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ function cleanupTestCache(): void {
|
|||||||
function readCachePackageJsonVersion(): string | undefined {
|
function readCachePackageJsonVersion(): string | undefined {
|
||||||
const content = readFileSync(join(TEST_CACHE_DIR, "package.json"), "utf-8")
|
const content = readFileSync(join(TEST_CACHE_DIR, "package.json"), "utf-8")
|
||||||
const pkg = JSON.parse(content) as { dependencies?: Record<string, string> }
|
const pkg = JSON.parse(content) as { dependencies?: Record<string, string> }
|
||||||
return pkg.dependencies?.["oh-my-opencode"]
|
return pkg.dependencies?.["oh-my-openagent"]
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("syncCachePackageJsonToIntent", () => {
|
describe("syncCachePackageJsonToIntent", () => {
|
||||||
@@ -61,7 +61,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
||||||
|
|
||||||
const pluginInfo: PluginEntryInfo = {
|
const pluginInfo: PluginEntryInfo = {
|
||||||
entry: "oh-my-opencode@latest",
|
entry: "oh-my-openagent@latest",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: "latest",
|
pinnedVersion: "latest",
|
||||||
configPath: "/tmp/opencode.json",
|
configPath: "/tmp/opencode.json",
|
||||||
@@ -80,7 +80,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
||||||
|
|
||||||
const pluginInfo: PluginEntryInfo = {
|
const pluginInfo: PluginEntryInfo = {
|
||||||
entry: "oh-my-opencode@next",
|
entry: "oh-my-openagent@next",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: "next",
|
pinnedVersion: "next",
|
||||||
configPath: "/tmp/opencode.json",
|
configPath: "/tmp/opencode.json",
|
||||||
@@ -99,7 +99,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
||||||
|
|
||||||
const pluginInfo: PluginEntryInfo = {
|
const pluginInfo: PluginEntryInfo = {
|
||||||
entry: "oh-my-opencode",
|
entry: "oh-my-openagent",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: null,
|
pinnedVersion: null,
|
||||||
configPath: "/tmp/opencode.json",
|
configPath: "/tmp/opencode.json",
|
||||||
@@ -120,7 +120,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
||||||
|
|
||||||
const pluginInfo: PluginEntryInfo = {
|
const pluginInfo: PluginEntryInfo = {
|
||||||
entry: "oh-my-opencode@latest",
|
entry: "oh-my-openagent@latest",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: "latest",
|
pinnedVersion: "latest",
|
||||||
configPath: "/tmp/opencode.json",
|
configPath: "/tmp/opencode.json",
|
||||||
@@ -140,7 +140,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
||||||
|
|
||||||
const pluginInfo: PluginEntryInfo = {
|
const pluginInfo: PluginEntryInfo = {
|
||||||
entry: "oh-my-opencode@latest",
|
entry: "oh-my-openagent@latest",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: "latest",
|
pinnedVersion: "latest",
|
||||||
configPath: "/tmp/opencode.json",
|
configPath: "/tmp/opencode.json",
|
||||||
@@ -165,7 +165,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
||||||
|
|
||||||
const pluginInfo: PluginEntryInfo = {
|
const pluginInfo: PluginEntryInfo = {
|
||||||
entry: "oh-my-opencode@latest",
|
entry: "oh-my-openagent@latest",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: "latest",
|
pinnedVersion: "latest",
|
||||||
configPath: "/tmp/opencode.json",
|
configPath: "/tmp/opencode.json",
|
||||||
@@ -184,7 +184,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
||||||
|
|
||||||
const pluginInfo: PluginEntryInfo = {
|
const pluginInfo: PluginEntryInfo = {
|
||||||
entry: "oh-my-opencode@3.10.0",
|
entry: "oh-my-openagent@3.10.0",
|
||||||
isPinned: true,
|
isPinned: true,
|
||||||
pinnedVersion: "3.10.0",
|
pinnedVersion: "3.10.0",
|
||||||
configPath: "/tmp/opencode.json",
|
configPath: "/tmp/opencode.json",
|
||||||
@@ -203,7 +203,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
||||||
|
|
||||||
const pluginInfo: PluginEntryInfo = {
|
const pluginInfo: PluginEntryInfo = {
|
||||||
entry: "oh-my-opencode@latest",
|
entry: "oh-my-openagent@latest",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: "latest",
|
pinnedVersion: "latest",
|
||||||
configPath: "/tmp/opencode.json",
|
configPath: "/tmp/opencode.json",
|
||||||
@@ -229,7 +229,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
||||||
|
|
||||||
const pluginInfo: PluginEntryInfo = {
|
const pluginInfo: PluginEntryInfo = {
|
||||||
entry: "oh-my-opencode@latest",
|
entry: "oh-my-openagent@latest",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: "latest",
|
pinnedVersion: "latest",
|
||||||
configPath: "/tmp/opencode.json",
|
configPath: "/tmp/opencode.json",
|
||||||
@@ -248,7 +248,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
mkdirSync(TEST_CACHE_DIR, { recursive: true })
|
mkdirSync(TEST_CACHE_DIR, { recursive: true })
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
join(TEST_CACHE_DIR, "package.json"),
|
join(TEST_CACHE_DIR, "package.json"),
|
||||||
JSON.stringify({ dependencies: { "oh-my-opencode": "3.10.0" } }, null, 2)
|
JSON.stringify({ dependencies: { "oh-my-openagent": "3.10.0" } }, null, 2)
|
||||||
)
|
)
|
||||||
|
|
||||||
const fs = await import("node:fs")
|
const fs = await import("node:fs")
|
||||||
@@ -267,7 +267,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
||||||
|
|
||||||
const pluginInfo: PluginEntryInfo = {
|
const pluginInfo: PluginEntryInfo = {
|
||||||
entry: "oh-my-opencode@latest",
|
entry: "oh-my-openagent@latest",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: "latest",
|
pinnedVersion: "latest",
|
||||||
configPath: "/tmp/opencode.json",
|
configPath: "/tmp/opencode.json",
|
||||||
@@ -293,7 +293,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
mkdirSync(TEST_CACHE_DIR, { recursive: true })
|
mkdirSync(TEST_CACHE_DIR, { recursive: true })
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
join(TEST_CACHE_DIR, "package.json"),
|
join(TEST_CACHE_DIR, "package.json"),
|
||||||
JSON.stringify({ dependencies: { "oh-my-opencode": "3.10.0" } }, null, 2)
|
JSON.stringify({ dependencies: { "oh-my-openagent": "3.10.0" } }, null, 2)
|
||||||
)
|
)
|
||||||
|
|
||||||
const fs = await import("node:fs")
|
const fs = await import("node:fs")
|
||||||
@@ -317,7 +317,7 @@ describe("syncCachePackageJsonToIntent", () => {
|
|||||||
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
const { syncCachePackageJsonToIntent } = await import("./sync-package-json")
|
||||||
|
|
||||||
const pluginInfo: PluginEntryInfo = {
|
const pluginInfo: PluginEntryInfo = {
|
||||||
entry: "oh-my-opencode@latest",
|
entry: "oh-my-openagent@latest",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: "latest",
|
pinnedVersion: "latest",
|
||||||
configPath: "/tmp/opencode.json",
|
configPath: "/tmp/opencode.json",
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ import * as path from "node:path"
|
|||||||
import * as os from "node:os"
|
import * as os from "node:os"
|
||||||
import { getOpenCodeCacheDir } from "../../shared/data-path"
|
import { getOpenCodeCacheDir } from "../../shared/data-path"
|
||||||
import { getOpenCodeConfigDir } from "../../shared/opencode-config-dir"
|
import { getOpenCodeConfigDir } from "../../shared/opencode-config-dir"
|
||||||
|
import { PLUGIN_NAME } from "../../shared/plugin-identity"
|
||||||
|
|
||||||
export const PACKAGE_NAME = "oh-my-opencode"
|
export const PACKAGE_NAME = PLUGIN_NAME
|
||||||
export const NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`
|
export const NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`
|
||||||
export const NPM_FETCH_TIMEOUT = 5000
|
export const NPM_FETCH_TIMEOUT = 5000
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ type ToastMessageGetter = (isUpdate: boolean, version?: string) => string
|
|||||||
|
|
||||||
function createPluginEntry(overrides?: Partial<PluginEntry>): PluginEntry {
|
function createPluginEntry(overrides?: Partial<PluginEntry>): PluginEntry {
|
||||||
return {
|
return {
|
||||||
entry: "oh-my-opencode@3.4.0",
|
entry: "oh-my-openagent@3.4.0",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinnedVersion: null,
|
pinnedVersion: null,
|
||||||
configPath: "/test/opencode.json",
|
configPath: "/test/opencode.json",
|
||||||
@@ -95,7 +95,7 @@ describe("runBackgroundUpdateCheck", () => {
|
|||||||
describe("#given no version available", () => {
|
describe("#given no version available", () => {
|
||||||
it("returns early when neither cached nor pinned version exists", async () => {
|
it("returns early when neither cached nor pinned version exists", async () => {
|
||||||
//#given
|
//#given
|
||||||
mockFindPluginEntry.mockReturnValue(createPluginEntry({ entry: "oh-my-opencode" }))
|
mockFindPluginEntry.mockReturnValue(createPluginEntry({ entry: "oh-my-openagent" }))
|
||||||
mockGetCachedVersion.mockReturnValue(null)
|
mockGetCachedVersion.mockReturnValue(null)
|
||||||
//#when
|
//#when
|
||||||
await runBackgroundUpdateCheck(mockCtx, true, getToastMessage)
|
await runBackgroundUpdateCheck(mockCtx, true, getToastMessage)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export async function showSpinnerToast(ctx: PluginInput, version: string, messag
|
|||||||
await ctx.client.tui
|
await ctx.client.tui
|
||||||
.showToast({
|
.showToast({
|
||||||
body: {
|
body: {
|
||||||
title: `${spinner} OhMyOpenCode ${version}`,
|
title: `${spinner} OhMyOpenAgent ${version}`,
|
||||||
message,
|
message,
|
||||||
variant: "info" as const,
|
variant: "info" as const,
|
||||||
duration: frameInterval + 50,
|
duration: frameInterval + 50,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export async function showUpdateAvailableToast(
|
|||||||
await ctx.client.tui
|
await ctx.client.tui
|
||||||
.showToast({
|
.showToast({
|
||||||
body: {
|
body: {
|
||||||
title: `OhMyOpenCode ${latestVersion}`,
|
title: `OhMyOpenAgent ${latestVersion}`,
|
||||||
message: getToastMessage(true, latestVersion),
|
message: getToastMessage(true, latestVersion),
|
||||||
variant: "info" as const,
|
variant: "info" as const,
|
||||||
duration: 8000,
|
duration: 8000,
|
||||||
@@ -23,7 +23,7 @@ export async function showAutoUpdatedToast(ctx: PluginInput, oldVersion: string,
|
|||||||
await ctx.client.tui
|
await ctx.client.tui
|
||||||
.showToast({
|
.showToast({
|
||||||
body: {
|
body: {
|
||||||
title: "OhMyOpenCode Updated!",
|
title: "OhMyOpenAgent Updated!",
|
||||||
message: `v${oldVersion} → v${newVersion}\nRestart OpenCode to apply.`,
|
message: `v${oldVersion} → v${newVersion}\nRestart OpenCode to apply.`,
|
||||||
variant: "success" as const,
|
variant: "success" as const,
|
||||||
duration: 8000,
|
duration: 8000,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ const PLATFORM_MAP: Record<string, PlatformInfo> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the cache directory for oh-my-opencode binaries.
|
* Get the cache directory for oh-my-openagent binaries.
|
||||||
* On Windows: Uses %LOCALAPPDATA% or %APPDATA% (Windows conventions)
|
* On Windows: Uses %LOCALAPPDATA% or %APPDATA% (Windows conventions)
|
||||||
* On Unix: Follows XDG Base Directory Specification
|
* On Unix: Follows XDG Base Directory Specification
|
||||||
*/
|
*/
|
||||||
@@ -48,12 +48,12 @@ export function getCacheDir(): string {
|
|||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA
|
||||||
const base = localAppData || join(homedir(), "AppData", "Local")
|
const base = localAppData || join(homedir(), "AppData", "Local")
|
||||||
return join(base, "oh-my-opencode", "bin")
|
return join(base, "oh-my-openagent", "bin")
|
||||||
}
|
}
|
||||||
|
|
||||||
const xdgCache = process.env.XDG_CACHE_HOME
|
const xdgCache = process.env.XDG_CACHE_HOME
|
||||||
const base = xdgCache || join(homedir(), ".cache")
|
const base = xdgCache || join(homedir(), ".cache")
|
||||||
return join(base, "oh-my-opencode", "bin")
|
return join(base, "oh-my-openagent", "bin")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,7 +113,7 @@ export async function downloadCommentChecker(): Promise<string | null> {
|
|||||||
const downloadUrl = `https://github.com/${REPO}/releases/download/v${version}/${assetName}`
|
const downloadUrl = `https://github.com/${REPO}/releases/download/v${version}/${assetName}`
|
||||||
|
|
||||||
debugLog(`Downloading from: ${downloadUrl}`)
|
debugLog(`Downloading from: ${downloadUrl}`)
|
||||||
log(`[oh-my-opencode] Downloading comment-checker binary...`)
|
log(`[oh-my-openagent] Downloading comment-checker binary...`)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Ensure cache directory exists
|
// Ensure cache directory exists
|
||||||
@@ -139,14 +139,14 @@ export async function downloadCommentChecker(): Promise<string | null> {
|
|||||||
ensureExecutable(binaryPath)
|
ensureExecutable(binaryPath)
|
||||||
|
|
||||||
debugLog(`Successfully downloaded binary to: ${binaryPath}`)
|
debugLog(`Successfully downloaded binary to: ${binaryPath}`)
|
||||||
log(`[oh-my-opencode] comment-checker binary ready.`)
|
log(`[oh-my-openagent] comment-checker binary ready.`)
|
||||||
|
|
||||||
return binaryPath
|
return binaryPath
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
debugLog(`Failed to download: ${err}`)
|
debugLog(`Failed to download: ${err}`)
|
||||||
log(`[oh-my-opencode] Failed to download comment-checker: ${err instanceof Error ? err.message : err}`)
|
log(`[oh-my-openagent] Failed to download comment-checker: ${err instanceof Error ? err.message : err}`)
|
||||||
log(`[oh-my-opencode] Comment checking disabled.`)
|
log(`[oh-my-openagent] Comment checking disabled.`)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ describe("updateConnectedProvidersCache", () => {
|
|||||||
|
|
||||||
test("does not remove unrelated files in the cache directory", async () => {
|
test("does not remove unrelated files in the cache directory", async () => {
|
||||||
//#given
|
//#given
|
||||||
const realCacheDir = join(fakeUserCacheRoot, "oh-my-opencode")
|
const realCacheDir = join(fakeUserCacheRoot, "oh-my-openagent")
|
||||||
const sentinelPath = join(realCacheDir, "connected-providers-cache.test-sentinel.json")
|
const sentinelPath = join(realCacheDir, "connected-providers-cache.test-sentinel.json")
|
||||||
mkdirSync(realCacheDir, { recursive: true })
|
mkdirSync(realCacheDir, { recursive: true })
|
||||||
writeFileSync(sentinelPath, JSON.stringify({ keep: true }))
|
writeFileSync(sentinelPath, JSON.stringify({ keep: true }))
|
||||||
|
|||||||
@@ -31,11 +31,11 @@ export function getCacheDir(): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the oh-my-opencode cache directory.
|
* Returns the oh-my-openagent cache directory.
|
||||||
* All platforms: ~/.cache/oh-my-opencode
|
* All platforms: ~/.cache/oh-my-openagent
|
||||||
*/
|
*/
|
||||||
export function getOmoOpenCodeCacheDir(): string {
|
export function getOmoOpenCodeCacheDir(): string {
|
||||||
return path.join(getCacheDir(), "oh-my-opencode")
|
return path.join(getCacheDir(), "oh-my-openagent")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -43,6 +43,24 @@ describe("external-plugin-detector", () => {
|
|||||||
expect(result.allPlugins).toContain("oh-my-opencode")
|
expect(result.allPlugins).toContain("oh-my-opencode")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("should return detected=false when only oh-my-openagent is configured", () => {
|
||||||
|
// given - opencode.json with only oh-my-openagent
|
||||||
|
const opencodeDir = path.join(tempDir, ".opencode")
|
||||||
|
fs.mkdirSync(opencodeDir, { recursive: true })
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(opencodeDir, "opencode.json"),
|
||||||
|
JSON.stringify({ plugin: ["oh-my-openagent"] })
|
||||||
|
)
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = detectExternalNotificationPlugin(tempDir)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result.detected).toBe(false)
|
||||||
|
expect(result.pluginName).toBeNull()
|
||||||
|
expect(result.allPlugins).toContain("oh-my-openagent")
|
||||||
|
})
|
||||||
|
|
||||||
test("should detect opencode-notifier plugin", () => {
|
test("should detect opencode-notifier plugin", () => {
|
||||||
// given - opencode.json with opencode-notifier
|
// given - opencode.json with opencode-notifier
|
||||||
const opencodeDir = path.join(tempDir, ".opencode")
|
const opencodeDir = path.join(tempDir, ".opencode")
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Detects external plugins that may conflict with oh-my-opencode features.
|
* Detects external plugins that may conflict with oh-my-openagent features.
|
||||||
* Used to prevent crashes from concurrent notification plugins.
|
* Used to prevent crashes from concurrent notification plugins.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ interface OpencodeConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Known notification plugins that conflict with oh-my-opencode's session-notification.
|
* Known notification plugins that conflict with oh-my-openagent's session-notification.
|
||||||
* Both plugins listen to session.idle and send notifications simultaneously,
|
* Both plugins listen to session.idle and send notifications simultaneously,
|
||||||
* which can cause crashes on Windows due to resource contention.
|
* which can cause crashes on Windows due to resource contention.
|
||||||
*/
|
*/
|
||||||
@@ -124,14 +124,14 @@ export function detectExternalNotificationPlugin(directory: string): ExternalNot
|
|||||||
* Generate a warning message for users with conflicting notification plugins.
|
* Generate a warning message for users with conflicting notification plugins.
|
||||||
*/
|
*/
|
||||||
export function getNotificationConflictWarning(pluginName: string): string {
|
export function getNotificationConflictWarning(pluginName: string): string {
|
||||||
return `[oh-my-opencode] External notification plugin detected: ${pluginName}
|
return `[oh-my-openagent] External notification plugin detected: ${pluginName}
|
||||||
|
|
||||||
Both oh-my-opencode and ${pluginName} listen to session.idle events.
|
Both oh-my-openagent and ${pluginName} listen to session.idle events.
|
||||||
Running both simultaneously can cause crashes on Windows.
|
Running both simultaneously can cause crashes on Windows.
|
||||||
|
|
||||||
oh-my-opencode's session-notification has been auto-disabled.
|
oh-my-openagent's session-notification has been auto-disabled.
|
||||||
|
|
||||||
To use oh-my-opencode's notifications instead, either:
|
To use oh-my-openagent's notifications instead, either:
|
||||||
1. Remove ${pluginName} from your opencode.json plugins
|
1. Remove ${pluginName} from your opencode.json plugins
|
||||||
2. Or set "notification": { "force_enable": true } in oh-my-opencode.json`
|
2. Or set "notification": { "force_enable": true } in oh-my-openagent.json`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import * as fs from "fs"
|
|||||||
import * as os from "os"
|
import * as os from "os"
|
||||||
import * as path from "path"
|
import * as path from "path"
|
||||||
|
|
||||||
const logFile = path.join(os.tmpdir(), "oh-my-opencode.log")
|
const logFile = path.join(os.tmpdir(), "oh-my-openagent.log")
|
||||||
|
|
||||||
export function log(message: string, data?: unknown): void {
|
export function log(message: string, data?: unknown): void {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ describe("opencode-config-dir", () => {
|
|||||||
expect(paths.configJson).toBe(join(expectedDir, "opencode.json"))
|
expect(paths.configJson).toBe(join(expectedDir, "opencode.json"))
|
||||||
expect(paths.configJsonc).toBe(join(expectedDir, "opencode.jsonc"))
|
expect(paths.configJsonc).toBe(join(expectedDir, "opencode.jsonc"))
|
||||||
expect(paths.packageJson).toBe(join(expectedDir, "package.json"))
|
expect(paths.packageJson).toBe(join(expectedDir, "package.json"))
|
||||||
expect(paths.omoConfig).toBe(join(expectedDir, "oh-my-opencode.json"))
|
expect(paths.omoConfig).toBe(join(expectedDir, "oh-my-openagent.json"))
|
||||||
})
|
})
|
||||||
|
|
||||||
test("returns all config paths for desktop binary", () => {
|
test("returns all config paths for desktop binary", () => {
|
||||||
@@ -304,7 +304,7 @@ describe("opencode-config-dir", () => {
|
|||||||
expect(paths.configJson).toBe(join(expectedDir, "opencode.json"))
|
expect(paths.configJson).toBe(join(expectedDir, "opencode.json"))
|
||||||
expect(paths.configJsonc).toBe(join(expectedDir, "opencode.jsonc"))
|
expect(paths.configJsonc).toBe(join(expectedDir, "opencode.jsonc"))
|
||||||
expect(paths.packageJson).toBe(join(expectedDir, "package.json"))
|
expect(paths.packageJson).toBe(join(expectedDir, "package.json"))
|
||||||
expect(paths.omoConfig).toBe(join(expectedDir, "oh-my-opencode.json"))
|
expect(paths.omoConfig).toBe(join(expectedDir, "oh-my-openagent.json"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export function getOpenCodeConfigPaths(options: OpenCodeConfigDirOptions): OpenC
|
|||||||
configJson: join(configDir, "opencode.json"),
|
configJson: join(configDir, "opencode.json"),
|
||||||
configJsonc: join(configDir, "opencode.jsonc"),
|
configJsonc: join(configDir, "opencode.jsonc"),
|
||||||
packageJson: join(configDir, "package.json"),
|
packageJson: join(configDir, "package.json"),
|
||||||
omoConfig: join(configDir, "oh-my-opencode.json"),
|
omoConfig: join(configDir, "oh-my-openagent.json")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
/**
|
/**
|
||||||
* Unified system directive prefix for oh-my-opencode internal messages.
|
* Unified system directive prefix for oh-my-openagent internal messages.
|
||||||
* All system-generated messages should use this prefix for consistent filtering.
|
* All system-generated messages should use this prefix for consistent filtering.
|
||||||
*
|
*
|
||||||
* Format: [SYSTEM DIRECTIVE: OH-MY-OPENCODE - {TYPE}]
|
* Format: [SYSTEM DIRECTIVE: OH-MY-OPENAGENT - {TYPE}]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const SYSTEM_DIRECTIVE_PREFIX = "[SYSTEM DIRECTIVE: OH-MY-OPENCODE"
|
export const SYSTEM_DIRECTIVE_PREFIX = "[SYSTEM DIRECTIVE: OH-MY-OPENAGENT"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a system directive header with the given type.
|
* Creates a system directive header with the given type.
|
||||||
* @param type - The directive type (e.g., "TODO CONTINUATION", "RALPH LOOP")
|
* @param type - The directive type (e.g., "TODO CONTINUATION", "RALPH LOOP")
|
||||||
* @returns Formatted directive string like "[SYSTEM DIRECTIVE: OH-MY-OPENCODE - TODO CONTINUATION]"
|
* @returns Formatted directive string like "[SYSTEM DIRECTIVE: OH-MY-OPENAGENT - TODO CONTINUATION]"
|
||||||
*/
|
*/
|
||||||
export function createSystemDirective(type: string): string {
|
export function createSystemDirective(type: string): string {
|
||||||
return `${SYSTEM_DIRECTIVE_PREFIX} - ${type}]`
|
return `${SYSTEM_DIRECTIVE_PREFIX} - ${type}]`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a message starts with the oh-my-opencode system directive prefix.
|
* Checks if a message starts with the oh-my-openagent system directive prefix.
|
||||||
* Used by keyword-detector and other hooks to skip system-generated messages.
|
* Used by keyword-detector and other hooks to skip system-generated messages.
|
||||||
* @param text - The message text to check
|
* @param text - The message text to check
|
||||||
* @returns true if the message is a system directive
|
* @returns true if the message is a system directive
|
||||||
|
|||||||
@@ -47,12 +47,12 @@ export function getCacheDir(): string {
|
|||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA
|
||||||
const base = localAppData || join(homedir(), "AppData", "Local")
|
const base = localAppData || join(homedir(), "AppData", "Local")
|
||||||
return join(base, "oh-my-opencode", "bin")
|
return join(base, "oh-my-openagent", "bin")
|
||||||
}
|
}
|
||||||
|
|
||||||
const xdgCache = process.env.XDG_CACHE_HOME
|
const xdgCache = process.env.XDG_CACHE_HOME
|
||||||
const base = xdgCache || join(homedir(), ".cache")
|
const base = xdgCache || join(homedir(), ".cache")
|
||||||
return join(base, "oh-my-opencode", "bin")
|
return join(base, "oh-my-openagent", "bin")
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBinaryName(): string {
|
export function getBinaryName(): string {
|
||||||
@@ -63,14 +63,12 @@ export function getCachedBinaryPath(): string | null {
|
|||||||
return getCachedBinaryPathShared(getCacheDir(), getBinaryName())
|
return getCachedBinaryPathShared(getCacheDir(), getBinaryName())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export async function downloadAstGrep(version: string = DEFAULT_VERSION): Promise<string | null> {
|
export async function downloadAstGrep(version: string = DEFAULT_VERSION): Promise<string | null> {
|
||||||
const platformKey = `${process.platform}-${process.arch}`
|
const platformKey = `${process.platform}-${process.arch}`
|
||||||
const platformInfo = PLATFORM_MAP[platformKey]
|
const platformInfo = PLATFORM_MAP[platformKey]
|
||||||
|
|
||||||
if (!platformInfo) {
|
if (!platformInfo) {
|
||||||
log(`[oh-my-opencode] Unsupported platform for ast-grep: ${platformKey}`)
|
log(`[oh-my-openagent] Unsupported platform for ast-grep: ${platformKey}`)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +84,7 @@ export async function downloadAstGrep(version: string = DEFAULT_VERSION): Promis
|
|||||||
const assetName = `app-${arch}-${os}.zip`
|
const assetName = `app-${arch}-${os}.zip`
|
||||||
const downloadUrl = `https://github.com/${REPO}/releases/download/${version}/${assetName}`
|
const downloadUrl = `https://github.com/${REPO}/releases/download/${version}/${assetName}`
|
||||||
|
|
||||||
log(`[oh-my-opencode] Downloading ast-grep binary...`)
|
log(`[oh-my-openagent] Downloading ast-grep binary...`)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const archivePath = join(cacheDir, assetName)
|
const archivePath = join(cacheDir, assetName)
|
||||||
@@ -96,12 +94,12 @@ export async function downloadAstGrep(version: string = DEFAULT_VERSION): Promis
|
|||||||
cleanupArchive(archivePath)
|
cleanupArchive(archivePath)
|
||||||
ensureExecutable(binaryPath)
|
ensureExecutable(binaryPath)
|
||||||
|
|
||||||
log(`[oh-my-opencode] ast-grep binary ready.`)
|
log(`[oh-my-openagent] ast-grep binary ready.`)
|
||||||
|
|
||||||
return binaryPath
|
return binaryPath
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log(
|
log(
|
||||||
`[oh-my-opencode] Failed to download ast-grep: ${err instanceof Error ? err.message : err}`
|
`[oh-my-openagent] Failed to download ast-grep: ${err instanceof Error ? err.message : err}`
|
||||||
)
|
)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export function createCallOmoAgent(
|
|||||||
|
|
||||||
// Check if agent is disabled
|
// Check if agent is disabled
|
||||||
if (disabledAgents.some((disabled) => disabled.toLowerCase() === normalizedAgent)) {
|
if (disabledAgents.some((disabled) => disabled.toLowerCase() === normalizedAgent)) {
|
||||||
return `Error: Agent "${normalizedAgent}" is disabled via disabled_agents configuration. Remove it from disabled_agents in your oh-my-opencode.json to use it.`
|
return `Error: Agent "${normalizedAgent}" is disabled via disabled_agents configuration. Remove it from disabled_agents in your oh-my-openagent.json to use it.`
|
||||||
}
|
}
|
||||||
|
|
||||||
const fallbackChain = resolveFallbackChainForCallOmoAgent({
|
const fallbackChain = resolveFallbackChainForCallOmoAgent({
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export async function resolveCategoryExecution(
|
|||||||
|
|
||||||
To use this category:
|
To use this category:
|
||||||
1. Connect a provider with this model: ${requirement.requiresModel}
|
1. Connect a provider with this model: ${requirement.requiresModel}
|
||||||
2. Or configure an alternative model in your oh-my-opencode.json for this category
|
2. Or configure an alternative model in your oh-my-openagent.json for this category
|
||||||
|
|
||||||
Available categories: ${allCategoryNames}`,
|
Available categories: ${allCategoryNames}`,
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ Available categories: ${allCategoryNames}`,
|
|||||||
|
|
||||||
Configure in one of:
|
Configure in one of:
|
||||||
1. OpenCode: Set "model" in opencode.json
|
1. OpenCode: Set "model" in opencode.json
|
||||||
2. Oh-My-OpenCode: Set category model in oh-my-opencode.json
|
2. Oh-My-OpenAgent: Set category model in oh-my-openagent.json
|
||||||
3. Provider: Connect a provider with available models
|
3. Provider: Connect a provider with available models
|
||||||
|
|
||||||
Current category: ${args.category}
|
Current category: ${args.category}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ function getPlatformKey(): string {
|
|||||||
|
|
||||||
function getInstallDir(): string {
|
function getInstallDir(): string {
|
||||||
const homeDir = process.env.HOME || process.env.USERPROFILE || "."
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "."
|
||||||
return join(homeDir, ".cache", "oh-my-opencode", "bin")
|
return join(homeDir, ".cache", "oh-my-openagent", "bin")
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRgPath(): string {
|
function getRgPath(): string {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export function formatServerLookupError(result: Exclude<ServerLookupResult, { st
|
|||||||
``,
|
``,
|
||||||
`Available servers: ${result.availableServers.slice(0, 10).join(", ")}${result.availableServers.length > 10 ? "..." : ""}`,
|
`Available servers: ${result.availableServers.slice(0, 10).join(", ")}${result.availableServers.length > 10 ? "..." : ""}`,
|
||||||
``,
|
``,
|
||||||
`To add a custom server, configure 'lsp' in oh-my-opencode.json:`,
|
`To add a custom server, configure 'lsp' in oh-my-openagent.json:`,
|
||||||
` {`,
|
` {`,
|
||||||
` "lsp": {`,
|
` "lsp": {`,
|
||||||
` "my-server": {`,
|
` "my-server": {`,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ describe("loadJsonFile", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
const userPath = join(tempBase, "oh-my-opencode.jsonc")
|
const userPath = join(tempBase, "oh-my-openagent.jsonc")
|
||||||
writeFileSync(userPath, userJsonc, "utf-8")
|
writeFileSync(userPath, userJsonc, "utf-8")
|
||||||
|
|
||||||
const servers = getMergedServers()
|
const servers = getMergedServers()
|
||||||
@@ -109,7 +109,7 @@ describe("loadJsonFile", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
const projectPath = join(tempProject, ".opencode", "oh-my-opencode.jsonc")
|
const projectPath = join(tempProject, ".opencode", "oh-my-openagent.jsonc")
|
||||||
writeFileSync(projectPath, projectJsonc, "utf-8")
|
writeFileSync(projectPath, projectJsonc, "utf-8")
|
||||||
|
|
||||||
process.chdir(tempProject)
|
process.chdir(tempProject)
|
||||||
@@ -146,8 +146,8 @@ describe("loadJsonFile", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
writeFileSync(join(tempBase, "oh-my-opencode.json"), jsonContent, "utf-8")
|
writeFileSync(join(tempBase, "oh-my-openagent.json"), jsonContent, "utf-8")
|
||||||
writeFileSync(join(tempBase, "oh-my-opencode.jsonc"), jsoncContent, "utf-8")
|
writeFileSync(join(tempBase, "oh-my-openagent.jsonc"), jsoncContent, "utf-8")
|
||||||
|
|
||||||
const servers = getMergedServers()
|
const servers = getMergedServers()
|
||||||
const found = servers.find(s => s.id === "conflict" && s.source === "user")
|
const found = servers.find(s => s.id === "conflict" && s.source === "user")
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { BUILTIN_SERVERS } from "./constants"
|
|||||||
import type { ResolvedServer } from "./types"
|
import type { ResolvedServer } from "./types"
|
||||||
import { getOpenCodeConfigDir } from "../../shared"
|
import { getOpenCodeConfigDir } from "../../shared"
|
||||||
import { parseJsonc, detectConfigFile } from "../../shared/jsonc-parser"
|
import { parseJsonc, detectConfigFile } from "../../shared/jsonc-parser"
|
||||||
|
import { CONFIG_BASENAME } from "../../shared/plugin-identity"
|
||||||
|
|
||||||
interface LspEntry {
|
interface LspEntry {
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
@@ -38,8 +39,8 @@ export function getConfigPaths(): { project: string; user: string; opencode: str
|
|||||||
const cwd = process.cwd()
|
const cwd = process.cwd()
|
||||||
const configDir = getOpenCodeConfigDir({ binary: "opencode" })
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" })
|
||||||
return {
|
return {
|
||||||
project: detectConfigFile(join(cwd, ".opencode", "oh-my-opencode")).path,
|
project: detectConfigFile(join(cwd, ".opencode", CONFIG_BASENAME)).path,
|
||||||
user: detectConfigFile(join(configDir, "oh-my-opencode")).path,
|
user: detectConfigFile(join(configDir, CONFIG_BASENAME)).path,
|
||||||
opencode: detectConfigFile(join(configDir, "opencode")).path,
|
opencode: detectConfigFile(join(configDir, "opencode")).path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export function isServerInstalled(command: string[]): boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runtime wrappers (bun/node) are always available in oh-my-opencode context
|
// Runtime wrappers (bun/node) are always available in oh-my-openagent context
|
||||||
if (cmd === "bun" || cmd === "node") {
|
if (cmd === "bun" || cmd === "node") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user