evil-omo 3.14.1 → 3.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/bin/platform.test.ts +15 -0
  2. package/dist/agents/atlas/agent.d.ts +1 -1
  3. package/dist/agents/atlas/default-prompt-sections.d.ts +6 -0
  4. package/dist/agents/atlas/default.d.ts +0 -9
  5. package/dist/agents/atlas/gemini-prompt-sections.d.ts +6 -0
  6. package/dist/agents/atlas/gemini.d.ts +0 -9
  7. package/dist/agents/atlas/gpt-prompt-sections.d.ts +6 -0
  8. package/dist/agents/atlas/gpt.d.ts +0 -9
  9. package/dist/agents/atlas/shared-prompt.d.ts +9 -0
  10. package/dist/agents/dynamic-agent-category-skills-guide.d.ts +2 -0
  11. package/dist/agents/dynamic-agent-core-sections.d.ts +10 -0
  12. package/dist/agents/dynamic-agent-policy-sections.d.ts +6 -0
  13. package/dist/agents/dynamic-agent-prompt-builder.d.ts +5 -35
  14. package/dist/agents/dynamic-agent-prompt-types.d.ts +20 -0
  15. package/dist/agents/dynamic-agent-tool-categorization.d.ts +3 -0
  16. package/dist/agents/hephaestus/agent.d.ts +1 -1
  17. package/dist/agents/hephaestus/gpt-5-3-codex.d.ts +1 -1
  18. package/dist/agents/hephaestus/gpt.d.ts +1 -1
  19. package/dist/agents/momus.d.ts +2 -2
  20. package/dist/agents/prometheus/behavioral-summary.d.ts +1 -1
  21. package/dist/agents/prometheus/identity-constraints.d.ts +1 -1
  22. package/dist/agents/prometheus/plan-generation.d.ts +1 -1
  23. package/dist/agents/prometheus/plan-template.d.ts +1 -1
  24. package/dist/agents/sisyphus/gpt-5-4.d.ts +14 -14
  25. package/dist/agents/sisyphus/index.d.ts +1 -1
  26. package/dist/agents/sisyphus.d.ts +1 -1
  27. package/dist/agents/types.d.ts +1 -0
  28. package/dist/cli/index.js +711 -475
  29. package/dist/cli/mcp-oauth/login.d.ts +6 -1
  30. package/dist/cli/run/event-state.d.ts +0 -2
  31. package/dist/cli/run/types.d.ts +0 -1
  32. package/dist/config/schema/agent-names.d.ts +2 -0
  33. package/dist/config/schema/agent-overrides.d.ts +330 -15
  34. package/dist/config/schema/background-task.d.ts +2 -0
  35. package/dist/config/schema/categories.d.ts +44 -2
  36. package/dist/config/schema/commands.d.ts +1 -0
  37. package/dist/config/schema/evil-omo-config.d.ts +341 -15
  38. package/dist/config/schema/experimental.d.ts +1 -0
  39. package/dist/config/schema/fallback-models.d.ts +67 -1
  40. package/dist/config/schema/hooks.d.ts +3 -0
  41. package/dist/config/schema/sisyphus-agent.d.ts +1 -0
  42. package/dist/config/schema/tmux.d.ts +11 -0
  43. package/dist/create-hooks.d.ts +6 -0
  44. package/dist/create-runtime-tmux-config.d.ts +9 -0
  45. package/dist/evil-omo.schema.json +1042 -3
  46. package/dist/features/background-agent/abort-with-timeout.d.ts +2 -0
  47. package/dist/features/background-agent/background-task-notification-template.d.ts +10 -4
  48. package/dist/features/background-agent/constants.d.ts +1 -0
  49. package/dist/features/background-agent/fallback-retry-handler.d.ts +1 -1
  50. package/dist/features/background-agent/manager.d.ts +10 -0
  51. package/dist/features/background-agent/process-cleanup.d.ts +1 -1
  52. package/dist/features/background-agent/session-existence.d.ts +3 -0
  53. package/dist/features/background-agent/task-poller.d.ts +1 -0
  54. package/dist/features/background-agent/types.d.ts +2 -0
  55. package/dist/features/builtin-commands/commands.d.ts +4 -1
  56. package/dist/features/builtin-commands/templates/handoff.d.ts +1 -1
  57. package/dist/features/builtin-commands/templates/init-deep.d.ts +1 -1
  58. package/dist/features/builtin-commands/templates/remove-ai-slops.d.ts +1 -0
  59. package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
  60. package/dist/features/builtin-commands/types.d.ts +1 -1
  61. package/dist/features/builtin-skills/skills/ai-slop-remover.d.ts +2 -0
  62. package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +1 -0
  63. package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +1 -0
  64. package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +1 -0
  65. package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +1 -0
  66. package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +1 -0
  67. package/dist/features/builtin-skills/skills/index.d.ts +2 -0
  68. package/dist/features/builtin-skills/skills/playwright-cli.d.ts +1 -1
  69. package/dist/features/builtin-skills/skills/review-work.d.ts +2 -0
  70. package/dist/features/claude-code-mcp-loader/configure-allowed-env-vars.d.ts +5 -0
  71. package/dist/features/claude-code-mcp-loader/index.d.ts +1 -0
  72. package/dist/features/claude-code-mcp-loader/scope-filter.d.ts +2 -0
  73. package/dist/features/claude-code-mcp-loader/types.d.ts +8 -4
  74. package/dist/features/claude-code-session-state/state.d.ts +2 -0
  75. package/dist/features/context-injector/collector.d.ts +1 -0
  76. package/dist/features/opencode-skill-loader/async-loader.d.ts +2 -2
  77. package/dist/features/skill-mcp-manager/manager.d.ts +4 -1
  78. package/dist/features/skill-mcp-manager/oauth-handler.d.ts +5 -4
  79. package/dist/features/skill-mcp-manager/types.d.ts +7 -0
  80. package/dist/features/tmux-subagent/manager.d.ts +15 -13
  81. package/dist/features/tmux-subagent/polling-manager.d.ts +5 -0
  82. package/dist/features/tmux-subagent/types.d.ts +2 -0
  83. package/dist/hooks/agent-usage-reminder/constants.d.ts +1 -1
  84. package/dist/hooks/anthropic-context-window-limit-recovery/message-builder.d.ts +4 -1
  85. package/dist/hooks/anthropic-context-window-limit-recovery/recovery-hook.d.ts +10 -0
  86. package/dist/hooks/anthropic-context-window-limit-recovery/recovery-hook.test-support.d.ts +29 -0
  87. package/dist/hooks/anthropic-context-window-limit-recovery/session-timeout-map.d.ts +2 -0
  88. package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +2 -0
  89. package/dist/hooks/anthropic-context-window-limit-recovery/types.d.ts +1 -0
  90. package/dist/hooks/atlas/subagent-session-id.d.ts +1 -0
  91. package/dist/hooks/atlas/system-reminder-templates.d.ts +2 -2
  92. package/dist/hooks/auto-slash-command/executor.d.ts +1 -0
  93. package/dist/hooks/auto-slash-command/hook.d.ts +1 -0
  94. package/dist/hooks/auto-update-checker/checker/sync-package-json.d.ts +1 -1
  95. package/dist/hooks/auto-update-checker/constants.d.ts +1 -0
  96. package/dist/hooks/auto-update-checker/hook/background-update-check.d.ts +29 -1
  97. package/dist/hooks/bash-file-read-guard.d.ts +2 -0
  98. package/dist/hooks/claude-code-hooks/claude-code-hooks-hook.d.ts +1 -0
  99. package/dist/hooks/claude-code-hooks/config-loader.d.ts +1 -0
  100. package/dist/hooks/claude-code-hooks/config.d.ts +1 -0
  101. package/dist/hooks/claude-code-hooks/handlers/session-event-handler.d.ts +3 -1
  102. package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
  103. package/dist/hooks/claude-code-hooks/tool-input-cache.d.ts +2 -0
  104. package/dist/hooks/claude-code-hooks/transcript.d.ts +1 -3
  105. package/dist/hooks/comment-checker/hook.d.ts +1 -0
  106. package/dist/hooks/comment-checker/pending-calls.d.ts +1 -0
  107. package/dist/hooks/index.d.ts +3 -0
  108. package/dist/hooks/legacy-plugin-toast/auto-migrate-runner.d.ts +2 -0
  109. package/dist/hooks/legacy-plugin-toast/auto-migrate.d.ts +7 -0
  110. package/dist/hooks/legacy-plugin-toast/hook.d.ts +18 -0
  111. package/dist/hooks/legacy-plugin-toast/index.d.ts +1 -0
  112. package/dist/hooks/legacy-plugin-toast/plugin-entry-migrator.d.ts +1 -0
  113. package/dist/hooks/model-fallback/chat-message-fallback-handler.d.ts +23 -0
  114. package/dist/hooks/model-fallback/next-fallback.d.ts +6 -0
  115. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +11 -0
  116. package/dist/hooks/rules-injector/constants.d.ts +1 -0
  117. package/dist/hooks/rules-injector/finder.d.ts +1 -1
  118. package/dist/hooks/rules-injector/hook.d.ts +2 -0
  119. package/dist/hooks/rules-injector/injector.d.ts +2 -0
  120. package/dist/hooks/rules-injector/rule-file-finder.d.ts +9 -1
  121. package/dist/hooks/runtime-fallback/fallback-models.d.ts +1 -1
  122. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +5 -1
  123. package/dist/hooks/start-work/context-info-builder.d.ts +12 -0
  124. package/dist/hooks/start-work/start-work-hook.d.ts +6 -0
  125. package/dist/hooks/start-work/worktree-block.d.ts +1 -0
  126. package/dist/hooks/todo-continuation-enforcer/resolve-message-info.d.ts +2 -2
  127. package/dist/hooks/todo-continuation-enforcer/session-state.d.ts +4 -3
  128. package/dist/hooks/todo-continuation-enforcer/types.d.ts +7 -0
  129. package/dist/hooks/todo-description-override/description.d.ts +1 -1
  130. package/dist/hooks/tool-pair-validator/hook.d.ts +28 -0
  131. package/dist/hooks/tool-pair-validator/index.d.ts +1 -0
  132. package/dist/hooks/write-existing-file-guard/hook.d.ts +12 -0
  133. package/dist/hooks/write-existing-file-guard/session-read-permissions.d.ts +3 -0
  134. package/dist/hooks/write-existing-file-guard/tool-execute-before-handler.d.ts +15 -0
  135. package/dist/index.js +9391 -4974
  136. package/dist/mcp/websearch.d.ts +2 -2
  137. package/dist/openclaw/dispatcher.d.ts +6 -0
  138. package/dist/plugin/command-execute-before.d.ts +17 -0
  139. package/dist/plugin/hooks/create-core-hooks.d.ts +3 -0
  140. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -1
  141. package/dist/plugin/hooks/create-tool-guard-hooks.d.ts +2 -1
  142. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -1
  143. package/dist/plugin/tool-registry.d.ts +1 -0
  144. package/dist/plugin/types.d.ts +1 -0
  145. package/dist/plugin-dispose.d.ts +3 -0
  146. package/dist/shared/agent-display-names.d.ts +8 -0
  147. package/dist/shared/archive-entry-validator.d.ts +6 -0
  148. package/dist/shared/background-output-consumption.d.ts +5 -0
  149. package/dist/shared/connected-providers-cache.d.ts +2 -1
  150. package/dist/shared/contains-path.d.ts +2 -0
  151. package/dist/shared/external-plugin-detector.d.ts +14 -0
  152. package/dist/shared/index.d.ts +3 -0
  153. package/dist/shared/is-abort-error.d.ts +1 -0
  154. package/dist/shared/json-file-cache-store.d.ts +16 -0
  155. package/dist/shared/jsonc-parser.d.ts +1 -0
  156. package/dist/shared/legacy-plugin-warning.d.ts +1 -0
  157. package/dist/shared/load-opencode-plugins.d.ts +1 -0
  158. package/dist/shared/log-legacy-plugin-startup-warning.d.ts +10 -1
  159. package/dist/shared/migrate-legacy-config-file.d.ts +1 -0
  160. package/dist/shared/migrate-legacy-plugin-entry.d.ts +1 -0
  161. package/dist/shared/model-capabilities/bundled-snapshot.d.ts +2 -0
  162. package/dist/shared/model-capabilities/get-model-capabilities.d.ts +2 -0
  163. package/dist/shared/model-capabilities/index.d.ts +3 -0
  164. package/dist/shared/model-capabilities/runtime-model-readers.d.ts +11 -0
  165. package/dist/shared/{model-capabilities.d.ts → model-capabilities/types.d.ts} +35 -32
  166. package/dist/shared/model-suggestion-retry.d.ts +0 -9
  167. package/dist/shared/plugin-entry-migrator.d.ts +3 -0
  168. package/dist/shared/plugin-identity.d.ts +2 -1
  169. package/dist/shared/session-category-registry.d.ts +0 -24
  170. package/dist/shared/session-cursor.d.ts +6 -0
  171. package/dist/shared/skill-path-resolver.d.ts +0 -8
  172. package/dist/shared/task-system-enabled.d.ts +6 -0
  173. package/dist/shared/tmux/tmux-utils/server-health.d.ts +1 -0
  174. package/dist/shared/tmux/tmux-utils/session-spawn.d.ts +3 -0
  175. package/dist/shared/tmux/tmux-utils/window-spawn.d.ts +3 -0
  176. package/dist/shared/tmux/tmux-utils.d.ts +3 -1
  177. package/dist/shared/write-file-atomically.d.ts +1 -0
  178. package/dist/shared/zip-entry-listing/powershell-zip-entry-listing.d.ts +4 -0
  179. package/dist/shared/zip-entry-listing/python-zip-entry-listing.d.ts +3 -0
  180. package/dist/shared/zip-entry-listing/read-zip-symlink-target.d.ts +1 -0
  181. package/dist/shared/zip-entry-listing/tar-zip-entry-listing.d.ts +3 -0
  182. package/dist/shared/zip-entry-listing/zipinfo-zip-entry-listing.d.ts +4 -0
  183. package/dist/shared/zip-entry-listing.d.ts +4 -0
  184. package/dist/tools/call-omo-agent/background-executor.d.ts +2 -1
  185. package/dist/tools/call-omo-agent/sync-executor.d.ts +2 -1
  186. package/dist/tools/delegate-task/anthropic-categories.d.ts +2 -0
  187. package/dist/tools/delegate-task/builtin-categories.d.ts +4 -0
  188. package/dist/tools/delegate-task/builtin-category-definition.d.ts +7 -0
  189. package/dist/tools/delegate-task/constants.d.ts +1 -12
  190. package/dist/tools/delegate-task/executor-types.d.ts +2 -1
  191. package/dist/tools/delegate-task/google-categories.d.ts +2 -0
  192. package/dist/tools/delegate-task/kimi-categories.d.ts +2 -0
  193. package/dist/tools/delegate-task/openai-categories.d.ts +2 -0
  194. package/dist/tools/delegate-task/prompt-builder.d.ts +1 -1
  195. package/dist/tools/delegate-task/sync-prompt-sender.d.ts +2 -0
  196. package/dist/tools/delegate-task/types.d.ts +2 -1
  197. package/dist/tools/grep/cli.d.ts +3 -2
  198. package/dist/tools/grep/constants.d.ts +1 -2
  199. package/dist/tools/hashline-edit/tool-description.d.ts +1 -1
  200. package/dist/tools/look-at/constants.d.ts +1 -1
  201. package/dist/tools/lsp/infer-extension.d.ts +1 -0
  202. package/dist/tools/session-manager/file-storage.d.ts +8 -0
  203. package/dist/tools/session-manager/sdk-storage.d.ts +8 -0
  204. package/dist/tools/session-manager/sdk-unavailable.d.ts +1 -0
  205. package/dist/tools/session-manager/storage.d.ts +1 -1
  206. package/dist/tools/skill/description-formatter.d.ts +3 -0
  207. package/dist/tools/skill/mcp-capability-formatter.d.ts +3 -0
  208. package/dist/tools/skill/native-skills.d.ts +12 -0
  209. package/dist/tools/skill/scope-priority.d.ts +4 -0
  210. package/dist/tools/skill/skill-body.d.ts +2 -0
  211. package/dist/tools/skill/skill-matcher.d.ts +5 -0
  212. package/dist/tools/skill/types.d.ts +30 -2
  213. package/dist/tools/skill-mcp/tools.d.ts +1 -1
  214. package/package.json +14 -14
  215. package/dist/hooks/openclaw.d.ts +0 -11
@@ -1,8 +1,17 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
2
  import type { ExperimentalConfig, OhMyOpenCodeConfig } from "../../config";
3
+ import { parseAnthropicTokenLimitError } from "./parser";
4
+ import { executeCompact, getLastAssistant } from "./executor";
5
+ import { log } from "../../shared/logger";
3
6
  export interface AnthropicContextWindowLimitRecoveryOptions {
4
7
  experimental?: ExperimentalConfig;
5
8
  pluginConfig: OhMyOpenCodeConfig;
9
+ dependencies?: {
10
+ executeCompact?: typeof executeCompact;
11
+ getLastAssistant?: typeof getLastAssistant;
12
+ log?: typeof log;
13
+ parseAnthropicTokenLimitError?: typeof parseAnthropicTokenLimitError;
14
+ };
6
15
  }
7
16
  export declare function createAnthropicContextWindowLimitRecoveryHook(ctx: PluginInput, options?: AnthropicContextWindowLimitRecoveryOptions): {
8
17
  event: ({ event }: {
@@ -11,4 +20,5 @@ export declare function createAnthropicContextWindowLimitRecoveryHook(ctx: Plugi
11
20
  properties?: unknown;
12
21
  };
13
22
  }) => Promise<void>;
23
+ dispose: () => void;
14
24
  };
@@ -0,0 +1,29 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ export type MockLastAssistant = {
3
+ info: {
4
+ summary?: boolean;
5
+ providerID: string;
6
+ modelID: string;
7
+ };
8
+ hasContent: boolean;
9
+ };
10
+ export declare const executeCompactMock: import("bun:test").Mock<typeof import("./executor").executeCompact>;
11
+ export declare const getLastAssistantMock: import("bun:test").Mock<typeof import("./message-builder").getLastAssistant>;
12
+ export declare const parseAnthropicTokenLimitErrorMock: import("bun:test").Mock<typeof import("./parser").parseAnthropicTokenLimitError>;
13
+ export declare function createRecoveryHook(): {
14
+ event: ({ event }: {
15
+ event: {
16
+ type: string;
17
+ properties?: unknown;
18
+ };
19
+ }) => Promise<void>;
20
+ dispose: () => void;
21
+ };
22
+ export declare function createMockContext(): PluginInput;
23
+ export declare function setupDelayedTimeoutMocks(): {
24
+ createUntrackedTimeout: () => ReturnType<typeof setTimeout>;
25
+ runScheduledTimeout: (index: number) => void;
26
+ restore: () => void;
27
+ getClearTimeoutCalls: () => Array<ReturnType<typeof setTimeout>>;
28
+ getScheduledTimeouts: () => Array<ReturnType<typeof setTimeout>>;
29
+ };
@@ -0,0 +1,2 @@
1
+ export declare function clearSessionTimeout(timeoutBySession: Map<string, ReturnType<typeof setTimeout>>, sessionID: string): void;
2
+ export declare function clearAllSessionTimeouts(timeoutBySession: Map<string, ReturnType<typeof setTimeout>>): void;
@@ -2,5 +2,7 @@ import type { AutoCompactState, RetryState, TruncateState } from "./types";
2
2
  export declare function getOrCreateRetryState(autoCompactState: AutoCompactState, sessionID: string): RetryState;
3
3
  export declare function getOrCreateTruncateState(autoCompactState: AutoCompactState, sessionID: string): TruncateState;
4
4
  export declare function clearSessionState(autoCompactState: AutoCompactState, sessionID: string): void;
5
+ export declare function setRetryTimer(autoCompactState: AutoCompactState, sessionID: string, timeout: ReturnType<typeof setTimeout>): void;
6
+ export declare function clearRetryTimer(autoCompactState: AutoCompactState, sessionID: string): void;
5
7
  export declare function getEmptyContentAttempt(autoCompactState: AutoCompactState, sessionID: string): number;
6
8
  export declare function incrementEmptyContentAttempt(autoCompactState: AutoCompactState, sessionID: string): number;
@@ -20,6 +20,7 @@ export interface AutoCompactState {
20
20
  pendingCompact: Set<string>;
21
21
  errorDataBySession: Map<string, ParsedTokenLimitError>;
22
22
  retryStateBySession: Map<string, RetryState>;
23
+ retryTimerBySession: Map<string, ReturnType<typeof setTimeout>>;
23
24
  truncateStateBySession: Map<string, TruncateState>;
24
25
  emptyContentAttemptBySession: Map<string, number>;
25
26
  compactionInProgress: Set<string>;
@@ -1,4 +1,5 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
+ export declare function extractSessionIdFromMetadata(metadata: unknown): string | undefined;
2
3
  export declare function extractSessionIdFromOutput(output: string): string | undefined;
3
4
  export declare function validateSubagentSessionId(input: {
4
5
  client: PluginInput["client"];
@@ -1,6 +1,6 @@
1
1
  export declare const DIRECT_WORK_REMINDER: string;
2
2
  export declare const BOULDER_CONTINUATION_PROMPT: string;
3
- export declare const VERIFICATION_REMINDER = "**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE. THEY ARE PROBABLY LYING.**\n\nSubagents say \"done\" when code has errors, tests pass trivially, logic is wrong,\nor they quietly added features nobody asked for. This happens EVERY TIME.\nAssume the work is broken until YOU prove otherwise.\n\n---\n\n**PHASE 1: READ THE CODE FIRST (before running anything)**\n\nDo NOT run tests yet. Read the code FIRST so you know what you're testing.\n\n1. `Bash(\"git diff --stat\")` \u2014 see exactly which files changed. Any file outside expected scope = scope creep.\n2. `Read` EVERY changed file \u2014 no exceptions, no skimming.\n3. For EACH file, critically ask:\n - Does this code ACTUALLY do what the task required? (Re-read the task, compare line by line)\n - Any stubs, TODOs, placeholders, hardcoded values? (`Grep` for TODO, FIXME, HACK, xxx)\n - Logic errors? Trace the happy path AND the error path in your head.\n - Anti-patterns? (`Grep` for `as any`, `@ts-ignore`, empty catch, console.log in changed files)\n - Scope creep? Did the subagent touch things or add features NOT in the task spec?\n4. Cross-check every claim:\n - Said \"Updated X\" \u2014 READ X. Actually updated, or just superficially touched?\n - Said \"Added tests\" \u2014 READ the tests. Do they test REAL behavior or just `expect(true).toBe(true)`?\n - Said \"Follows patterns\" \u2014 OPEN a reference file. Does it ACTUALLY match?\n\n**If you cannot explain what every changed line does, you have NOT reviewed it.**\n\n**PHASE 2: RUN AUTOMATED CHECKS (targeted, then broad)**\n\nNow that you understand the code, verify mechanically:\n1. `lsp_diagnostics` on EACH changed file \u2014 ZERO new errors\n2. Run tests for changed modules FIRST, then full suite\n3. Build/typecheck \u2014 exit 0\n\nIf Phase 1 found issues but Phase 2 passes: Phase 2 is WRONG. The code has bugs that tests don't cover. Fix the code.\n\n**PHASE 3: HANDS-ON QA \u2014 ACTUALLY RUN IT (MANDATORY for user-facing changes)**\n\nTests and linters CANNOT catch: visual bugs, wrong CLI output, broken user flows, API response shape issues.\n\n**If this task produced anything a user would SEE or INTERACT with, you MUST launch it and verify yourself.**\n\n- **Frontend/UI**: `/playwright` skill \u2014 load the page, click through the flow, check console. Verify: page loads, interactions work, console clean, responsive.\n- **TUI/CLI**: `interactive_bash` \u2014 run the command, try good input, try bad input, try --help. Verify: command runs, output correct, error messages helpful, edge inputs handled.\n- **API/Backend**: `Bash` with curl \u2014 hit the endpoint, check response body, send malformed input. Verify: returns 200, body correct, error cases return proper errors.\n- **Config/Build**: Actually start the service or import the config. Verify: loads without error, backward compatible.\n\nThis is NOT optional \"if applicable\". If the deliverable is user-facing and you did not run it, you are shipping untested work.\n\n**PHASE 4: GATE DECISION \u2014 Should you proceed to the next task?**\n\nAnswer honestly:\n1. Can I explain what EVERY changed line does? (If no \u2014 back to Phase 1)\n2. Did I SEE it work with my own eyes? (If user-facing and no \u2014 back to Phase 3)\n3. Am I confident nothing existing is broken? (If no \u2014 run broader tests)\n\nALL three must be YES. \"Probably\" = NO. \"I think so\" = NO. Investigate until CERTAIN.\n\n- **All 3 YES** \u2014 Proceed: mark task complete, move to next.\n- **Any NO** \u2014 Reject: resume session with `session_id`, fix the specific issue.\n- **Unsure** \u2014 Reject: \"unsure\" = \"no\". Investigate until you have a definitive answer.\n\n**DO NOT proceed to the next task until all 4 phases are complete and the gate passes.**";
4
- export declare const VERIFICATION_REMINDER_GEMINI = "**THE SUBAGENT HAS FINISHED. THEIR WORK IS EXTREMELY SUSPICIOUS.**\n\nThe subagent CLAIMS this task is done. Based on thousands of executions, subagent claims are FALSE more often than true.\nThey ROUTINELY:\n- Ship code with syntax errors they didn't bother to check\n- Create stub implementations with TODOs and call it \"done\"\n- Write tests that pass trivially (testing nothing meaningful)\n- Implement logic that does NOT match what was requested\n- Add features nobody asked for and call it \"improvement\"\n- Report \"all tests pass\" when they didn't run any tests\n\n**This is NOT a theoretical warning. This WILL happen on this task. Assume the work is BROKEN.**\n\n**YOU MUST VERIFY WITH ACTUAL TOOL CALLS. NOT REASONING. TOOL CALLS.**\nThinking \"it looks correct\" is NOT verification. Running `lsp_diagnostics` IS.\n\n---\n\n**PHASE 1: READ THE CODE FIRST (DO NOT SKIP \u2014 DO NOT RUN TESTS YET)**\n\nRead the code FIRST so you know what you're testing.\n\n1. `Bash(\"git diff --stat\")` \u2014 see exactly which files changed.\n2. `Read` EVERY changed file \u2014 no exceptions, no skimming.\n3. For EACH file:\n - Does this code ACTUALLY do what the task required? RE-READ the task spec.\n - Any stubs, TODOs, placeholders? `Grep` for TODO, FIXME, HACK, xxx\n - Anti-patterns? `Grep` for `as any`, `@ts-ignore`, empty catch\n - Scope creep? Did the subagent add things NOT in the task spec?\n4. Cross-check EVERY claim against actual code.\n\n**If you cannot explain what every changed line does, GO BACK AND READ AGAIN.**\n\n**PHASE 2: RUN AUTOMATED CHECKS**\n\n1. `lsp_diagnostics` on EACH changed file \u2014 ZERO new errors. ACTUALLY RUN THIS.\n2. Run tests for changed modules, then full suite. ACTUALLY RUN THESE.\n3. Build/typecheck \u2014 exit 0.\n\nIf Phase 1 found issues but Phase 2 passes: Phase 2 is WRONG. Fix the code.\n\n**PHASE 3: HANDS-ON QA (MANDATORY for user-facing changes)**\n\n- **Frontend/UI**: `/playwright`\n- **TUI/CLI**: `interactive_bash`\n- **API/Backend**: `Bash` with curl\n\n**If user-facing and you did not run it, you are shipping UNTESTED BROKEN work.**\n\n**PHASE 4: GATE DECISION**\n\n1. Can I explain what EVERY changed line does? (If no \u2192 Phase 1)\n2. Did I SEE it work via tool calls? (If user-facing and no \u2192 Phase 3)\n3. Am I confident nothing is broken? (If no \u2192 broader tests)\n\nALL three must be YES. \"Probably\" = NO. \"I think so\" = NO.\n\n**DO NOT proceed to the next task until all 4 phases are complete.**";
3
+ export declare const VERIFICATION_REMINDER = "**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE. THEY ARE PROBABLY LYING.**\n\nSubagents say \"done\" when code has errors, tests pass trivially, logic is wrong,\nor they quietly added features nobody asked for. This happens EVERY TIME.\nAssume the work is broken until YOU prove otherwise.\n\n---\n\n**PHASE 1: READ THE CODE FIRST (before running anything)**\n\nDo NOT run tests yet. Read the code FIRST so you know what you're testing.\n\n1. `Bash(\"git diff --stat\")` - see exactly which files changed. Any file outside expected scope = scope creep.\n2. `Read` EVERY changed file - no exceptions, no skimming.\n3. For EACH file, critically ask:\n - Does this code ACTUALLY do what the task required? (Re-read the task, compare line by line)\n - Any stubs, TODOs, placeholders, hardcoded values? (`Grep` for TODO, FIXME, HACK, xxx)\n - Logic errors? Trace the happy path AND the error path in your head.\n - Anti-patterns? (`Grep` for `as any`, `@ts-ignore`, empty catch, console.log in changed files)\n - Scope creep? Did the subagent touch things or add features NOT in the task spec?\n4. Cross-check every claim:\n - Said \"Updated X\" - READ X. Actually updated, or just superficially touched?\n - Said \"Added tests\" - READ the tests. Do they test REAL behavior or just `expect(true).toBe(true)`?\n - Said \"Follows patterns\" - OPEN a reference file. Does it ACTUALLY match?\n\n**If you cannot explain what every changed line does, you have NOT reviewed it.**\n\n**PHASE 2: RUN AUTOMATED CHECKS (targeted, then broad)**\n\nNow that you understand the code, verify mechanically:\n1. `lsp_diagnostics` on EACH changed file - ZERO new errors\n2. Run tests for changed modules FIRST, then full suite\n3. Build/typecheck - exit 0\n\nIf Phase 1 found issues but Phase 2 passes: Phase 2 is WRONG. The code has bugs that tests don't cover. Fix the code.\n\n**PHASE 3: HANDS-ON QA - ACTUALLY RUN IT (MANDATORY for user-facing changes)**\n\nTests and linters CANNOT catch: visual bugs, wrong CLI output, broken user flows, API response shape issues.\n\n**If this task produced anything a user would SEE or INTERACT with, you MUST launch it and verify yourself.**\n\n- **Frontend/UI**: `/playwright` skill - load the page, click through the flow, check console. Verify: page loads, interactions work, console clean, responsive.\n- **TUI/CLI**: `interactive_bash` - run the command, try good input, try bad input, try --help. Verify: command runs, output correct, error messages helpful, edge inputs handled.\n- **API/Backend**: `Bash` with curl - hit the endpoint, check response body, send malformed input. Verify: returns 200, body correct, error cases return proper errors.\n- **Config/Build**: Actually start the service or import the config. Verify: loads without error, backward compatible.\n\nThis is NOT optional \"if applicable\". If the deliverable is user-facing and you did not run it, you are shipping untested work.\n\n**PHASE 4: GATE DECISION - Should you proceed to the next task?**\n\nAnswer honestly:\n1. Can I explain what EVERY changed line does? (If no - back to Phase 1)\n2. Did I SEE it work with my own eyes? (If user-facing and no - back to Phase 3)\n3. Am I confident nothing existing is broken? (If no - run broader tests)\n\nALL three must be YES. \"Probably\" = NO. \"I think so\" = NO. Investigate until CERTAIN.\n\n- **All 3 YES** - Proceed: mark task complete, move to next.\n- **Any NO** - Reject: resume session with `session_id`, fix the specific issue.\n- **Unsure** - Reject: \"unsure\" = \"no\". Investigate until you have a definitive answer.\n\n**DO NOT proceed to the next task until all 4 phases are complete and the gate passes.**";
4
+ export declare const VERIFICATION_REMINDER_GEMINI = "**THE SUBAGENT HAS FINISHED. THEIR WORK IS EXTREMELY SUSPICIOUS.**\n\nThe subagent CLAIMS this task is done. Based on thousands of executions, subagent claims are FALSE more often than true.\nThey ROUTINELY:\n- Ship code with syntax errors they didn't bother to check\n- Create stub implementations with TODOs and call it \"done\"\n- Write tests that pass trivially (testing nothing meaningful)\n- Implement logic that does NOT match what was requested\n- Add features nobody asked for and call it \"improvement\"\n- Report \"all tests pass\" when they didn't run any tests\n\n**This is NOT a theoretical warning. This WILL happen on this task. Assume the work is BROKEN.**\n\n**YOU MUST VERIFY WITH ACTUAL TOOL CALLS. NOT REASONING. TOOL CALLS.**\nThinking \"it looks correct\" is NOT verification. Running `lsp_diagnostics` IS.\n\n---\n\n**PHASE 1: READ THE CODE FIRST (DO NOT SKIP - DO NOT RUN TESTS YET)**\n\nRead the code FIRST so you know what you're testing.\n\n1. `Bash(\"git diff --stat\")` - see exactly which files changed.\n2. `Read` EVERY changed file - no exceptions, no skimming.\n3. For EACH file:\n - Does this code ACTUALLY do what the task required? RE-READ the task spec.\n - Any stubs, TODOs, placeholders? `Grep` for TODO, FIXME, HACK, xxx\n - Anti-patterns? `Grep` for `as any`, `@ts-ignore`, empty catch\n - Scope creep? Did the subagent add things NOT in the task spec?\n4. Cross-check EVERY claim against actual code.\n\n**If you cannot explain what every changed line does, GO BACK AND READ AGAIN.**\n\n**PHASE 2: RUN AUTOMATED CHECKS**\n\n1. `lsp_diagnostics` on EACH changed file - ZERO new errors. ACTUALLY RUN THIS.\n2. Run tests for changed modules, then full suite. ACTUALLY RUN THESE.\n3. Build/typecheck - exit 0.\n\nIf Phase 1 found issues but Phase 2 passes: Phase 2 is WRONG. Fix the code.\n\n**PHASE 3: HANDS-ON QA (MANDATORY for user-facing changes)**\n\n- **Frontend/UI**: `/playwright`\n- **TUI/CLI**: `interactive_bash`\n- **API/Backend**: `Bash` with curl\n\n**If user-facing and you did not run it, you are shipping UNTESTED BROKEN work.**\n\n**PHASE 4: GATE DECISION**\n\n1. Can I explain what EVERY changed line does? (If no \u2192 Phase 1)\n2. Did I SEE it work via tool calls? (If user-facing and no \u2192 Phase 3)\n3. Am I confident nothing is broken? (If no \u2192 broader tests)\n\nALL three must be YES. \"Probably\" = NO. \"I think so\" = NO.\n\n**DO NOT proceed to the next task until all 4 phases are complete.**";
5
5
  export declare const ORCHESTRATOR_DELEGATION_REQUIRED: string;
6
6
  export declare const SINGLE_TASK_DIRECTIVE: string;
@@ -5,6 +5,7 @@ export interface ExecutorOptions {
5
5
  pluginsEnabled?: boolean;
6
6
  enabledPluginsOverride?: Record<string, boolean>;
7
7
  agent?: string;
8
+ directory?: string;
8
9
  }
9
10
  export interface ExecuteResult {
10
11
  success: boolean;
@@ -4,6 +4,7 @@ export interface AutoSlashCommandHookOptions {
4
4
  skills?: LoadedSkill[];
5
5
  pluginsEnabled?: boolean;
6
6
  enabledPluginsOverride?: Record<string, boolean>;
7
+ directory?: string;
7
8
  }
8
9
  export declare function createAutoSlashCommandHook(options?: AutoSlashCommandHookOptions): {
9
10
  "chat.message": (input: AutoSlashCommandHookInput, output: AutoSlashCommandHookOutput) => Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import type { PluginEntryInfo } from "./plugin-entry";
2
2
  export interface SyncResult {
3
3
  synced: boolean;
4
- error: "file_not_found" | "plugin_not_in_deps" | "parse_error" | "write_error" | null;
4
+ error: "parse_error" | "write_error" | null;
5
5
  message?: string;
6
6
  }
7
7
  export declare function syncCachePackageJsonToIntent(pluginInfo: PluginEntryInfo): SyncResult;
@@ -1,6 +1,7 @@
1
1
  export declare const PACKAGE_NAME = "evil-omo";
2
2
  export declare const NPM_REGISTRY_URL = "https://registry.npmjs.org/-/package/evil-omo/dist-tags";
3
3
  export declare const NPM_FETCH_TIMEOUT = 5000;
4
+ export declare const CACHE_ROOT_DIR: string;
4
5
  export declare const CACHE_DIR: string;
5
6
  export declare const VERSION_FILE: string;
6
7
  export declare function getWindowsAppdataDir(): string | null;
@@ -1,2 +1,30 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
- export declare function runBackgroundUpdateCheck(ctx: PluginInput, autoUpdate: boolean, getToastMessage: (isUpdate: boolean, latestVersion?: string) => string): Promise<void>;
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { runBunInstallWithDetails } from "../../../cli/config-manager";
5
+ import { log } from "../../../shared/logger";
6
+ import { getOpenCodeCacheDir, getOpenCodeConfigPaths } from "../../../shared";
7
+ import { invalidatePackage } from "../cache";
8
+ import { extractChannel } from "../version-channel";
9
+ import { findPluginEntry, getCachedVersion, getLatestVersion, syncCachePackageJsonToIntent } from "../checker";
10
+ import { showAutoUpdatedToast, showUpdateAvailableToast } from "./update-toasts";
11
+ type BackgroundUpdateCheckDeps = {
12
+ existsSync: typeof existsSync;
13
+ join: typeof join;
14
+ runBunInstallWithDetails: typeof runBunInstallWithDetails;
15
+ log: typeof log;
16
+ getOpenCodeCacheDir: typeof getOpenCodeCacheDir;
17
+ getOpenCodeConfigPaths: typeof getOpenCodeConfigPaths;
18
+ invalidatePackage: typeof invalidatePackage;
19
+ extractChannel: typeof extractChannel;
20
+ findPluginEntry: typeof findPluginEntry;
21
+ getCachedVersion: typeof getCachedVersion;
22
+ getLatestVersion: typeof getLatestVersion;
23
+ syncCachePackageJsonToIntent: typeof syncCachePackageJsonToIntent;
24
+ showUpdateAvailableToast: typeof showUpdateAvailableToast;
25
+ showAutoUpdatedToast: typeof showAutoUpdatedToast;
26
+ };
27
+ type BackgroundUpdateCheckRunner = (ctx: PluginInput, autoUpdate: boolean, getToastMessage: (isUpdate: boolean, latestVersion?: string) => string) => Promise<void>;
28
+ export declare function createBackgroundUpdateCheckRunner(overrides?: Partial<BackgroundUpdateCheckDeps>): BackgroundUpdateCheckRunner;
29
+ export declare const runBackgroundUpdateCheck: BackgroundUpdateCheckRunner;
30
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { Hooks } from "@opencode-ai/plugin";
2
+ export declare function createBashFileReadGuardHook(): Hooks;
@@ -45,4 +45,5 @@ export declare function createClaudeCodeHooksHook(ctx: PluginInput, config?: Plu
45
45
  properties?: unknown;
46
46
  };
47
47
  }) => Promise<void>;
48
+ dispose: () => void;
48
49
  };
@@ -9,5 +9,6 @@ export interface DisabledHooksConfig {
9
9
  export interface PluginExtendedConfig {
10
10
  disabledHooks?: DisabledHooksConfig;
11
11
  }
12
+ export declare function clearPluginExtendedConfigCache(): void;
12
13
  export declare function loadPluginExtendedConfig(): Promise<PluginExtendedConfig>;
13
14
  export declare function isHookCommandDisabled(eventType: ClaudeHookEvent, command: string, config: PluginExtendedConfig | null): boolean;
@@ -1,3 +1,4 @@
1
1
  import type { ClaudeHooksConfig } from "./types";
2
2
  export declare function getClaudeSettingsPaths(customPath?: string): string[];
3
+ export declare function clearClaudeHooksConfigCache(): void;
3
4
  export declare function loadClaudeHooksConfig(customSettingsPath?: string): Promise<ClaudeHooksConfig | null>;
@@ -1,8 +1,10 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
+ import type { ContextCollector } from "../../../features/context-injector";
2
3
  import type { PluginConfig } from "../types";
3
- export declare function createSessionEventHandler(ctx: PluginInput, config: PluginConfig): (input: {
4
+ export declare function createSessionEventHandler(ctx: PluginInput, config: PluginConfig, contextCollector?: ContextCollector): (input: {
4
5
  event: {
5
6
  type: string;
6
7
  properties?: unknown;
7
8
  };
8
9
  }) => Promise<void>;
10
+ export declare function disposeSessionEventHandler(contextCollector?: ContextCollector): void;
@@ -7,3 +7,4 @@ export declare const sessionInterruptState: Map<string, {
7
7
  interrupted: boolean;
8
8
  }>;
9
9
  export declare function clearSessionHookState(sessionID: string): void;
10
+ export declare function clearAllSessionHookState(): void;
@@ -3,3 +3,5 @@
3
3
  */
4
4
  export declare function cacheToolInput(sessionId: string, toolName: string, invocationId: string, toolInput: Record<string, unknown>): void;
5
5
  export declare function getToolInput(sessionId: string, toolName: string, invocationId: string): Record<string, unknown> | null;
6
+ export declare function clearToolInputCache(sessionId?: string): void;
7
+ export declare function stopToolInputCacheCleanup(): void;
@@ -6,6 +6,7 @@ export declare function appendTranscriptEntry(sessionId: string, entry: Transcri
6
6
  * Call on session.deleted to prevent memory accumulation.
7
7
  */
8
8
  export declare function clearTranscriptCache(sessionId?: string): void;
9
+ export declare function hasTranscriptCacheEntry(sessionId: string): boolean;
9
10
  /**
10
11
  * Build Claude Code compatible transcript from session messages.
11
12
  * Uses per-session cache to avoid redundant session.messages() API calls.
@@ -23,7 +24,4 @@ export declare function buildTranscriptFromSession(client: {
23
24
  }) => Promise<unknown>;
24
25
  };
25
26
  }, sessionId: string, directory: string, currentToolName: string, currentToolInput: Record<string, unknown>): Promise<string | null>;
26
- /**
27
- * Delete temp transcript file (call in finally block)
28
- */
29
27
  export declare function deleteTempTranscript(path: string | null): void;
@@ -16,4 +16,5 @@ export declare function createCommentCheckerHooks(config?: CommentCheckerConfig)
16
16
  output: string;
17
17
  metadata: unknown;
18
18
  }) => Promise<void>;
19
+ dispose: () => void;
19
20
  };
@@ -1,4 +1,5 @@
1
1
  import type { PendingCall } from "./types";
2
2
  export declare function startPendingCallCleanup(): void;
3
+ export declare function stopPendingCallCleanup(): void;
3
4
  export declare function registerPendingCall(callID: string, pendingCall: PendingCall): void;
4
5
  export declare function takePendingCall(callID: string): PendingCall | undefined;
@@ -23,6 +23,7 @@ export { createKeywordDetectorHook } from "./keyword-detector";
23
23
  export { createNonInteractiveEnvHook } from "./non-interactive-env";
24
24
  export { createInteractiveBashSessionHook } from "./interactive-bash-session";
25
25
  export { createThinkingBlockValidatorHook } from "./thinking-block-validator";
26
+ export { createToolPairValidatorHook } from "./tool-pair-validator";
26
27
  export { createCategorySkillReminderHook } from "./category-skill-reminder";
27
28
  export { createRalphLoopHook, type RalphLoopHook } from "./ralph-loop";
28
29
  export { createNoSisyphusGptHook } from "./no-sisyphus-gpt";
@@ -44,8 +45,10 @@ export { createPreemptiveCompactionHook } from "./preemptive-compaction";
44
45
  export { createTasksTodowriteDisablerHook } from "./tasks-todowrite-disabler";
45
46
  export { createRuntimeFallbackHook, type RuntimeFallbackHook, type RuntimeFallbackOptions } from "./runtime-fallback";
46
47
  export { createWriteExistingFileGuardHook } from "./write-existing-file-guard";
48
+ export { createBashFileReadGuardHook } from "./bash-file-read-guard";
47
49
  export { createHashlineReadEnhancerHook } from "./hashline-read-enhancer";
48
50
  export { createJsonErrorRecoveryHook, JSON_ERROR_TOOL_EXCLUDE_LIST, JSON_ERROR_PATTERNS, JSON_ERROR_REMINDER } from "./json-error-recovery";
49
51
  export { createReadImageResizerHook } from "./read-image-resizer";
50
52
  export { createTodoDescriptionOverrideHook } from "./todo-description-override";
51
53
  export { createWebFetchRedirectGuardHook } from "./webfetch-redirect-guard";
54
+ export { createLegacyPluginToastHook } from "./legacy-plugin-toast";
@@ -0,0 +1,2 @@
1
+ export { autoMigrateLegacyPluginEntry } from "./auto-migrate";
2
+ export type { MigrationResult } from "./auto-migrate";
@@ -0,0 +1,7 @@
1
+ export interface MigrationResult {
2
+ migrated: boolean;
3
+ from: string | null;
4
+ to: string | null;
5
+ configPath: string | null;
6
+ }
7
+ export declare function autoMigrateLegacyPluginEntry(overrideConfigDir?: string): MigrationResult;
@@ -0,0 +1,18 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ import { checkForLegacyPluginEntry } from "../../shared/legacy-plugin-warning";
3
+ import { log } from "../../shared/logger";
4
+ import { autoMigrateLegacyPluginEntry } from "./auto-migrate-runner";
5
+ type LegacyPluginToastDeps = {
6
+ checkForLegacyPluginEntry?: typeof checkForLegacyPluginEntry;
7
+ log?: typeof log;
8
+ autoMigrateLegacyPluginEntry?: typeof autoMigrateLegacyPluginEntry;
9
+ };
10
+ export declare function createLegacyPluginToastHook(ctx: PluginInput, deps?: LegacyPluginToastDeps): {
11
+ event: ({ event }: {
12
+ event: {
13
+ type: string;
14
+ properties?: unknown;
15
+ };
16
+ }) => Promise<void>;
17
+ };
18
+ export {};
@@ -0,0 +1 @@
1
+ export { createLegacyPluginToastHook } from "./hook";
@@ -0,0 +1 @@
1
+ export { migrateLegacyPluginEntry } from "../../shared/migrate-legacy-plugin-entry";
@@ -0,0 +1,23 @@
1
+ import type { ChatMessageHandlerOutput, ChatMessageInput } from "../../plugin/chat-message";
2
+ export declare function applyFallbackToChatMessage(params: {
3
+ input: ChatMessageInput;
4
+ output: ChatMessageHandlerOutput;
5
+ fallback: {
6
+ providerID: string;
7
+ modelID: string;
8
+ variant?: string;
9
+ };
10
+ toast?: (input: {
11
+ title: string;
12
+ message: string;
13
+ variant?: "info" | "success" | "warning" | "error";
14
+ duration?: number;
15
+ }) => void | Promise<void>;
16
+ onApplied?: (input: {
17
+ sessionID: string;
18
+ providerID: string;
19
+ modelID: string;
20
+ variant?: string;
21
+ }) => void | Promise<void>;
22
+ lastToastKey: Map<string, string>;
23
+ }): Promise<void>;
@@ -0,0 +1,6 @@
1
+ import type { ModelFallbackState } from "./hook";
2
+ export declare function getNextReachableFallback(sessionID: string, state: ModelFallbackState): {
3
+ providerID: string;
4
+ modelID: string;
5
+ variant?: string;
6
+ } | null;
@@ -0,0 +1,11 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ export type SessionMessage = {
3
+ info?: {
4
+ role?: string;
5
+ };
6
+ parts?: Array<{
7
+ type: string;
8
+ text?: string;
9
+ }>;
10
+ };
11
+ export declare function createPluginInput(messages: SessionMessage[]): PluginInput;
@@ -4,4 +4,5 @@ export declare const PROJECT_RULE_SUBDIRS: [string, string][];
4
4
  export declare const PROJECT_RULE_FILES: string[];
5
5
  export declare const GITHUB_INSTRUCTIONS_PATTERN: RegExp;
6
6
  export declare const USER_RULE_DIR = ".claude/rules";
7
+ export declare const OPENCODE_USER_RULE_DIRS: string[];
7
8
  export declare const RULE_EXTENSIONS: string[];
@@ -1,3 +1,3 @@
1
1
  export { findProjectRoot } from "./project-root-finder";
2
2
  export { calculateDistance } from "./rule-distance";
3
- export { findRuleFiles } from "./rule-file-finder";
3
+ export { findRuleFiles, type FindRuleFilesOptions } from "./rule-file-finder";
@@ -20,6 +20,8 @@ interface EventInput {
20
20
  }
21
21
  export declare function createRulesInjectorHook(ctx: PluginInput, modelCacheState?: {
22
22
  anthropicContext1MEnabled: boolean;
23
+ }, options?: {
24
+ skipClaudeUserRules?: boolean;
23
25
  }): {
24
26
  "tool.execute.before": (input: ToolExecuteInput, output: ToolExecuteBeforeOutput) => Promise<void>;
25
27
  "tool.execute.after": (input: ToolExecuteInput, output: ToolExecuteOutput) => Promise<void>;
@@ -1,3 +1,4 @@
1
+ import type { FindRuleFilesOptions } from "./rule-file-finder";
1
2
  import type { SessionInjectedRulesCache } from "./cache";
2
3
  type ToolExecuteOutput = {
3
4
  title: string;
@@ -14,6 +15,7 @@ export declare function createRuleInjectionProcessor(deps: {
14
15
  workspaceDirectory: string;
15
16
  truncator: DynamicTruncator;
16
17
  getSessionCache: (sessionID: string) => SessionInjectedRulesCache;
18
+ ruleFinderOptions?: FindRuleFilesOptions;
17
19
  }): {
18
20
  processFilePathForInjection: (filePath: string, sessionID: string, output: ToolExecuteOutput) => Promise<void>;
19
21
  };
@@ -1,4 +1,12 @@
1
1
  import type { RuleFileCandidate } from "./types";
2
+ export interface FindRuleFilesOptions {
3
+ /**
4
+ * When true, skip loading rules from ~/.claude/rules/.
5
+ * Use when claude_code integration is disabled to prevent
6
+ * Claude Code-specific instructions from leaking into non-Claude agents.
7
+ */
8
+ skipClaudeUserRules?: boolean;
9
+ }
2
10
  /**
3
11
  * Find all rule files for a given context.
4
12
  * Searches from currentFile upward to projectRoot for rule directories,
@@ -12,4 +20,4 @@ import type { RuleFileCandidate } from "./types";
12
20
  * @param currentFile - Current file being edited (for distance calculation)
13
21
  * @returns Array of rule file candidates sorted by distance
14
22
  */
15
- export declare function findRuleFiles(projectRoot: string | null, homeDir: string, currentFile: string): RuleFileCandidate[];
23
+ export declare function findRuleFiles(projectRoot: string | null, homeDir: string, currentFile: string, options?: FindRuleFilesOptions): RuleFileCandidate[];
@@ -9,6 +9,6 @@ export declare function getFallbackModelsForSession(sessionID: string, agent: st
9
9
  /**
10
10
  * Returns the raw fallback model entries (strings and objects) for a session.
11
11
  * Use this when per-model settings (temperature, reasoningEffort, etc.) must be
12
- * preserved e.g. before passing to buildFallbackChainFromModels.
12
+ * preserved - e.g. before passing to buildFallbackChainFromModels.
13
13
  */
14
14
  export declare function getRawFallbackModels(sessionID: string, agent: string | undefined, pluginConfig: OhMyOpenCodeConfig | undefined): (string | FallbackModelObject)[] | undefined;
@@ -1,7 +1,11 @@
1
- export declare function buildRetryModelPayload(model: string): {
1
+ export declare function buildRetryModelPayload(model: string, agentSettings?: {
2
+ variant?: string;
3
+ reasoningEffort?: string;
4
+ }): {
2
5
  model: {
3
6
  providerID: string;
4
7
  modelID: string;
5
8
  };
6
9
  variant?: string;
10
+ reasoningEffort?: string;
7
11
  } | undefined;
@@ -0,0 +1,12 @@
1
+ import { readBoulderState } from "../../features/boulder-state";
2
+ import type { PluginInput } from "@opencode-ai/plugin";
3
+ export declare function buildStartWorkContextInfo(params: {
4
+ ctx: PluginInput;
5
+ explicitPlanName: string | null;
6
+ existingState: ReturnType<typeof readBoulderState>;
7
+ sessionId: string;
8
+ timestamp: string;
9
+ activeAgent: string;
10
+ worktreePath: string | undefined;
11
+ worktreeBlock: string;
12
+ }): string;
@@ -4,6 +4,11 @@ interface StartWorkHookInput {
4
4
  sessionID: string;
5
5
  messageID?: string;
6
6
  }
7
+ interface StartWorkCommandExecuteBeforeInput {
8
+ sessionID: string;
9
+ command: string;
10
+ arguments: string;
11
+ }
7
12
  interface StartWorkHookOutput {
8
13
  message?: Record<string, unknown>;
9
14
  parts: Array<{
@@ -13,5 +18,6 @@ interface StartWorkHookOutput {
13
18
  }
14
19
  export declare function createStartWorkHook(ctx: PluginInput): {
15
20
  "chat.message": (input: StartWorkHookInput, output: StartWorkHookOutput) => Promise<void>;
21
+ "command.execute.before": (input: StartWorkCommandExecuteBeforeInput, output: StartWorkHookOutput) => Promise<void>;
16
22
  };
17
23
  export {};
@@ -0,0 +1 @@
1
+ export declare function createWorktreeActiveBlock(worktreePath: string): string;
@@ -1,3 +1,3 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
- import type { ResolveLatestMessageInfoResult } from "./types";
3
- export declare function resolveLatestMessageInfo(ctx: PluginInput, sessionID: string): Promise<ResolveLatestMessageInfoResult>;
2
+ import type { MessageWithInfo, ResolveLatestMessageInfoResult } from "./types";
3
+ export declare function resolveLatestMessageInfo(ctx: PluginInput, sessionID: string, prefetchedMessages?: MessageWithInfo[]): Promise<ResolveLatestMessageInfoResult>;
@@ -1,15 +1,16 @@
1
- import type { SessionState, Todo } from "./types";
1
+ import type { ContinuationProgressOptions, SessionState, Todo } from "./types";
2
2
  export interface ContinuationProgressUpdate {
3
3
  previousIncompleteCount?: number;
4
4
  previousStagnationCount: number;
5
5
  stagnationCount: number;
6
6
  hasProgressed: boolean;
7
- progressSource: "none" | "todo";
7
+ progressSource: "none" | "todo" | "activity";
8
8
  }
9
9
  export interface SessionStateStore {
10
10
  getState: (sessionID: string) => SessionState;
11
11
  getExistingState: (sessionID: string) => SessionState | undefined;
12
- trackContinuationProgress: (sessionID: string, incompleteCount: number, todos?: Todo[]) => ContinuationProgressUpdate;
12
+ recordActivity: (sessionID: string) => void;
13
+ trackContinuationProgress: (sessionID: string, incompleteCount: number, todos?: Todo[], options?: ContinuationProgressOptions) => ContinuationProgressUpdate;
13
14
  resetContinuationProgress: (sessionID: string) => void;
14
15
  cancelCountdown: (sessionID: string) => void;
15
16
  cleanup: (sessionID: string) => void;
@@ -27,6 +27,7 @@ export interface SessionState {
27
27
  countdownTimer?: ReturnType<typeof setTimeout>;
28
28
  countdownInterval?: ReturnType<typeof setInterval>;
29
29
  isRecovering?: boolean;
30
+ wasCancelled?: boolean;
30
31
  countdownStartedAt?: number;
31
32
  abortDetectedAt?: number;
32
33
  lastIncompleteCount?: number;
@@ -55,6 +56,9 @@ export interface MessageInfo {
55
56
  modelID?: string;
56
57
  tools?: Record<string, ToolPermission>;
57
58
  }
59
+ export interface MessageWithInfo {
60
+ info?: MessageInfo;
61
+ }
58
62
  export interface ResolvedMessageInfo {
59
63
  agent?: string;
60
64
  model?: {
@@ -67,3 +71,6 @@ export interface ResolveLatestMessageInfoResult {
67
71
  resolvedInfo?: ResolvedMessageInfo;
68
72
  encounteredCompaction: boolean;
69
73
  }
74
+ export interface ContinuationProgressOptions {
75
+ allowActivityProgress?: boolean;
76
+ }
@@ -1 +1 @@
1
- export declare const TODOWRITE_DESCRIPTION = "Use this tool to create and manage a structured task list for tracking progress on multi-step work.\n\n## Todo Format (MANDATORY)\n\nEach todo title MUST encode four elements: WHERE, WHY, HOW, and EXPECTED RESULT.\n\nFormat: \"[WHERE] [HOW] to [WHY] \u2014 expect [RESULT]\"\n\nGOOD:\n- \"src/utils/validation.ts: Add validateEmail() for input sanitization \u2014 returns boolean\"\n- \"UserService.create(): Call validateEmail() before DB insert \u2014 rejects invalid emails with 400\"\n- \"validation.test.ts: Add test for missing @ sign \u2014 expect validateEmail('foo') to return false\"\n\nBAD:\n- \"Implement email validation\" (where? how? what result?)\n- \"Add dark mode\" (this is a feature, not a todo)\n- \"Fix auth\" (what file? what changes? what's expected?)\n\n## Granularity Rules\n\nEach todo MUST be a single atomic action completable in 1-3 tool calls. If it needs more, split it.\n\n**Size test**: Can you complete this todo by editing one file or running one command? If not, it's too big.\n\n## Task Management\n- One in_progress at a time. Complete it before starting the next.\n- Mark completed immediately after finishing each item.\n- Skip this tool for single trivial tasks (one-step, obvious action).";
1
+ export declare const TODOWRITE_DESCRIPTION = "Use this tool to create and manage a structured task list for tracking progress on multi-step work.\n\n## Todo Format (MANDATORY)\n\nEach todo title MUST encode four elements: WHERE, WHY, HOW, and EXPECTED RESULT.\n\nFormat: \"[WHERE] [HOW] to [WHY] - expect [RESULT]\"\n\nGOOD:\n- \"src/utils/validation.ts: Add validateEmail() for input sanitization - returns boolean\"\n- \"UserService.create(): Call validateEmail() before DB insert - rejects invalid emails with 400\"\n- \"validation.test.ts: Add test for missing @ sign - expect validateEmail('foo') to return false\"\n\nBAD:\n- \"Implement email validation\" (where? how? what result?)\n- \"Add dark mode\" (feature, not a todo)\n- \"Fix auth\" (what file? what changes? what's expected?)\n\n## Granularity Rules\n\nEach todo MUST be a single atomic action completable in 1-3 tool calls. If it needs more, split it.\n\n**Size test**: Can you complete this todo by editing one file or running one command? If not, it's too big.\n\n## Task Management\n- One in_progress at a time. Complete it before starting the next.\n- Mark completed immediately after finishing each item.\n- Skip this tool for single trivial tasks (one-step, obvious action).";
@@ -0,0 +1,28 @@
1
+ import type { Message, Part } from "@opencode-ai/sdk";
2
+ type ToolUsePart = {
3
+ type: "tool_use";
4
+ id: string;
5
+ [key: string]: unknown;
6
+ };
7
+ type ToolResultPart = {
8
+ type: "tool_result";
9
+ tool_use_id: string;
10
+ content: string;
11
+ [key: string]: unknown;
12
+ };
13
+ type TransformPart = Part | ToolUsePart | ToolResultPart;
14
+ type TransformMessageInfo = Message | {
15
+ role: "user";
16
+ sessionID?: string;
17
+ };
18
+ interface MessageWithParts {
19
+ info: TransformMessageInfo;
20
+ parts: TransformPart[];
21
+ }
22
+ type MessagesTransformHook = {
23
+ "experimental.chat.messages.transform"?: (input: Record<string, never>, output: {
24
+ messages: MessageWithParts[];
25
+ }) => Promise<void>;
26
+ };
27
+ export declare function createToolPairValidatorHook(): MessagesTransformHook;
28
+ export {};
@@ -0,0 +1 @@
1
+ export { createToolPairValidatorHook } from "./hook";
@@ -1,3 +1,15 @@
1
1
  import type { Hooks, PluginInput } from "@opencode-ai/plugin";
2
+ export type GuardArgs = {
3
+ filePath?: string;
4
+ path?: string;
5
+ file_path?: string;
6
+ overwrite?: boolean | string;
7
+ };
2
8
  export declare const MAX_TRACKED_PATHS_PER_SESSION = 1024;
9
+ export declare function asRecord(value: unknown): Record<string, unknown> | undefined;
10
+ export declare function getPathFromArgs(args: GuardArgs | undefined): string | undefined;
11
+ export declare function resolveInputPath(ctx: PluginInput, inputPath: string): string;
12
+ export declare function isPathInsideDirectory(pathToCheck: string, directory: string): boolean;
13
+ export declare function toCanonicalPath(absolutePath: string): string;
14
+ export declare function isOverwriteEnabled(value: boolean | string | undefined): boolean;
3
15
  export declare function createWriteExistingFileGuardHook(ctx: PluginInput): Hooks;
@@ -0,0 +1,3 @@
1
+ export declare function touchSession(sessionLastAccess: Map<string, number>, sessionID: string): void;
2
+ export declare function evictLeastRecentlyUsedSession(readPermissionsBySession: Map<string, Set<string>>, sessionLastAccess: Map<string, number>): void;
3
+ export declare function trimSessionReadSet(readSet: Set<string>, maxTrackedPathsPerSession: number): void;