oh-my-opencode 3.12.3 → 3.13.1

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 (69) hide show
  1. package/README.ja.md +11 -0
  2. package/README.ko.md +11 -0
  3. package/README.md +12 -2
  4. package/README.ru.md +11 -0
  5. package/README.zh-cn.md +11 -0
  6. package/dist/agents/prometheus/system-prompt.d.ts +1 -1
  7. package/dist/cli/index.js +193 -126
  8. package/dist/config/schema/hooks.d.ts +1 -1
  9. package/dist/config/schema/oh-my-opencode-config.d.ts +31 -0
  10. package/dist/config/schema/openclaw.d.ts +64 -0
  11. package/dist/create-hooks.d.ts +1 -1
  12. package/dist/features/background-agent/constants.d.ts +3 -3
  13. package/dist/features/boulder-state/index.d.ts +1 -0
  14. package/dist/features/boulder-state/storage.d.ts +10 -1
  15. package/dist/features/boulder-state/top-level-task.d.ts +2 -0
  16. package/dist/features/boulder-state/types.d.ts +28 -0
  17. package/dist/hooks/atlas/boulder-continuation-injector.d.ts +2 -0
  18. package/dist/hooks/atlas/subagent-session-id.d.ts +7 -1
  19. package/dist/hooks/atlas/tool-execute-after.d.ts +2 -1
  20. package/dist/hooks/atlas/tool-execute-before.d.ts +2 -0
  21. package/dist/hooks/atlas/types.d.ts +13 -1
  22. package/dist/hooks/index.d.ts +1 -1
  23. package/dist/hooks/keyword-detector/constants.d.ts +1 -1
  24. package/dist/hooks/keyword-detector/ultrawork/index.d.ts +1 -1
  25. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +5 -0
  26. package/dist/hooks/openclaw.d.ts +11 -0
  27. package/dist/hooks/preemptive-compaction-degradation-monitor.d.ts +55 -0
  28. package/dist/hooks/preemptive-compaction-no-text-tail.d.ts +18 -0
  29. package/dist/hooks/session-recovery/storage/thinking-prepend.d.ts +27 -2
  30. package/dist/hooks/todo-continuation-enforcer/compaction-guard.d.ts +2 -0
  31. package/dist/hooks/todo-continuation-enforcer/handler.d.ts +0 -1
  32. package/dist/hooks/todo-continuation-enforcer/idle-event.d.ts +0 -1
  33. package/dist/hooks/todo-continuation-enforcer/types.d.ts +2 -1
  34. package/dist/hooks/webfetch-redirect-guard/constants.d.ts +6 -0
  35. package/dist/hooks/webfetch-redirect-guard/hook.d.ts +19 -0
  36. package/dist/hooks/webfetch-redirect-guard/index.d.ts +1 -0
  37. package/dist/hooks/webfetch-redirect-guard/redirect-resolution.d.ts +16 -0
  38. package/dist/index.js +1925 -1134
  39. package/dist/oh-my-opencode.schema.json +141 -0
  40. package/dist/openclaw/config.d.ts +8 -0
  41. package/dist/openclaw/daemon.d.ts +1 -0
  42. package/dist/openclaw/dispatcher.d.ts +16 -0
  43. package/dist/openclaw/index.d.ts +5 -0
  44. package/dist/openclaw/reply-listener.d.ts +31 -0
  45. package/dist/openclaw/session-registry.d.ts +17 -0
  46. package/dist/openclaw/tmux.d.ts +8 -0
  47. package/dist/openclaw/types.d.ts +38 -0
  48. package/dist/plugin/chat-params.d.ts +5 -1
  49. package/dist/plugin/hooks/create-continuation-hooks.d.ts +1 -2
  50. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
  51. package/dist/plugin/hooks/create-tool-guard-hooks.d.ts +2 -1
  52. package/dist/plugin/normalize-tool-arg-schemas.d.ts +1 -0
  53. package/dist/plugin-handlers/prometheus-agent-config-builder.d.ts +1 -0
  54. package/dist/shared/jsonc-parser.d.ts +4 -0
  55. package/dist/shared/shell-env.d.ts +1 -1
  56. package/dist/tools/delegate-task/categories.d.ts +1 -0
  57. package/dist/tools/delegate-task/constants.d.ts +2 -2
  58. package/dist/tools/delegate-task/model-selection.d.ts +1 -0
  59. package/dist/tools/delegate-task/subagent-resolver.d.ts +1 -1
  60. package/dist/tools/hashline-edit/formatter-trigger.d.ts +38 -0
  61. package/dist/tools/hashline-edit/hashline-edit-executor.d.ts +2 -1
  62. package/dist/tools/hashline-edit/tools.d.ts +2 -1
  63. package/package.json +12 -12
  64. package/dist/hooks/gpt-permission-continuation/assistant-message.d.ts +0 -23
  65. package/dist/hooks/gpt-permission-continuation/constants.d.ts +0 -4
  66. package/dist/hooks/gpt-permission-continuation/detector.d.ts +0 -1
  67. package/dist/hooks/gpt-permission-continuation/handler.d.ts +0 -12
  68. package/dist/hooks/gpt-permission-continuation/index.d.ts +0 -13
  69. package/dist/hooks/gpt-permission-continuation/session-state.d.ts +0 -15
@@ -3,7 +3,6 @@ export declare const HookNameSchema: z.ZodEnum<{
3
3
  atlas: "atlas";
4
4
  "ralph-loop": "ralph-loop";
5
5
  "start-work": "start-work";
6
- "gpt-permission-continuation": "gpt-permission-continuation";
7
6
  "todo-continuation-enforcer": "todo-continuation-enforcer";
8
7
  "context-window-monitor": "context-window-monitor";
9
8
  "session-recovery": "session-recovery";
@@ -49,5 +48,6 @@ export declare const HookNameSchema: z.ZodEnum<{
49
48
  "hashline-read-enhancer": "hashline-read-enhancer";
50
49
  "read-image-resizer": "read-image-resizer";
51
50
  "todo-description-override": "todo-description-override";
51
+ "webfetch-redirect-guard": "webfetch-redirect-guard";
52
52
  }>;
53
53
  export type HookName = z.infer<typeof HookNameSchema>;
@@ -1351,6 +1351,37 @@ export declare const OhMyOpenCodeConfigSchema: z.ZodObject<{
1351
1351
  notification: z.ZodOptional<z.ZodObject<{
1352
1352
  force_enable: z.ZodOptional<z.ZodBoolean>;
1353
1353
  }, z.core.$strip>>;
1354
+ openclaw: z.ZodOptional<z.ZodObject<{
1355
+ enabled: z.ZodDefault<z.ZodBoolean>;
1356
+ gateways: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1357
+ type: z.ZodDefault<z.ZodEnum<{
1358
+ command: "command";
1359
+ http: "http";
1360
+ }>>;
1361
+ url: z.ZodOptional<z.ZodString>;
1362
+ method: z.ZodDefault<z.ZodString>;
1363
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1364
+ command: z.ZodOptional<z.ZodString>;
1365
+ timeout: z.ZodOptional<z.ZodNumber>;
1366
+ }, z.core.$strip>>>;
1367
+ hooks: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1368
+ enabled: z.ZodDefault<z.ZodBoolean>;
1369
+ gateway: z.ZodString;
1370
+ instruction: z.ZodString;
1371
+ }, z.core.$strip>>>;
1372
+ replyListener: z.ZodOptional<z.ZodObject<{
1373
+ discordBotToken: z.ZodOptional<z.ZodString>;
1374
+ discordChannelId: z.ZodOptional<z.ZodString>;
1375
+ discordMention: z.ZodOptional<z.ZodString>;
1376
+ authorizedDiscordUserIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
1377
+ telegramBotToken: z.ZodOptional<z.ZodString>;
1378
+ telegramChatId: z.ZodOptional<z.ZodString>;
1379
+ pollIntervalMs: z.ZodDefault<z.ZodNumber>;
1380
+ rateLimitPerMinute: z.ZodDefault<z.ZodNumber>;
1381
+ maxMessageLength: z.ZodDefault<z.ZodNumber>;
1382
+ includePrefix: z.ZodDefault<z.ZodBoolean>;
1383
+ }, z.core.$strip>>;
1384
+ }, z.core.$strip>>;
1354
1385
  babysitting: z.ZodOptional<z.ZodObject<{
1355
1386
  timeout_ms: z.ZodDefault<z.ZodNumber>;
1356
1387
  }, z.core.$strip>>;
@@ -0,0 +1,64 @@
1
+ import { z } from "zod";
2
+ export declare const OpenClawGatewaySchema: z.ZodObject<{
3
+ type: z.ZodDefault<z.ZodEnum<{
4
+ command: "command";
5
+ http: "http";
6
+ }>>;
7
+ url: z.ZodOptional<z.ZodString>;
8
+ method: z.ZodDefault<z.ZodString>;
9
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
10
+ command: z.ZodOptional<z.ZodString>;
11
+ timeout: z.ZodOptional<z.ZodNumber>;
12
+ }, z.core.$strip>;
13
+ export declare const OpenClawHookSchema: z.ZodObject<{
14
+ enabled: z.ZodDefault<z.ZodBoolean>;
15
+ gateway: z.ZodString;
16
+ instruction: z.ZodString;
17
+ }, z.core.$strip>;
18
+ export declare const OpenClawReplyListenerConfigSchema: z.ZodObject<{
19
+ discordBotToken: z.ZodOptional<z.ZodString>;
20
+ discordChannelId: z.ZodOptional<z.ZodString>;
21
+ discordMention: z.ZodOptional<z.ZodString>;
22
+ authorizedDiscordUserIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
23
+ telegramBotToken: z.ZodOptional<z.ZodString>;
24
+ telegramChatId: z.ZodOptional<z.ZodString>;
25
+ pollIntervalMs: z.ZodDefault<z.ZodNumber>;
26
+ rateLimitPerMinute: z.ZodDefault<z.ZodNumber>;
27
+ maxMessageLength: z.ZodDefault<z.ZodNumber>;
28
+ includePrefix: z.ZodDefault<z.ZodBoolean>;
29
+ }, z.core.$strip>;
30
+ export declare const OpenClawConfigSchema: z.ZodObject<{
31
+ enabled: z.ZodDefault<z.ZodBoolean>;
32
+ gateways: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
33
+ type: z.ZodDefault<z.ZodEnum<{
34
+ command: "command";
35
+ http: "http";
36
+ }>>;
37
+ url: z.ZodOptional<z.ZodString>;
38
+ method: z.ZodDefault<z.ZodString>;
39
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
40
+ command: z.ZodOptional<z.ZodString>;
41
+ timeout: z.ZodOptional<z.ZodNumber>;
42
+ }, z.core.$strip>>>;
43
+ hooks: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
44
+ enabled: z.ZodDefault<z.ZodBoolean>;
45
+ gateway: z.ZodString;
46
+ instruction: z.ZodString;
47
+ }, z.core.$strip>>>;
48
+ replyListener: z.ZodOptional<z.ZodObject<{
49
+ discordBotToken: z.ZodOptional<z.ZodString>;
50
+ discordChannelId: z.ZodOptional<z.ZodString>;
51
+ discordMention: z.ZodOptional<z.ZodString>;
52
+ authorizedDiscordUserIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
53
+ telegramBotToken: z.ZodOptional<z.ZodString>;
54
+ telegramChatId: z.ZodOptional<z.ZodString>;
55
+ pollIntervalMs: z.ZodDefault<z.ZodNumber>;
56
+ rateLimitPerMinute: z.ZodDefault<z.ZodNumber>;
57
+ maxMessageLength: z.ZodDefault<z.ZodNumber>;
58
+ includePrefix: z.ZodDefault<z.ZodBoolean>;
59
+ }, z.core.$strip>>;
60
+ }, z.core.$strip>;
61
+ export type OpenClawConfig = z.infer<typeof OpenClawConfigSchema>;
62
+ export type OpenClawGateway = z.infer<typeof OpenClawGatewaySchema>;
63
+ export type OpenClawHook = z.infer<typeof OpenClawHookSchema>;
64
+ export type OpenClawReplyListenerConfig = z.infer<typeof OpenClawReplyListenerConfigSchema>;
@@ -27,7 +27,6 @@ export declare function createHooks(args: {
27
27
  disposeHooks: () => void;
28
28
  categorySkillReminder: ReturnType<typeof import("./hooks").createCategorySkillReminderHook> | null;
29
29
  autoSlashCommand: ReturnType<typeof import("./hooks").createAutoSlashCommandHook> | null;
30
- gptPermissionContinuation: ReturnType<typeof import("./hooks").createGptPermissionContinuationHook> | null;
31
30
  stopContinuationGuard: ReturnType<typeof import("./hooks").createStopContinuationGuardHook> | null;
32
31
  compactionContextInjector: ReturnType<typeof import("./hooks").createCompactionContextInjector> | null;
33
32
  compactionTodoPreserver: ReturnType<typeof import("./hooks").createCompactionTodoPreserverHook> | null;
@@ -51,6 +50,7 @@ export declare function createHooks(args: {
51
50
  jsonErrorRecovery: ReturnType<typeof import("./hooks").createJsonErrorRecoveryHook> | null;
52
51
  readImageResizer: ReturnType<typeof import("./hooks").createReadImageResizerHook> | null;
53
52
  todoDescriptionOverride: ReturnType<typeof import("./hooks").createTodoDescriptionOverrideHook> | null;
53
+ webfetchRedirectGuard: ReturnType<typeof import("./hooks").createWebFetchRedirectGuardHook> | null;
54
54
  contextWindowMonitor: ReturnType<typeof import("./hooks").createContextWindowMonitorHook> | null;
55
55
  preemptiveCompaction: ReturnType<typeof import("./hooks").createPreemptiveCompactionHook> | null;
56
56
  sessionRecovery: ReturnType<typeof import("./hooks").createSessionRecoveryHook> | null;
@@ -3,9 +3,9 @@ import type { BackgroundTask, LaunchInput } from "./types";
3
3
  export declare const TASK_TTL_MS: number;
4
4
  export declare const TERMINAL_TASK_TTL_MS: number;
5
5
  export declare const MIN_STABILITY_TIME_MS: number;
6
- export declare const DEFAULT_STALE_TIMEOUT_MS = 1200000;
7
- export declare const DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS = 1800000;
8
- export declare const DEFAULT_MAX_TOOL_CALLS = 200;
6
+ export declare const DEFAULT_STALE_TIMEOUT_MS = 2700000;
7
+ export declare const DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS = 3600000;
8
+ export declare const DEFAULT_MAX_TOOL_CALLS = 4000;
9
9
  export declare const DEFAULT_CIRCUIT_BREAKER_CONSECUTIVE_THRESHOLD = 20;
10
10
  export declare const DEFAULT_CIRCUIT_BREAKER_ENABLED = true;
11
11
  export declare const MIN_RUNTIME_BEFORE_STALE_MS = 30000;
@@ -1,3 +1,4 @@
1
1
  export * from "./types";
2
2
  export * from "./constants";
3
3
  export * from "./storage";
4
+ export * from "./top-level-task";
@@ -3,12 +3,21 @@
3
3
  *
4
4
  * Handles reading/writing boulder.json for active plan tracking.
5
5
  */
6
- import type { BoulderState, PlanProgress } from "./types";
6
+ import type { BoulderState, PlanProgress, TaskSessionState } from "./types";
7
7
  export declare function getBoulderFilePath(directory: string): string;
8
8
  export declare function readBoulderState(directory: string): BoulderState | null;
9
9
  export declare function writeBoulderState(directory: string, state: BoulderState): boolean;
10
10
  export declare function appendSessionId(directory: string, sessionId: string): BoulderState | null;
11
11
  export declare function clearBoulderState(directory: string): boolean;
12
+ export declare function getTaskSessionState(directory: string, taskKey: string): TaskSessionState | null;
13
+ export declare function upsertTaskSessionState(directory: string, input: {
14
+ taskKey: string;
15
+ taskLabel: string;
16
+ taskTitle: string;
17
+ sessionId: string;
18
+ agent?: string;
19
+ category?: string;
20
+ }): BoulderState | null;
12
21
  /**
13
22
  * Find Prometheus plan files for this project.
14
23
  * Prometheus stores plans at: {project}/.sisyphus/plans/{name}.md
@@ -0,0 +1,2 @@
1
+ import type { TopLevelTaskRef } from "./types";
2
+ export declare function readCurrentTopLevelTask(planPath: string): TopLevelTaskRef | null;
@@ -17,6 +17,8 @@ export interface BoulderState {
17
17
  agent?: string;
18
18
  /** Absolute path to the git worktree root where work happens */
19
19
  worktree_path?: string;
20
+ /** Preferred reusable subagent sessions keyed by current top-level plan task */
21
+ task_sessions?: Record<string, TaskSessionState>;
20
22
  }
21
23
  export interface PlanProgress {
22
24
  /** Total number of checkboxes */
@@ -26,3 +28,29 @@ export interface PlanProgress {
26
28
  /** Whether all tasks are done */
27
29
  isComplete: boolean;
28
30
  }
31
+ export interface TaskSessionState {
32
+ /** Stable identifier for the current top-level plan task (e.g. todo:1 / final-wave:F1) */
33
+ task_key: string;
34
+ /** Original task label from the plan file */
35
+ task_label: string;
36
+ /** Full task title from the plan file */
37
+ task_title: string;
38
+ /** Preferred reusable subagent session */
39
+ session_id: string;
40
+ /** Agent associated with the task session, when known */
41
+ agent?: string;
42
+ /** Category associated with the task session, when known */
43
+ category?: string;
44
+ /** Last update timestamp */
45
+ updated_at: string;
46
+ }
47
+ export interface TopLevelTaskRef {
48
+ /** Stable identifier for the current top-level plan task */
49
+ key: string;
50
+ /** Task section in the Prometheus plan */
51
+ section: "todo" | "final-wave";
52
+ /** Original label token (e.g. 1 / F1) */
53
+ label: string;
54
+ /** Full task title extracted from the checkbox line */
55
+ title: string;
56
+ }
@@ -9,6 +9,8 @@ export declare function injectBoulderContinuation(input: {
9
9
  total: number;
10
10
  agent?: string;
11
11
  worktreePath?: string;
12
+ preferredTaskSessionId?: string;
13
+ preferredTaskTitle?: string;
12
14
  backgroundManager?: BackgroundManager;
13
15
  sessionState: SessionState;
14
16
  }): Promise<void>;
@@ -1 +1,7 @@
1
- export declare function extractSessionIdFromOutput(output: string): string;
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ export declare function extractSessionIdFromOutput(output: string): string | undefined;
3
+ export declare function validateSubagentSessionId(input: {
4
+ client: PluginInput["client"];
5
+ sessionID?: string;
6
+ lineageSessionIDs: string[];
7
+ }): Promise<string | undefined>;
@@ -1,9 +1,10 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
- import type { SessionState } from "./types";
2
+ import type { PendingTaskRef, SessionState } from "./types";
3
3
  import type { ToolExecuteAfterInput, ToolExecuteAfterOutput } from "./types";
4
4
  export declare function createToolExecuteAfterHandler(input: {
5
5
  ctx: PluginInput;
6
6
  pendingFilePaths: Map<string, string>;
7
+ pendingTaskRefs: Map<string, PendingTaskRef>;
7
8
  autoCommit: boolean;
8
9
  getState: (sessionID: string) => SessionState;
9
10
  }): (toolInput: ToolExecuteAfterInput, toolOutput: ToolExecuteAfterOutput) => Promise<void>;
@@ -1,7 +1,9 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
+ import type { PendingTaskRef } from "./types";
2
3
  export declare function createToolExecuteBeforeHandler(input: {
3
4
  ctx: PluginInput;
4
5
  pendingFilePaths: Map<string, string>;
6
+ pendingTaskRefs: Map<string, PendingTaskRef>;
5
7
  }): (toolInput: {
6
8
  tool: string;
7
9
  sessionID?: string;
@@ -1,5 +1,6 @@
1
1
  import type { AgentOverrides } from "../../config";
2
2
  import type { BackgroundManager } from "../../features/background-agent";
3
+ import type { TopLevelTaskRef } from "../../features/boulder-state";
3
4
  export type ModelInfo = {
4
5
  providerID: string;
5
6
  modelID: string;
@@ -8,7 +9,6 @@ export interface AtlasHookOptions {
8
9
  directory: string;
9
10
  backgroundManager?: BackgroundManager;
10
11
  isContinuationStopped?: (sessionID: string) => boolean;
11
- shouldSkipContinuation?: (sessionID: string) => boolean;
12
12
  agentOverrides?: AgentOverrides;
13
13
  /** Enable auto-commit after each atomic task completion (default: true) */
14
14
  autoCommit?: boolean;
@@ -23,6 +23,18 @@ export interface ToolExecuteAfterOutput {
23
23
  output: string;
24
24
  metadata: Record<string, unknown>;
25
25
  }
26
+ export type TrackedTopLevelTaskRef = Pick<TopLevelTaskRef, "key" | "label" | "title">;
27
+ export type PendingTaskRef = {
28
+ kind: "track";
29
+ task: TrackedTopLevelTaskRef;
30
+ } | {
31
+ kind: "skip";
32
+ reason: "explicit_resume";
33
+ } | {
34
+ kind: "skip";
35
+ reason: "ambiguous_task_key";
36
+ task: TrackedTopLevelTaskRef;
37
+ };
26
38
  export interface SessionState {
27
39
  lastEventWasAbortError?: boolean;
28
40
  lastContinuationInjectedAt?: number;
@@ -27,7 +27,6 @@ export { createCategorySkillReminderHook } from "./category-skill-reminder";
27
27
  export { createRalphLoopHook, type RalphLoopHook } from "./ralph-loop";
28
28
  export { createNoSisyphusGptHook } from "./no-sisyphus-gpt";
29
29
  export { createNoHephaestusNonGptHook } from "./no-hephaestus-non-gpt";
30
- export { createGptPermissionContinuationHook, type GptPermissionContinuationHook } from "./gpt-permission-continuation";
31
30
  export { createAutoSlashCommandHook } from "./auto-slash-command";
32
31
  export { createEditErrorRecoveryHook } from "./edit-error-recovery";
33
32
  export { createPrometheusMdOnlyHook } from "./prometheus-md-only";
@@ -49,3 +48,4 @@ export { createHashlineReadEnhancerHook } from "./hashline-read-enhancer";
49
48
  export { createJsonErrorRecoveryHook, JSON_ERROR_TOOL_EXCLUDE_LIST, JSON_ERROR_PATTERNS, JSON_ERROR_REMINDER } from "./json-error-recovery";
50
49
  export { createReadImageResizerHook } from "./read-image-resizer";
51
50
  export { createTodoDescriptionOverrideHook } from "./todo-description-override";
51
+ export { createWebFetchRedirectGuardHook } from "./webfetch-redirect-guard";
@@ -1,6 +1,6 @@
1
1
  export declare const CODE_BLOCK_PATTERN: RegExp;
2
2
  export declare const INLINE_CODE_PATTERN: RegExp;
3
- export { isPlannerAgent, getUltraworkMessage } from "./ultrawork";
3
+ export { isPlannerAgent, isNonOmoAgent, getUltraworkMessage } from "./ultrawork";
4
4
  export { SEARCH_PATTERN, SEARCH_MESSAGE } from "./search";
5
5
  export { ANALYZE_PATTERN, ANALYZE_MESSAGE } from "./analyze";
6
6
  export type KeywordDetector = {
@@ -7,7 +7,7 @@
7
7
  * 3. Gemini models → gemini.ts
8
8
  * 4. Default (Claude, etc.) → default.ts (optimized for Claude series)
9
9
  */
10
- export { isPlannerAgent, isGptModel, isGeminiModel, getUltraworkSource, } from "./source-detector";
10
+ export { isPlannerAgent, isNonOmoAgent, isGptModel, isGeminiModel, getUltraworkSource, } from "./source-detector";
11
11
  export type { UltraworkSource } from "./source-detector";
12
12
  export { ULTRAWORK_PLANNER_SECTION, getPlannerUltraworkMessage, } from "./planner";
13
13
  export { ULTRAWORK_GPT_MESSAGE, getGptUltraworkMessage } from "./gpt";
@@ -13,6 +13,11 @@ import { isGptModel, isGeminiModel } from "../../../agents/types";
13
13
  * Planners don't need ultrawork injection (they ARE the planner).
14
14
  */
15
15
  export declare function isPlannerAgent(agentName?: string): boolean;
16
+ /**
17
+ * Checks if agent is a non-OMO agent (e.g., OpenCode's built-in Builder/Plan).
18
+ * Non-OMO agents should not receive keyword injection (search-mode, analyze-mode, etc.).
19
+ */
20
+ export declare function isNonOmoAgent(agentName?: string): boolean;
16
21
  export { isGptModel, isGeminiModel };
17
22
  /** Ultrawork message source type */
18
23
  export type UltraworkSource = "planner" | "gpt" | "gemini" | "default";
@@ -0,0 +1,11 @@
1
+ import type { PluginContext } from "../plugin/types";
2
+ import type { OhMyOpenCodeConfig } from "../config";
3
+ export declare function createOpenClawHook(ctx: PluginContext, pluginConfig: OhMyOpenCodeConfig): {
4
+ event: (input: any) => Promise<void>;
5
+ "tool.execute.before": (input: {
6
+ tool: string;
7
+ sessionID: string;
8
+ }, output: {
9
+ args: Record<string, unknown>;
10
+ }) => Promise<void>;
11
+ } | null;
@@ -0,0 +1,55 @@
1
+ import type { OhMyOpenCodeConfig } from "../config";
2
+ interface CompactionTargetState {
3
+ providerID: string;
4
+ modelID: string;
5
+ }
6
+ interface ClientLike {
7
+ session: {
8
+ summarize: (input: {
9
+ path: {
10
+ id: string;
11
+ };
12
+ body: {
13
+ providerID: string;
14
+ modelID: string;
15
+ };
16
+ query: {
17
+ directory: string;
18
+ };
19
+ }) => Promise<unknown>;
20
+ messages: (input: {
21
+ path: {
22
+ id: string;
23
+ };
24
+ query?: {
25
+ directory: string;
26
+ };
27
+ }) => Promise<unknown>;
28
+ };
29
+ tui: {
30
+ showToast: (input: {
31
+ body: {
32
+ title: string;
33
+ message: string;
34
+ variant: "warning";
35
+ duration: number;
36
+ };
37
+ }) => Promise<unknown>;
38
+ };
39
+ }
40
+ export interface AssistantCompactionMessageInfo {
41
+ sessionID: string;
42
+ id?: string;
43
+ }
44
+ export declare function createPostCompactionDegradationMonitor(args: {
45
+ client: ClientLike;
46
+ directory: string;
47
+ pluginConfig: OhMyOpenCodeConfig;
48
+ tokenCache: Map<string, CompactionTargetState>;
49
+ compactionInProgress: Set<string>;
50
+ }): {
51
+ clear: (sessionID: string) => void;
52
+ onSessionCompacted: (sessionID: string) => void;
53
+ onAssistantMessageUpdated: (info: AssistantCompactionMessageInfo) => Promise<void>;
54
+ };
55
+ export {};
@@ -0,0 +1,18 @@
1
+ export declare function isStepOnlyNoTextParts(parts: unknown): boolean;
2
+ export declare function resolveNoTextTailFromSession(args: {
3
+ client: {
4
+ session: {
5
+ messages: (input: {
6
+ path: {
7
+ id: string;
8
+ };
9
+ query?: {
10
+ directory: string;
11
+ };
12
+ }) => Promise<unknown>;
13
+ };
14
+ };
15
+ sessionID: string;
16
+ messageID?: string;
17
+ directory: string;
18
+ }): Promise<boolean>;
@@ -1,5 +1,30 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
+ import type { MessageData, StoredPart } from "../types";
3
+ import { log, isSqliteBackend, patchPart } from "../../../shared";
2
4
  type OpencodeClient = PluginInput["client"];
3
- export declare function prependThinkingPart(sessionID: string, messageID: string): boolean;
4
- export declare function prependThinkingPartAsync(client: OpencodeClient, sessionID: string, messageID: string): Promise<boolean>;
5
+ type StoredSignedThinkingPart = StoredPart & {
6
+ type: "thinking" | "redacted_thinking";
7
+ signature: string;
8
+ };
9
+ type SDKMessagePart = NonNullable<MessageData["parts"]>[number];
10
+ type SDKSignedThinkingPart = SDKMessagePart & {
11
+ id: string;
12
+ type: "thinking" | "redacted_thinking";
13
+ signature: string;
14
+ };
15
+ type ThinkingPrependDeps = {
16
+ isSqliteBackend: typeof isSqliteBackend;
17
+ patchPart: typeof patchPart;
18
+ log: typeof log;
19
+ findLastThinkingPart: typeof findLastThinkingPart;
20
+ findLastThinkingPartFromSDK: typeof findLastThinkingPartFromSDK;
21
+ readTargetPartIDs: typeof readTargetPartIDs;
22
+ readTargetPartIDsFromSDK: typeof readTargetPartIDsFromSDK;
23
+ };
24
+ declare function readTargetPartIDs(messageID: string): string[];
25
+ declare function readTargetPartIDsFromSDK(client: OpencodeClient, sessionID: string, messageID: string): Promise<string[]>;
26
+ declare function findLastThinkingPart(sessionID: string, beforeMessageID: string): StoredSignedThinkingPart | null;
27
+ export declare function prependThinkingPart(sessionID: string, messageID: string, deps?: ThinkingPrependDeps): boolean;
28
+ declare function findLastThinkingPartFromSDK(client: OpencodeClient, sessionID: string, beforeMessageID: string): Promise<SDKSignedThinkingPart | null>;
29
+ export declare function prependThinkingPartAsync(client: OpencodeClient, sessionID: string, messageID: string, deps?: ThinkingPrependDeps): Promise<boolean>;
5
30
  export {};
@@ -1,2 +1,4 @@
1
1
  import type { SessionState } from "./types";
2
+ export declare function armCompactionGuard(state: SessionState, now: number): number;
3
+ export declare function acknowledgeCompactionGuard(state: SessionState, compactionEpoch: number | undefined): boolean;
2
4
  export declare function isCompactionGuardActive(state: SessionState, now: number): boolean;
@@ -7,7 +7,6 @@ export declare function createTodoContinuationHandler(args: {
7
7
  backgroundManager?: BackgroundManager;
8
8
  skipAgents?: string[];
9
9
  isContinuationStopped?: (sessionID: string) => boolean;
10
- shouldSkipContinuation?: (sessionID: string) => boolean;
11
10
  }): (input: {
12
11
  event: {
13
12
  type: string;
@@ -8,5 +8,4 @@ export declare function handleSessionIdle(args: {
8
8
  backgroundManager?: BackgroundManager;
9
9
  skipAgents?: string[];
10
10
  isContinuationStopped?: (sessionID: string) => boolean;
11
- shouldSkipContinuation?: (sessionID: string) => boolean;
12
11
  }): Promise<void>;
@@ -4,7 +4,6 @@ export interface TodoContinuationEnforcerOptions {
4
4
  backgroundManager?: BackgroundManager;
5
5
  skipAgents?: string[];
6
6
  isContinuationStopped?: (sessionID: string) => boolean;
7
- shouldSkipContinuation?: (sessionID: string) => boolean;
8
7
  }
9
8
  export interface TodoContinuationEnforcer {
10
9
  handler: (input: {
@@ -37,6 +36,8 @@ export interface SessionState {
37
36
  stagnationCount: number;
38
37
  consecutiveFailures: number;
39
38
  recentCompactionAt?: number;
39
+ recentCompactionEpoch?: number;
40
+ acknowledgedCompactionEpoch?: number;
40
41
  }
41
42
  export interface MessageInfo {
42
43
  id?: string;
@@ -0,0 +1,6 @@
1
+ export declare const DEFAULT_WEBFETCH_TIMEOUT_MS = 30000;
2
+ export declare const MAX_WEBFETCH_TIMEOUT_MS = 120000;
3
+ export declare const MAX_WEBFETCH_REDIRECTS = 10;
4
+ export declare const WEBFETCH_REDIRECT_GUARD_STALE_TIMEOUT_MS: number;
5
+ export declare const WEBFETCH_REDIRECT_ERROR_PATTERNS: readonly [RegExp, RegExp];
6
+ export declare const WEBFETCH_REDIRECT_STATUSES: Set<number>;
@@ -0,0 +1,19 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ type ToolExecuteInput = {
3
+ tool: string;
4
+ sessionID: string;
5
+ callID: string;
6
+ };
7
+ type ToolExecuteBeforeOutput = {
8
+ args: Record<string, unknown>;
9
+ };
10
+ type ToolExecuteAfterOutput = {
11
+ title: string;
12
+ output: string;
13
+ metadata: Record<string, unknown>;
14
+ };
15
+ export declare function createWebFetchRedirectGuardHook(_ctx: PluginInput): {
16
+ "tool.execute.before": (input: ToolExecuteInput, output: ToolExecuteBeforeOutput) => Promise<void>;
17
+ "tool.execute.after": (input: ToolExecuteInput, output: ToolExecuteAfterOutput) => Promise<void>;
18
+ };
19
+ export {};
@@ -0,0 +1 @@
1
+ export { createWebFetchRedirectGuardHook } from "./hook";
@@ -0,0 +1,16 @@
1
+ export type WebFetchFormat = "markdown" | "text" | "html";
2
+ type RedirectResolutionParams = {
3
+ url: string;
4
+ format: WebFetchFormat;
5
+ timeoutSeconds?: number;
6
+ };
7
+ export type RedirectResolutionResult = {
8
+ type: "resolved";
9
+ url: string;
10
+ } | {
11
+ type: "exceeded";
12
+ url: string;
13
+ maxRedirects: number;
14
+ };
15
+ export declare function resolveWebFetchRedirects(params: RedirectResolutionParams): Promise<RedirectResolutionResult>;
16
+ export {};