@wolfx/oh-my-openagent 4.1.2 → 4.2.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 (163) hide show
  1. package/README.ja.md +1 -0
  2. package/README.ko.md +1 -0
  3. package/README.md +1 -0
  4. package/README.ru.md +1 -0
  5. package/README.zh-cn.md +1 -0
  6. package/dist/agents/atlas/default-prompt-sections.d.ts +3 -3
  7. package/dist/agents/atlas/gemini-prompt-sections.d.ts +2 -2
  8. package/dist/agents/atlas/gpt-prompt-sections.d.ts +2 -2
  9. package/dist/agents/atlas/kimi-prompt-sections.d.ts +3 -3
  10. package/dist/agents/atlas/opus-4-7-prompt-sections.d.ts +3 -3
  11. package/dist/agents/momus.d.ts +1 -1
  12. package/dist/agents/prometheus/behavioral-summary.d.ts +1 -1
  13. package/dist/agents/prometheus/high-accuracy-mode.d.ts +1 -1
  14. package/dist/agents/prometheus/identity-constraints.d.ts +1 -1
  15. package/dist/agents/prometheus/plan-generation.d.ts +1 -1
  16. package/dist/agents/prometheus/plan-template.d.ts +1 -1
  17. package/dist/config/schema/team-mode.d.ts +1 -1
  18. package/dist/features/background-agent/error-classifier.d.ts +1 -0
  19. package/dist/features/background-agent/fallback-retry-handler.d.ts +15 -0
  20. package/dist/features/background-agent/manager.d.ts +11 -8
  21. package/dist/features/background-agent/parent-wake-notifier.d.ts +74 -0
  22. package/dist/features/background-agent/process-cleanup.d.ts +2 -0
  23. package/dist/features/background-agent/session-route.d.ts +12 -0
  24. package/dist/features/background-agent/spawner.d.ts +2 -2
  25. package/dist/features/background-agent/task-registry.d.ts +6 -0
  26. package/dist/features/background-agent/types.d.ts +2 -0
  27. package/dist/features/boulder-state/constants.d.ts +4 -4
  28. package/dist/features/boulder-state/storage.d.ts +1 -1
  29. package/dist/features/builtin-commands/templates/init-deep.d.ts +1 -1
  30. package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
  31. package/dist/features/context-injector/injector.d.ts +1 -1
  32. package/dist/features/opencode-skill-loader/git-master-template-injection.d.ts +18 -0
  33. package/dist/features/run-continuation-state/constants.d.ts +1 -1
  34. package/dist/features/team-mode/team-layout-tmux/resolve-caller-tmux-session.d.ts +3 -1
  35. package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +3 -3
  36. package/dist/features/team-mode/tools/messaging.d.ts +1 -0
  37. package/dist/features/team-mode/types.d.ts +2 -2
  38. package/dist/features/tmux-subagent/attachable-session-status.d.ts +1 -1
  39. package/dist/features/tmux-subagent/manager.d.ts +6 -0
  40. package/dist/features/tmux-subagent/pane-state-parser.d.ts +2 -0
  41. package/dist/features/tmux-subagent/polling-manager.d.ts +6 -2
  42. package/dist/features/tmux-subagent/types.d.ts +4 -0
  43. package/dist/hooks/atlas/boulder-continuation-injector.d.ts +1 -0
  44. package/dist/hooks/atlas/omo-path.d.ts +6 -0
  45. package/dist/hooks/atlas/tool-execute-after.d.ts +3 -0
  46. package/dist/hooks/atlas/tool-progress.d.ts +14 -0
  47. package/dist/hooks/atlas/types.d.ts +7 -0
  48. package/dist/hooks/auto-slash-command/detector.d.ts +2 -0
  49. package/dist/hooks/auto-update-checker/cache.d.ts +8 -1
  50. package/dist/hooks/auto-update-checker/checker/cached-version.d.ts +8 -1
  51. package/dist/hooks/background-notification/hook.d.ts +0 -6
  52. package/dist/hooks/compaction-context-injector/types.d.ts +1 -0
  53. package/dist/hooks/interactive-bash-session/state-manager.d.ts +1 -1
  54. package/dist/hooks/json-error-recovery/hook.d.ts +1 -1
  55. package/dist/hooks/keyword-detector/detector.d.ts +1 -0
  56. package/dist/hooks/keyword-detector/ultrawork/default.d.ts +1 -1
  57. package/dist/hooks/keyword-detector/ultrawork/gemini.d.ts +1 -1
  58. package/dist/hooks/keyword-detector/ultrawork/planner.d.ts +1 -1
  59. package/dist/hooks/prometheus-md-only/constants.d.ts +1 -1
  60. package/dist/hooks/prometheus-md-only/path-policy.d.ts +3 -3
  61. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +11 -0
  62. package/dist/hooks/ralph-loop/constants.d.ts +1 -1
  63. package/dist/hooks/ralph-loop/continuation-prompt-injector.d.ts +4 -0
  64. package/dist/hooks/ralph-loop/iteration-continuation.d.ts +4 -0
  65. package/dist/hooks/rules-injector/injector.d.ts +9 -2
  66. package/dist/hooks/rules-injector/matcher.d.ts +5 -0
  67. package/dist/hooks/rules-injector/project-root-finder.d.ts +4 -0
  68. package/dist/hooks/rules-injector/rule-scan-cache.d.ts +9 -2
  69. package/dist/hooks/runtime-fallback/constants.d.ts +10 -0
  70. package/dist/hooks/runtime-fallback/first-prompt-watchdog.d.ts +25 -0
  71. package/dist/hooks/runtime-fallback/hook.d.ts +14 -1
  72. package/dist/hooks/runtime-fallback/last-user-retry-parts.d.ts +10 -2
  73. package/dist/hooks/runtime-fallback/types.d.ts +10 -0
  74. package/dist/hooks/session-recovery/detect-error-type.d.ts +1 -1
  75. package/dist/hooks/session-recovery/hook.d.ts +1 -0
  76. package/dist/hooks/session-recovery/interrupted-idle-message-fetch-timeout.d.ts +7 -0
  77. package/dist/hooks/session-recovery/recover-tool-result-missing.d.ts +6 -1
  78. package/dist/hooks/session-recovery/types.d.ts +12 -0
  79. package/dist/hooks/shared/prompt-async-gate.d.ts +1 -0
  80. package/dist/hooks/shared/session-idle-settle.d.ts +1 -11
  81. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  82. package/dist/hooks/team-mode-status-injector/hook.d.ts +2 -1
  83. package/dist/hooks/todo-continuation-enforcer/pending-question-detection.d.ts +2 -0
  84. package/dist/hooks/todo-continuation-enforcer/session-state.d.ts +3 -4
  85. package/dist/hooks/todo-continuation-enforcer/types.d.ts +2 -3
  86. package/dist/hooks/tool-pair-validator/hook.d.ts +7 -2
  87. package/dist/hooks/unstable-agent-babysitter/task-message-analyzer.d.ts +1 -0
  88. package/dist/hooks/write-existing-file-guard/tool-execute-before-handler.d.ts +1 -0
  89. package/dist/index.d.ts +1 -1
  90. package/dist/index.js +44361 -78083
  91. package/dist/mcp/index.d.ts +3 -1
  92. package/dist/mcp/lsp.d.ts +13 -0
  93. package/dist/mcp/types.d.ts +1 -0
  94. package/dist/plugin/build-team-idle-wake-hint-client.d.ts +12 -0
  95. package/dist/plugin/chat-message.d.ts +1 -1
  96. package/dist/plugin/tool-registry.d.ts +1 -2
  97. package/dist/plugin-dispose.d.ts +0 -3
  98. package/dist/shared/agent-sort-shim.d.ts +1 -0
  99. package/dist/shared/delegated-child-session-bootstrap.d.ts +25 -0
  100. package/dist/shared/dynamic-truncator.d.ts +2 -0
  101. package/dist/shared/host-skill-config.d.ts +2 -0
  102. package/dist/shared/index.d.ts +2 -0
  103. package/dist/shared/internal-initiator-marker.d.ts +25 -0
  104. package/dist/shared/legacy-workspace-migration.d.ts +5 -0
  105. package/dist/shared/logger.d.ts +12 -0
  106. package/dist/shared/model-error-classifier.d.ts +2 -0
  107. package/dist/shared/model-resolution-pipeline.d.ts +4 -0
  108. package/dist/shared/opencode-http-api.d.ts +9 -0
  109. package/dist/shared/prompt-async-gate.d.ts +82 -0
  110. package/dist/shared/replace-tool-args.d.ts +13 -0
  111. package/dist/shared/session-idle-settle.d.ts +11 -0
  112. package/dist/shared/tmux/tmux-utils/pane-activate.d.ts +1 -0
  113. package/dist/shared/tmux/tmux-utils/pane-close.d.ts +10 -0
  114. package/dist/shared/tmux/tmux-utils/pane-command.d.ts +2 -0
  115. package/dist/shared/tmux/tmux-utils/pane-replace.d.ts +11 -1
  116. package/dist/shared/tmux/tmux-utils/pane-spawn.d.ts +1 -1
  117. package/dist/shared/tmux/tmux-utils/server-health.d.ts +12 -1
  118. package/dist/shared/tmux/tmux-utils/session-spawn.d.ts +2 -2
  119. package/dist/shared/tmux/tmux-utils/window-spawn.d.ts +1 -1
  120. package/dist/shared/tmux/tmux-utils.d.ts +2 -0
  121. package/dist/testing/create-plugin-module.d.ts +41 -0
  122. package/dist/tools/background-task/constants.d.ts +1 -1
  123. package/dist/tools/background-task/with-sdk-call-timeout.d.ts +7 -0
  124. package/dist/tools/call-omo-agent/session-creator.d.ts +2 -1
  125. package/dist/tools/call-omo-agent/sync-executor.d.ts +2 -2
  126. package/dist/tools/delegate-task/subagent-discovery.d.ts +1 -0
  127. package/dist/tools/delegate-task/sync-prompt-sender.d.ts +2 -1
  128. package/dist/tools/delegate-task/sync-session-creator.d.ts +2 -0
  129. package/dist/tools/delegate-task/sync-task.d.ts +1 -1
  130. package/dist/tools/index.d.ts +0 -3
  131. package/dist/tools/interactive-bash/tools.d.ts +5 -0
  132. package/package.json +4 -2
  133. package/dist/hooks/atlas/sisyphus-path.d.ts +0 -6
  134. package/dist/tools/lsp/client.d.ts +0 -3
  135. package/dist/tools/lsp/config.d.ts +0 -3
  136. package/dist/tools/lsp/constants.d.ts +0 -6
  137. package/dist/tools/lsp/diagnostics-tool.d.ts +0 -2
  138. package/dist/tools/lsp/directory-diagnostics.d.ts +0 -1
  139. package/dist/tools/lsp/find-references-tool.d.ts +0 -2
  140. package/dist/tools/lsp/goto-definition-tool.d.ts +0 -2
  141. package/dist/tools/lsp/index.d.ts +0 -8
  142. package/dist/tools/lsp/infer-extension.d.ts +0 -1
  143. package/dist/tools/lsp/language-config.d.ts +0 -1
  144. package/dist/tools/lsp/language-mappings.d.ts +0 -3
  145. package/dist/tools/lsp/lsp-client-connection.d.ts +0 -4
  146. package/dist/tools/lsp/lsp-client-transport.d.ts +0 -22
  147. package/dist/tools/lsp/lsp-client-wrapper.d.ts +0 -9
  148. package/dist/tools/lsp/lsp-client.d.ts +0 -17
  149. package/dist/tools/lsp/lsp-formatters.d.ts +0 -13
  150. package/dist/tools/lsp/lsp-manager-process-cleanup.d.ts +0 -15
  151. package/dist/tools/lsp/lsp-manager-temp-directory-cleanup.d.ts +0 -8
  152. package/dist/tools/lsp/lsp-process.d.ts +0 -29
  153. package/dist/tools/lsp/lsp-server.d.ts +0 -24
  154. package/dist/tools/lsp/rename-tools.d.ts +0 -3
  155. package/dist/tools/lsp/server-config-loader.d.ts +0 -25
  156. package/dist/tools/lsp/server-definitions.d.ts +0 -3
  157. package/dist/tools/lsp/server-installation.d.ts +0 -1
  158. package/dist/tools/lsp/server-path-bases.d.ts +0 -1
  159. package/dist/tools/lsp/server-resolution.d.ts +0 -15
  160. package/dist/tools/lsp/symbols-tool.d.ts +0 -2
  161. package/dist/tools/lsp/tools.d.ts +0 -5
  162. package/dist/tools/lsp/types.d.ts +0 -123
  163. package/dist/tools/lsp/workspace-edit.d.ts +0 -8
@@ -3,6 +3,7 @@ export declare function isAbortedSessionError(error: unknown): boolean;
3
3
  export declare function getErrorText(error: unknown): string;
4
4
  export declare function extractErrorName(error: unknown): string | undefined;
5
5
  export declare function extractErrorMessage(error: unknown): string | undefined;
6
+ export declare function extractErrorStatusCode(error: unknown): number | undefined;
6
7
  interface EventPropertiesLike {
7
8
  [key: string]: unknown;
8
9
  }
@@ -1,11 +1,25 @@
1
1
  import type { BackgroundTask } from "./types";
2
2
  import type { ConcurrencyManager } from "./concurrency";
3
3
  import type { OpencodeClient, QueueItem } from "./constants";
4
+ import { log, readConnectedProvidersCache, readProviderModelsCache } from "../../shared";
5
+ import { shouldRetryError, getNextFallback, hasMoreFallbacks, selectFallbackProvider } from "../../shared/model-error-classifier";
6
+ import { transformModelForProvider } from "../../shared/provider-model-id-transform";
7
+ export type FallbackRetryHandlerDeps = {
8
+ log: typeof log;
9
+ readProviderModelsCache: typeof readProviderModelsCache;
10
+ readConnectedProvidersCache: typeof readConnectedProvidersCache;
11
+ shouldRetryError: typeof shouldRetryError;
12
+ getNextFallback: typeof getNextFallback;
13
+ hasMoreFallbacks: typeof hasMoreFallbacks;
14
+ selectFallbackProvider: typeof selectFallbackProvider;
15
+ transformModelForProvider: typeof transformModelForProvider;
16
+ };
4
17
  export declare function tryFallbackRetry(args: {
5
18
  task: BackgroundTask;
6
19
  errorInfo: {
7
20
  name?: string;
8
21
  message?: string;
22
+ statusCode?: number;
9
23
  };
10
24
  source: string;
11
25
  concurrencyManager: ConcurrencyManager;
@@ -21,4 +35,5 @@ export declare function tryFallbackRetry(args: {
21
35
  failedError?: string;
22
36
  nextModel: string;
23
37
  }) => void;
38
+ deps?: Partial<FallbackRetryHandlerDeps>;
24
39
  }): Promise<boolean>;
@@ -1,10 +1,10 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
+ import type { BackgroundTaskConfig, TmuxConfig } from "../../config/schema";
2
3
  import type { ModelFallbackControllerAccessor } from "../../hooks/model-fallback";
3
- import type { BackgroundTask, LaunchInput, ResumeInput } from "./types";
4
- import { TaskHistory } from "./task-history";
5
4
  import { log } from "../../shared";
6
- import type { BackgroundTaskConfig, TmuxConfig } from "../../config/schema";
7
5
  import { type SubagentSpawnContext } from "./subagent-spawn-limits";
6
+ import { TaskHistory } from "./task-history";
7
+ import type { BackgroundTask, LaunchInput, ResumeInput } from "./types";
8
8
  interface EventProperties {
9
9
  sessionID?: string;
10
10
  info?: {
@@ -56,8 +56,7 @@ export declare class BackgroundManager {
56
56
  private completedTaskSummaries;
57
57
  private idleDeferralTimers;
58
58
  private notificationQueueByParent;
59
- private pendingParentWakes;
60
- private pendingParentWakeTimers;
59
+ private readonly parentWakeNotifier;
61
60
  private observedOutputSessions;
62
61
  private observedIncompleteTodosBySession;
63
62
  private rootDescendantCounts;
@@ -86,6 +85,8 @@ export declare class BackgroundManager {
86
85
  private removeTask;
87
86
  private archiveCompletedTask;
88
87
  private updateTaskParent;
88
+ private captureResumeTaskSnapshot;
89
+ private restoreTaskAfterSkippedResume;
89
90
  private removeTaskFromParentIndex;
90
91
  launch(input: LaunchInput): Promise<BackgroundTask>;
91
92
  private processKey;
@@ -113,17 +114,20 @@ export declare class BackgroundManager {
113
114
  resume(input: ResumeInput): Promise<BackgroundTask>;
114
115
  private checkSessionTodos;
115
116
  private markSessionOutputObserved;
117
+ private clearDispatchedParentWake;
118
+ private requeueDispatchedParentWake;
116
119
  private clearSessionOutputObserved;
117
120
  private clearSessionTodoObservation;
118
121
  private hasOutputSignalFromPart;
119
122
  handleEvent(event: Event): void;
123
+ private interruptTaskFromAsyncPromptFailure;
120
124
  private handleSessionErrorEvent;
121
125
  private tryFallbackRetry;
122
126
  markForNotification(task: BackgroundTask): void;
123
127
  getPendingNotifications(sessionID: string): BackgroundTask[];
124
128
  clearNotifications(sessionID: string): void;
125
129
  queuePendingNotification(sessionID: string | undefined, notification: string): void;
126
- injectPendingNotificationsIntoChatMessage(output: {
130
+ injectPendingNotificationsIntoChatMessage(_output: {
127
131
  parts: Array<{
128
132
  type: string;
129
133
  text?: string;
@@ -172,11 +176,10 @@ export declare class BackgroundManager {
172
176
  */
173
177
  private tryCompleteTask;
174
178
  private notifyParentSession;
179
+ private resolveParentWakePromptContext;
175
180
  private isSessionActive;
176
181
  private queuePendingParentWake;
177
182
  private flushPendingParentWake;
178
- private schedulePendingParentWakeFlush;
179
- private clearPendingParentWakeTimer;
180
183
  private hasRunningTasks;
181
184
  private pruneStaleTasksAndNotifications;
182
185
  private checkAndInterruptStaleTasks;
@@ -0,0 +1,74 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ type OpencodeClient = PluginInput["client"];
3
+ export type ParentWakePromptContext = {
4
+ agent?: string;
5
+ model?: {
6
+ providerID: string;
7
+ modelID: string;
8
+ };
9
+ variant?: string;
10
+ tools?: Record<string, boolean>;
11
+ };
12
+ export type PendingParentWake = {
13
+ promptContext: ParentWakePromptContext;
14
+ notifications: string[];
15
+ shouldReply: boolean;
16
+ dispatchedAt?: number;
17
+ toolCallDeferralStartedAt?: number;
18
+ };
19
+ type ParentWakeNotifierDeps = {
20
+ client: OpencodeClient;
21
+ directory: string;
22
+ enqueueNotificationForParent: (parentSessionID: string | undefined, operation: () => Promise<void>) => Promise<void>;
23
+ };
24
+ type ParentWakeNotifierOptions = {
25
+ pendingRetryMs: number;
26
+ acceptedMessageSkewMs: number;
27
+ toolCallDeferMaxMs: number;
28
+ failureRequeueWindowMs: number;
29
+ /**
30
+ * If the latest message in the parent session is a `user` message added
31
+ * within this window, the parent-wake injection is deferred. Prevents the
32
+ * race where a parent-wake `dispatchInternalPrompt` collides with a fresh
33
+ * user prompt, which on macOS/Electron has triggered native SIGABRT crashes
34
+ * inside OpenCode's `@parcel/watcher` TSFN callback path. See issue #4120.
35
+ */
36
+ userMessageInProgressWindowMs: number;
37
+ };
38
+ export declare class ParentWakeNotifier {
39
+ private readonly deps;
40
+ private readonly options;
41
+ private pendingParentWakes;
42
+ private pendingParentWakeTimers;
43
+ private dispatchedParentWakes;
44
+ private dispatchedParentWakeTimers;
45
+ constructor(deps: ParentWakeNotifierDeps, options: ParentWakeNotifierOptions);
46
+ getPendingParentWakes(): Map<string, PendingParentWake>;
47
+ getPendingParentWakeTimers(): Map<string, ReturnType<typeof setTimeout>>;
48
+ getDispatchedParentWakes(): Map<string, PendingParentWake>;
49
+ getDispatchedParentWakeTimers(): Map<string, ReturnType<typeof setTimeout>>;
50
+ queuePendingParentWake(sessionID: string, notification: string, promptContext: ParentWakePromptContext, shouldReply: boolean, delayMs?: number): void;
51
+ flushPendingParentWake(sessionID: string): Promise<void>;
52
+ clearDispatchedParentWake(sessionID: string): void;
53
+ requeueDispatchedParentWake(sessionID: string, reason: string): Promise<boolean>;
54
+ schedulePendingParentWakeFlush(sessionID: string, delayMs?: number): void;
55
+ clearPendingParentWakeTimer(sessionID: string): void;
56
+ shutdown(): void;
57
+ private isSessionActive;
58
+ private resolveParentWakePromptContext;
59
+ private cloneParentWake;
60
+ private trackDispatchedParentWake;
61
+ private loadParentWakeSessionMessages;
62
+ private getParentWakeMessageRole;
63
+ private getParentWakeMessageFinish;
64
+ private getParentWakeMessageCreatedAt;
65
+ private parentWakePartIsWaitingOnTool;
66
+ private latestAssistantTurnIsWaitingOnTools;
67
+ private parentWakeMessageHasOutput;
68
+ private parentWakeMessageContainsNotification;
69
+ private isUserMessageInProgress;
70
+ private shouldDeferParentWakeForSessionHistory;
71
+ private hasAcceptedMessageAfterDispatchedParentWake;
72
+ private requeueWake;
73
+ }
74
+ export {};
@@ -2,6 +2,8 @@
2
2
  export declare function __disableScheduledForcedExitForTesting(): void;
3
3
  /** @internal test-only */
4
4
  export declare function __enableScheduledForcedExitForTesting(): void;
5
+ /** @internal test-only seam: exposes the error normalizer used by registerErrorEvent. */
6
+ export declare function describeProcessCleanupError(error: unknown): Record<string, unknown>;
5
7
  interface CleanupTarget {
6
8
  shutdown(): void | Promise<void>;
7
9
  }
@@ -0,0 +1,12 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ import { promptWithModelSuggestionRetry } from "../../shared";
3
+ type OpencodeClient = PluginInput["client"];
4
+ type PromptAsyncArgs = Parameters<OpencodeClient["session"]["promptAsync"]>[0];
5
+ type PromptRetryClient = Parameters<typeof promptWithModelSuggestionRetry>[0];
6
+ type PromptRetryArgs = Parameters<typeof promptWithModelSuggestionRetry>[1];
7
+ type SessionMessagesArgs = Parameters<OpencodeClient["session"]["messages"]>[0];
8
+ export declare function routeSessionPrompt(args: PromptAsyncArgs, directory: string): PromptAsyncArgs;
9
+ export declare function promptAsyncInDirectory(client: OpencodeClient, args: PromptAsyncArgs, directory: string): Promise<unknown>;
10
+ export declare function promptWithRetryInDirectory(client: PromptRetryClient, args: PromptRetryArgs, directory: string): Promise<void>;
11
+ export declare function messagesInDirectory(client: OpencodeClient, args: SessionMessagesArgs, directory: string): Promise<unknown>;
12
+ export {};
@@ -1,6 +1,6 @@
1
- import type { BackgroundTask, LaunchInput, ResumeInput } from "./types";
2
- import type { OpencodeClient, OnSubagentSessionCreated, QueueItem } from "./constants";
3
1
  import type { ConcurrencyManager } from "./concurrency";
2
+ import type { OnSubagentSessionCreated, OpencodeClient, QueueItem } from "./constants";
3
+ import type { BackgroundTask, LaunchInput, ResumeInput } from "./types";
4
4
  export declare const FALLBACK_AGENT = "general";
5
5
  export declare function isAgentNotFoundError(error: unknown): boolean;
6
6
  export declare function buildFallbackBody(originalBody: Record<string, unknown>, fallbackAgent: string, options?: {
@@ -0,0 +1,6 @@
1
+ import type { BackgroundTask } from "./types";
2
+ export declare function rememberBackgroundTask(task: BackgroundTask): void;
3
+ export declare function archiveBackgroundTask(task: BackgroundTask): void;
4
+ export declare function getRegisteredBackgroundTask(taskID: string): BackgroundTask | undefined;
5
+ export declare function forgetBackgroundTask(taskID: string): void;
6
+ export declare function clearBackgroundTaskRegistryForTesting(): void;
@@ -64,6 +64,8 @@ export interface BackgroundTask {
64
64
  parentAgent?: string;
65
65
  /** Parent session's tool restrictions for notification prompts */
66
66
  parentTools?: Record<string, boolean>;
67
+ skillContent?: string;
68
+ sessionPermission?: SessionPermissionRule[];
67
69
  /** Marks if the task was launched from an unstable agent/category */
68
70
  isUnstableAgent?: boolean;
69
71
  /** Category used for this task (e.g., 'quick', 'visual-engineering') */
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Boulder State Constants
3
3
  */
4
- export declare const BOULDER_DIR = ".sisyphus";
4
+ export declare const BOULDER_DIR = ".omo";
5
5
  export declare const BOULDER_FILE = "boulder.json";
6
- export declare const BOULDER_STATE_PATH = ".sisyphus/boulder.json";
6
+ export declare const BOULDER_STATE_PATH = ".omo/boulder.json";
7
7
  export declare const NOTEPAD_DIR = "notepads";
8
- export declare const NOTEPAD_BASE_PATH = ".sisyphus/notepads";
8
+ export declare const NOTEPAD_BASE_PATH = ".omo/notepads";
9
9
  /** Prometheus plan directory pattern */
10
- export declare const PROMETHEUS_PLANS_DIR = ".sisyphus/plans";
10
+ export declare const PROMETHEUS_PLANS_DIR = ".omo/plans";
@@ -21,7 +21,7 @@ export declare function upsertTaskSessionState(directory: string, input: {
21
21
  }): BoulderState | null;
22
22
  /**
23
23
  * Find Prometheus plan files for this project.
24
- * Prometheus stores plans at: {project}/.sisyphus/plans/{name}.md
24
+ * Prometheus stores plans at: {project}/.omo/plans/{name}.md
25
25
  */
26
26
  export declare function findPrometheusPlans(directory: string): string[];
27
27
  /**
@@ -1 +1 @@
1
- export declare const INIT_DEEP_TEMPLATE = "# /init-deep\n\nGenerate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.\n\n## Usage\n\n```\n/init-deep # Update mode: modify existing + create new where warranted\n/init-deep --create-new # Read existing \u2192 remove all \u2192 regenerate from scratch\n/init-deep --max-depth=2 # Limit directory depth (default: 3)\n```\n\n---\n\n## Workflow (High-Level)\n\n1. **Discovery + Analysis** (concurrent)\n - Fire background explore agents immediately\n - Main session: bash structure + LSP codemap + read existing AGENTS.md\n2. **Score & Decide** - Determine AGENTS.md locations from merged findings\n3. **Generate** - Root first, then subdirs in parallel\n4. **Review** - Deduplicate, trim, validate\n\n<critical>\n**TodoWrite ALL phases. Mark in_progress \u2192 completed in real-time.**\n```\nTodoWrite([\n { id: \"discovery\", content: \"Fire explore agents + LSP codemap + read existing\", status: \"pending\", priority: \"high\" },\n { id: \"scoring\", content: \"Score directories, determine locations\", status: \"pending\", priority: \"high\" },\n { id: \"generate\", content: \"Generate AGENTS.md files (root + subdirs)\", status: \"pending\", priority: \"high\" },\n { id: \"review\", content: \"Deduplicate, validate, trim\", status: \"pending\", priority: \"medium\" }\n])\n```\n</critical>\n\n---\n\n## Phase 1: Discovery + Analysis (Concurrent)\n\n**Mark \"discovery\" as in_progress.**\n\n### Fire Background Explore Agents IMMEDIATELY\n\nDon't wait-these run async while main session works.\n\n```\n// Fire all at once, collect results later\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore project structure\", run_in_background=true, prompt=\"Project structure: PREDICT standard patterns for detected language \u2192 REPORT deviations only\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find entry points\", run_in_background=true, prompt=\"Entry points: FIND main files \u2192 REPORT non-standard organization\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find conventions\", run_in_background=true, prompt=\"Conventions: FIND config files (.eslintrc, pyproject.toml, .editorconfig) \u2192 REPORT project-specific rules\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find anti-patterns\", run_in_background=true, prompt=\"Anti-patterns: FIND 'DO NOT', 'NEVER', 'ALWAYS', 'DEPRECATED' comments \u2192 LIST forbidden patterns\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore build/CI\", run_in_background=true, prompt=\"Build/CI: FIND .github/workflows, Makefile \u2192 REPORT non-standard patterns\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find test patterns\", run_in_background=true, prompt=\"Test patterns: FIND test configs, test structure \u2192 REPORT unique conventions\")\n```\n\n<dynamic-agents>\n**DYNAMIC AGENT SPAWNING**: After bash analysis, spawn ADDITIONAL explore agents based on project scale:\n\n| Factor | Threshold | Additional Agents |\n|--------|-----------|-------------------|\n| **Total files** | >100 | +1 per 100 files |\n| **Total lines** | >10k | +1 per 10k lines |\n| **Directory depth** | \u22654 | +2 for deep exploration |\n| **Large files (>500 lines)** | >10 files | +1 for complexity hotspots |\n| **Monorepo** | detected | +1 per package/workspace |\n| **Multiple languages** | >1 | +1 per language |\n\n```bash\n# Measure project scale first\ntotal_files=$(find . -type f -not -path '*/node_modules/*' -not -path '*/.git/*' | wc -l)\ntotal_lines=$(find . -type f \\( -name \"*.ts\" -o -name \"*.py\" -o -name \"*.go\" \\) -not -path '*/node_modules/*' -exec wc -l {} + 2>/dev/null | tail -1 | awk '{print $1}')\nlarge_files=$(find . -type f \\( -name \"*.ts\" -o -name \"*.py\" \\) -not -path '*/node_modules/*' -exec wc -l {} + 2>/dev/null | awk '$1 > 500 {count++} END {print count+0}')\nmax_depth=$(find . -type d -not -path '*/node_modules/*' -not -path '*/.git/*' | awk -F/ '{print NF}' | sort -rn | head -1)\n```\n\nExample spawning:\n```\n// 500 files, 50k lines, depth 6, 15 large files \u2192 spawn 5+5+2+1 = 13 additional agents\ntask(subagent_type=\"explore\", load_skills=[], description=\"Analyze large files\", run_in_background=true, prompt=\"Large file analysis: FIND files >500 lines, REPORT complexity hotspots\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore deep modules\", run_in_background=true, prompt=\"Deep modules at depth 4+: FIND hidden patterns, internal conventions\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find shared utilities\", run_in_background=true, prompt=\"Cross-cutting concerns: FIND shared utilities across directories\")\n// ... more based on calculation\n```\n</dynamic-agents>\n\n### Main Session: Concurrent Analysis\n\n**While background agents run**, main session does:\n\n#### 1. Bash Structural Analysis\n```bash\n# Directory depth + file counts\nfind . -type d -not -path '*/\\.*' -not -path '*/node_modules/*' -not -path '*/venv/*' -not -path '*/dist/*' -not -path '*/build/*' | awk -F/ '{print NF-1}' | sort -n | uniq -c\n\n# Files per directory (top 30)\nfind . -type f -not -path '*/\\.*' -not -path '*/node_modules/*' | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -30\n\n# Code concentration by extension\nfind . -type f \\( -name \"*.py\" -o -name \"*.ts\" -o -name \"*.tsx\" -o -name \"*.js\" -o -name \"*.go\" -o -name \"*.rs\" \\) -not -path '*/node_modules/*' | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -20\n\n# Existing AGENTS.md / CLAUDE.md\nfind . -type f \\( -name \"AGENTS.md\" -o -name \"CLAUDE.md\" \\) -not -path '*/node_modules/*' 2>/dev/null\n```\n\n#### 2. Read Existing AGENTS.md\n```\nFor each existing file found:\n Read(filePath=file)\n Extract: key insights, conventions, anti-patterns\n Store in EXISTING_AGENTS map\n```\n\nIf `--create-new`: Read all existing first (preserve context) \u2192 then delete all \u2192 regenerate.\n\n#### 3. LSP Codemap (if available)\n```\nLspServers() # Check availability\n\n# Entry points (parallel)\nLspDocumentSymbols(filePath=\"src/index.ts\")\nLspDocumentSymbols(filePath=\"main.py\")\n\n# Key symbols (parallel)\nLspWorkspaceSymbols(filePath=\".\", query=\"class\")\nLspWorkspaceSymbols(filePath=\".\", query=\"interface\")\nLspWorkspaceSymbols(filePath=\".\", query=\"function\")\n\n# Centrality for top exports\nLspFindReferences(filePath=\"...\", line=X, character=Y)\n```\n\n**LSP Fallback**: If unavailable, rely on explore agents + AST-grep.\n\n### Collect Background Results\n\n```\n// After main session analysis done, collect all task results\nfor each task_id: background_output(task_id=\"...\")\n```\n\n**Merge: bash + LSP + existing + explore findings. Mark \"discovery\" as completed.**\n\n---\n\n## Phase 2: Scoring & Location Decision\n\n**Mark \"scoring\" as in_progress.**\n\n### Scoring Matrix\n\n| Factor | Weight | High Threshold | Source |\n|--------|--------|----------------|--------|\n| File count | 3x | >20 | bash |\n| Subdir count | 2x | >5 | bash |\n| Code ratio | 2x | >70% | bash |\n| Unique patterns | 1x | Has own config | explore |\n| Module boundary | 2x | Has index.ts/__init__.py | bash |\n| Symbol density | 2x | >30 symbols | LSP |\n| Export count | 2x | >10 exports | LSP |\n| Reference centrality | 3x | >20 refs | LSP |\n\n### Decision Rules\n\n| Score | Action |\n|-------|--------|\n| **Root (.)** | ALWAYS create |\n| **>15** | Create AGENTS.md |\n| **8-15** | Create if distinct domain |\n| **<8** | Skip (parent covers) |\n\n### Output\n```\nAGENTS_LOCATIONS = [\n { path: \".\", type: \"root\" },\n { path: \"src/hooks\", score: 18, reason: \"high complexity\" },\n { path: \"src/api\", score: 12, reason: \"distinct domain\" }\n]\n```\n\n**Mark \"scoring\" as completed.**\n\n---\n\n## Phase 3: Generate AGENTS.md\n\n**Mark \"generate\" as in_progress.**\n\n<critical>\n**File Writing Rule**: If AGENTS.md already exists at the target path \u2192 use `Edit` tool. If it does NOT exist \u2192 use `Write` tool.\nNEVER use Write to overwrite an existing file. ALWAYS check existence first via `Read` or discovery results.\n</critical>\n\n### Root AGENTS.md (Full Treatment)\n\n```markdown\n# PROJECT KNOWLEDGE BASE\n\n**Generated:** {TIMESTAMP}\n**Commit:** {SHORT_SHA}\n**Branch:** {BRANCH}\n\n## OVERVIEW\n{1-2 sentences: what + core stack}\n\n## STRUCTURE\n\\`\\`\\`\n{root}/\n\u251C\u2500\u2500 {dir}/ # {non-obvious purpose only}\n\u2514\u2500\u2500 {entry}\n\\`\\`\\`\n\n## WHERE TO LOOK\n| Task | Location | Notes |\n|------|----------|-------|\n\n## CODE MAP\n{From LSP - skip if unavailable or project <10 files}\n\n| Symbol | Type | Location | Refs | Role |\n|--------|------|----------|------|------|\n\n## CONVENTIONS\n{ONLY deviations from standard}\n\n## ANTI-PATTERNS (THIS PROJECT)\n{Explicitly forbidden here}\n\n## UNIQUE STYLES\n{Project-specific}\n\n## COMMANDS\n\\`\\`\\`bash\n{dev/test/build}\n\\`\\`\\`\n\n## NOTES\n{Gotchas}\n```\n\n**Quality gates**: 50-150 lines, no generic advice, no obvious info.\n\n### Subdirectory AGENTS.md (Parallel)\n\nLaunch writing tasks for each location:\n\n```\nfor loc in AGENTS_LOCATIONS (except root):\n task(category=\"writing\", load_skills=[], run_in_background=false, description=\"Generate AGENTS.md\", prompt=\\`\n Generate AGENTS.md for: ${loc.path}\n - Reason: ${loc.reason}\n - 30-80 lines max\n - NEVER repeat parent content\n - Sections: OVERVIEW (1 line), STRUCTURE (if >5 subdirs), WHERE TO LOOK, CONVENTIONS (if different), ANTI-PATTERNS\n \\`)\n```\n\n**Wait for all. Mark \"generate\" as completed.**\n\n---\n\n## Phase 4: Review & Deduplicate\n\n**Mark \"review\" as in_progress.**\n\nFor each generated file:\n- Remove generic advice\n- Remove parent duplicates\n- Trim to size limits\n- Verify telegraphic style\n\n**Mark \"review\" as completed.**\n\n---\n\n## Final Report\n\n```\n=== init-deep Complete ===\n\nMode: {update | create-new}\n\nFiles:\n [OK] ./AGENTS.md (root, {N} lines)\n [OK] ./src/hooks/AGENTS.md ({N} lines)\n\nDirs Analyzed: {N}\nAGENTS.md Created: {N}\nAGENTS.md Updated: {N}\n\nHierarchy:\n ./AGENTS.md\n \u2514\u2500\u2500 src/hooks/AGENTS.md\n```\n\n---\n\n## Anti-Patterns\n\n- **Static agent count**: MUST vary agents based on project size/depth\n- **Sequential execution**: MUST parallel (explore + LSP concurrent)\n- **Ignoring existing**: ALWAYS read existing first, even with --create-new\n- **Over-documenting**: Not every dir needs AGENTS.md\n- **Redundancy**: Child never repeats parent\n- **Generic content**: Remove anything that applies to ALL projects\n- **Verbose style**: Telegraphic or die";
1
+ export declare const INIT_DEEP_TEMPLATE = "# /init-deep\n\nGenerate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.\n\n## Usage\n\n```\n/init-deep # Update mode: modify existing + create new where warranted\n/init-deep --create-new # Read existing \u2192 remove all \u2192 regenerate from scratch\n/init-deep --max-depth=2 # Limit directory depth (default: 3)\n```\n\n---\n\n## Workflow (High-Level)\n\n1. **Discovery + Analysis** (concurrent)\n - Fire background explore agents immediately\n - Main session: bash structure + LSP codemap + read existing AGENTS.md\n2. **Score & Decide** - Determine AGENTS.md locations from merged findings\n3. **Generate** - Root first, then subdirs in parallel\n4. **Review** - Deduplicate, trim, validate\n\n<critical>\n**TodoWrite ALL phases. Mark in_progress \u2192 completed in real-time.**\n```\nTodoWrite([\n { id: \"discovery\", content: \"Fire explore agents + LSP codemap + read existing\", status: \"pending\", priority: \"high\" },\n { id: \"scoring\", content: \"Score directories, determine locations\", status: \"pending\", priority: \"high\" },\n { id: \"generate\", content: \"Generate AGENTS.md files (root + subdirs)\", status: \"pending\", priority: \"high\" },\n { id: \"review\", content: \"Deduplicate, validate, trim\", status: \"pending\", priority: \"medium\" }\n])\n```\n</critical>\n\n---\n\n## Phase 1: Discovery + Analysis (Concurrent)\n\n**Mark \"discovery\" as in_progress.**\n\n### Fire Background Explore Agents IMMEDIATELY\n\nDon't wait-these run async while main session works.\n\n```\n// Fire all at once, collect results later\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore project structure\", run_in_background=true, prompt=\"Project structure: PREDICT standard patterns for detected language \u2192 REPORT deviations only\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find entry points\", run_in_background=true, prompt=\"Entry points: FIND main files \u2192 REPORT non-standard organization\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find conventions\", run_in_background=true, prompt=\"Conventions: FIND config files (.eslintrc, pyproject.toml, .editorconfig) \u2192 REPORT project-specific rules\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find anti-patterns\", run_in_background=true, prompt=\"Anti-patterns: FIND 'DO NOT', 'NEVER', 'ALWAYS', 'DEPRECATED' comments \u2192 LIST forbidden patterns\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore build/CI\", run_in_background=true, prompt=\"Build/CI: FIND .github/workflows, Makefile \u2192 REPORT non-standard patterns\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find test patterns\", run_in_background=true, prompt=\"Test patterns: FIND test configs, test structure \u2192 REPORT unique conventions\")\n```\n\n<dynamic-agents>\n**DYNAMIC AGENT SPAWNING**: After bash analysis, spawn ADDITIONAL explore agents based on project scale:\n\n| Factor | Threshold | Additional Agents |\n|--------|-----------|-------------------|\n| **Total files** | >100 | +1 per 100 files |\n| **Total lines** | >10k | +1 per 10k lines |\n| **Directory depth** | \u22654 | +2 for deep exploration |\n| **Large files (>500 lines)** | >10 files | +1 for complexity hotspots |\n| **Monorepo** | detected | +1 per package/workspace |\n| **Multiple languages** | >1 | +1 per language |\n\n```bash\n# Measure project scale first\ntotal_files=$(find . -type f -not -path '*/node_modules/*' -not -path '*/.git/*' | wc -l)\ntotal_lines=$(find . -type f \\( -name \"*.ts\" -o -name \"*.py\" -o -name \"*.go\" \\) -not -path '*/node_modules/*' -exec wc -l {} + 2>/dev/null | tail -1 | awk '{print $1}')\nlarge_files=$(find . -type f \\( -name \"*.ts\" -o -name \"*.py\" \\) -not -path '*/node_modules/*' -exec wc -l {} + 2>/dev/null | awk '$1 > 500 {count++} END {print count+0}')\nmax_depth=$(find . -type d -not -path '*/node_modules/*' -not -path '*/.git/*' | awk -F/ '{print NF}' | sort -rn | head -1)\n```\n\nExample spawning:\n```\n// 500 files, 50k lines, depth 6, 15 large files \u2192 spawn 5+5+2+1 = 13 additional agents\ntask(subagent_type=\"explore\", load_skills=[], description=\"Analyze large files\", run_in_background=true, prompt=\"Large file analysis: FIND files >500 lines, REPORT complexity hotspots\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore deep modules\", run_in_background=true, prompt=\"Deep modules at depth 4+: FIND hidden patterns, internal conventions\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find shared utilities\", run_in_background=true, prompt=\"Cross-cutting concerns: FIND shared utilities across directories\")\n// ... more based on calculation\n```\n</dynamic-agents>\n\n### Main Session: Concurrent Analysis\n\n**While background agents run**, main session does:\n\n#### 1. Bash Structural Analysis\n```bash\n# Directory depth + file counts\nfind . -type d -not -path '*/\\.*' -not -path '*/node_modules/*' -not -path '*/venv/*' -not -path '*/dist/*' -not -path '*/build/*' | awk -F/ '{print NF-1}' | sort -n | uniq -c\n\n# Files per directory (top 30)\nfind . -type f -not -path '*/\\.*' -not -path '*/node_modules/*' | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -30\n\n# Code concentration by extension\nfind . -type f \\( -name \"*.py\" -o -name \"*.ts\" -o -name \"*.tsx\" -o -name \"*.js\" -o -name \"*.go\" -o -name \"*.rs\" \\) -not -path '*/node_modules/*' | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -20\n\n# Existing AGENTS.md / CLAUDE.md\nfind . -type f \\( -name \"AGENTS.md\" -o -name \"CLAUDE.md\" \\) -not -path '*/node_modules/*' 2>/dev/null\n```\n\n#### 2. Read Existing AGENTS.md\n```\nFor each existing file found:\n Read(filePath=file)\n Extract: key insights, conventions, anti-patterns\n Store in EXISTING_AGENTS map\n```\n\nIf `--create-new`: Read all existing first (preserve context) \u2192 then delete all \u2192 regenerate.\n\n#### 3. LSP Codemap (if available)\n```\nLspServers() # Check availability\n\n# Entry points (parallel)\nLspDocumentSymbols(filePath=\"src/index.ts\")\nLspDocumentSymbols(filePath=\"main.py\")\n\n# Key symbols (parallel)\nLspWorkspaceSymbols(filePath=\".\", query=\"class\")\nLspWorkspaceSymbols(filePath=\".\", query=\"interface\")\nLspWorkspaceSymbols(filePath=\".\", query=\"function\")\n\n# Centrality for top exports\nLspFindReferences(filePath=\"...\", line=X, character=Y)\n```\n\n**LSP Fallback**: If unavailable, rely on explore agents + AST-grep.\n\n### Collect Background Results\n\n```\n// After main session analysis done, collect all task results\nfor each background task ID (`bg_...`): background_output(task_id=\"bg_...\")\n```\n\n**Merge: bash + LSP + existing + explore findings. Mark \"discovery\" as completed.**\n\n---\n\n## Phase 2: Scoring & Location Decision\n\n**Mark \"scoring\" as in_progress.**\n\n### Scoring Matrix\n\n| Factor | Weight | High Threshold | Source |\n|--------|--------|----------------|--------|\n| File count | 3x | >20 | bash |\n| Subdir count | 2x | >5 | bash |\n| Code ratio | 2x | >70% | bash |\n| Unique patterns | 1x | Has own config | explore |\n| Module boundary | 2x | Has index.ts/__init__.py | bash |\n| Symbol density | 2x | >30 symbols | LSP |\n| Export count | 2x | >10 exports | LSP |\n| Reference centrality | 3x | >20 refs | LSP |\n\n### Decision Rules\n\n| Score | Action |\n|-------|--------|\n| **Root (.)** | ALWAYS create |\n| **>15** | Create AGENTS.md |\n| **8-15** | Create if distinct domain |\n| **<8** | Skip (parent covers) |\n\n### Output\n```\nAGENTS_LOCATIONS = [\n { path: \".\", type: \"root\" },\n { path: \"src/hooks\", score: 18, reason: \"high complexity\" },\n { path: \"src/api\", score: 12, reason: \"distinct domain\" }\n]\n```\n\n**Mark \"scoring\" as completed.**\n\n---\n\n## Phase 3: Generate AGENTS.md\n\n**Mark \"generate\" as in_progress.**\n\n<critical>\n**File Writing Rule**: If AGENTS.md already exists at the target path \u2192 use `Edit` tool. If it does NOT exist \u2192 use `Write` tool.\nNEVER use Write to overwrite an existing file. ALWAYS check existence first via `Read` or discovery results.\n</critical>\n\n### Root AGENTS.md (Full Treatment)\n\n```markdown\n# PROJECT KNOWLEDGE BASE\n\n**Generated:** {TIMESTAMP}\n**Commit:** {SHORT_SHA}\n**Branch:** {BRANCH}\n\n## OVERVIEW\n{1-2 sentences: what + core stack}\n\n## STRUCTURE\n\\`\\`\\`\n{root}/\n\u251C\u2500\u2500 {dir}/ # {non-obvious purpose only}\n\u2514\u2500\u2500 {entry}\n\\`\\`\\`\n\n## WHERE TO LOOK\n| Task | Location | Notes |\n|------|----------|-------|\n\n## CODE MAP\n{From LSP - skip if unavailable or project <10 files}\n\n| Symbol | Type | Location | Refs | Role |\n|--------|------|----------|------|------|\n\n## CONVENTIONS\n{ONLY deviations from standard}\n\n## ANTI-PATTERNS (THIS PROJECT)\n{Explicitly forbidden here}\n\n## UNIQUE STYLES\n{Project-specific}\n\n## COMMANDS\n\\`\\`\\`bash\n{dev/test/build}\n\\`\\`\\`\n\n## NOTES\n{Gotchas}\n```\n\n**Quality gates**: 50-150 lines, no generic advice, no obvious info.\n\n### Subdirectory AGENTS.md (Parallel)\n\nLaunch writing tasks for each location:\n\n```\nfor loc in AGENTS_LOCATIONS (except root):\n task(category=\"writing\", load_skills=[], run_in_background=false, description=\"Generate AGENTS.md\", prompt=\\`\n Generate AGENTS.md for: ${loc.path}\n - Reason: ${loc.reason}\n - 30-80 lines max\n - NEVER repeat parent content\n - Sections: OVERVIEW (1 line), STRUCTURE (if >5 subdirs), WHERE TO LOOK, CONVENTIONS (if different), ANTI-PATTERNS\n \\`)\n```\n\n**Wait for all. Mark \"generate\" as completed.**\n\n---\n\n## Phase 4: Review & Deduplicate\n\n**Mark \"review\" as in_progress.**\n\nFor each generated file:\n- Remove generic advice\n- Remove parent duplicates\n- Trim to size limits\n- Verify telegraphic style\n\n**Mark \"review\" as completed.**\n\n---\n\n## Final Report\n\n```\n=== init-deep Complete ===\n\nMode: {update | create-new}\n\nFiles:\n [OK] ./AGENTS.md (root, {N} lines)\n [OK] ./src/hooks/AGENTS.md ({N} lines)\n\nDirs Analyzed: {N}\nAGENTS.md Created: {N}\nAGENTS.md Updated: {N}\n\nHierarchy:\n ./AGENTS.md\n \u2514\u2500\u2500 src/hooks/AGENTS.md\n```\n\n---\n\n## Anti-Patterns\n\n- **Static agent count**: MUST vary agents based on project size/depth\n- **Sequential execution**: MUST parallel (explore + LSP concurrent)\n- **Ignoring existing**: ALWAYS read existing first, even with --create-new\n- **Over-documenting**: Not every dir needs AGENTS.md\n- **Redundancy**: Child never repeats parent\n- **Generic content**: Remove anything that applies to ALL projects\n- **Verbose style**: Telegraphic or die";
@@ -1 +1 @@
1
- export declare const START_WORK_TEMPLATE = "You are starting a Sisyphus work session.\n\n## ARGUMENTS\n\n- `/start-work [plan-name] [--worktree <path>]`\n - `plan-name` (optional): name or partial match of the plan to start\n - `--worktree <path>` (optional): absolute path to an existing git worktree to work in\n - If specified and valid: hook pre-sets worktree_path in boulder.json\n - If specified but invalid: you must run `git worktree add <path> <branch>` first\n - If omitted: work directly in the current project directory (no worktree)\n\n## WHAT TO DO\n\n1. **Find available plans**: Search for Prometheus-generated plan files at `.sisyphus/plans/`\n\n2. **Check for active boulder state**: Read `.sisyphus/boulder.json` if it exists\n\n3. **Decision logic**:\n - If multiple active works are listed in your context:\n - This means boulder.json has more than one work with status: `active` or `paused`\n - Use the Question tool to ask the user which plan to resume\n - Resume by running `/start-work {plan-name}` for the selected plan\n - If the user says \"start a new plan\", continue with cold-start auto-selection logic\n - If exactly one active work is listed and the user did not name a plan:\n - Auto-resume that single active work\n - If no active plan OR plan is complete:\n - List available plan files\n - If ONE plan: auto-select it\n - If MULTIPLE plans: show list with timestamps, ask user to select\n\n4. **Worktree Setup** (ONLY when `--worktree` was explicitly specified and `worktree_path` not already set in boulder.json):\n 1. `git worktree list --porcelain` - see available worktrees\n 2. Create: `git worktree add <absolute-path> <branch-or-HEAD>`\n 3. Update boulder.json to add `\"worktree_path\": \"<absolute-path>\"`\n 4. All work happens inside that worktree directory\n\n5. **Create/Update boulder.json**:\n ```json\n {\n \"active_plan\": \"/absolute/path/to/plan.md\",\n \"started_at\": \"ISO_TIMESTAMP\",\n \"session_ids\": [\"session_id_1\", \"session_id_2\"],\n \"plan_name\": \"plan-name\",\n \"worktree_path\": \"/absolute/path/to/git/worktree\"\n }\n ```\n\n6. **Read the plan file** and start executing tasks according to atlas workflow\n\n## OUTPUT FORMAT\n\nWhen listing plans for selection:\n```\nAvailable Work Plans\n\nCurrent Time: {ISO timestamp}\nSession ID: {current session id}\n\n1. [plan-name-1.md] - Modified: {date} - Progress: 3/10 tasks\n2. [plan-name-2.md] - Modified: {date} - Progress: 0/5 tasks\n\nWhich plan would you like to work on? (Enter number or plan name)\n```\n\nWhen resuming existing work:\n```\nResuming Work Session\n\nActive Plan: {plan-name}\nProgress: {completed}/{total} tasks\nSessions: {count} (appending current session)\nWorktree: {worktree_path}\n\nReading plan and continuing from last incomplete task...\n```\n\nWhen auto-selecting single plan:\n```\nStarting Work Session\n\nPlan: {plan-name}\nSession ID: {session_id}\nStarted: {timestamp}\nWorktree: {worktree_path}\n\nReading plan and beginning execution...\n```\n\n## CRITICAL\n\n- The session_id is injected by the hook - use it directly\n- Always update boulder.json BEFORE starting work\n- If worktree_path is set in boulder.json, all work happens inside that worktree directory\n- Read the FULL plan file before delegating any tasks\n- Follow atlas delegation protocols (7-section format)\n\n## TASK BREAKDOWN (MANDATORY)\n\nAfter reading the plan file, you MUST decompose every plan task into granular, implementation-level sub-steps and register ALL of them as task/todo items BEFORE starting any work.\n\n**How to break down**:\n- Each plan checkbox item (e.g., `- [ ] Add user authentication`) must be split into concrete, actionable sub-tasks\n- Sub-tasks should be specific enough that each one touches a clear set of files/functions\n- Include: file to modify, what to change, expected behavior, and how to verify\n- Do NOT leave any task vague - \"implement feature X\" is NOT acceptable; \"add validateToken() to src/auth/middleware.ts that checks JWT expiry and returns 401\" IS acceptable\n\n**Example breakdown**:\nPlan task: `- [ ] Add rate limiting to API`\n\u2192 Todo items:\n 1. Create `src/middleware/rate-limiter.ts` with sliding window algorithm (max 100 req/min per IP)\n 2. Add RateLimiter middleware to `src/app.ts` router chain, before auth middleware\n 3. Add rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining) to response in `rate-limiter.ts`\n 4. Add test: verify 429 response after exceeding limit in `src/middleware/rate-limiter.test.ts`\n 5. Add test: verify headers are present on normal responses\n\nRegister these as task/todo items so progress is tracked and visible throughout the session.\n\n## WORKTREE COMPLETION\n\nWhen working in a worktree (`worktree_path` is set in boulder.json) and ALL plan tasks are complete:\n1. Commit all remaining changes in the worktree\n2. **Sync .sisyphus state back**: Copy `.sisyphus/` from the worktree to the main repo before removal.\n This is CRITICAL when `.sisyphus/` is gitignored - state written during worktree execution would otherwise be lost.\n ```bash\n cp -r <worktree-path>/.sisyphus/* <main-repo>/.sisyphus/ 2>/dev/null || true\n ```\n3. Switch to the main working directory (the original repo, NOT the worktree)\n4. Merge the worktree branch into the current branch: `git merge <worktree-branch>`\n5. If merge succeeds, clean up: `git worktree remove <worktree-path>`\n6. Remove the boulder.json state\n\nThis is the DEFAULT behavior when `--worktree` was used. Skip merge only if the user explicitly instructs otherwise (e.g., asks to create a PR instead).";
1
+ export declare const START_WORK_TEMPLATE = "You are starting a Sisyphus work session.\n\n## ARGUMENTS\n\n- `/start-work [plan-name] [--worktree <path>]`\n - `plan-name` (optional): name or partial match of the plan to start\n - `--worktree <path>` (optional): absolute path to an existing git worktree to work in\n - If specified and valid: hook pre-sets worktree_path in boulder.json\n - If specified but invalid: you must run `git worktree add <path> <branch>` first\n - If omitted: work directly in the current project directory (no worktree)\n\n## WHAT TO DO\n\n1. **Find available plans**: Search for Prometheus-generated plan files at `.omo/plans/`\n\n2. **Check for active boulder state**: Read `.omo/boulder.json` if it exists\n\n3. **Decision logic**:\n - If multiple active works are listed in your context:\n - This means boulder.json has more than one work with status: `active` or `paused`\n - Use the Question tool to ask the user which plan to resume\n - Resume by running `/start-work {plan-name}` for the selected plan\n - If the user says \"start a new plan\", continue with cold-start auto-selection logic\n - If exactly one active work is listed and the user did not name a plan:\n - Auto-resume that single active work\n - If no active plan OR plan is complete:\n - List available plan files\n - If ONE plan: auto-select it\n - If MULTIPLE plans: show list with timestamps, ask user to select\n\n4. **Worktree Setup** (ONLY when `--worktree` was explicitly specified and `worktree_path` not already set in boulder.json):\n 1. `git worktree list --porcelain` - see available worktrees\n 2. Create: `git worktree add <absolute-path> <branch-or-HEAD>`\n 3. Update boulder.json to add `\"worktree_path\": \"<absolute-path>\"`\n 4. All work happens inside that worktree directory\n\n5. **Create/Update boulder.json**:\n ```json\n {\n \"active_plan\": \"/absolute/path/to/plan.md\",\n \"started_at\": \"ISO_TIMESTAMP\",\n \"session_ids\": [\"session_id_1\", \"session_id_2\"],\n \"plan_name\": \"plan-name\",\n \"worktree_path\": \"/absolute/path/to/git/worktree\"\n }\n ```\n\n6. **Read the plan file** and start executing tasks according to atlas workflow\n\n## OUTPUT FORMAT\n\nWhen listing plans for selection:\n```\nAvailable Work Plans\n\nCurrent Time: {ISO timestamp}\nSession ID: {current session id}\n\n1. [plan-name-1.md] - Modified: {date} - Progress: 3/10 tasks\n2. [plan-name-2.md] - Modified: {date} - Progress: 0/5 tasks\n\nWhich plan would you like to work on? (Enter number or plan name)\n```\n\nWhen resuming existing work:\n```\nResuming Work Session\n\nActive Plan: {plan-name}\nProgress: {completed}/{total} tasks\nSessions: {count} (appending current session)\nWorktree: {worktree_path}\n\nReading plan and continuing from last incomplete task...\n```\n\nWhen auto-selecting single plan:\n```\nStarting Work Session\n\nPlan: {plan-name}\nSession ID: {session_id}\nStarted: {timestamp}\nWorktree: {worktree_path}\n\nReading plan and beginning execution...\n```\n\n## CRITICAL\n\n- The session_id is injected by the hook - use it directly\n- Always update boulder.json BEFORE starting work\n- If worktree_path is set in boulder.json, all work happens inside that worktree directory\n- Read the FULL plan file before delegating any tasks\n- Follow atlas delegation protocols (7-section format)\n\n## TASK BREAKDOWN (MANDATORY)\n\nAfter reading the plan file, you MUST decompose every plan task into granular, implementation-level sub-steps and register ALL of them as task/todo items BEFORE starting any work.\n\n**How to break down**:\n- Each plan checkbox item (e.g., `- [ ] Add user authentication`) must be split into concrete, actionable sub-tasks\n- Sub-tasks should be specific enough that each one touches a clear set of files/functions\n- Include: file to modify, what to change, expected behavior, and how to verify\n- Do NOT leave any task vague - \"implement feature X\" is NOT acceptable; \"add validateToken() to src/auth/middleware.ts that checks JWT expiry and returns 401\" IS acceptable\n\n**Example breakdown**:\nPlan task: `- [ ] Add rate limiting to API`\n\u2192 Todo items:\n 1. Create `src/middleware/rate-limiter.ts` with sliding window algorithm (max 100 req/min per IP)\n 2. Add RateLimiter middleware to `src/app.ts` router chain, before auth middleware\n 3. Add rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining) to response in `rate-limiter.ts`\n 4. Add test: verify 429 response after exceeding limit in `src/middleware/rate-limiter.test.ts`\n 5. Add test: verify headers are present on normal responses\n\nRegister these as task/todo items so progress is tracked and visible throughout the session.\n\n## WORKTREE COMPLETION\n\nWhen working in a worktree (`worktree_path` is set in boulder.json) and ALL plan tasks are complete:\n1. Commit all remaining changes in the worktree\n2. **Sync .omo state back**: Copy `.omo/` from the worktree to the main repo before removal.\n This is CRITICAL when `.omo/` is gitignored - state written during worktree execution would otherwise be lost.\n ```bash\n cp -r <worktree-path>/.omo/* <main-repo>/.omo/ 2>/dev/null || true\n ```\n3. Switch to the main working directory (the original repo, NOT the worktree)\n4. Merge the worktree branch into the current branch: `git merge <worktree-branch>`\n5. If merge succeeds, clean up: `git worktree remove <worktree-path>`\n6. Remove the boulder.json state\n\nThis is the DEFAULT behavior when `--worktree` was used. Skip merge only if the user explicitly instructs otherwise (e.g., asks to create a PR instead).";
@@ -1,5 +1,5 @@
1
- import type { ContextCollector } from "./collector";
2
1
  import type { Message, Part } from "@opencode-ai/sdk";
2
+ import type { ContextCollector } from "./collector";
3
3
  interface OutputPart {
4
4
  type: string;
5
5
  text?: string;
@@ -1,2 +1,20 @@
1
1
  import { type GitMasterConfig } from "../../config/schema";
2
+ import { type ShellType } from "../../shared/shell-env";
3
+ /**
4
+ * Parse a bash-format env prefix string ("VAR=value VAR2=value2") into a Record.
5
+ * Only handles simple KEY=VALUE pairs (no quoting needed since assertValidGitEnvPrefix
6
+ * already validates the format is shell-safe alphanumeric assignments).
7
+ */
8
+ export declare function parseBashEnvPrefix(prefix: string): Record<string, string>;
9
+ /**
10
+ * Build the shell-aware command prefix for git commands.
11
+ * Uses the shared shell detection and env prefix builder to emit correct syntax
12
+ * for PowerShell ($env:VAR='value';), cmd (set VAR="value" &&),
13
+ * csh (setenv VAR value;), or unix (VAR=value).
14
+ *
15
+ * For unix shells, we use the inline VAR=value prefix style (not export) to match
16
+ * the original behavior where the env var applies only to the immediately following command.
17
+ * For csh/tcsh, we use setenv syntax since csh does not support inline VAR=value.
18
+ */
19
+ export declare function buildShellAwareGitPrefix(bashPrefix: string, shellType?: ShellType): string;
2
20
  export declare function injectGitMasterConfig(template: string, config?: GitMasterConfig): string;
@@ -1 +1 @@
1
- export declare const CONTINUATION_MARKER_DIR = ".sisyphus/run-continuation";
1
+ export declare const CONTINUATION_MARKER_DIR = ".omo/run-continuation";
@@ -1,7 +1,9 @@
1
+ import type { TmuxCommandResult } from "../../../shared/tmux";
1
2
  type ResolvedCallerTmuxSession = {
2
3
  sessionId: string;
3
4
  paneId: string;
4
5
  windowTarget: string;
5
6
  };
6
- export declare function resolveCallerTmuxSession(tmuxPath: string): Promise<ResolvedCallerTmuxSession | null>;
7
+ type RunTmuxCommand = (tmuxPath: string, args: string[]) => Promise<TmuxCommandResult>;
8
+ export declare function resolveCallerTmuxSession(tmuxPath: string, callerPaneId?: string | undefined, runCommand?: RunTmuxCommand): Promise<ResolvedCallerTmuxSession | null>;
7
9
  export {};
@@ -13,7 +13,7 @@ export declare const createTeamRunMock: import("bun:test").Mock<(spec: TeamSpec,
13
13
  teamName: string;
14
14
  specSource: "user" | "project";
15
15
  createdAt: number;
16
- status: "deleted" | "failed" | "active" | "creating" | "shutdown_requested" | "deleting" | "orphaned";
16
+ status: "active" | "failed" | "deleted" | "creating" | "shutdown_requested" | "deleting" | "orphaned";
17
17
  members: {
18
18
  name: string;
19
19
  agentType: "leader" | "general-purpose";
@@ -108,7 +108,7 @@ export declare const loadTeamSpecMock: import("bun:test").Mock<() => Promise<{
108
108
  export declare const listActiveTeamsMock: import("bun:test").Mock<() => Promise<{
109
109
  teamRunId: string;
110
110
  teamName: string;
111
- status: "deleted" | "failed" | "active" | "creating" | "shutdown_requested" | "deleting" | "orphaned";
111
+ status: "active" | "failed" | "deleted" | "creating" | "shutdown_requested" | "deleting" | "orphaned";
112
112
  memberCount: number;
113
113
  scope: "user" | "project";
114
114
  }[]>>;
@@ -118,7 +118,7 @@ export declare const loadRuntimeStateMock: import("bun:test").Mock<(teamRunId: s
118
118
  teamName: string;
119
119
  specSource: "user" | "project";
120
120
  createdAt: number;
121
- status: "deleted" | "failed" | "active" | "creating" | "shutdown_requested" | "deleting" | "orphaned";
121
+ status: "active" | "failed" | "deleted" | "creating" | "shutdown_requested" | "deleting" | "orphaned";
122
122
  members: {
123
123
  name: string;
124
124
  agentType: "leader" | "general-purpose";
@@ -23,6 +23,7 @@ export type LiveDeliveryClient = {
23
23
  directory: string;
24
24
  };
25
25
  }): Promise<unknown>;
26
+ status?: () => Promise<unknown>;
26
27
  };
27
28
  };
28
29
  export type TeamSendMessageToolDeps = {
@@ -255,9 +255,9 @@ export declare const RuntimeStateSchema: z.ZodObject<{
255
255
  }>;
256
256
  createdAt: z.ZodNumber;
257
257
  status: z.ZodEnum<{
258
- deleted: "deleted";
259
- failed: "failed";
260
258
  active: "active";
259
+ failed: "failed";
260
+ deleted: "deleted";
261
261
  creating: "creating";
262
262
  shutdown_requested: "shutdown_requested";
263
263
  deleting: "deleting";
@@ -1,4 +1,4 @@
1
- declare const ATTACHABLE_SESSION_STATUSES: readonly ["idle", "running"];
1
+ declare const ATTACHABLE_SESSION_STATUSES: readonly ["idle", "running", "busy"];
2
2
  export type AttachableSessionStatus = (typeof ATTACHABLE_SESSION_STATUSES)[number];
3
3
  export declare function isAttachableSessionStatus(status: string | undefined): status is AttachableSessionStatus;
4
4
  export {};
@@ -2,6 +2,7 @@ import type { PluginInput } from "@opencode-ai/plugin";
2
2
  import type { TmuxConfig } from "../../config/schema";
3
3
  import type { WindowState } from "./types";
4
4
  import * as sharedModule from "../../shared";
5
+ import { executeActions, executeAction } from "./action-executor";
5
6
  type OpencodeClient = PluginInput["client"];
6
7
  interface SessionCreatedEvent {
7
8
  type: string;
@@ -21,6 +22,8 @@ export interface TmuxUtilDeps {
21
22
  client: OpencodeClient;
22
23
  sessionId: string;
23
24
  }) => Promise<boolean>;
25
+ executeActions: typeof executeActions;
26
+ executeAction: typeof executeAction;
24
27
  log: typeof sharedModule.log;
25
28
  }
26
29
  export declare class TmuxSessionManager {
@@ -47,6 +50,7 @@ export declare class TmuxSessionManager {
47
50
  private isolatedContainerNullStateCount;
48
51
  private staleSweepCompleted;
49
52
  private staleSweepInProgress;
53
+ private isolatedSessionManagerId;
50
54
  constructor(ctx: PluginInput, tmuxConfig: TmuxConfig, deps?: Partial<TmuxUtilDeps>);
51
55
  private isEnabled;
52
56
  private isIsolated;
@@ -61,8 +65,10 @@ export declare class TmuxSessionManager {
61
65
  private cleanupIsolatedContainerAfterSessionDeletion;
62
66
  private markSessionClosePending;
63
67
  private queryWindowStateSafely;
68
+ private activateTrackedSessionPane;
64
69
  private windowStateContainsPane;
65
70
  private finalizeForceRemoveCandidate;
71
+ private canAutoActivatePane;
66
72
  private closeTrackedSessionPane;
67
73
  private finalizeTrackedSessionClose;
68
74
  private closeTrackedSession;
@@ -2,6 +2,8 @@ import type { TmuxPaneInfo } from "./types";
2
2
  type ParsedPaneState = {
3
3
  windowWidth: number;
4
4
  windowHeight: number;
5
+ windowActive: boolean;
6
+ sessionAttached: boolean;
5
7
  panes: TmuxPaneInfo[];
6
8
  };
7
9
  export declare function parsePaneStateOutput(stdout: string): ParsedPaneState | null;
@@ -1,13 +1,16 @@
1
1
  import type { OpencodeClient } from "../../tools/delegate-task/types";
2
- import type { TrackedSession } from "./types";
2
+ import type { TrackedSession, WindowState } from "./types";
3
3
  export declare class TmuxPollingManager {
4
4
  private client;
5
5
  private sessions;
6
6
  private closeSessionById;
7
7
  private retryPendingCloses?;
8
+ private getWindowState?;
9
+ private activateSessionPane?;
10
+ private canActivatePane;
8
11
  private pollInterval?;
9
12
  private pollingInFlight;
10
- constructor(client: OpencodeClient, sessions: Map<string, TrackedSession>, closeSessionById: (sessionId: string) => Promise<void>, retryPendingCloses?: (() => Promise<void>) | undefined);
13
+ constructor(client: OpencodeClient, sessions: Map<string, TrackedSession>, closeSessionById: (sessionId: string) => Promise<void>, retryPendingCloses?: (() => Promise<void>) | undefined, getWindowState?: (() => Promise<WindowState | null>) | undefined, activateSessionPane?: ((tracked: TrackedSession) => Promise<boolean>) | undefined, canActivatePane?: (state: WindowState) => boolean);
11
14
  handleEvent(event: {
12
15
  type: string;
13
16
  properties?: Record<string, unknown>;
@@ -16,4 +19,5 @@ export declare class TmuxPollingManager {
16
19
  stopPolling(): void;
17
20
  private pollSessions;
18
21
  private getEventSessionId;
22
+ private activateFocusedPanes;
19
23
  }
@@ -2,6 +2,8 @@ export interface TrackedSession {
2
2
  sessionId: string;
3
3
  paneId: string;
4
4
  description: string;
5
+ attachActivated: boolean;
6
+ attachActivatedAt?: Date;
5
7
  createdAt: Date;
6
8
  lastSeenAt: Date;
7
9
  closePending: boolean;
@@ -25,6 +27,8 @@ export interface TmuxPaneInfo {
25
27
  export interface WindowState {
26
28
  windowWidth: number;
27
29
  windowHeight: number;
30
+ windowActive?: boolean;
31
+ sessionAttached?: boolean;
28
32
  mainPane: TmuxPaneInfo | null;
29
33
  agentPanes: TmuxPaneInfo[];
30
34
  }
@@ -13,4 +13,5 @@ export declare function injectBoulderContinuation(input: {
13
13
  preferredTaskTitle?: string;
14
14
  backgroundManager?: BackgroundTaskStatusProvider;
15
15
  sessionState: SessionState;
16
+ idleSettleMs?: number;
16
17
  }): Promise<BoulderContinuationResult>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Cross-platform check if a path is inside .omo/ directory.
3
+ * Handles both forward slashes (Unix) and backslashes (Windows).
4
+ * Uses path segment matching instead of substring matching.
5
+ */
6
+ export declare function isOmoPath(filePath: string): boolean;
@@ -1,4 +1,5 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
+ import { collectGitDiffStats, formatFileChanges } from "../../shared/git-worktree";
2
3
  import type { PendingTaskRef, SessionState } from "./types";
3
4
  import type { ToolExecuteAfterInput, ToolExecuteAfterOutput } from "./types";
4
5
  export declare function createToolExecuteAfterHandler(input: {
@@ -9,4 +10,6 @@ export declare function createToolExecuteAfterHandler(input: {
9
10
  autoCommit: boolean;
10
11
  getState: (sessionID: string) => SessionState;
11
12
  isCallerOrchestrator?: (sessionID: string | undefined) => Promise<boolean>;
13
+ collectGitDiffStats?: typeof collectGitDiffStats;
14
+ formatFileChanges?: typeof formatFileChanges;
12
15
  }): (toolInput: ToolExecuteAfterInput, toolOutput: ToolExecuteAfterOutput | undefined) => Promise<void>;
@@ -0,0 +1,14 @@
1
+ import type { SessionState } from "./types";
2
+ export declare const MAX_BOULDER_CONTINUATION_NO_TOOL_PROGRESS = 3;
3
+ export type ToolProgressOutput = {
4
+ title?: string;
5
+ output?: string;
6
+ };
7
+ export declare function isTangibleProgressTool(toolName: string): boolean;
8
+ export declare function didToolMakeProgress(output: ToolProgressOutput): boolean;
9
+ export declare function recordToolProgress(state: SessionState, now?: number): void;
10
+ export declare function resetStallStateForPlanChange(state: SessionState, planPath: string): void;
11
+ export declare function markContinuationInjectedAwaitingToolProgress(state: SessionState): void;
12
+ export declare function updateNoToolProgressIterations(state: SessionState): number;
13
+ export declare function shouldAbortForNoToolProgress(state: SessionState): boolean;
14
+ export declare function markContinuationStalled(state: SessionState, planName: string, planPath: string): void;
@@ -54,4 +54,11 @@ export interface SessionState {
54
54
  pendingFinalWaveTaskCount?: number;
55
55
  approvedFinalWaveTaskCount?: number;
56
56
  boulderCompletionNudgedAt?: Record<string, number>;
57
+ awaitingToolProgressAfterContinuation?: boolean;
58
+ iterationsSinceLastToolProgress?: number;
59
+ lastToolProgressAt?: number;
60
+ stalledContinuationReason?: string;
61
+ stalledContinuationPlanPath?: string;
62
+ /** The plan path the in-progress no-tool-progress counter is keyed to. Changes here reset the counter. */
63
+ activeContinuationPlanPath?: string;
57
64
  }
@@ -6,8 +6,10 @@ export declare function detectSlashCommand(text: string): ParsedSlashCommand | n
6
6
  export declare function extractPromptText(parts: Array<{
7
7
  type: string;
8
8
  text?: string;
9
+ synthetic?: boolean;
9
10
  }>): string;
10
11
  export declare function findSlashCommandPartIndex(parts: Array<{
11
12
  type: string;
12
13
  text?: string;
14
+ synthetic?: boolean;
13
15
  }>): number;
@@ -1,3 +1,10 @@
1
- export declare function invalidatePackage(packageName?: string): boolean;
1
+ interface InvalidatePackageOptions {
2
+ acceptedPackageNames?: readonly string[];
3
+ cacheDir?: string;
4
+ defaultPackageName?: string;
5
+ userConfigDir?: string;
6
+ }
7
+ export declare function invalidatePackage(packageName?: string, options?: InvalidatePackageOptions): boolean;
2
8
  /** @deprecated Use invalidatePackage instead - this nukes ALL plugins */
3
9
  export declare function invalidateCache(): boolean;
10
+ export {};