feat(hooks): auto-disable directory-agents-injector for OpenCode 1.1.37+ native support (#1204)
* feat(delegate-task): add prometheus self-delegation block and delegate_task permission - Block prometheus from delegating to itself via delegate_task - Grant delegate_task permission to prometheus when called as subagent - Other subagents still have delegate_task disabled * feat(version): add OPENCODE_NATIVE_AGENTS_INJECTION_VERSION constant * docs: add deprecation notes for directory-agents-injector * feat(hooks): auto-disable directory-agents-injector for OpenCode 1.1.37+ --------- Co-authored-by: justsisyphus <justsisyphus@users.noreply.github.com>
This commit is contained in:
parent
68e0a32183
commit
acc19fcd41
@ -768,6 +768,8 @@ Disable specific built-in hooks via `disabled_hooks` in `~/.config/opencode/oh-m
|
|||||||
|
|
||||||
Available hooks: `todo-continuation-enforcer`, `context-window-monitor`, `session-recovery`, `session-notification`, `comment-checker`, `grep-output-truncator`, `tool-output-truncator`, `directory-agents-injector`, `directory-readme-injector`, `empty-task-response-detector`, `think-mode`, `anthropic-context-window-limit-recovery`, `rules-injector`, `background-notification`, `auto-update-checker`, `startup-toast`, `keyword-detector`, `agent-usage-reminder`, `non-interactive-env`, `interactive-bash-session`, `compaction-context-injector`, `thinking-block-validator`, `claude-code-hooks`, `ralph-loop`, `preemptive-compaction`
|
Available hooks: `todo-continuation-enforcer`, `context-window-monitor`, `session-recovery`, `session-notification`, `comment-checker`, `grep-output-truncator`, `tool-output-truncator`, `directory-agents-injector`, `directory-readme-injector`, `empty-task-response-detector`, `think-mode`, `anthropic-context-window-limit-recovery`, `rules-injector`, `background-notification`, `auto-update-checker`, `startup-toast`, `keyword-detector`, `agent-usage-reminder`, `non-interactive-env`, `interactive-bash-session`, `compaction-context-injector`, `thinking-block-validator`, `claude-code-hooks`, `ralph-loop`, `preemptive-compaction`
|
||||||
|
|
||||||
|
**Note on `directory-agents-injector`**: This hook is **automatically disabled** when running on OpenCode 1.1.37+ because OpenCode now has native support for dynamically resolving AGENTS.md files from subdirectories (PR #10678). This prevents duplicate AGENTS.md injection. For older OpenCode versions, the hook remains active to provide the same functionality.
|
||||||
|
|
||||||
**Note on `auto-update-checker` and `startup-toast`**: The `startup-toast` hook is a sub-feature of `auto-update-checker`. To disable only the startup toast notification while keeping update checking enabled, add `"startup-toast"` to `disabled_hooks`. To disable all update checking features (including the toast), add `"auto-update-checker"` to `disabled_hooks`.
|
**Note on `auto-update-checker` and `startup-toast`**: The `startup-toast` hook is a sub-feature of `auto-update-checker`. To disable only the startup toast notification while keeping update checking enabled, add `"startup-toast"` to `disabled_hooks`. To disable all update checking features (including the toast), add `"auto-update-checker"` to `disabled_hooks`.
|
||||||
|
|
||||||
## MCPs
|
## MCPs
|
||||||
|
|||||||
@ -320,7 +320,7 @@ Hooks intercept and modify behavior at key points in the agent lifecycle.
|
|||||||
|
|
||||||
| Hook | Event | Description |
|
| Hook | Event | Description |
|
||||||
|------|-------|-------------|
|
|------|-------|-------------|
|
||||||
| **directory-agents-injector** | PostToolUse | Auto-injects AGENTS.md when reading files. Walks from file to project root, collecting all AGENTS.md files. |
|
| **directory-agents-injector** | PostToolUse | Auto-injects AGENTS.md when reading files. Walks from file to project root, collecting all AGENTS.md files. **Deprecated for OpenCode 1.1.37+** - Auto-disabled when native AGENTS.md injection is available. |
|
||||||
| **directory-readme-injector** | PostToolUse | Auto-injects README.md for directory context. |
|
| **directory-readme-injector** | PostToolUse | Auto-injects README.md for directory context. |
|
||||||
| **rules-injector** | PostToolUse | Injects rules from `.claude/rules/` when conditions match. Supports globs and alwaysApply. |
|
| **rules-injector** | PostToolUse | Injects rules from `.claude/rules/` when conditions match. Supports globs and alwaysApply. |
|
||||||
| **compaction-context-injector** | Stop | Preserves critical context during session compaction. |
|
| **compaction-context-injector** | Stop | Preserves critical context during session compaction. |
|
||||||
|
|||||||
25
src/index.ts
25
src/index.ts
@ -78,7 +78,7 @@ import { SkillMcpManager } from "./features/skill-mcp-manager";
|
|||||||
import { initTaskToastManager } from "./features/task-toast-manager";
|
import { initTaskToastManager } from "./features/task-toast-manager";
|
||||||
import { TmuxSessionManager } from "./features/tmux-subagent";
|
import { TmuxSessionManager } from "./features/tmux-subagent";
|
||||||
import { type HookName } from "./config";
|
import { type HookName } from "./config";
|
||||||
import { log, detectExternalNotificationPlugin, getNotificationConflictWarning, resetMessageCursor, includesCaseInsensitive, hasConnectedProvidersCache } from "./shared";
|
import { log, detectExternalNotificationPlugin, getNotificationConflictWarning, resetMessageCursor, includesCaseInsensitive, hasConnectedProvidersCache, getOpenCodeVersion, isOpenCodeVersionAtLeast, OPENCODE_NATIVE_AGENTS_INJECTION_VERSION } from "./shared";
|
||||||
import { loadPluginConfig } from "./plugin-config";
|
import { loadPluginConfig } from "./plugin-config";
|
||||||
import { createModelCacheState, getModelLimit } from "./plugin-state";
|
import { createModelCacheState, getModelLimit } from "./plugin-state";
|
||||||
import { createConfigHandler } from "./plugin-handlers";
|
import { createConfigHandler } from "./plugin-handlers";
|
||||||
@ -136,9 +136,26 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
|
|||||||
experimental: pluginConfig.experimental,
|
experimental: pluginConfig.experimental,
|
||||||
})
|
})
|
||||||
: null;
|
: null;
|
||||||
const directoryAgentsInjector = isHookEnabled("directory-agents-injector")
|
// Check for native OpenCode AGENTS.md injection support before creating hook
|
||||||
? createDirectoryAgentsInjectorHook(ctx)
|
let directoryAgentsInjector = null;
|
||||||
: null;
|
if (isHookEnabled("directory-agents-injector")) {
|
||||||
|
const currentVersion = getOpenCodeVersion();
|
||||||
|
const hasNativeSupport = currentVersion !== null &&
|
||||||
|
isOpenCodeVersionAtLeast(OPENCODE_NATIVE_AGENTS_INJECTION_VERSION);
|
||||||
|
|
||||||
|
if (hasNativeSupport) {
|
||||||
|
console.warn(
|
||||||
|
`[oh-my-opencode] directory-agents-injector hook auto-disabled: ` +
|
||||||
|
`OpenCode ${currentVersion} has native AGENTS.md support (>= ${OPENCODE_NATIVE_AGENTS_INJECTION_VERSION})`
|
||||||
|
);
|
||||||
|
log("directory-agents-injector auto-disabled due to native OpenCode support", {
|
||||||
|
currentVersion,
|
||||||
|
nativeVersion: OPENCODE_NATIVE_AGENTS_INJECTION_VERSION,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
directoryAgentsInjector = createDirectoryAgentsInjectorHook(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
const directoryReadmeInjector = isHookEnabled("directory-readme-injector")
|
const directoryReadmeInjector = isHookEnabled("directory-readme-injector")
|
||||||
? createDirectoryReadmeInjectorHook(ctx)
|
? createDirectoryReadmeInjectorHook(ctx)
|
||||||
: null;
|
: null;
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import {
|
|||||||
resetVersionCache,
|
resetVersionCache,
|
||||||
setVersionCache,
|
setVersionCache,
|
||||||
MINIMUM_OPENCODE_VERSION,
|
MINIMUM_OPENCODE_VERSION,
|
||||||
|
OPENCODE_NATIVE_AGENTS_INJECTION_VERSION,
|
||||||
} from "./opencode-version"
|
} from "./opencode-version"
|
||||||
|
|
||||||
describe("opencode-version", () => {
|
describe("opencode-version", () => {
|
||||||
@ -220,4 +221,46 @@ describe("opencode-version", () => {
|
|||||||
expect(MINIMUM_OPENCODE_VERSION).toBe("1.1.1")
|
expect(MINIMUM_OPENCODE_VERSION).toBe("1.1.1")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("OPENCODE_NATIVE_AGENTS_INJECTION_VERSION", () => {
|
||||||
|
test("is set to 1.1.37", () => {
|
||||||
|
// #given the native agents injection version constant
|
||||||
|
// #when exported
|
||||||
|
// #then it should be 1.1.37 (PR #10678)
|
||||||
|
expect(OPENCODE_NATIVE_AGENTS_INJECTION_VERSION).toBe("1.1.37")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("version detection works correctly with native agents version", () => {
|
||||||
|
// #given OpenCode version at or above native agents injection version
|
||||||
|
setVersionCache("1.1.37")
|
||||||
|
|
||||||
|
// #when checking against native agents version
|
||||||
|
const result = isOpenCodeVersionAtLeast(OPENCODE_NATIVE_AGENTS_INJECTION_VERSION)
|
||||||
|
|
||||||
|
// #then returns true (native support available)
|
||||||
|
expect(result).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("version detection returns false for older versions", () => {
|
||||||
|
// #given OpenCode version below native agents injection version
|
||||||
|
setVersionCache("1.1.36")
|
||||||
|
|
||||||
|
// #when checking against native agents version
|
||||||
|
const result = isOpenCodeVersionAtLeast(OPENCODE_NATIVE_AGENTS_INJECTION_VERSION)
|
||||||
|
|
||||||
|
// #then returns false (no native support)
|
||||||
|
expect(result).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("returns true when version detection fails (fail-safe)", () => {
|
||||||
|
// #given version cannot be detected
|
||||||
|
setVersionCache(null)
|
||||||
|
|
||||||
|
// #when checking against native agents version
|
||||||
|
const result = isOpenCodeVersionAtLeast(OPENCODE_NATIVE_AGENTS_INJECTION_VERSION)
|
||||||
|
|
||||||
|
// #then returns true (assume latest, enable native support)
|
||||||
|
expect(result).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -6,6 +6,15 @@ import { execSync } from "child_process"
|
|||||||
*/
|
*/
|
||||||
export const MINIMUM_OPENCODE_VERSION = "1.1.1"
|
export const MINIMUM_OPENCODE_VERSION = "1.1.1"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenCode version that introduced native AGENTS.md injection.
|
||||||
|
* PR #10678 merged on Jan 26, 2026 - OpenCode now dynamically resolves
|
||||||
|
* AGENTS.md files from subdirectories as the agent explores them.
|
||||||
|
* When this version is detected, the directory-agents-injector hook
|
||||||
|
* is auto-disabled to prevent duplicate AGENTS.md loading.
|
||||||
|
*/
|
||||||
|
export const OPENCODE_NATIVE_AGENTS_INJECTION_VERSION = "1.1.37"
|
||||||
|
|
||||||
const NOT_CACHED = Symbol("NOT_CACHED")
|
const NOT_CACHED = Symbol("NOT_CACHED")
|
||||||
let cachedVersion: string | null | typeof NOT_CACHED = NOT_CACHED
|
let cachedVersion: string | null | typeof NOT_CACHED = NOT_CACHED
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user