Treated an object-valued mcpServers manifest field as the server map, rooting relative stdio paths at the plugin root, so plugins declaring servers inline no longer fell through to .mcp.json.
Fixes#6871
Resolved mcpServers file pointers from OMP and Claude plugin manifests before the conventional root config fallback.
Updated marketplace installer documentation for runtime symlink and lockfile registration.
Fixes#6871
- Add the `ts-no-local-is-record` built-in rule to detect local `isRecord` definitions and direct agents to shared guards.
- Add unit tests validating detection of local function and lambda definitions for the new rule.
The /extensions dashboard built one tab per provider from its displayName.
The .agent/.agents config-standard provider used "Agents (standard)", which
collided with the first-class /agents subagents feature even though the tab
only surfaces skills, rules, prompts, commands, and context/system files.
Renamed DISPLAY_NAME to "Agent Dirs (.agent/.agents)".
Fixes#5821
- Added `interruptMode: never` to all updated Go, Rust, and TypeScript built-in discovery rule files.
- Changed `ts-no-inline-cast-access.md` from `interruptMode: tool-only` to `interruptMode: never`.
The previous follow-up rooted path-like commands at the resolved cwd in
the shared resolvePluginStdioPaths helper, which regressed plugin
.mcp.json semantics: plugin commands are relative to the plugin package
root, so a plugin shipping ./bin/server with cwd="work" would resolve to
<pkg>/work/bin/server and ENOENT. Add a commandBase parameter defaulting
to "config-dir" (the plugin contract) and pass "cwd" only from the Codex
importer, where the OS resolves the relative command against the spawned
process cwd.
Fixes#5561
resolvePluginStdioPaths resolved a path-like command against the config
directory unconditionally, but the stdio transport spawns the subprocess
with the rooted cwd as its process cwd, so the OS resolves a relative
command from there. For cwd="server", command="./bin/mcp" that meant OMP
looked for <configDir>/bin/mcp instead of <configDir>/server/bin/mcp.
Root cwd first, then resolve path-like commands from that rooted cwd,
falling back to configDir only when no cwd is set.
Fixes#5561
The Codex config.toml importer copied only command/args/url into the
returned MCPServer, dropping cwd and leaving relative command values
verbatim. MCP stdio spawning resolved those against the session cwd, so
the bundled Codex Computer Use server (relative command, cwd = ".") failed
with ENOENT. Route command/cwd through resolvePluginStdioPaths against the
config directory, matching the claude-plugins/omp-plugins fix in #5481.
Fixes#5561
- Added schema and type updates for task-agent fields and model resolver settings.
- Extended discovery helper logic to carry resolved task-agent metadata through execution setup.
- Updated task/agent registration and execution paths to use the new capability/field data.
- Expanded test coverage for agent-field parsing, model resolution, and executor prewalk behavior.
Discovered plugin .mcp.json stdio servers launched relative command/cwd
values against the session cwd instead of the plugin's config directory,
breaking bundled ChatGPT/Codex plugins (e.g. Computer Use) with ENOENT
when spawning ./... from an unrelated cwd.
The claude-plugins and omp-plugins providers now resolve relative cwd and
path-like command (./ or ../) against the .mcp.json directory via a shared
resolvePluginStdioPaths helper; bare executables such as npx are left
untouched so PATH lookup still works.
Fixes#5330
- Configured the default `task` subagent to use `auto` thinking.
- Enabled `auto` as a valid thinking-level value in agent frontmatter.
- Adjusted thinking-level precedence to ensure that explicit `:level` suffixes in resolved model patterns override agent-defined defaults.
Synthesized project .omp/RULES.md as a distinct sticky rule name so capability dedup no longer shadows it behind the user sticky rule.
Added a public rules capability regression test covering user and project sticky RULES.md files loading together.
Fixes#4739
Skipped the home directory during Claude project skill walk-up so disabling Claude user skills cannot reload the same files as project skills.
Added regression coverage for the home-skill duplicate path with an enabled agents fallback.
Fixes#4648
Claude plugin manifests may declare a `skills` path that resolves directly to a
directory whose `SKILL.md` IS the skill (e.g. `"skills": ["./"]` or a
subdirectory containing only `SKILL.md`). `scanSkillsFromDir` only scanned
`<dir>/<name>/SKILL.md` children, so the single-skill directory layout — the
common shape the Claude plugins reference documents for plugins shipping one
skill — silently dropped every array-form manifest entry that pointed at it.
Add an opt-in `includeSelf` flag to `ScanSkillsFromDirOptions`: when set,
`<dir>/SKILL.md` (if present) is loaded as a skill in addition to the existing
child scan. The Claude plugin skills loader opts in; every other provider
(agents, builtin, claude.ts, codex, github, omp-plugins, opencode) keeps the
strict child-scan semantic they rely on. Frontmatter `name` still wins over
the directory basename fallback.
Regression test: `skills: ["./single"]` where `./single/SKILL.md` is the only
skill file loads the skill under its frontmatter name.
Claude plugin manifests allow command path entries to name either directories
or flat `.md` command files. The array resolver was now preserving those file
paths, but `loadSlashCommands` still sent every resolved entry through
`loadFilesFromDir`, which only globs inside directories. A manifest such as
`{"commands":["./custom/deploy.md"]}` therefore replaced the default scan
and then loaded nothing.
Teach the command loader to stat each resolved entry: `.md` files are read as
single slash commands with the same plugin namespace and source metadata as
directory-loaded files; directories continue through `loadFilesFromDir`.
Missing entries keep the existing silent-empty behavior.
Add a regression test covering a mixed array of a direct command file and a
command directory while proving default `commands/` remains replaced unless
listed explicitly.
Review feedback on #4610: array-form skills was silently replacing the
default `skills/` scan when the manifest declared any explicit entries.
Per the Claude plugins reference "Path behavior rules"
(https://code.claude.com/docs/en/plugins-reference#path-behavior-rules):
- `skills` ADDS to the default `skills/` scan
- `commands` / `slash-commands` REPLACE the default `commands/` scan
`resolvePluginDir` now takes an explicit `includeFallback` flag. `loadSkills`
passes `true` (fallback + declared entries, deduped by resolved absolute
path so a manifest may still list `./skills` alongside extras without
double-load); `loadSlashCommands` passes `false` (replace semantic
preserved). Deduplication keeps the fallback first and declared entries
in manifest order.
Regression tests cover both semantics: skills-array merges with default
`skills/`; commands-array replaces default `commands/` so a stray
`commands/default.md` no longer loads once the manifest declares an
alternative — matching Claude's documented behavior.
The Claude plugin manifest allows `commands`, `slash-commands`, and `skills`
to be either a single string or an array of strings — documented under
https://code.claude.com/docs/en/plugins-reference#path-behavior-rules and
used by real marketplace plugins such as addyosmani/agent-skills whose
plugin.json declares `"commands": ["./.claude/commands", "./commands"]`.
`resolvePluginDir` in `packages/coding-agent/src/discovery/claude-plugins.ts`
typed those manifest fields as `string` only, so array-shaped values were
silently dropped: no items loaded, no warning surfaced. Slash commands
(`spec`, `plan`, `build`, `test`, `review`) never appeared in the picker.
Normalize `string | string[]` at the resolver, load every in-root entry,
and emit one out-of-plugin-root warning per bad entry so misconfigured
paths remain observable. Skills and slash-command loaders now fan out over
the resolved directory list and merge warnings from all sources.
Fixes#4609
- Added eight new Go-specific rules to the discovery package.
- Registered the new Go rules in the default rule source index.
- Covered the new Go AST matching conditions with test cases in `builtin-defaults.test.ts`.
Codex discovery surfaced every `~/.codex/hooks/*.{ts,js}` file as an OMP
hook (silently defaulting untyped names to `pre:<basename>`), and
`discoverExtensionPaths` then handed those paths to `loadExtension` for
dynamic import. A standalone Codex hook script with a top-level
`process.exit(0)` terminated the host CLI cleanly — `try/catch` around
`await import()` cannot intercept a synchronous exit, so OMP died at the
`loadExtensions:start` startup marker with no error surface.
Two-layer fix:
- `packages/coding-agent/src/extensibility/utils.ts`: new
`withExitGuard` helper patches `process.exit` for the duration of a
guarded callback so an exit raises `ExtensionExitError` instead of
terminating the process; nested and concurrent guards restore correctly
via depth counter.
- `extensibility/extensions/loader.ts`, `extensibility/hooks/loader.ts`,
and `extensibility/plugins/manager.ts` wrap their dynamic-import sites
in `withExitGuard` so the existing per-module `try/catch` records the
intercepted exit as a load error and OMP keeps starting.
- `discovery/codex.ts:loadHooks` no longer treats arbitrary files as
OMP hooks: only `pre-<tool>.{ts,js}` and `post-<tool>.{ts,js}` are
registered. Files like `memory-bank-reminder.ts` are silently skipped
rather than imported as extension factories.
Adds regression coverage:
- `test/extension-loader-process-exit.test.ts` — `loadExtensions` /
`loadHooks` return errors and leave `process.exit` restored when a
module exits at import time; sibling modules still load.
- `test/discovery/codex-hooks-discovery.test.ts` — codex provider
registers `pre-*` / `post-*` files and drops everything else.
Fixes#3680
Filtered marketplace-managed runtime symlinks out of the npm plugin listing and OMP extension-package status provider while keeping marketplace installs available to the runtime loader. Added regressions for both duplicate surfaces.
Fixes#3628
Expanded environment variable placeholders in Claude marketplace plugin MCP url and headers before registration. Added a regression test covering context7-style HTTP server headers.\n\nFixes #3621
- Renamed the `find` and `search` tools to `glob` and `grep` respectively across the codebase to improve command clarity.
- Implemented full-stack support for the renamed tools, including CLI arguments, system prompts, SDK exports, and tool registration.
- Added automated migration logic in `settings` to transform legacy `find` and `search` configuration keys to their new equivalents.
- Updated the `collab-web` renderer registry to ensure backwards compatibility with legacy tool outputs.
Mapped OpenCode MCP array commands to stdio command plus args and accepted environment as the provider-native env key.\n\nAdded regression coverage for array command normalization, environment mapping, env fallback, and empty args omission.\n\nFixes #3180
- Replaced usage of `ReturnType<typeof setTimeout>` and `ReturnType<typeof setInterval>` with the explicit `Timer` type across the codebase.
- Updated several type definitions and function signatures to use concrete types instead of inferred return types for improved clarity and maintainability.
- Migrated all wire protocol, schema definitions, and tools validation from Zod to ArkType across multiple packages.
- Updated extension runtimes, custom tools loader, and TypeBox compatibility shim to expose and use ArkType instances.
- Added a comprehensive ArkType migration guide, validation parity tests, and helper utilities.
- Removed redundant PDF asset routing and parsing implementations from the read tool.
- Added a new builtin rule definition file, `ts-no-inline-cast-access.md`, with AST patterns that flag inline cast member access and usage guidance.
- Registered the new rule in `src/discovery/builtin-rules/index.ts` so it is included in the built-in TypeScript rule set.
- Updated `ts-no-any.md` to recommend schema parsing at trust boundaries and clarified when to choose schema parsing, guards, or unchecked casts.
GitHub documents applyTo as a single comma-separated string (e.g.
"**/*.ts,**/*.tsx") and treats both ** and **/* as all-files. The rule
loader kept the whole CSV value as one glob and missed **/* for
always-apply. Split applyTo via parseCSV and include **/* as all-files.
Addresses review feedback on #2734.
Added GitHub Copilot instruction-file discovery to the github rule provider path, mapping applyTo frontmatter into always-apply or glob-scoped rules and avoiding duplicate always-apply prompt content when context imports the same file.\n\nFixes #2731
When a Claude plugin skill's SKILL.md frontmatter uses a display-style
name (e.g. `name: Understand Anything`), the synthesized slash command
inherited that text. `expandSlashCommand` splits the command at the
first whitespace, so `/understand` never resolved and the multi-word
form could not expand either.
Use `path.basename(path.dirname(skill.path))` so the slash command
always matches the documented `skills/<name>/SKILL.md` → `/<name>`
contract while the frontmatter still drives the description/body.
Fixes#2415
Add a default-off "auto-learn" loop. When `autolearn.enabled` is set, after the
agent stops a session controller nudges it to capture reusable lessons: durable
facts go to long-term memory and repeatable procedures become "managed skills" —
SKILL.md files written to an isolated ~/.omp/agent/managed-skills directory that is
discovered and surfaced like authored skills but never overwrites them.
Two tools back this:
- `manage_skill` — create/update/delete managed skills.
- `learn` — record a lesson, optionally minting/enhancing a managed skill in the
same call (requires a hindsight/mnemopi memory backend).
The nudge is passive by default (a hidden reminder rides the next turn);
`autolearn.autoContinue` instead auto-runs one capture turn at stop, and
`autolearn.minToolCalls` (default 5) gates trivial turns. Plan/goal-mode turns and
subagents are never nudged, and the controller re-checks the live setting at fire
time so a mid-session opt-out takes effect.
Isolation & precedence: managed skills are a separate lowest-priority discovery
provider, so an authored skill of the same name wins across every provider and
custom directory regardless of third-party toggles; a disabled higher-priority
authored skill can never hide a managed one, and managed never masks an enabled
authored skill. Managed names and descriptions are sanitized on both write and
read (control/format chars, angle brackets, and Markdown fences) before they render
into the system prompt, and the SKILL.md byte cap is enforced on the final
serialized file.
Default off → zero footprint when disabled.
Loaded Claude Code marketplace plugin SKILL.md files into the slash-command capability so Claude-native plugin docs like /understand work in autocomplete and invocation.\n\nAdded a regression covering OMP installed plugin registries and bare slash-command expansion.\n\nFixes #2415
Address review against GitHub Copilot CLI docs (add-custom-instructions):
- COPILOT_CUSTOM_INSTRUCTIONS_DIRS: each dir contributes AGENTS.md (context) and .github/instructions/**/*.instructions.md (recursive), per spec. Dropped the non-spec <dir>/copilot-instructions.md and the wrong top-level <dir>/*.instructions.md scan.
- Scan the project .github/instructions/ tree recursively ('within or below').
- Prompts: .github/prompts/*.prompt.md is a VS Code construct, not a Copilot CLI feature; dropped the fictional ~/.copilot/prompts/ user dir and reframed comments/descriptions accordingly.
The github provider only scanned the project .github/ tree, so Copilot CLI's user-global config was ignored. Add user-global instructions (~/.copilot/copilot-instructions.md), COPILOT_HOME relocation, COPILOT_CUSTOM_INSTRUCTIONS_DIRS (copilot-instructions.md + *.instructions.md), and prompt discovery (*.prompt.md in .github/prompts/ and ~/.copilot/prompts/).
Closes#1913, #1915, #1916.