Compare commits

..

5 Commits

Author SHA1 Message Date
github-actions[bot]
8776af4c34 release: v2.1.6 2025-12-16 15:48:53 +00:00
YeonGyu-Kim
90baab301a fix(agents): restrict OmO-Plan to read-only tools, inherit from default plan agent (#72) (#75)
Remove OmO agent permission spread from omoPlanBase to ensure OmO-Plan:
- Uses read-only tools only (read, glob, grep, etc)
- Focuses on planning and analysis
- Can ask follow-up questions for clarification
- Does not execute code changes

🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
2025-12-17 00:44:30 +09:00
YeonGyu-Kim
715756b68a Optimize tool descriptions for token efficiency (#73)
* Optimize background-task tool descriptions for token efficiency

- BACKGROUND_TASK_DESCRIPTION: 571 chars → 127 chars
- BACKGROUND_OUTPUT_DESCRIPTION: 268 chars → 95 chars
- BACKGROUND_CANCEL_DESCRIPTION: 374 chars → 83 chars

Follows token efficiency improvements pattern from PR #71.

🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)

* Optimize call-omo-agent tool description for token efficiency

- CALL_OMO_AGENT_DESCRIPTION: 841 chars → 156 chars (~81% reduction)
- Follows pattern from PR #71 where LSP tool descriptions were optimized
- Maintains core information while removing redundant explanations

🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)

* Optimize look-at tool description for token efficiency

🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)

* Optimize interactive-bash tool description for token efficiency

346 chars → 130 chars (~62% reduction), following PR #71 pattern.

🤖 Generated with assistance of OhMyOpenCode
2025-12-17 00:38:38 +09:00
YeonGyu-Kim
cdde8da7ba Optimize LSP tool descriptions for token efficiency (#71)
* bump up dependencies

* Optimize LSP tool descriptions for token efficiency

- Reduce verbose descriptions to concise versions (~63% character reduction)
- Minimize parameter descriptions (1826 → 671 characters)
- Remove redundant describe() calls for self-explanatory parameters
- Total: ~390 tokens saved from system prompts

🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
2025-12-17 00:16:21 +09:00
YeonGyu-Kim
d7ce7402e6 Update README 2025-12-16 23:31:03 +09:00
9 changed files with 61 additions and 133 deletions

View File

@@ -113,12 +113,13 @@ Hand this doc to an agent and let them set it up.
### For Those Who Want to Read
Welcome. Introducing OmO (Oh-Mo).
Everything below is customizable. Take what you want. All features are enabled by default. You don't have to do anything.
Everything below is customizable. Take what you want.
All features are enabled by default. You don't have to do anything. Battery Included, works out of the box.
- Claude Code Compatibility: Command, Agent, Skill, MCP, Hook(PreToolUse, PostToolUse, UserPromptSubmit, Stop)
- Full LSP / AstGrep Support: Refactor with confidence.
- Comment Checker: No AI-like Comments Anymore.
- Full LSP / AstGrep Support: Explore precisely, Refactor with confidence.
- Todo Continuation Enforcer: Forces the agent to continue if it quits halfway.
- Comment Checker: Prevents AI from adding excessive comments.
- Curated Agents
- OmO: Super smart main agent (Opus 4.5 High)
- Oracle: Design, debugging (GPT 5.2 Medium)

View File

@@ -7,9 +7,9 @@
"dependencies": {
"@ast-grep/cli": "^0.40.0",
"@ast-grep/napi": "^0.40.0",
"@code-yeongyu/comment-checker": "^0.5.0",
"@code-yeongyu/comment-checker": "^0.6.0",
"@openauthjs/openauth": "^0.4.3",
"@opencode-ai/plugin": "^1.0.150",
"@opencode-ai/plugin": "^1.0.162",
"hono": "^4.10.4",
"picomatch": "^4.0.2",
"xdg-basedir": "^5.1.0",
@@ -68,13 +68,13 @@
"@ast-grep/napi-win32-x64-msvc": ["@ast-grep/napi-win32-x64-msvc@0.40.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Hk2IwfPqMFGZt5SRxsoWmGLxBXxprow4LRp1eG6V8EEiJCNHxZ9ZiEaIc5bNvMDBjHVSnqZAXT22dROhrcSKQg=="],
"@code-yeongyu/comment-checker": ["@code-yeongyu/comment-checker@0.5.0", "", { "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ], "bin": { "comment-checker": "bin/comment-checker" } }, "sha512-rKD2qQnTVUacsVQtpu3I5Sxi09X/XpOwS9fcmbUv1yfUL6llraaPuLmmxMBMRcmm7Zu31yEPVKCeUkVODfRL1g=="],
"@code-yeongyu/comment-checker": ["@code-yeongyu/comment-checker@0.6.0", "", { "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ], "bin": { "comment-checker": "bin/comment-checker" } }, "sha512-VtDPrhbUJcb5BIS18VMcY/N/xSLbMr6dpU9MO1NYQyEDhI4pSIx07K4gOlCutG/nHVCjO+HEarn8rttODP+5UA=="],
"@openauthjs/openauth": ["@openauthjs/openauth@0.4.3", "", { "dependencies": { "@standard-schema/spec": "1.0.0-beta.3", "aws4fetch": "1.0.20", "jose": "5.9.6" }, "peerDependencies": { "arctic": "^2.2.2", "hono": "^4.0.0" } }, "sha512-RlnjqvHzqcbFVymEwhlUEuac4utA5h4nhSK/i2szZuQmxTIqbGUxZ+nM+avM+VV4Ing+/ZaNLKILoXS3yrkOOw=="],
"@opencode-ai/plugin": ["@opencode-ai/plugin@1.0.150", "", { "dependencies": { "@opencode-ai/sdk": "1.0.150", "zod": "4.1.8" } }, "sha512-XmY3yydk120GBv2KeLxSZlElFx4Zx9TYLa3bS9X1TxXot42UeoMLEi3Xa46yboYnWwp4bC9Fu+Gd1E7hypG8Jw=="],
"@opencode-ai/plugin": ["@opencode-ai/plugin@1.0.162", "", { "dependencies": { "@opencode-ai/sdk": "1.0.162", "zod": "4.1.8" } }, "sha512-tiJw7SCfSlG/3tY2O0J2UT06OLuazOzsv1zYlFbLxLy/EVedtW0pzxYalO20a4e//vInvOXFkhd2jLyB5vNEVA=="],
"@opencode-ai/sdk": ["@opencode-ai/sdk@1.0.150", "", {}, "sha512-Nz9Di8UD/GK01w3N+jpiGNB733pYkNY8RNLbuE/HUxEGSP5apbXBY0IdhbW7859sXZZK38kF1NqOx4UxwBf4Bw=="],
"@opencode-ai/sdk": ["@opencode-ai/sdk@1.0.162", "", {}, "sha512-+XqRErBUt9eb1m3i/7WkZc/QCKCCjTaGV3MvhLhs/CUwbUn767D/ugzcG/i2ec8j/4nQmjJbjPDRmrQfvF1Qjw=="],
"@oslojs/asn1": ["@oslojs/asn1@1.0.0", "", { "dependencies": { "@oslojs/binary": "1.0.0" } }, "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA=="],

View File

@@ -1,6 +1,6 @@
{
"name": "oh-my-opencode",
"version": "2.1.5",
"version": "2.1.6",
"description": "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@@ -48,9 +48,9 @@
"dependencies": {
"@ast-grep/cli": "^0.40.0",
"@ast-grep/napi": "^0.40.0",
"@code-yeongyu/comment-checker": "^0.5.0",
"@code-yeongyu/comment-checker": "^0.6.0",
"@openauthjs/openauth": "^0.4.3",
"@opencode-ai/plugin": "^1.0.150",
"@opencode-ai/plugin": "^1.0.162",
"hono": "^4.10.4",
"picomatch": "^4.0.2",
"xdg-basedir": "^5.1.0",

View File

@@ -312,7 +312,6 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
const { name: _planName, ...planConfigWithoutName } = config.agent?.plan ?? {};
const omoPlanOverride = pluginConfig.agents?.["OmO-Plan"];
const omoPlanBase = {
...builtinAgents.OmO,
...planConfigWithoutName,
description: `${config.agent?.plan?.description ?? "Plan agent"} (OhMyOpenCode version)`,
color: config.agent?.plan?.color ?? "#6495ED",

View File

@@ -1,36 +1,7 @@
export const BACKGROUND_TASK_DESCRIPTION = `Launch a background agent task that runs asynchronously.
export const BACKGROUND_TASK_DESCRIPTION = `Run agent task in background. Returns task_id immediately; notifies on completion.
The task runs in a separate session while you continue with other work. The system will notify you when the task completes.
Use \`background_output\` to get results. Prompts MUST be in English.`
Use this for:
- Long-running research tasks
- Complex analysis that doesn't need immediate results
- Parallel workloads to maximize throughput
export const BACKGROUND_OUTPUT_DESCRIPTION = `Get output from background task. System notifies on completion, so block=true rarely needed.`
Arguments:
- description: Short task description (shown in status)
- prompt: Full detailed prompt for the agent (MUST be in English for optimal LLM performance)
- agent: Agent type to use (any agent allowed)
IMPORTANT: Always write prompts in English regardless of user's language. LLMs perform significantly better with English prompts.
Returns immediately with task ID and session info. Use \`background_output\` to check progress or retrieve results.`
export const BACKGROUND_OUTPUT_DESCRIPTION = `Get output from a background task.
Arguments:
- task_id: Required task ID to get output from
- block: If true, wait for task completion. If false (default), return current status immediately.
- timeout: Max wait time in ms when blocking (default: 60000, max: 600000)
The system automatically notifies when background tasks complete. You typically don't need block=true.`
export const BACKGROUND_CANCEL_DESCRIPTION = `Cancel running background task(s).
Only works for tasks with status "running". Aborts the background session and marks the task as cancelled.
Arguments:
- taskId: Task ID to cancel (optional if all=true)
- all: Set to true to cancel ALL running background tasks at once (default: false)
**Cleanup Before Answer**: When you have gathered sufficient information and are ready to provide your final answer to the user, use \`all=true\` to cancel ALL running background tasks first, then deliver your response. This conserves resources and ensures clean workflow completion.`
export const BACKGROUND_CANCEL_DESCRIPTION = `Cancel running background task(s). Use all=true to cancel ALL before final answer.`

View File

@@ -1,25 +1,7 @@
export const ALLOWED_AGENTS = ["explore", "librarian"] as const
export const CALL_OMO_AGENT_DESCRIPTION = `Launch a new agent to handle complex, multi-step tasks autonomously.
export const CALL_OMO_AGENT_DESCRIPTION = `Spawn explore/librarian agent. run_in_background REQUIRED (true=async with task_id, false=sync).
This is a restricted version of the Task tool that only allows spawning explore and librarian agents.
Available: {agents}
Available agent types:
{agents}
When using this tool, you must specify a subagent_type parameter to select which agent type to use.
**IMPORTANT: run_in_background parameter is REQUIRED**
- \`run_in_background=true\`: Task runs asynchronously in background. Returns immediately with task_id.
The system will notify you when the task completes.
Use \`background_output\` tool with task_id to check progress (block=false returns full status info).
- \`run_in_background=false\`: Task runs synchronously. Waits for completion and returns full result.
Usage notes:
1. Launch multiple agents concurrently whenever possible, to maximize performance
2. When the agent is done, it will return a single message back to you
3. Each agent invocation is stateless unless you provide a session_id
4. Your prompt should contain a highly detailed task description for the agent to perform autonomously
5. Clearly tell the agent whether you expect it to write code or just to do research
6. For long-running research tasks, use run_in_background=true to avoid blocking
7. **IMPORTANT**: Always write prompts in English regardless of user's language. LLMs perform significantly better with English prompts.`
Prompts MUST be in English. Use \`background_output\` for async results.`

View File

@@ -11,12 +11,6 @@ export const BLOCKED_TMUX_SUBCOMMANDS = [
"pipep",
]
export const INTERACTIVE_BASH_DESCRIPTION = `Execute tmux commands for interactive terminal session management.
export const INTERACTIVE_BASH_DESCRIPTION = `Execute tmux commands. Use "omo-{name}" session pattern.
Use session names following the pattern "omo-{name}" for automatic tracking.
BLOCKED COMMANDS (use bash tool instead):
- capture-pane / capturep: Use bash to read output files or pipe output
- save-buffer / saveb: Use bash to save content to files
- show-buffer / showb: Use bash to read buffer content
- pipe-pane / pipep: Use bash for piping output`
Blocked (use bash instead): capture-pane, save-buffer, show-buffer, pipe-pane.`

View File

@@ -1,10 +1,3 @@
export const MULTIMODAL_LOOKER_AGENT = "multimodal-looker" as const
export const LOOK_AT_DESCRIPTION = `Analyze media files (PDFs, images, diagrams) that require visual interpretation.
Parameters:
- file_path: Absolute path to the file to analyze
- goal: What specific information to extract (be specific for better results)
This tool uses a separate context window with Gemini 2.5 Flash for multimodal analysis,
saving tokens in the main conversation while providing accurate visual interpretation.`
export const LOOK_AT_DESCRIPTION = `Analyze media files (PDFs, images, diagrams) via Gemini 2.5 Flash in separate context. Saves main context tokens.`

View File

@@ -35,12 +35,11 @@ import type {
export const lsp_hover = tool({
description:
"Get type information, documentation, and signature for a symbol at a specific position in a file. Use this when you need to understand what a variable, function, class, or any identifier represents.",
description: "Get type info, docs, and signature for a symbol at position.",
args: {
filePath: tool.schema.string().describe("The absolute path to the file"),
line: tool.schema.number().min(1).describe("Line number (1-based)"),
character: tool.schema.number().min(0).describe("Character position (0-based)"),
filePath: tool.schema.string(),
line: tool.schema.number().min(1).describe("1-based"),
character: tool.schema.number().min(0).describe("0-based"),
},
execute: async (args, context) => {
try {
@@ -57,12 +56,11 @@ export const lsp_hover = tool({
})
export const lsp_goto_definition = tool({
description:
"Jump to the source definition of a symbol (variable, function, class, type, import, etc.). Use this when you need to find WHERE something is defined.",
description: "Jump to symbol definition. Find WHERE something is defined.",
args: {
filePath: tool.schema.string().describe("The absolute path to the file"),
line: tool.schema.number().min(1).describe("Line number (1-based)"),
character: tool.schema.number().min(0).describe("Character position (0-based)"),
filePath: tool.schema.string(),
line: tool.schema.number().min(1).describe("1-based"),
character: tool.schema.number().min(0).describe("0-based"),
},
execute: async (args, context) => {
try {
@@ -95,12 +93,11 @@ export const lsp_goto_definition = tool({
})
export const lsp_find_references = tool({
description:
"Find ALL usages/references of a symbol across the entire workspace. Use this when you need to understand the impact of changing something.",
description: "Find ALL usages/references of a symbol across the entire workspace.",
args: {
filePath: tool.schema.string().describe("The absolute path to the file"),
line: tool.schema.number().min(1).describe("Line number (1-based)"),
character: tool.schema.number().min(0).describe("Character position (0-based)"),
filePath: tool.schema.string(),
line: tool.schema.number().min(1).describe("1-based"),
character: tool.schema.number().min(0).describe("0-based"),
includeDeclaration: tool.schema.boolean().optional().describe("Include the declaration itself"),
},
execute: async (args, context) => {
@@ -133,10 +130,9 @@ export const lsp_find_references = tool({
})
export const lsp_document_symbols = tool({
description:
"Get a hierarchical outline of all symbols (classes, functions, methods, variables, types, constants) in a single file. Use this to quickly understand a file's structure.",
description: "Get hierarchical outline of all symbols in a file.",
args: {
filePath: tool.schema.string().describe("The absolute path to the file"),
filePath: tool.schema.string(),
},
execute: async (args, context) => {
try {
@@ -172,12 +168,11 @@ export const lsp_document_symbols = tool({
})
export const lsp_workspace_symbols = tool({
description:
"Search for symbols by name across the ENTIRE workspace/project. Use this when you know (or partially know) a symbol's name but don't know which file it's in.",
description: "Search symbols by name across ENTIRE workspace.",
args: {
filePath: tool.schema.string().describe("A file path in the workspace to determine the workspace root"),
query: tool.schema.string().describe("The symbol name to search for (supports fuzzy matching)"),
limit: tool.schema.number().optional().describe("Maximum number of results to return"),
filePath: tool.schema.string(),
query: tool.schema.string().describe("Symbol name (fuzzy match)"),
limit: tool.schema.number().optional().describe("Max results"),
},
execute: async (args, context) => {
try {
@@ -208,10 +203,9 @@ export const lsp_workspace_symbols = tool({
})
export const lsp_diagnostics = tool({
description:
"Get all errors, warnings, and hints for a file from the language server. Use this to check if code has type errors, syntax issues, or linting problems BEFORE running the build.",
description: "Get errors, warnings, hints from language server BEFORE running build.",
args: {
filePath: tool.schema.string().describe("The absolute path to the file"),
filePath: tool.schema.string(),
severity: tool.schema
.enum(["error", "warning", "information", "hint", "all"])
.optional()
@@ -256,7 +250,7 @@ export const lsp_diagnostics = tool({
})
export const lsp_servers = tool({
description: "List all available LSP servers and check if they are installed. Use this to see what language support is available.",
description: "List available LSP servers and installation status.",
args: {},
execute: async (_args, context) => {
try {
@@ -278,12 +272,11 @@ export const lsp_servers = tool({
})
export const lsp_prepare_rename = tool({
description:
"Check if a symbol at a specific position can be renamed. Use this BEFORE attempting to rename to validate the operation and get the current symbol name.",
description: "Check if rename is valid. Use BEFORE lsp_rename.",
args: {
filePath: tool.schema.string().describe("The absolute path to the file"),
line: tool.schema.number().min(1).describe("Line number (1-based)"),
character: tool.schema.number().min(0).describe("Character position (0-based)"),
filePath: tool.schema.string(),
line: tool.schema.number().min(1).describe("1-based"),
character: tool.schema.number().min(0).describe("0-based"),
},
execute: async (args, context) => {
try {
@@ -303,13 +296,12 @@ export const lsp_prepare_rename = tool({
})
export const lsp_rename = tool({
description:
"Rename a symbol across the entire workspace. This APPLIES the rename to all files. Use lsp_prepare_rename first to check if rename is possible.",
description: "Rename symbol across entire workspace. APPLIES changes to all files.",
args: {
filePath: tool.schema.string().describe("The absolute path to the file"),
line: tool.schema.number().min(1).describe("Line number (1-based)"),
character: tool.schema.number().min(0).describe("Character position (0-based)"),
newName: tool.schema.string().describe("The new name for the symbol"),
filePath: tool.schema.string(),
line: tool.schema.number().min(1).describe("1-based"),
character: tool.schema.number().min(0).describe("0-based"),
newName: tool.schema.string().describe("New symbol name"),
},
execute: async (args, context) => {
try {
@@ -327,14 +319,13 @@ export const lsp_rename = tool({
})
export const lsp_code_actions = tool({
description:
"Get available code actions for a range in the file. Code actions include quick fixes, refactorings (extract, inline, rewrite), and source actions (organize imports, fix all). Use this to discover what automated changes the language server can perform.",
description: "Get available quick fixes, refactorings, and source actions (organize imports, fix all).",
args: {
filePath: tool.schema.string().describe("The absolute path to the file"),
startLine: tool.schema.number().min(1).describe("Start line number (1-based)"),
startCharacter: tool.schema.number().min(0).describe("Start character position (0-based)"),
endLine: tool.schema.number().min(1).describe("End line number (1-based)"),
endCharacter: tool.schema.number().min(0).describe("End character position (0-based)"),
filePath: tool.schema.string(),
startLine: tool.schema.number().min(1).describe("1-based"),
startCharacter: tool.schema.number().min(0).describe("0-based"),
endLine: tool.schema.number().min(1).describe("1-based"),
endCharacter: tool.schema.number().min(0).describe("0-based"),
kind: tool.schema
.enum([
"quickfix",
@@ -372,13 +363,10 @@ export const lsp_code_actions = tool({
})
export const lsp_code_action_resolve = tool({
description:
"Resolve and APPLY a code action. This resolves the full details and applies the changes to files. Use after getting a code action from lsp_code_actions.",
description: "Resolve and APPLY a code action from lsp_code_actions.",
args: {
filePath: tool.schema
.string()
.describe("The absolute path to a file in the workspace (used to find the LSP server)"),
codeAction: tool.schema.string().describe("The code action JSON object as returned by lsp_code_actions (stringified)"),
filePath: tool.schema.string(),
codeAction: tool.schema.string().describe("Code action JSON from lsp_code_actions"),
},
execute: async (args, context) => {
try {