oh-my-opencode 3.7.3 → 3.8.0

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 (146) hide show
  1. package/README.ja.md +206 -243
  2. package/README.ko.md +205 -244
  3. package/README.md +176 -174
  4. package/README.zh-cn.md +211 -255
  5. package/dist/agents/atlas/default.d.ts +1 -1
  6. package/dist/agents/atlas/gpt.d.ts +1 -1
  7. package/dist/agents/atlas/prompt-section-builder.d.ts +1 -1
  8. package/dist/agents/builtin-agents/environment-context.d.ts +5 -1
  9. package/dist/agents/builtin-agents/general-agents.d.ts +1 -0
  10. package/dist/agents/builtin-agents/hephaestus-agent.d.ts +1 -0
  11. package/dist/agents/builtin-agents/sisyphus-agent.d.ts +1 -0
  12. package/dist/agents/builtin-agents.d.ts +1 -1
  13. package/dist/agents/dynamic-agent-prompt-builder.d.ts +0 -5
  14. package/dist/agents/index.d.ts +2 -1
  15. package/dist/agents/metis.d.ts +1 -1
  16. package/dist/agents/prometheus/behavioral-summary.d.ts +1 -1
  17. package/dist/agents/prometheus/gpt.d.ts +24 -0
  18. package/dist/agents/prometheus/identity-constraints.d.ts +1 -1
  19. package/dist/agents/prometheus/index.d.ts +3 -1
  20. package/dist/agents/prometheus/interview-mode.d.ts +1 -1
  21. package/dist/agents/prometheus/plan-generation.d.ts +1 -1
  22. package/dist/agents/prometheus/plan-template.d.ts +1 -1
  23. package/dist/agents/prometheus/system-prompt.d.ts +13 -2
  24. package/dist/agents/sisyphus-junior/agent.d.ts +1 -1
  25. package/dist/agents/types.d.ts +1 -0
  26. package/dist/cli/config-manager/antigravity-provider-configuration.d.ts +2 -2
  27. package/dist/cli/fallback-chain-resolution.d.ts +1 -1
  28. package/dist/cli/index.js +527 -175
  29. package/dist/cli/model-fallback-requirements.d.ts +3 -0
  30. package/dist/cli/provider-model-id-transform.d.ts +1 -1
  31. package/dist/cli/run/event-state.d.ts +4 -0
  32. package/dist/cli/run/stdin-suppression.d.ts +12 -0
  33. package/dist/cli/run/timestamp-output.d.ts +5 -0
  34. package/dist/cli/run/types.d.ts +1 -0
  35. package/dist/config/index.d.ts +2 -2
  36. package/dist/config/schema/agent-overrides.d.ts +75 -0
  37. package/dist/config/schema/categories.d.ts +2 -0
  38. package/dist/config/schema/experimental.d.ts +2 -0
  39. package/dist/config/schema/fallback-models.d.ts +3 -0
  40. package/dist/config/schema/hooks.d.ts +4 -3
  41. package/dist/config/schema/oh-my-opencode-config.d.ts +87 -47
  42. package/dist/config/schema/ralph-loop.d.ts +4 -0
  43. package/dist/config/schema/runtime-fallback.d.ts +10 -0
  44. package/dist/config/schema.d.ts +2 -0
  45. package/dist/create-hooks.d.ts +8 -5
  46. package/dist/features/background-agent/manager.d.ts +3 -0
  47. package/dist/features/background-agent/parent-session-context-resolver.d.ts +1 -0
  48. package/dist/features/background-agent/types.d.ts +7 -0
  49. package/dist/features/builtin-commands/templates/ralph-loop.d.ts +1 -1
  50. package/dist/features/claude-code-session-state/state.d.ts +1 -0
  51. package/dist/features/task-toast-manager/manager.d.ts +5 -0
  52. package/dist/features/task-toast-manager/types.d.ts +2 -1
  53. package/dist/features/tmux-subagent/action-executor.d.ts +10 -3
  54. package/dist/features/tmux-subagent/grid-planning.d.ts +5 -3
  55. package/dist/features/tmux-subagent/manager.d.ts +12 -0
  56. package/dist/features/tmux-subagent/pane-split-availability.d.ts +0 -1
  57. package/dist/features/tmux-subagent/spawn-target-finder.d.ts +2 -2
  58. package/dist/features/tmux-subagent/tmux-grid-constants.d.ts +4 -0
  59. package/dist/features/tmux-subagent/types.d.ts +2 -0
  60. package/dist/hooks/atlas/recent-model-resolver.d.ts +6 -0
  61. package/dist/hooks/atlas/system-reminder-templates.d.ts +1 -1
  62. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +28 -0
  63. package/dist/hooks/hashline-edit-diff-enhancer/index.d.ts +1 -0
  64. package/dist/hooks/index.d.ts +5 -2
  65. package/dist/hooks/model-fallback/hook.d.ts +60 -0
  66. package/dist/hooks/no-hephaestus-non-gpt/hook.d.ts +16 -0
  67. package/dist/hooks/no-hephaestus-non-gpt/index.d.ts +1 -0
  68. package/dist/hooks/{sisyphus-gpt-hephaestus-reminder → no-sisyphus-gpt}/hook.d.ts +6 -1
  69. package/dist/hooks/no-sisyphus-gpt/index.d.ts +1 -0
  70. package/dist/hooks/ralph-loop/command-arguments.d.ts +8 -0
  71. package/dist/hooks/ralph-loop/continuation-prompt-injector.d.ts +1 -0
  72. package/dist/hooks/ralph-loop/iteration-continuation.d.ts +12 -0
  73. package/dist/hooks/ralph-loop/loop-state-controller.d.ts +2 -0
  74. package/dist/hooks/ralph-loop/ralph-loop-event-handler.d.ts +1 -0
  75. package/dist/hooks/ralph-loop/ralph-loop-hook.d.ts +1 -0
  76. package/dist/hooks/ralph-loop/session-reset-strategy.d.ts +3 -0
  77. package/dist/hooks/ralph-loop/types.d.ts +1 -0
  78. package/dist/hooks/runtime-fallback/agent-resolver.d.ts +5 -0
  79. package/dist/hooks/runtime-fallback/auto-retry.d.ts +10 -0
  80. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +20 -0
  81. package/dist/hooks/runtime-fallback/constants.d.ts +19 -0
  82. package/dist/hooks/runtime-fallback/error-classifier.d.ts +17 -0
  83. package/dist/hooks/runtime-fallback/event-handler.d.ts +8 -0
  84. package/dist/hooks/runtime-fallback/fallback-models.d.ts +2 -0
  85. package/dist/hooks/runtime-fallback/fallback-state.d.ts +6 -0
  86. package/dist/hooks/runtime-fallback/hook.d.ts +3 -0
  87. package/dist/hooks/runtime-fallback/index.d.ts +2 -0
  88. package/dist/hooks/runtime-fallback/message-update-handler.d.ts +5 -0
  89. package/dist/hooks/runtime-fallback/types.d.ts +59 -0
  90. package/dist/hooks/session-recovery/detect-error-type.d.ts +2 -1
  91. package/dist/hooks/session-recovery/recover-unavailable-tool.d.ts +5 -0
  92. package/dist/hooks/session-recovery/types.d.ts +1 -0
  93. package/dist/hooks/todo-continuation-enforcer/continuation-injection.d.ts +1 -0
  94. package/dist/hooks/todo-continuation-enforcer/countdown.d.ts +1 -0
  95. package/dist/hooks/unstable-agent-babysitter/task-message-analyzer.d.ts +1 -0
  96. package/dist/hooks/unstable-agent-babysitter/unstable-agent-babysitter-hook.d.ts +2 -0
  97. package/dist/hooks/write-existing-file-guard/hook.d.ts +1 -0
  98. package/dist/index.js +6614 -3149
  99. package/dist/oh-my-opencode.schema.json +3681 -0
  100. package/dist/plugin/chat-headers.d.ts +4 -0
  101. package/dist/plugin/chat-message.d.ts +9 -8
  102. package/dist/plugin/chat-params.d.ts +2 -3
  103. package/dist/plugin/event.d.ts +2 -6
  104. package/dist/plugin/hooks/create-core-hooks.d.ts +8 -5
  105. package/dist/plugin/hooks/create-session-hooks.d.ts +7 -5
  106. package/dist/plugin/hooks/create-tool-guard-hooks.d.ts +2 -1
  107. package/dist/plugin/hooks/create-transform-hooks.d.ts +1 -1
  108. package/dist/plugin/system-transform.d.ts +5 -0
  109. package/dist/plugin/types.d.ts +7 -1
  110. package/dist/plugin/ultrawork-db-model-override.d.ts +11 -0
  111. package/dist/plugin/ultrawork-model-override.d.ts +37 -0
  112. package/dist/shared/index.d.ts +4 -0
  113. package/dist/shared/internal-initiator-marker.d.ts +5 -0
  114. package/dist/shared/model-error-classifier.d.ts +31 -0
  115. package/dist/shared/model-resolution-pipeline.d.ts +1 -0
  116. package/dist/shared/model-resolver.d.ts +6 -0
  117. package/dist/shared/prompt-tools.d.ts +3 -0
  118. package/dist/shared/provider-model-id-transform.d.ts +1 -0
  119. package/dist/shared/session-category-registry.d.ts +32 -0
  120. package/dist/shared/session-model-state.d.ts +7 -0
  121. package/dist/shared/tmux/tmux-utils/layout.d.ts +17 -2
  122. package/dist/tools/delegate-task/background-task.d.ts +2 -1
  123. package/dist/tools/delegate-task/category-resolver.d.ts +2 -0
  124. package/dist/tools/delegate-task/constants.d.ts +1 -1
  125. package/dist/tools/delegate-task/skill-resolver.d.ts +1 -0
  126. package/dist/tools/delegate-task/subagent-resolver.d.ts +2 -0
  127. package/dist/tools/delegate-task/sync-task.d.ts +1 -1
  128. package/dist/tools/hashline-edit/constants.d.ts +5 -2
  129. package/dist/tools/hashline-edit/diff-utils.d.ts +6 -0
  130. package/dist/tools/hashline-edit/edit-operations.d.ts +4 -4
  131. package/dist/tools/hashline-edit/hash-computation.d.ts +1 -1
  132. package/dist/tools/hashline-edit/index.d.ts +1 -1
  133. package/dist/tools/hashline-edit/types.d.ts +4 -4
  134. package/dist/tools/hashline-edit/validation.d.ts +1 -0
  135. package/dist/tools/index.d.ts +2 -2
  136. package/dist/tools/skill/constants.d.ts +2 -2
  137. package/dist/tools/skill/types.d.ts +4 -0
  138. package/dist/tools/slashcommand/index.d.ts +1 -1
  139. package/dist/tools/slashcommand/types.d.ts +1 -7
  140. package/package.json +10 -10
  141. package/dist/cli/run/opencode-bin-path.d.ts +0 -3
  142. package/dist/hooks/sisyphus-gpt-hephaestus-reminder/index.d.ts +0 -1
  143. package/dist/tools/slashcommand/skill-command-converter.d.ts +0 -3
  144. package/dist/tools/slashcommand/slashcommand-description.d.ts +0 -3
  145. package/dist/tools/slashcommand/slashcommand-tool.d.ts +0 -4
  146. package/dist/tools/slashcommand/tools.d.ts +0 -2
@@ -3,5 +3,9 @@ export declare const RalphLoopConfigSchema: z.ZodObject<{
3
3
  enabled: z.ZodDefault<z.ZodBoolean>;
4
4
  default_max_iterations: z.ZodDefault<z.ZodNumber>;
5
5
  state_dir: z.ZodOptional<z.ZodString>;
6
+ default_strategy: z.ZodDefault<z.ZodEnum<{
7
+ reset: "reset";
8
+ continue: "continue";
9
+ }>>;
6
10
  }, z.core.$strip>;
7
11
  export type RalphLoopConfig = z.infer<typeof RalphLoopConfigSchema>;
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+ export declare const RuntimeFallbackConfigSchema: z.ZodObject<{
3
+ enabled: z.ZodOptional<z.ZodBoolean>;
4
+ retry_on_errors: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
5
+ max_fallback_attempts: z.ZodOptional<z.ZodNumber>;
6
+ cooldown_seconds: z.ZodOptional<z.ZodNumber>;
7
+ timeout_seconds: z.ZodOptional<z.ZodNumber>;
8
+ notify_on_fallback: z.ZodOptional<z.ZodBoolean>;
9
+ }, z.core.$strip>;
10
+ export type RuntimeFallbackConfig = z.infer<typeof RuntimeFallbackConfigSchema>;
@@ -9,11 +9,13 @@ export * from "./schema/comment-checker";
9
9
  export * from "./schema/commands";
10
10
  export * from "./schema/dynamic-context-pruning";
11
11
  export * from "./schema/experimental";
12
+ export * from "./schema/fallback-models";
12
13
  export * from "./schema/git-master";
13
14
  export * from "./schema/hooks";
14
15
  export * from "./schema/notification";
15
16
  export * from "./schema/oh-my-opencode-config";
16
17
  export * from "./schema/ralph-loop";
18
+ export * from "./schema/runtime-fallback";
17
19
  export * from "./schema/skills";
18
20
  export * from "./schema/sisyphus";
19
21
  export * from "./schema/sisyphus-agent";
@@ -24,7 +24,7 @@ export declare function createHooks(args: {
24
24
  unstableAgentBabysitter: ReturnType<typeof import("./plugin/unstable-agent-babysitter").createUnstableAgentBabysitter> | null;
25
25
  backgroundNotificationHook: ReturnType<typeof import("./hooks").createBackgroundNotificationHook> | null;
26
26
  atlasHook: ReturnType<typeof import("./hooks").createAtlasHook> | null;
27
- claudeCodeHooks: ReturnType<typeof import("./hooks").createClaudeCodeHooksHook>;
27
+ claudeCodeHooks: ReturnType<typeof import("./hooks").createClaudeCodeHooksHook> | null;
28
28
  keywordDetector: ReturnType<typeof import("./hooks").createKeywordDetectorHook> | null;
29
29
  contextInjectorMessagesTransform: ReturnType<typeof import("./features/context-injector").createContextInjectorMessagesTransformHook>;
30
30
  thinkingBlockValidator: ReturnType<typeof import("./hooks").createThinkingBlockValidatorHook> | null;
@@ -37,11 +37,13 @@ export declare function createHooks(args: {
37
37
  tasksTodowriteDisabler: ReturnType<typeof import("./hooks").createTasksTodowriteDisablerHook> | null;
38
38
  writeExistingFileGuard: ReturnType<typeof import("./hooks").createWriteExistingFileGuardHook> | null;
39
39
  hashlineReadEnhancer: ReturnType<typeof import("./hooks").createHashlineReadEnhancerHook> | null;
40
+ jsonErrorRecovery: ReturnType<typeof import("./hooks").createJsonErrorRecoveryHook> | null;
40
41
  contextWindowMonitor: ReturnType<typeof import("./hooks").createContextWindowMonitorHook> | null;
41
42
  preemptiveCompaction: ReturnType<typeof import("./hooks").createPreemptiveCompactionHook> | null;
42
43
  sessionRecovery: ReturnType<typeof import("./hooks").createSessionRecoveryHook> | null;
43
44
  sessionNotification: ReturnType<typeof import("./hooks").createSessionNotification> | null;
44
45
  thinkMode: ReturnType<typeof import("./hooks").createThinkModeHook> | null;
46
+ modelFallback: ReturnType<typeof import("./hooks").createModelFallbackHook> | null;
45
47
  anthropicContextWindowLimitRecovery: ReturnType<typeof import("./hooks").createAnthropicContextWindowLimitRecoveryHook> | null;
46
48
  autoUpdateChecker: ReturnType<typeof import("./hooks").createAutoUpdateCheckerHook> | null;
47
49
  agentUsageReminder: ReturnType<typeof import("./hooks").createAgentUsageReminderHook> | null;
@@ -49,13 +51,14 @@ export declare function createHooks(args: {
49
51
  interactiveBashSession: ReturnType<typeof import("./hooks").createInteractiveBashSessionHook> | null;
50
52
  ralphLoop: ReturnType<typeof import("./hooks").createRalphLoopHook> | null;
51
53
  editErrorRecovery: ReturnType<typeof import("./hooks").createEditErrorRecoveryHook> | null;
52
- jsonErrorRecovery: ReturnType<typeof import("./hooks").createJsonErrorRecoveryHook> | null;
53
54
  delegateTaskRetry: ReturnType<typeof import("./hooks").createDelegateTaskRetryHook> | null;
54
55
  startWork: ReturnType<typeof import("./hooks").createStartWorkHook> | null;
55
56
  prometheusMdOnly: ReturnType<typeof import("./hooks").createPrometheusMdOnlyHook> | null;
56
57
  sisyphusJuniorNotepad: ReturnType<typeof import("./hooks").createSisyphusJuniorNotepadHook> | null;
57
- sisyphusGptHephaestusReminder: ReturnType<typeof import("./hooks").createSisyphusGptHephaestusReminderHook> | null;
58
- questionLabelTruncator: ReturnType<typeof import("./hooks").createQuestionLabelTruncatorHook>;
59
- taskResumeInfo: ReturnType<typeof import("./hooks").createTaskResumeInfoHook>;
58
+ noSisyphusGpt: ReturnType<typeof import("./hooks").createNoSisyphusGptHook> | null;
59
+ noHephaestusNonGpt: ReturnType<typeof import("./hooks").createNoHephaestusNonGptHook> | null;
60
+ questionLabelTruncator: ReturnType<typeof import("./hooks").createQuestionLabelTruncatorHook> | null;
61
+ taskResumeInfo: ReturnType<typeof import("./hooks").createTaskResumeInfoHook> | null;
60
62
  anthropicEffort: ReturnType<typeof import("./hooks/anthropic-effort").createAnthropicEffortHook> | null;
63
+ runtimeFallback: ReturnType<typeof import("./hooks").createRuntimeFallbackHook> | null;
61
64
  };
@@ -73,6 +73,7 @@ export declare class BackgroundManager {
73
73
  resume(input: ResumeInput): Promise<BackgroundTask>;
74
74
  private checkSessionTodos;
75
75
  handleEvent(event: Event): void;
76
+ private tryFallbackRetry;
76
77
  markForNotification(task: BackgroundTask): void;
77
78
  getPendingNotifications(sessionID: string): BackgroundTask[];
78
79
  clearNotifications(sessionID: string): void;
@@ -119,6 +120,8 @@ export declare class BackgroundManager {
119
120
  private formatDuration;
120
121
  private isAbortedSessionError;
121
122
  private getErrorText;
123
+ private extractErrorName;
124
+ private extractErrorMessage;
122
125
  private isRecord;
123
126
  private getSessionErrorMessage;
124
127
  private hasRunningTasks;
@@ -10,5 +10,6 @@ export declare function resolveParentSessionAgentAndModel(input: {
10
10
  }): Promise<{
11
11
  agent?: string;
12
12
  model?: AgentModel;
13
+ tools?: Record<string, boolean>;
13
14
  }>;
14
15
  export {};
@@ -1,3 +1,4 @@
1
+ import type { FallbackEntry } from "../../shared/model-requirements";
1
2
  export type BackgroundTaskStatus = "pending" | "running" | "completed" | "error" | "cancelled" | "interrupt";
2
3
  export interface TaskProgress {
3
4
  toolCalls: number;
@@ -30,6 +31,10 @@ export interface BackgroundTask {
30
31
  modelID: string;
31
32
  variant?: string;
32
33
  };
34
+ /** Fallback chain for runtime retry on model errors */
35
+ fallbackChain?: FallbackEntry[];
36
+ /** Number of fallback retry attempts made */
37
+ attemptCount?: number;
33
38
  /** Active concurrency slot key */
34
39
  concurrencyKey?: string;
35
40
  /** Persistent key for re-acquiring concurrency on resume */
@@ -64,6 +69,8 @@ export interface LaunchInput {
64
69
  modelID: string;
65
70
  variant?: string;
66
71
  };
72
+ /** Fallback chain for runtime retry on model errors */
73
+ fallbackChain?: FallbackEntry[];
67
74
  isUnstableAgent?: boolean;
68
75
  skills?: string[];
69
76
  skillContent?: string;
@@ -1,2 +1,2 @@
1
- export declare const RALPH_LOOP_TEMPLATE = "You are starting a Ralph Loop - a self-referential development loop that runs until task completion.\n\n## How Ralph Loop Works\n\n1. You will work on the task continuously\n2. When you believe the task is FULLY complete, output: `<promise>{{COMPLETION_PROMISE}}</promise>`\n3. If you don't output the promise, the loop will automatically inject another prompt to continue\n4. Maximum iterations: Configurable (default 100)\n\n## Rules\n\n- Focus on completing the task fully, not partially\n- Don't output the completion promise until the task is truly done\n- Each iteration should make meaningful progress toward the goal\n- If stuck, try different approaches\n- Use todos to track your progress\n\n## Exit Conditions\n\n1. **Completion**: Output your completion promise tag when fully complete\n2. **Max Iterations**: Loop stops automatically at limit\n3. **Cancel**: User runs `/cancel-ralph` command\n\n## Your Task\n\nParse the arguments below and begin working on the task. The format is:\n`\"task description\" [--completion-promise=TEXT] [--max-iterations=N]`\n\nDefault completion promise is \"DONE\" and default max iterations is 100.";
1
+ export declare const RALPH_LOOP_TEMPLATE = "You are starting a Ralph Loop - a self-referential development loop that runs until task completion.\n\n## How Ralph Loop Works\n\n1. You will work on the task continuously\n2. When you believe the task is FULLY complete, output: `<promise>{{COMPLETION_PROMISE}}</promise>`\n3. If you don't output the promise, the loop will automatically inject another prompt to continue\n4. Maximum iterations: Configurable (default 100)\n\n## Rules\n\n- Focus on completing the task fully, not partially\n- Don't output the completion promise until the task is truly done\n- Each iteration should make meaningful progress toward the goal\n- If stuck, try different approaches\n- Use todos to track your progress\n\n## Exit Conditions\n\n1. **Completion**: Output your completion promise tag when fully complete\n2. **Max Iterations**: Loop stops automatically at limit\n3. **Cancel**: User runs `/cancel-ralph` command\n\n## Your Task\n\nParse the arguments below and begin working on the task. The format is:\n`\"task description\" [--completion-promise=TEXT] [--max-iterations=N] [--strategy=reset|continue]`\n\nDefault completion promise is \"DONE\" and default max iterations is 100.";
2
2
  export declare const CANCEL_RALPH_TEMPLATE = "Cancel the currently active Ralph Loop.\n\nThis will:\n1. Stop the loop from continuing\n2. Clear the loop state file\n3. Allow the session to end normally\n\nCheck if a loop is active and cancel it. Inform the user of the result.";
@@ -1,4 +1,5 @@
1
1
  export declare const subagentSessions: Set<string>;
2
+ export declare const syncSubagentSessions: Set<string>;
2
3
  export declare function setMainSession(id: string | undefined): void;
3
4
  export declare function getMainSessionID(): string | undefined;
4
5
  /** @internal For testing only */
@@ -10,6 +10,7 @@ export declare class TaskToastManager {
10
10
  setConcurrencyManager(manager: ConcurrencyManager): void;
11
11
  addTask(task: {
12
12
  id: string;
13
+ sessionID?: string;
13
14
  description: string;
14
15
  agent: string;
15
16
  isBackground: boolean;
@@ -22,6 +23,10 @@ export declare class TaskToastManager {
22
23
  * Update task status
23
24
  */
24
25
  updateTask(id: string, status: TaskStatus): void;
26
+ /**
27
+ * Update model info for a task by session ID
28
+ */
29
+ updateTaskModelBySession(sessionID: string, modelInfo: ModelFallbackInfo): void;
25
30
  /**
26
31
  * Remove completed/error task
27
32
  */
@@ -2,11 +2,12 @@ import type { ModelSource } from "../../shared/model-resolver";
2
2
  export type TaskStatus = "running" | "queued" | "completed" | "error";
3
3
  export interface ModelFallbackInfo {
4
4
  model: string;
5
- type: "user-defined" | "inherited" | "category-default" | "system-default";
5
+ type: "user-defined" | "inherited" | "category-default" | "system-default" | "runtime-fallback";
6
6
  source?: ModelSource;
7
7
  }
8
8
  export interface TrackedTask {
9
9
  id: string;
10
+ sessionID?: string;
10
11
  description: string;
11
12
  agent: string;
12
13
  status: TaskStatus;
@@ -1,6 +1,7 @@
1
- import type { PaneAction } from "./types";
2
- import type { ActionResult, ExecuteContext } from "./action-executor-core";
3
- export type { ActionExecutorDeps, ActionResult, ExecuteContext } from "./action-executor-core";
1
+ import type { TmuxConfig } from "../../config/schema";
2
+ import type { PaneAction, WindowState } from "./types";
3
+ import type { ActionResult } from "./action-executor-core";
4
+ export type { ActionExecutorDeps, ActionResult } from "./action-executor-core";
4
5
  export interface ExecuteActionsResult {
5
6
  success: boolean;
6
7
  spawnedPaneId?: string;
@@ -9,5 +10,11 @@ export interface ExecuteActionsResult {
9
10
  result: ActionResult;
10
11
  }>;
11
12
  }
13
+ export interface ExecuteContext {
14
+ config: TmuxConfig;
15
+ serverUrl: string;
16
+ windowState: WindowState;
17
+ sourcePaneId?: string;
18
+ }
12
19
  export declare function executeAction(action: PaneAction, ctx: ExecuteContext): Promise<ActionResult>;
13
20
  export declare function executeActions(actions: PaneAction[], ctx: ExecuteContext): Promise<ExecuteActionsResult>;
@@ -1,4 +1,4 @@
1
- import type { TmuxPaneInfo } from "./types";
1
+ import type { CapacityConfig, TmuxPaneInfo } from "./types";
2
2
  export interface GridCapacity {
3
3
  cols: number;
4
4
  rows: number;
@@ -14,6 +14,8 @@ export interface GridPlan {
14
14
  slotWidth: number;
15
15
  slotHeight: number;
16
16
  }
17
- export declare function calculateCapacity(windowWidth: number, windowHeight: number, minPaneWidth?: number, mainPaneWidth?: number): GridCapacity;
18
- export declare function computeGridPlan(windowWidth: number, windowHeight: number, paneCount: number, mainPaneWidth?: number, minPaneWidth?: number): GridPlan;
17
+ type CapacityOptions = CapacityConfig | number | undefined;
18
+ export declare function calculateCapacity(windowWidth: number, windowHeight: number, options?: CapacityOptions, mainPaneWidth?: number): GridCapacity;
19
+ export declare function computeGridPlan(windowWidth: number, windowHeight: number, paneCount: number, options?: CapacityOptions, mainPaneWidth?: number): GridPlan;
19
20
  export declare function mapPaneToSlot(pane: TmuxPaneInfo, plan: GridPlan, mainPaneWidth: number): GridSlot;
21
+ export {};
@@ -33,14 +33,26 @@ export declare class TmuxSessionManager {
33
33
  private sourcePaneId;
34
34
  private sessions;
35
35
  private pendingSessions;
36
+ private spawnQueue;
37
+ private deferredSessions;
38
+ private deferredQueue;
39
+ private deferredAttachInterval?;
40
+ private deferredAttachTickScheduled;
41
+ private nullStateCount;
36
42
  private deps;
37
43
  private pollingManager;
38
44
  constructor(ctx: PluginInput, tmuxConfig: TmuxConfig, deps?: TmuxUtilDeps);
39
45
  private isEnabled;
40
46
  private getCapacityConfig;
41
47
  private getSessionMappings;
48
+ private enqueueDeferredSession;
49
+ private removeDeferredSession;
50
+ private startDeferredAttachLoop;
51
+ private stopDeferredAttachLoop;
52
+ private tryAttachDeferredSession;
42
53
  private waitForSessionReady;
43
54
  onSessionCreated(event: SessionCreatedEvent): Promise<void>;
55
+ private enqueueSpawn;
44
56
  onSessionDeleted(event: {
45
57
  sessionID: string;
46
58
  }): Promise<void>;
@@ -5,5 +5,4 @@ export declare function isSplittableAtCount(agentAreaWidth: number, paneCount: n
5
5
  export declare function findMinimalEvictions(agentAreaWidth: number, currentCount: number, minPaneWidth?: number): number | null;
6
6
  export declare function canSplitPane(pane: TmuxPaneInfo, direction: SplitDirection, minPaneWidth?: number): boolean;
7
7
  export declare function canSplitPaneAnyDirection(pane: TmuxPaneInfo, minPaneWidth?: number): boolean;
8
- export declare function canSplitPaneAnyDirectionWithMinWidth(pane: TmuxPaneInfo, minPaneWidth?: number): boolean;
9
8
  export declare function getBestSplitDirection(pane: TmuxPaneInfo, minPaneWidth?: number): SplitDirection | null;
@@ -1,6 +1,6 @@
1
- import type { SplitDirection, WindowState } from "./types";
1
+ import type { CapacityConfig, SplitDirection, WindowState } from "./types";
2
2
  export interface SpawnTarget {
3
3
  targetPaneId: string;
4
4
  splitDirection: SplitDirection;
5
5
  }
6
- export declare function findSpawnTarget(state: WindowState, minPaneWidth?: number): SpawnTarget | null;
6
+ export declare function findSpawnTarget(state: WindowState, config: CapacityConfig): SpawnTarget | null;
@@ -1,3 +1,4 @@
1
+ import type { CapacityConfig } from "./types";
1
2
  export declare const MAIN_PANE_RATIO = 0.5;
2
3
  export declare const MAX_COLS = 2;
3
4
  export declare const MAX_ROWS = 3;
@@ -5,3 +6,6 @@ export declare const MAX_GRID_SIZE = 4;
5
6
  export declare const DIVIDER_SIZE = 1;
6
7
  export declare const MIN_SPLIT_WIDTH: number;
7
8
  export declare const MIN_SPLIT_HEIGHT: number;
9
+ export declare function getMainPaneSizePercent(config?: CapacityConfig): number;
10
+ export declare function computeMainPaneWidth(windowWidth: number, config?: CapacityConfig): number;
11
+ export declare function computeAgentAreaWidth(windowWidth: number, config?: CapacityConfig): number;
@@ -48,6 +48,8 @@ export interface SpawnDecision {
48
48
  reason?: string;
49
49
  }
50
50
  export interface CapacityConfig {
51
+ layout?: string;
52
+ mainPaneSize?: number;
51
53
  mainPaneMinWidth: number;
52
54
  agentPaneWidth: number;
53
55
  }
@@ -1,3 +1,9 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
2
  import type { ModelInfo } from "./types";
3
+ type PromptContext = {
4
+ model?: ModelInfo;
5
+ tools?: Record<string, boolean>;
6
+ };
7
+ export declare function resolveRecentPromptContextForSession(ctx: PluginInput, sessionID: string): Promise<PromptContext>;
3
8
  export declare function resolveRecentModelForSession(ctx: PluginInput, sessionID: string): Promise<ModelInfo | undefined>;
9
+ export {};
@@ -1,5 +1,5 @@
1
1
  export declare const DIRECT_WORK_REMINDER: string;
2
2
  export declare const BOULDER_CONTINUATION_PROMPT: string;
3
- export declare const VERIFICATION_REMINDER = "**MANDATORY: WHAT YOU MUST DO RIGHT NOW**\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\nCRITICAL: Subagents FREQUENTLY LIE about completion.\nTests FAILING, code has ERRORS, implementation INCOMPLETE - but they say \"done\".\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n**STEP 1: AUTOMATED VERIFICATION (DO THIS FIRST)**\n\nRun these commands YOURSELF - do NOT trust agent's claims:\n1. `lsp_diagnostics` on changed files \u2192 Must be CLEAN\n2. `bash` to run tests \u2192 Must PASS\n3. `bash` to run build/typecheck \u2192 Must succeed\n\n**STEP 2: MANUAL CODE REVIEW (NON-NEGOTIABLE \u2014 DO NOT SKIP)**\n\nAutomated checks are NECESSARY but INSUFFICIENT. You MUST read the actual code.\n\n**RIGHT NOW \u2014 `Read` EVERY file the subagent touched. No exceptions.**\n\nFor EACH changed file, verify:\n1. Does the implementation logic ACTUALLY match the task requirements?\n2. Are there incomplete stubs (TODO comments, placeholder code, hardcoded values)?\n3. Are there logic errors, off-by-one bugs, or missing edge cases?\n4. Does it follow existing codebase patterns and conventions?\n5. Are imports correct? No unused or missing imports?\n6. Is error handling present where needed?\n\n**Cross-check the subagent's claims against reality:**\n- Subagent said \"Updated X\" \u2192 READ X. Is it actually updated?\n- Subagent said \"Added tests\" \u2192 READ tests. Do they test the RIGHT behavior?\n- Subagent said \"Follows patterns\" \u2192 COMPARE with reference. Does it actually?\n\n**If you cannot explain what the changed code does, you have not reviewed it.**\n**If you skip this step, you are rubber-stamping broken work.**\n\n**STEP 3: DETERMINE IF HANDS-ON QA IS NEEDED**\n\n| Deliverable Type | QA Method | Tool |\n|------------------|-----------|------|\n| **Frontend/UI** | Browser interaction | `/playwright` skill |\n| **TUI/CLI** | Run interactively | `interactive_bash` (tmux) |\n| **API/Backend** | Send real requests | `bash` with curl |\n\nStatic analysis CANNOT catch: visual bugs, animation issues, user flow breakages.\n\n**STEP 4: IF QA IS NEEDED - ADD TO TODO IMMEDIATELY**\n\n```\ntodowrite([\n { id: \"qa-X\", content: \"HANDS-ON QA: [specific verification action]\", status: \"pending\", priority: \"high\" }\n])\n```\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n**BLOCKING: DO NOT proceed until Steps 1-4 are ALL completed.**\n**Skipping Step 2 (manual code review) = unverified work = FAILURE.**";
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
4
  export declare const ORCHESTRATOR_DELEGATION_REQUIRED: string;
5
5
  export declare const SINGLE_TASK_DIRECTIVE: string;
@@ -0,0 +1,28 @@
1
+ interface HashlineEditDiffEnhancerConfig {
2
+ hashline_edit?: {
3
+ enabled: boolean;
4
+ };
5
+ }
6
+ type BeforeInput = {
7
+ tool: string;
8
+ sessionID: string;
9
+ callID: string;
10
+ };
11
+ type BeforeOutput = {
12
+ args: Record<string, unknown>;
13
+ };
14
+ type AfterInput = {
15
+ tool: string;
16
+ sessionID: string;
17
+ callID: string;
18
+ };
19
+ type AfterOutput = {
20
+ title: string;
21
+ output: string;
22
+ metadata: Record<string, unknown>;
23
+ };
24
+ export declare function createHashlineEditDiffEnhancerHook(config: HashlineEditDiffEnhancerConfig): {
25
+ "tool.execute.before": (input: BeforeInput, output: BeforeOutput) => Promise<void>;
26
+ "tool.execute.after": (input: AfterInput, output: AfterOutput) => Promise<void>;
27
+ };
28
+ export {};
@@ -0,0 +1 @@
1
+ export { createHashlineEditDiffEnhancerHook } from "./hook";
@@ -13,6 +13,7 @@ export { createDirectoryReadmeInjectorHook } from "./directory-readme-injector";
13
13
  export { createEmptyTaskResponseDetectorHook } from "./empty-task-response-detector";
14
14
  export { createAnthropicContextWindowLimitRecoveryHook, type AnthropicContextWindowLimitRecoveryOptions } from "./anthropic-context-window-limit-recovery";
15
15
  export { createThinkModeHook } from "./think-mode";
16
+ export { createModelFallbackHook, setPendingModelFallback, clearPendingModelFallback, type ModelFallbackState } from "./model-fallback/hook";
16
17
  export { createClaudeCodeHooksHook } from "./claude-code-hooks";
17
18
  export { createRulesInjectorHook } from "./rules-injector";
18
19
  export { createBackgroundNotificationHook } from "./background-notification";
@@ -24,10 +25,10 @@ export { createInteractiveBashSessionHook } from "./interactive-bash-session";
24
25
  export { createThinkingBlockValidatorHook } from "./thinking-block-validator";
25
26
  export { createCategorySkillReminderHook } from "./category-skill-reminder";
26
27
  export { createRalphLoopHook, type RalphLoopHook } from "./ralph-loop";
27
- export { createSisyphusGptHephaestusReminderHook } from "./sisyphus-gpt-hephaestus-reminder";
28
+ export { createNoSisyphusGptHook } from "./no-sisyphus-gpt";
29
+ export { createNoHephaestusNonGptHook } from "./no-hephaestus-non-gpt";
28
30
  export { createAutoSlashCommandHook } from "./auto-slash-command";
29
31
  export { createEditErrorRecoveryHook } from "./edit-error-recovery";
30
- export { createJsonErrorRecoveryHook } from "./json-error-recovery";
31
32
  export { createPrometheusMdOnlyHook } from "./prometheus-md-only";
32
33
  export { createSisyphusJuniorNotepadHook } from "./sisyphus-junior-notepad";
33
34
  export { createTaskResumeInfoHook } from "./task-resume-info";
@@ -41,5 +42,7 @@ export { createCompactionTodoPreserverHook } from "./compaction-todo-preserver";
41
42
  export { createUnstableAgentBabysitterHook } from "./unstable-agent-babysitter";
42
43
  export { createPreemptiveCompactionHook } from "./preemptive-compaction";
43
44
  export { createTasksTodowriteDisablerHook } from "./tasks-todowrite-disabler";
45
+ export { createRuntimeFallbackHook, type RuntimeFallbackHook, type RuntimeFallbackOptions } from "./runtime-fallback";
44
46
  export { createWriteExistingFileGuardHook } from "./write-existing-file-guard";
45
47
  export { createHashlineReadEnhancerHook } from "./hashline-read-enhancer";
48
+ export { createJsonErrorRecoveryHook, JSON_ERROR_TOOL_EXCLUDE_LIST, JSON_ERROR_PATTERNS, JSON_ERROR_REMINDER } from "./json-error-recovery";
@@ -0,0 +1,60 @@
1
+ import type { FallbackEntry } from "../../shared/model-requirements";
2
+ import type { ChatMessageInput, ChatMessageHandlerOutput } from "../../plugin/chat-message";
3
+ type FallbackToast = (input: {
4
+ title: string;
5
+ message: string;
6
+ variant?: "info" | "success" | "warning" | "error";
7
+ duration?: number;
8
+ }) => void | Promise<void>;
9
+ type FallbackCallback = (input: {
10
+ sessionID: string;
11
+ providerID: string;
12
+ modelID: string;
13
+ variant?: string;
14
+ }) => void | Promise<void>;
15
+ export type ModelFallbackState = {
16
+ providerID: string;
17
+ modelID: string;
18
+ fallbackChain: FallbackEntry[];
19
+ attemptCount: number;
20
+ pending: boolean;
21
+ };
22
+ export declare function setSessionFallbackChain(sessionID: string, fallbackChain: FallbackEntry[] | undefined): void;
23
+ export declare function clearSessionFallbackChain(sessionID: string): void;
24
+ /**
25
+ * Sets a pending model fallback for a session.
26
+ * Called when a model error is detected in session.error handler.
27
+ */
28
+ export declare function setPendingModelFallback(sessionID: string, agentName: string, currentProviderID: string, currentModelID: string): boolean;
29
+ /**
30
+ * Gets the next fallback model for a session.
31
+ * Increments attemptCount each time called.
32
+ */
33
+ export declare function getNextFallback(sessionID: string): {
34
+ providerID: string;
35
+ modelID: string;
36
+ variant?: string;
37
+ } | null;
38
+ /**
39
+ * Clears the pending fallback for a session.
40
+ * Called after fallback is successfully applied.
41
+ */
42
+ export declare function clearPendingModelFallback(sessionID: string): void;
43
+ /**
44
+ * Checks if there's a pending fallback for a session.
45
+ */
46
+ export declare function hasPendingModelFallback(sessionID: string): boolean;
47
+ /**
48
+ * Gets the current fallback state for a session (for debugging).
49
+ */
50
+ export declare function getFallbackState(sessionID: string): ModelFallbackState | undefined;
51
+ /**
52
+ * Creates a chat.message hook that applies model fallbacks when pending.
53
+ */
54
+ export declare function createModelFallbackHook(args?: {
55
+ toast?: FallbackToast;
56
+ onApplied?: FallbackCallback;
57
+ }): {
58
+ "chat.message": (input: ChatMessageInput, output: ChatMessageHandlerOutput) => Promise<void>;
59
+ };
60
+ export {};
@@ -0,0 +1,16 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ export declare function createNoHephaestusNonGptHook(ctx: PluginInput): {
3
+ "chat.message": (input: {
4
+ sessionID: string;
5
+ agent?: string;
6
+ model?: {
7
+ providerID: string;
8
+ modelID: string;
9
+ };
10
+ }, output?: {
11
+ message?: {
12
+ agent?: string;
13
+ [key: string]: unknown;
14
+ };
15
+ }) => Promise<void>;
16
+ };
@@ -0,0 +1 @@
1
+ export { createNoHephaestusNonGptHook } from "./hook";
@@ -1,5 +1,5 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
- export declare function createSisyphusGptHephaestusReminderHook(ctx: PluginInput): {
2
+ export declare function createNoSisyphusGptHook(ctx: PluginInput): {
3
3
  "chat.message": (input: {
4
4
  sessionID: string;
5
5
  agent?: string;
@@ -7,5 +7,10 @@ export declare function createSisyphusGptHephaestusReminderHook(ctx: PluginInput
7
7
  providerID: string;
8
8
  modelID: string;
9
9
  };
10
+ }, output?: {
11
+ message?: {
12
+ agent?: string;
13
+ [key: string]: unknown;
14
+ };
10
15
  }) => Promise<void>;
11
16
  };
@@ -0,0 +1 @@
1
+ export { createNoSisyphusGptHook } from "./hook";
@@ -0,0 +1,8 @@
1
+ export type RalphLoopStrategy = "reset" | "continue";
2
+ export type ParsedRalphLoopArguments = {
3
+ prompt: string;
4
+ maxIterations?: number;
5
+ completionPromise?: string;
6
+ strategy?: RalphLoopStrategy;
7
+ };
8
+ export declare function parseRalphLoopArguments(rawArguments: string): ParsedRalphLoopArguments;
@@ -4,4 +4,5 @@ export declare function injectContinuationPrompt(ctx: PluginInput, options: {
4
4
  prompt: string;
5
5
  directory: string;
6
6
  apiTimeoutMs: number;
7
+ inheritFromSessionID?: string;
7
8
  }): Promise<void>;
@@ -0,0 +1,12 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ import type { RalphLoopState } from "./types";
3
+ type ContinuationOptions = {
4
+ directory: string;
5
+ apiTimeoutMs: number;
6
+ previousSessionID: string;
7
+ loopState: {
8
+ setSessionID: (sessionID: string) => RalphLoopState | null;
9
+ };
10
+ };
11
+ export declare function continueIteration(ctx: PluginInput, state: RalphLoopState, options: ContinuationOptions): Promise<void>;
12
+ export {};
@@ -8,9 +8,11 @@ export declare function createLoopStateController(options: {
8
8
  maxIterations?: number;
9
9
  completionPromise?: string;
10
10
  ultrawork?: boolean;
11
+ strategy?: "reset" | "continue";
11
12
  }): boolean;
12
13
  cancelLoop(sessionID: string): boolean;
13
14
  getState(): RalphLoopState | null;
14
15
  clear(): boolean;
15
16
  incrementIteration(): RalphLoopState | null;
17
+ setSessionID(sessionID: string): RalphLoopState | null;
16
18
  };
@@ -9,6 +9,7 @@ type LoopStateController = {
9
9
  getState: () => RalphLoopState | null;
10
10
  clear: () => boolean;
11
11
  incrementIteration: () => RalphLoopState | null;
12
+ setSessionID: (sessionID: string) => RalphLoopState | null;
12
13
  };
13
14
  type RalphLoopEventHandlerOptions = {
14
15
  directory: string;
@@ -11,6 +11,7 @@ export interface RalphLoopHook {
11
11
  maxIterations?: number;
12
12
  completionPromise?: string;
13
13
  ultrawork?: boolean;
14
+ strategy?: "reset" | "continue";
14
15
  }) => boolean;
15
16
  cancelLoop: (sessionID: string) => boolean;
16
17
  getState: () => RalphLoopState | null;
@@ -0,0 +1,3 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ export declare function createIterationSession(ctx: PluginInput, parentSessionID: string, directory: string): Promise<string | null>;
3
+ export declare function selectSessionInTui(client: PluginInput["client"], sessionID: string): Promise<boolean>;
@@ -8,6 +8,7 @@ export interface RalphLoopState {
8
8
  prompt: string;
9
9
  session_id?: string;
10
10
  ultrawork?: boolean;
11
+ strategy?: "reset" | "continue";
11
12
  }
12
13
  export interface RalphLoopOptions {
13
14
  config?: RalphLoopConfig;
@@ -0,0 +1,5 @@
1
+ export declare const AGENT_NAMES: string[];
2
+ export declare const agentPattern: RegExp;
3
+ export declare function detectAgentFromSession(sessionID: string): string | undefined;
4
+ export declare function normalizeAgentName(agent: string | undefined): string | undefined;
5
+ export declare function resolveAgentForSession(sessionID: string, eventAgent?: string): string | undefined;
@@ -0,0 +1,10 @@
1
+ import type { HookDeps } from "./types";
2
+ export declare function createAutoRetryHelpers(deps: HookDeps): {
3
+ abortSessionRequest: (sessionID: string, source: string) => Promise<void>;
4
+ clearSessionFallbackTimeout: (sessionID: string) => void;
5
+ scheduleSessionFallbackTimeout: (sessionID: string, resolvedAgent?: string) => void;
6
+ autoRetryWithFallback: (sessionID: string, newModel: string, resolvedAgent: string | undefined, source: string) => Promise<void>;
7
+ resolveAgentForSessionFromContext: (sessionID: string, eventAgent?: string) => Promise<string | undefined>;
8
+ cleanupStaleSessions: () => void;
9
+ };
10
+ export type AutoRetryHelpers = ReturnType<typeof createAutoRetryHelpers>;
@@ -0,0 +1,20 @@
1
+ import type { HookDeps } from "./types";
2
+ export declare function createChatMessageHandler(deps: HookDeps): (input: {
3
+ sessionID: string;
4
+ agent?: string;
5
+ model?: {
6
+ providerID: string;
7
+ modelID: string;
8
+ };
9
+ }, output: {
10
+ message: {
11
+ model?: {
12
+ providerID: string;
13
+ modelID: string;
14
+ };
15
+ };
16
+ parts?: Array<{
17
+ type: string;
18
+ text?: string;
19
+ }>;
20
+ }) => Promise<void>;