open-multi-agent-kit 0.91.0 → 0.93.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 (168) hide show
  1. package/CHANGELOG.md +32 -1
  2. package/README.md +2 -2
  3. package/dist/core/agent-session.d.ts +29 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +89 -21
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/command-safety.d.ts.map +1 -1
  8. package/dist/core/command-safety.js +0 -50
  9. package/dist/core/command-safety.js.map +1 -1
  10. package/dist/core/compaction/branch-summarization.d.ts +5 -1
  11. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  12. package/dist/core/compaction/branch-summarization.js +5 -7
  13. package/dist/core/compaction/branch-summarization.js.map +1 -1
  14. package/dist/core/compaction/compaction.d.ts +12 -3
  15. package/dist/core/compaction/compaction.d.ts.map +1 -1
  16. package/dist/core/compaction/compaction.js +28 -15
  17. package/dist/core/compaction/compaction.js.map +1 -1
  18. package/dist/core/compaction/transaction.d.ts.map +1 -1
  19. package/dist/core/compaction/transaction.js +7 -3
  20. package/dist/core/compaction/transaction.js.map +1 -1
  21. package/dist/core/context-budget-headroom-candidates.d.ts.map +1 -1
  22. package/dist/core/context-budget-headroom-candidates.js +21 -11
  23. package/dist/core/context-budget-headroom-candidates.js.map +1 -1
  24. package/dist/core/context-budget-system-prompt-items.d.ts +1 -0
  25. package/dist/core/context-budget-system-prompt-items.d.ts.map +1 -1
  26. package/dist/core/context-budget-system-prompt-items.js +7 -8
  27. package/dist/core/context-budget-system-prompt-items.js.map +1 -1
  28. package/dist/core/extensions/builtin/command-safety-gate.d.ts +8 -0
  29. package/dist/core/extensions/builtin/command-safety-gate.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/command-safety-gate.js +23 -0
  31. package/dist/core/extensions/builtin/command-safety-gate.js.map +1 -1
  32. package/dist/core/extensions/runner.d.ts.map +1 -1
  33. package/dist/core/extensions/runner.js +4 -0
  34. package/dist/core/extensions/runner.js.map +1 -1
  35. package/dist/core/extensions/types.d.ts +2 -0
  36. package/dist/core/extensions/types.d.ts.map +1 -1
  37. package/dist/core/extensions/types.js.map +1 -1
  38. package/dist/core/keybindings.d.ts +5 -0
  39. package/dist/core/keybindings.d.ts.map +1 -1
  40. package/dist/core/keybindings.js +5 -0
  41. package/dist/core/keybindings.js.map +1 -1
  42. package/dist/core/loadouts.d.ts.map +1 -1
  43. package/dist/core/loadouts.js +27 -48
  44. package/dist/core/loadouts.js.map +1 -1
  45. package/dist/core/model-resolver.d.ts +41 -3
  46. package/dist/core/model-resolver.d.ts.map +1 -1
  47. package/dist/core/model-resolver.js +17 -9
  48. package/dist/core/model-resolver.js.map +1 -1
  49. package/dist/core/provider-resilience.d.ts.map +1 -1
  50. package/dist/core/provider-resilience.js +3 -1
  51. package/dist/core/provider-resilience.js.map +1 -1
  52. package/dist/core/reasoning-router-v4-weights.d.ts.map +1 -1
  53. package/dist/core/reasoning-router-v4-weights.js +9 -3
  54. package/dist/core/reasoning-router-v4-weights.js.map +1 -1
  55. package/dist/core/reasoning-router-v4.d.ts.map +1 -1
  56. package/dist/core/reasoning-router-v4.js +94 -24
  57. package/dist/core/reasoning-router-v4.js.map +1 -1
  58. package/dist/core/resource-loader.d.ts.map +1 -1
  59. package/dist/core/resource-loader.js +11 -5
  60. package/dist/core/resource-loader.js.map +1 -1
  61. package/dist/core/session-file-compaction.d.ts.map +1 -1
  62. package/dist/core/session-file-compaction.js +39 -5
  63. package/dist/core/session-file-compaction.js.map +1 -1
  64. package/dist/core/session-termination.d.ts.map +1 -1
  65. package/dist/core/session-termination.js +1 -1
  66. package/dist/core/session-termination.js.map +1 -1
  67. package/dist/core/settings-manager.d.ts +3 -0
  68. package/dist/core/settings-manager.d.ts.map +1 -1
  69. package/dist/core/settings-manager.js +8 -0
  70. package/dist/core/settings-manager.js.map +1 -1
  71. package/dist/core/system-prompt.d.ts.map +1 -1
  72. package/dist/core/system-prompt.js +36 -31
  73. package/dist/core/system-prompt.js.map +1 -1
  74. package/dist/core/tools/bash.d.ts +2 -0
  75. package/dist/core/tools/bash.d.ts.map +1 -1
  76. package/dist/core/tools/bash.js +38 -11
  77. package/dist/core/tools/bash.js.map +1 -1
  78. package/dist/main.d.ts.map +1 -1
  79. package/dist/main.js +112 -11
  80. package/dist/main.js.map +1 -1
  81. package/dist/modes/interactive/components/control-panel-box.d.ts +27 -0
  82. package/dist/modes/interactive/components/control-panel-box.d.ts.map +1 -1
  83. package/dist/modes/interactive/components/control-panel-box.js +60 -8
  84. package/dist/modes/interactive/components/control-panel-box.js.map +1 -1
  85. package/dist/modes/interactive/components/control-panel-layout.d.ts.map +1 -1
  86. package/dist/modes/interactive/components/control-panel-layout.js +100 -45
  87. package/dist/modes/interactive/components/control-panel-layout.js.map +1 -1
  88. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts +9 -0
  89. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts.map +1 -1
  90. package/dist/modes/interactive/components/control-panel-runtime-status.js +10 -8
  91. package/dist/modes/interactive/components/control-panel-runtime-status.js.map +1 -1
  92. package/dist/modes/interactive/components/control-panel-sparkles.d.ts +5 -0
  93. package/dist/modes/interactive/components/control-panel-sparkles.d.ts.map +1 -1
  94. package/dist/modes/interactive/components/control-panel-sparkles.js +14 -9
  95. package/dist/modes/interactive/components/control-panel-sparkles.js.map +1 -1
  96. package/dist/modes/interactive/components/footer.d.ts +10 -0
  97. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  98. package/dist/modes/interactive/components/footer.js +3 -3
  99. package/dist/modes/interactive/components/footer.js.map +1 -1
  100. package/dist/modes/interactive/components/status-sidebar.d.ts +49 -0
  101. package/dist/modes/interactive/components/status-sidebar.d.ts.map +1 -0
  102. package/dist/modes/interactive/components/status-sidebar.js +253 -0
  103. package/dist/modes/interactive/components/status-sidebar.js.map +1 -0
  104. package/dist/modes/interactive/interactive-mode.d.ts +9 -0
  105. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  106. package/dist/modes/interactive/interactive-mode.js +94 -20
  107. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  108. package/dist/modes/interactive/theme/omk-neon-control.json +13 -13
  109. package/dist/modes/print-mode.d.ts.map +1 -1
  110. package/dist/modes/print-mode.js +9 -0
  111. package/dist/modes/print-mode.js.map +1 -1
  112. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  113. package/dist/modes/rpc/rpc-mode.js +1 -0
  114. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  115. package/dist/utils/clipboard.d.ts.map +1 -1
  116. package/dist/utils/clipboard.js +19 -8
  117. package/dist/utils/clipboard.js.map +1 -1
  118. package/docs/adaptorch-preview-spec.md +174 -0
  119. package/docs/adaptorch-preview.md +1 -1
  120. package/docs/compaction.md +20 -13
  121. package/docs/correctness-wall.md +13 -5
  122. package/docs/custom-provider.md +8 -8
  123. package/docs/development.md +2 -2
  124. package/docs/docs.json +4 -0
  125. package/docs/environment-variables.md +90 -0
  126. package/docs/extensions.md +8 -8
  127. package/docs/index.md +1 -0
  128. package/docs/json.md +4 -4
  129. package/docs/providers.md +1 -1
  130. package/docs/rpc.md +5 -2
  131. package/docs/session-format.md +5 -5
  132. package/docs/settings.md +1 -0
  133. package/docs/skills.md +2 -0
  134. package/docs/themes.md +2 -2
  135. package/docs/tui.md +4 -4
  136. package/docs/usage.md +4 -0
  137. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  138. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  139. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  140. package/examples/extensions/gondolin/package-lock.json +2 -2
  141. package/examples/extensions/gondolin/package.json +1 -1
  142. package/examples/extensions/sandbox/package-lock.json +2 -2
  143. package/examples/extensions/sandbox/package.json +1 -1
  144. package/examples/extensions/subagent/README.md +35 -10
  145. package/examples/extensions/subagent/adaptive-agent-runtime.test.ts +234 -0
  146. package/examples/extensions/subagent/adaptive-agent-runtime.ts +240 -0
  147. package/examples/extensions/subagent/adaptive-result.ts +112 -0
  148. package/examples/extensions/subagent/agents.test.ts +86 -0
  149. package/examples/extensions/subagent/agents.ts +18 -4
  150. package/examples/extensions/subagent/capabilities.ts +15 -1
  151. package/examples/extensions/subagent/checkpoint-runtime.test.ts +125 -0
  152. package/examples/extensions/subagent/checkpoint-runtime.ts +198 -0
  153. package/examples/extensions/subagent/deadline-budget.test.ts +135 -0
  154. package/examples/extensions/subagent/deadline-budget.ts +242 -0
  155. package/examples/extensions/subagent/deadline-profile-store.test.ts +72 -0
  156. package/examples/extensions/subagent/deadline-profile-store.ts +172 -0
  157. package/examples/extensions/subagent/domain-profiles.ts +272 -0
  158. package/examples/extensions/subagent/fixtures/fake-omk-json.mjs +13 -0
  159. package/examples/extensions/subagent/fixtures/hanging-process-tree.mjs +40 -0
  160. package/examples/extensions/subagent/index.ts +253 -137
  161. package/examples/extensions/subagent/managed-process.test.ts +178 -0
  162. package/examples/extensions/subagent/managed-process.ts +236 -0
  163. package/examples/extensions/subagent/subagent-extension-smoke.test.ts +112 -0
  164. package/examples/extensions/subagent/subagent-runtime-types.ts +76 -0
  165. package/examples/extensions/with-deps/package-lock.json +2 -2
  166. package/examples/extensions/with-deps/package.json +1 -1
  167. package/npm-shrinkwrap.json +21 -21
  168. package/package.json +10 -7
package/docs/json.md CHANGED
@@ -8,7 +8,7 @@ Outputs all session events as JSON lines to stdout. Useful for integrating omk i
8
8
 
9
9
  ## Event Types
10
10
 
11
- Events are defined in [`AgentSessionEvent`](https://github.com/earendil-works/omk-mono/blob/main/packages/coding-agent/src/core/agent-session.ts#L102):
11
+ Events are defined in [`AgentSessionEvent`](https://github.com/dmae97/omk/blob/main/packages/coding-agent/src/core/agent-session.ts#L102):
12
12
 
13
13
  ```typescript
14
14
  type AgentSessionEvent =
@@ -22,7 +22,7 @@ type AgentSessionEvent =
22
22
 
23
23
  `queue_update` emits the full pending steering and follow-up queues whenever they change. `compaction_start` and `compaction_end` cover both manual and automatic compaction.
24
24
 
25
- Base events from [`AgentEvent`](https://github.com/earendil-works/omk-mono/blob/main/packages/agent/src/types.ts#L179):
25
+ Base events from [`AgentEvent`](https://github.com/dmae97/omk/blob/main/packages/agent/src/types.ts#L179):
26
26
 
27
27
  ```typescript
28
28
  type AgentEvent =
@@ -44,12 +44,12 @@ type AgentEvent =
44
44
 
45
45
  ## Message Types
46
46
 
47
- Base messages from [`packages/ai/src/types.ts`](https://github.com/earendil-works/omk-mono/blob/main/packages/ai/src/types.ts#L134):
47
+ Base messages from [`packages/ai/src/types.ts`](https://github.com/dmae97/omk/blob/main/packages/ai/src/types.ts#L134):
48
48
  - `UserMessage` (line 134)
49
49
  - `AssistantMessage` (line 140)
50
50
  - `ToolResultMessage` (line 152)
51
51
 
52
- Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/earendil-works/omk-mono/blob/main/packages/coding-agent/src/core/messages.ts#L29):
52
+ Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/dmae97/omk/blob/main/packages/coding-agent/src/core/messages.ts#L29):
53
53
  - `BashExecutionMessage` (line 29)
54
54
  - `CustomMessage` (line 46)
55
55
  - `BranchSummaryMessage` (line 55)
package/docs/providers.md CHANGED
@@ -89,7 +89,7 @@ omk
89
89
  | Xiaomi MiMo Token Plan (Singapore) | `XIAOMI_TOKEN_PLAN_SGP_API_KEY` | `xiaomi-token-plan-sgp` |
90
90
  | Zyloo | `ZYLOO_API_KEY` | `zyloo` |
91
91
 
92
- Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/earendil-works/omk-mono/blob/main/packages/ai/src/env-api-keys.ts) in [`packages/ai/src/env-api-keys.ts`](https://github.com/earendil-works/omk-mono/blob/main/packages/ai/src/env-api-keys.ts).
92
+ Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/dmae97/omk/blob/main/packages/ai/src/env-api-keys.ts) in [`packages/ai/src/env-api-keys.ts`](https://github.com/dmae97/omk/blob/main/packages/ai/src/env-api-keys.ts).
93
93
 
94
94
  #### Zyloo
95
95
 
package/docs/rpc.md CHANGED
@@ -424,12 +424,14 @@ Response:
424
424
 
425
425
  #### bash
426
426
 
427
- Execute a shell command and add output to conversation context.
427
+ Execute a shell command and add output to conversation context. Output streams as `bash_execution_update` events while the command runs; the response contains the final result.
428
428
 
429
429
  ```json
430
- {"type": "bash", "command": "ls -la"}
430
+ {"id": "req-1", "type": "bash", "command": "ls -la"}
431
431
  ```
432
432
 
433
+ Include an `id` to associate streamed `bash_execution_update` events with this command.
434
+
433
435
  Response:
434
436
  ```json
435
437
  {
@@ -753,6 +755,7 @@ Events are streamed to stdout as JSON lines during agent operation. Events do NO
753
755
  | `message_start` | Message begins |
754
756
  | `message_update` | Streaming update (text/thinking/toolcall deltas) |
755
757
  | `message_end` | Message completes |
758
+ | `bash_execution_update` | Direct RPC bash command output chunk (includes originating command `id`) |
756
759
  | `tool_execution_start` | Tool begins execution |
757
760
  | `tool_execution_update` | Tool execution progress (streaming output) |
758
761
  | `tool_execution_end` | Tool completes |
@@ -28,11 +28,11 @@ Existing sessions are automatically migrated to the current version (v3) when lo
28
28
 
29
29
  ## Source Files
30
30
 
31
- Source on GitHub ([omk-mono](https://github.com/earendil-works/omk-mono)):
32
- - [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/earendil-works/omk-mono/blob/main/packages/coding-agent/src/core/session-manager.ts) - Session entry types and SessionManager
33
- - [`packages/coding-agent/src/core/messages.ts`](https://github.com/earendil-works/omk-mono/blob/main/packages/coding-agent/src/core/messages.ts) - Extended message types (BashExecutionMessage, CustomMessage, etc.)
34
- - [`packages/ai/src/types.ts`](https://github.com/earendil-works/omk-mono/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
35
- - [`packages/agent/src/types.ts`](https://github.com/earendil-works/omk-mono/blob/main/packages/agent/src/types.ts) - AgentMessage union type
31
+ Source on GitHub ([omk-mono](https://github.com/dmae97/omk)):
32
+ - [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/dmae97/omk/blob/main/packages/coding-agent/src/core/session-manager.ts) - Session entry types and SessionManager
33
+ - [`packages/coding-agent/src/core/messages.ts`](https://github.com/dmae97/omk/blob/main/packages/coding-agent/src/core/messages.ts) - Extended message types (BashExecutionMessage, CustomMessage, etc.)
34
+ - [`packages/ai/src/types.ts`](https://github.com/dmae97/omk/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
35
+ - [`packages/agent/src/types.ts`](https://github.com/dmae97/omk/blob/main/packages/agent/src/types.ts) - AgentMessage union type
36
36
 
37
37
  For TypeScript definitions in your project, inspect `node_modules/open-multi-agent-kit/dist/` and `node_modules/omk-ai/dist/`.
38
38
 
package/docs/settings.md CHANGED
@@ -77,6 +77,7 @@ Advisory-only hint source for the v4 auto thinking-level resolver. Read from the
77
77
  | `editorPaddingX` | number | `0` | Horizontal padding for input editor (0-3) |
78
78
  | `autocompleteMaxVisible` | number | `5` | Max visible items in autocomplete dropdown (3-20) |
79
79
  | `showHardwareCursor` | boolean | `false` | Show the terminal cursor while TUI positions it for IME support |
80
+ | `pinStatusSidebar` | boolean | `false` | Pin the bottom status bar as a responsive right rail (opencode-style): width scales with the terminal (~26%, 34–48 cols), the MCP roster grows on taller terminals, and the content column shrinks to match so the prompt is never covered. Toggle anytime with `Ctrl+Q`. Also enabled by `OMK_PIN_STATUS_SIDEBAR=1` |
80
81
 
81
82
  ### Telemetry and update checks
82
83
 
package/docs/skills.md CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  Skills are self-contained capability packages that the agent loads on-demand. A skill provides specialized workflows, setup instructions, helper scripts, and reference documentation for specific tasks.
6
6
 
7
+ OMK ships with **no built-in skills** — every skill is user-installed via the locations below, an OMK package, or `--skill`. The default session has zero skills and zero MCP servers configured.
8
+
7
9
  OMK implements the [Agent Skills standard](https://agentskills.io/specification), warning about most violations but remaining lenient. OMK allows skill names to differ from their parent directory even though the standard disallows it; that rule is suboptimal for shared skill directories used across multiple agent harnesses.
8
10
 
9
11
  ## Table of Contents
package/docs/themes.md CHANGED
@@ -56,7 +56,7 @@ vim ~/.omk/agent/themes/my-theme.json
56
56
 
57
57
  ```json
58
58
  {
59
- "$schema": "https://raw.githubusercontent.com/earendil-works/omk/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
59
+ "$schema": "https://raw.githubusercontent.com/dmae97/omk/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
60
60
  "name": "my-theme",
61
61
  "vars": {
62
62
  "primary": "#00aaff",
@@ -126,7 +126,7 @@ vim ~/.omk/agent/themes/my-theme.json
126
126
 
127
127
  ```json
128
128
  {
129
- "$schema": "https://raw.githubusercontent.com/earendil-works/omk/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
129
+ "$schema": "https://raw.githubusercontent.com/dmae97/omk/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
130
130
  "name": "my-theme",
131
131
  "vars": {
132
132
  "blue": "#0066cc",
package/docs/tui.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Extensions and custom tools can render custom TUI components for interactive user interfaces. This page covers the component system and available building blocks.
6
6
 
7
- **Source:** [`omk-tui`](https://github.com/earendil-works/omk-mono/tree/main/packages/tui)
7
+ **Source:** [`omk-tui`](https://github.com/dmae97/omk/tree/main/packages/tui)
8
8
 
9
9
  ## Component Interface
10
10
 
@@ -742,7 +742,7 @@ ctx.ui.setStatus("my-ext", ctx.ui.theme.fg("accent", "● active"));
742
742
  ctx.ui.setStatus("my-ext", undefined);
743
743
  ```
744
744
 
745
- **Examples:** [status-line.ts](../examples/extensions/status-line.ts), [plan-mode.ts](../examples/extensions/plan-mode.ts), [preset.ts](../examples/extensions/preset.ts)
745
+ **Examples:** [status-line.ts](../examples/extensions/status-line.ts), [plan-mode.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts)
746
746
 
747
747
  ### Pattern 4b: Working Indicator Customization
748
748
 
@@ -802,7 +802,7 @@ ctx.ui.setWidget("my-widget", (_tui, theme) => {
802
802
  ctx.ui.setWidget("my-widget", undefined);
803
803
  ```
804
804
 
805
- **Examples:** [plan-mode.ts](../examples/extensions/plan-mode.ts)
805
+ **Examples:** [plan-mode.ts](../examples/extensions/plan-mode/index.ts)
806
806
 
807
807
  ### Pattern 6: Custom Footer
808
808
 
@@ -919,7 +919,7 @@ export default function (omk: ExtensionAPI) {
919
919
  - **Selection UI**: [examples/extensions/preset.ts](../examples/extensions/preset.ts) - SelectList with DynamicBorder framing
920
920
  - **Async with cancel**: [examples/extensions/qna.ts](../examples/extensions/qna.ts) - BorderedLoader for LLM calls
921
921
  - **Settings toggles**: [examples/extensions/tools.ts](../examples/extensions/tools.ts) - SettingsList for tool enable/disable
922
- - **Status indicators**: [examples/extensions/plan-mode.ts](../examples/extensions/plan-mode.ts) - setStatus and setWidget
922
+ - **Status indicators**: [examples/extensions/plan-mode/index.ts](../examples/extensions/plan-mode/index.ts) - setStatus and setWidget
923
923
  - **Working indicator**: [examples/extensions/working-indicator.ts](../examples/extensions/working-indicator.ts) - setWorkingIndicator
924
924
  - **Custom footer**: [examples/extensions/custom-footer.ts](../examples/extensions/custom-footer.ts) - setFooter with stats
925
925
  - **Custom editor**: [examples/extensions/modal-editor.ts](../examples/extensions/modal-editor.ts) - Vim-like modal editing
package/docs/usage.md CHANGED
@@ -151,6 +151,8 @@ OMK loads `AGENTS.md` or `CLAUDE.md` at startup from:
151
151
 
152
152
  Use context files for project conventions, commands, safety rules, and preferences. Disable loading with `--no-context-files` or `-nc`.
153
153
 
154
+ The core prompt builder places a fixed runtime trust boundary before loaded context and skill metadata. Global context can constrain project context, but loaded resources cannot expand user authorization or override active runtime/security controls. Context paths and text are XML-escaped before prompt assembly so resource content cannot break out of its structural envelope. This is defense in depth, not a code sandbox: extensions are executable trusted code and can explicitly rewrite the system prompt or final provider payload.
155
+
154
156
  ### System Prompt Files
155
157
 
156
158
  Replace the default system prompt with:
@@ -160,6 +162,8 @@ Replace the default system prompt with:
160
162
 
161
163
  Append to the default prompt without replacing it with `APPEND_SYSTEM.md` in either location.
162
164
 
165
+ Replacing or appending the default prompt does not remove the core runtime trust boundary; OMK inserts it after custom prompt text and before context files and skills.
166
+
163
167
  ## Exporting and Sharing Sessions
164
168
 
165
169
  Use `/export [file]` to write a session to HTML.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omk-extension-custom-provider-anthropic",
3
- "version": "0.91.0",
3
+ "version": "0.93.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omk-extension-custom-provider-anthropic",
9
- "version": "0.91.0",
9
+ "version": "0.93.0",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sdk": "0.52.0"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "omk-extension-custom-provider-anthropic",
3
3
  "private": true,
4
- "version": "0.91.0",
4
+ "version": "0.93.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "omk-extension-custom-provider-gitlab-duo",
3
3
  "private": true,
4
- "version": "0.91.0",
4
+ "version": "0.93.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omk-extension-gondolin",
3
- "version": "0.91.0",
3
+ "version": "0.93.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omk-extension-gondolin",
9
- "version": "0.91.0",
9
+ "version": "0.93.0",
10
10
  "dependencies": {
11
11
  "@earendil-works/gondolin": "0.12.0"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "omk-extension-gondolin",
3
3
  "private": true,
4
- "version": "0.91.0",
4
+ "version": "0.93.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omk-extension-sandbox",
3
- "version": "0.91.0",
3
+ "version": "0.93.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omk-extension-sandbox",
9
- "version": "0.91.0",
9
+ "version": "0.93.0",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sandbox-runtime": "0.0.26"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "omk-extension-sandbox",
3
3
  "private": true,
4
- "version": "0.91.0",
4
+ "version": "0.93.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -9,15 +9,25 @@ Delegate tasks to specialized subagents with isolated context windows.
9
9
  - **Parallel streaming**: All parallel tasks stream updates simultaneously
10
10
  - **Markdown rendering**: Final output rendered with proper formatting (expanded view)
11
11
  - **Usage tracking**: Shows turns, tokens, cost, and context usage per agent
12
- - **Abort support**: Ctrl+C propagates to kill subagent processes
12
+ - **Abort support**: Ctrl+C propagates to the entire detached subagent process tree
13
+ - **Dual-budget planning**: Predictive sharding uses both estimated tokens and learned wall-clock demand
14
+ - **Checkpoint resume**: A cutoff resumes only the unfinished shard with bounded prior evidence
15
+ - **Cutoff learning**: Completion/cutoff history is persisted per provider and model under the agent state directory
16
+ - **Bounded cost**: At most 3 semantic shards and 1 resume across the whole logical task by default
13
17
 
14
18
  ## Structure
15
19
 
16
20
  ```
17
21
  subagent/
18
22
  ├── README.md # This file
19
- ├── index.ts # The extension (entry point)
20
- ├── agents.ts # Agent discovery logic
23
+ ├── index.ts # The extension entry point
24
+ ├── adaptive-agent-runtime.ts # Shard/checkpoint/resume coordinator
25
+ ├── checkpoint-runtime.ts # Bounded checkpoint protocol
26
+ ├── deadline-budget.ts # Token + wall-clock planning and cutoff learning
27
+ ├── deadline-profile-store.ts # Persistent provider/model profiles
28
+ ├── managed-process.ts # Process-tree termination and cleanup
29
+ ├── subagent-runtime-types.ts # Typed result/deadline metadata
30
+ ├── agents.ts # Agent discovery logic
21
31
  ├── agents/ # Sample agent definitions
22
32
  │ ├── scout.md # Fast recon, returns compressed context
23
33
  │ ├── planner.md # Creates implementation plans
@@ -36,8 +46,12 @@ From the repository root, symlink the files:
36
46
  ```bash
37
47
  # Symlink the extension (must be in a subdirectory with index.ts)
38
48
  mkdir -p ~/.omk/agent/extensions/subagent
39
- ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/index.ts" ~/.omk/agent/extensions/subagent/index.ts
40
- ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/agents.ts" ~/.omk/agent/extensions/subagent/agents.ts
49
+ src="$(pwd)/packages/coding-agent/examples/extensions/subagent"
50
+ for f in index.ts agents.ts agent-capability-router.ts capabilities.ts domain-profiles.ts \
51
+ adaptive-agent-runtime.ts adaptive-result.ts checkpoint-runtime.ts deadline-budget.ts \
52
+ deadline-profile-store.ts managed-process.ts subagent-runtime-types.ts; do
53
+ ln -sf "$src/$f" ~/.omk/agent/extensions/subagent/$f
54
+ done
41
55
 
42
56
  # Symlink agents
43
57
  mkdir -p ~/.omk/agent/agents
@@ -92,9 +106,16 @@ Use a chain: first have scout find the read tool, then have planner suggest impr
92
106
 
93
107
  | Mode | Parameter | Description |
94
108
  |------|-----------|-------------|
95
- | Single | `{ agent, task }` | One agent, one task |
96
- | Parallel | `{ tasks: [...] }` | Multiple agents run concurrently (max 8, 4 concurrent) |
97
- | Chain | `{ chain: [...] }` | Sequential with `{previous}` placeholder |
109
+ | Single | `{ agent, task }` | One logical task; the runtime may split it into bounded semantic shards |
110
+ | Parallel | `{ tasks: [...] }` | Multiple logical tasks run concurrently (max 8, 4 concurrent) |
111
+ | Chain | `{ chain: [...] }` | Sequential with `{previous}` placeholder and a fair deadline share per remaining step |
112
+
113
+ Optional execution controls:
114
+
115
+ | Parameter | Default | Description |
116
+ |-----------|---------|-------------|
117
+ | `executionBudgetMs` | `840000` | Internal hard budget, leaving 60 seconds before a configured 900000 ms tool timeout |
118
+ | `maxResumeAttempts` | `1` | Retries only the active unfinished shard; accepted range is 0-2 |
98
119
 
99
120
  ## Output Display
100
121
 
@@ -164,8 +185,10 @@ Project agents override user agents with the same name when `agentScope: "both"`
164
185
 
165
186
  - **Exit code != 0**: Tool returns error with stderr/output
166
187
  - **stopReason "error"**: LLM error propagated with error message
167
- - **stopReason "aborted"**: User abort (Ctrl+C) kills subprocess, throws error
168
- - **Chain mode**: Stops at first failing step, reports which step failed
188
+ - **stopReason "aborted"**: User abort (Ctrl+C) terminates and reaps the subprocess tree
189
+ - **stopReason "deadline"**: Internal cutoff returns elapsed/deadline/checkpoint/resume metadata instead of reaching the outer tool timeout
190
+ - **Chain mode**: Stops at first failing step, reports which step failed, and preserves completed earlier steps
191
+ - **Duplicate prevention**: A cutoff with no new checkpoint or streamed evidence is not retried
169
192
 
170
193
  ## Limitations
171
194
 
@@ -173,3 +196,5 @@ Project agents override user agents with the same name when `agentScope: "both"`
173
196
  - Parallel model-visible output is capped at 50 KB per task; full results remain in tool details
174
197
  - Agents discovered fresh on each invocation (allows editing mid-session)
175
198
  - Parallel mode limited to 8 tasks, 4 concurrent
199
+ - Automatic semantic pre-sharding requires an explicit numbered/checklist action list; indivisible prose is checkpointed and resumed as one shard
200
+ - Checkpoints are best-effort child artifacts plus runtime-captured stream evidence; workspace side effects remain the source of truth after a cutoff
@@ -0,0 +1,234 @@
1
+ import * as fs from "node:fs";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+ import type { Message } from "omk-ai";
5
+ import { afterEach, describe, expect, it } from "vitest";
6
+ import { type RunAttemptInput, runAdaptiveAgent } from "./adaptive-agent-runtime.ts";
7
+ import { createExecutionBudget } from "./deadline-budget.ts";
8
+ import { DeadlineProfileStore } from "./deadline-profile-store.ts";
9
+ import { emptyUsage, type SingleResult, type SubagentAttemptResult } from "./subagent-runtime-types.ts";
10
+
11
+ const cleanupPaths: string[] = [];
12
+
13
+ function assistant(text: string): Message {
14
+ return { role: "assistant", content: [{ type: "text", text }] } as Message;
15
+ }
16
+
17
+ function attempt(input: RunAttemptInput, outcome: "completed" | "cutoff" | "failed", text = ""): SubagentAttemptResult {
18
+ const exitCode = outcome === "completed" ? 0 : outcome === "failed" ? 1 : 124;
19
+ const result: SingleResult = {
20
+ agent: "reviewer",
21
+ agentSource: "user",
22
+ task: input.logicalTask,
23
+ exitCode,
24
+ messages: text === "" ? [] : [assistant(text)],
25
+ stderr: "",
26
+ usage: emptyUsage(),
27
+ output: text,
28
+ model: "openai-codex/gpt-5.6",
29
+ ...(outcome === "cutoff"
30
+ ? { stopReason: "deadline", errorMessage: "attempt cutoff" }
31
+ : { stopReason: outcome === "failed" ? "error" : "end" }),
32
+ };
33
+ return {
34
+ result,
35
+ process: {
36
+ reason: outcome === "failed" ? "completed" : outcome,
37
+ elapsedMs: outcome === "completed" ? 10 : input.cutoffMs,
38
+ cleanup: { termSent: outcome === "cutoff", killSent: false, processGroup: true },
39
+ },
40
+ };
41
+ }
42
+
43
+ afterEach(async () => {
44
+ await Promise.all(cleanupPaths.splice(0).map((entry) => fs.promises.rm(entry, { recursive: true, force: true })));
45
+ });
46
+
47
+ describe("adaptive subagent execution", () => {
48
+ it("resumes only the unfinished shard from bounded checkpoint evidence", async () => {
49
+ const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-resume-"));
50
+ cleanupPaths.push(dir);
51
+ const calls: RunAttemptInput[] = [];
52
+ const outputs = ["completed boundary inspection", "finished remaining cleanup"];
53
+ const result = await runAdaptiveAgent({
54
+ agentName: "reviewer",
55
+ agentSource: "user",
56
+ logicalTask: "Review and fix the process boundary.",
57
+ model: "openai-codex/gpt-5.6",
58
+ budget: createExecutionBudget({
59
+ hardDeadlineMs: 5_000,
60
+ cleanupReserveMs: 100,
61
+ maxResumeAttempts: 1,
62
+ maxTaskShards: 3,
63
+ }),
64
+ pendingSequentialTasks: 1,
65
+ checkpointPrefix: path.join(dir, "checkpoint-"),
66
+ profileStore: new DeadlineProfileStore(path.join(dir, "profiles.json")),
67
+ policy: { fallbackAttemptMs: 1_000, minimumAttemptMs: 1, maxTokensPerShard: 6_000 },
68
+ runAttempt: async (input) => {
69
+ calls.push(input);
70
+ return attempt(input, calls.length === 1 ? "cutoff" : "completed", outputs[calls.length - 1]);
71
+ },
72
+ });
73
+
74
+ expect(calls).toHaveLength(2);
75
+ expect(calls[1]?.task).toContain("completed boundary inspection");
76
+ expect(calls[1]?.task).toContain("Do not repeat completed side effects");
77
+ expect(result.deadline).toMatchObject({ outcome: "completed", resumeCount: 1, completedShardIds: ["shard-1"] });
78
+ expect(result.output).toContain("completed boundary inspection");
79
+ expect(result.output).toContain("finished remaining cleanup");
80
+ });
81
+
82
+ it("learns the provider/model observed from output when the agent inherits its model", async () => {
83
+ const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-observed-model-"));
84
+ cleanupPaths.push(dir);
85
+ const store = new DeadlineProfileStore(path.join(dir, "profiles.json"));
86
+ const result = await runAdaptiveAgent({
87
+ agentName: "reviewer",
88
+ agentSource: "user",
89
+ logicalTask: "Review the process boundary.",
90
+ budget: createExecutionBudget({
91
+ hardDeadlineMs: 5_000,
92
+ cleanupReserveMs: 100,
93
+ maxResumeAttempts: 1,
94
+ maxTaskShards: 3,
95
+ }),
96
+ pendingSequentialTasks: 1,
97
+ checkpointPrefix: path.join(dir, "checkpoint-"),
98
+ profileStore: store,
99
+ policy: { fallbackAttemptMs: 1_000, minimumAttemptMs: 1, maxTokensPerShard: 6_000 },
100
+ runAttempt: async (input) => attempt(input, "completed", "review complete"),
101
+ });
102
+
103
+ expect(result.deadline).toMatchObject({ provider: "openai-codex", model: "gpt-5.6" });
104
+ expect(await store.profileFor("openai-codex", "gpt-5.6")).toMatchObject({ samples: 1, completions: 1 });
105
+ });
106
+
107
+ it("preserves process failures instead of labeling them as deadline cutoffs", async () => {
108
+ const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-failure-"));
109
+ cleanupPaths.push(dir);
110
+ const result = await runAdaptiveAgent({
111
+ agentName: "reviewer",
112
+ agentSource: "user",
113
+ logicalTask: "Run the failing fixture.",
114
+ budget: createExecutionBudget({
115
+ hardDeadlineMs: 5_000,
116
+ cleanupReserveMs: 100,
117
+ maxResumeAttempts: 1,
118
+ maxTaskShards: 3,
119
+ }),
120
+ pendingSequentialTasks: 1,
121
+ checkpointPrefix: path.join(dir, "checkpoint-"),
122
+ profileStore: new DeadlineProfileStore(path.join(dir, "profiles.json")),
123
+ policy: { fallbackAttemptMs: 1_000, minimumAttemptMs: 1, maxTokensPerShard: 6_000 },
124
+ runAttempt: async (input) => attempt(input, "failed", ""),
125
+ });
126
+
127
+ expect(result).toMatchObject({ exitCode: 1, stopReason: "error", errorMessage: "Subagent process failed" });
128
+ expect(result.deadline).toMatchObject({ outcome: "failed" });
129
+ });
130
+
131
+ it("does not retry a cutoff that produced no checkpoint or streamed progress", async () => {
132
+ const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-duplicate-"));
133
+ cleanupPaths.push(dir);
134
+ let calls = 0;
135
+ const result = await runAdaptiveAgent({
136
+ agentName: "reviewer",
137
+ agentSource: "user",
138
+ logicalTask: "Review the process boundary.",
139
+ model: "openai-codex/gpt-5.6",
140
+ budget: createExecutionBudget({
141
+ hardDeadlineMs: 5_000,
142
+ cleanupReserveMs: 100,
143
+ maxResumeAttempts: 2,
144
+ maxTaskShards: 3,
145
+ }),
146
+ pendingSequentialTasks: 1,
147
+ checkpointPrefix: path.join(dir, "checkpoint-"),
148
+ profileStore: new DeadlineProfileStore(path.join(dir, "profiles.json")),
149
+ policy: { fallbackAttemptMs: 1_000, minimumAttemptMs: 1, maxTokensPerShard: 6_000 },
150
+ runAttempt: async (input) => {
151
+ calls += 1;
152
+ return attempt(input, "cutoff");
153
+ },
154
+ });
155
+
156
+ expect(calls).toBe(1);
157
+ expect(result.deadline).toMatchObject({ outcome: "cutoff", resumeCount: 0, duplicateResumeBlocked: true });
158
+ });
159
+
160
+ it("never re-executes shards that already completed", async () => {
161
+ const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-shards-"));
162
+ cleanupPaths.push(dir);
163
+ const shardIds: string[] = [];
164
+ const task = [
165
+ "Upgrade runtime:",
166
+ "1. Inspect the process.",
167
+ "2. Add cleanup.",
168
+ "3. Implement metadata.",
169
+ "4. Run tests.",
170
+ ].join("\n");
171
+ const result = await runAdaptiveAgent({
172
+ agentName: "worker",
173
+ agentSource: "user",
174
+ logicalTask: task,
175
+ model: "anthropic/claude-sonnet",
176
+ budget: createExecutionBudget({
177
+ hardDeadlineMs: 5_000,
178
+ cleanupReserveMs: 100,
179
+ maxResumeAttempts: 1,
180
+ maxTaskShards: 3,
181
+ }),
182
+ pendingSequentialTasks: 1,
183
+ checkpointPrefix: path.join(dir, "checkpoint-"),
184
+ profileStore: new DeadlineProfileStore(path.join(dir, "profiles.json")),
185
+ policy: { fallbackAttemptMs: 200, minimumAttemptMs: 1, maxTokensPerShard: 20 },
186
+ runAttempt: async (input) => {
187
+ shardIds.push(input.shardId);
188
+ return attempt(input, "completed", `done ${input.shardId}`);
189
+ },
190
+ });
191
+
192
+ expect(shardIds.length).toBeGreaterThan(1);
193
+ expect(new Set(shardIds).size).toBe(shardIds.length);
194
+ expect(result.deadline?.remainingShardIds).toEqual([]);
195
+ });
196
+
197
+ it("caps resume cost across the whole logical task rather than once per shard", async () => {
198
+ const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-cost-cap-"));
199
+ cleanupPaths.push(dir);
200
+ const shardIds: string[] = [];
201
+ const task = [
202
+ "Upgrade runtime:",
203
+ "1. Inspect the process.",
204
+ "2. Add cleanup.",
205
+ "3. Implement metadata.",
206
+ "4. Run tests.",
207
+ ].join("\n");
208
+ const result = await runAdaptiveAgent({
209
+ agentName: "worker",
210
+ agentSource: "user",
211
+ logicalTask: task,
212
+ model: "openai-codex/gpt-5.6",
213
+ budget: createExecutionBudget({
214
+ hardDeadlineMs: 5_000,
215
+ cleanupReserveMs: 100,
216
+ maxResumeAttempts: 1,
217
+ maxTaskShards: 3,
218
+ }),
219
+ pendingSequentialTasks: 1,
220
+ checkpointPrefix: path.join(dir, "checkpoint-"),
221
+ profileStore: new DeadlineProfileStore(path.join(dir, "profiles.json")),
222
+ policy: { fallbackAttemptMs: 200, minimumAttemptMs: 1, maxTokensPerShard: 20 },
223
+ runAttempt: async (input) => {
224
+ shardIds.push(input.shardId);
225
+ const outcome = shardIds.length === 2 ? "completed" : "cutoff";
226
+ return attempt(input, outcome, `progress ${input.shardId} ${shardIds.length}`);
227
+ },
228
+ });
229
+
230
+ expect(shardIds).toEqual(["shard-1", "shard-1", "shard-2"]);
231
+ expect(result.deadline).toMatchObject({ resumeCount: 1, outcome: "cutoff" });
232
+ expect(result.deadline?.remainingShardIds).toContain("shard-2");
233
+ });
234
+ });