loadouts 0.3.0 → 0.4.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 (190) hide show
  1. package/bundled/embedded/pi/loadouts-runtime.ts +6543 -1504
  2. package/bundled/extensions/loadouts-runtime/index.ts +6543 -1504
  3. package/bundled/loadouts/opencode-runtime.yaml +2 -4
  4. package/bundled/opencode/plugins/loadouts/index.js +39198 -0
  5. package/bundled/opencode/plugins/loadouts/package.json +9 -0
  6. package/bundled/{embedded/opencode/loadouts-runtime.tsx → opencode/plugins/loadouts/tui.js} +4008 -1556
  7. package/dist/builtins/agent-transforms.d.ts.map +1 -1
  8. package/dist/builtins/agent-transforms.js +31 -10
  9. package/dist/builtins/agent-transforms.js.map +1 -1
  10. package/dist/builtins/index.d.ts.map +1 -1
  11. package/dist/builtins/index.js +14 -5
  12. package/dist/builtins/index.js.map +1 -1
  13. package/dist/builtins/kinds/opencode-cli-config.d.ts +3 -0
  14. package/dist/builtins/kinds/opencode-cli-config.d.ts.map +1 -0
  15. package/dist/builtins/kinds/opencode-cli-config.js +10 -0
  16. package/dist/builtins/kinds/opencode-cli-config.js.map +1 -0
  17. package/dist/builtins/kinds/opencode-plugin-dir.d.ts +3 -0
  18. package/dist/builtins/kinds/opencode-plugin-dir.d.ts.map +1 -0
  19. package/dist/builtins/kinds/opencode-plugin-dir.js +11 -0
  20. package/dist/builtins/kinds/opencode-plugin-dir.js.map +1 -0
  21. package/dist/builtins/tools/opencode.d.ts.map +1 -1
  22. package/dist/builtins/tools/opencode.js +10 -7
  23. package/dist/builtins/tools/opencode.js.map +1 -1
  24. package/dist/cli/commands/activate.d.ts.map +1 -1
  25. package/dist/cli/commands/activate.js +0 -7
  26. package/dist/cli/commands/activate.js.map +1 -1
  27. package/dist/cli/commands/session.d.ts +3 -0
  28. package/dist/cli/commands/session.d.ts.map +1 -0
  29. package/dist/cli/commands/session.js +68 -0
  30. package/dist/cli/commands/session.js.map +1 -0
  31. package/dist/cli/commands/status.js +1 -1
  32. package/dist/cli/commands/status.js.map +1 -1
  33. package/dist/cli/commands/sync.d.ts.map +1 -1
  34. package/dist/cli/commands/sync.js +5 -5
  35. package/dist/cli/commands/sync.js.map +1 -1
  36. package/dist/cli/index.d.ts.map +1 -1
  37. package/dist/cli/index.js +2 -0
  38. package/dist/cli/index.js.map +1 -1
  39. package/dist/core/discovery.js +1 -1
  40. package/dist/core/discovery.js.map +1 -1
  41. package/dist/core/import-discovery.d.ts.map +1 -1
  42. package/dist/core/import-discovery.js +2 -0
  43. package/dist/core/import-discovery.js.map +1 -1
  44. package/dist/core/registry.d.ts +5 -0
  45. package/dist/core/registry.d.ts.map +1 -1
  46. package/dist/core/registry.js.map +1 -1
  47. package/dist/core/render.d.ts.map +1 -1
  48. package/dist/core/render.js +29 -1
  49. package/dist/core/render.js.map +1 -1
  50. package/dist/core/resolve.d.ts.map +1 -1
  51. package/dist/core/resolve.js +1 -0
  52. package/dist/core/resolve.js.map +1 -1
  53. package/dist/core/runtime.d.ts +4 -0
  54. package/dist/core/runtime.d.ts.map +1 -1
  55. package/dist/core/runtime.js +10 -3
  56. package/dist/core/runtime.js.map +1 -1
  57. package/dist/core/schema.d.ts +59 -0
  58. package/dist/core/schema.d.ts.map +1 -1
  59. package/dist/core/schema.js +5 -0
  60. package/dist/core/schema.js.map +1 -1
  61. package/dist/core/types.d.ts +13 -0
  62. package/dist/core/types.d.ts.map +1 -1
  63. package/dist/integrations/opencode/advertisement.d.ts +7 -0
  64. package/dist/integrations/opencode/advertisement.d.ts.map +1 -0
  65. package/dist/integrations/opencode/advertisement.js +17 -0
  66. package/dist/integrations/opencode/advertisement.js.map +1 -0
  67. package/dist/integrations/opencode/client.d.ts +12 -0
  68. package/dist/integrations/opencode/client.d.ts.map +1 -0
  69. package/dist/integrations/opencode/client.js +48 -0
  70. package/dist/integrations/opencode/client.js.map +1 -0
  71. package/dist/integrations/opencode/command.d.ts +11 -0
  72. package/dist/integrations/opencode/command.d.ts.map +1 -0
  73. package/dist/integrations/opencode/command.js +19 -0
  74. package/dist/integrations/opencode/command.js.map +1 -0
  75. package/dist/integrations/opencode/delta.d.ts +15 -0
  76. package/dist/integrations/opencode/delta.d.ts.map +1 -0
  77. package/dist/integrations/opencode/delta.js +75 -0
  78. package/dist/integrations/opencode/delta.js.map +1 -0
  79. package/dist/integrations/opencode/session.d.ts +207 -0
  80. package/dist/integrations/opencode/session.d.ts.map +1 -0
  81. package/dist/integrations/opencode/session.js +201 -0
  82. package/dist/integrations/opencode/session.js.map +1 -0
  83. package/dist/lib/gitignore.d.ts +7 -3
  84. package/dist/lib/gitignore.d.ts.map +1 -1
  85. package/dist/lib/gitignore.js +15 -7
  86. package/dist/lib/gitignore.js.map +1 -1
  87. package/dist/tui/core/actions.d.ts +3 -4
  88. package/dist/tui/core/actions.d.ts.map +1 -1
  89. package/dist/tui/core/actions.js +21 -15
  90. package/dist/tui/core/actions.js.map +1 -1
  91. package/dist/tui/core/controller.d.ts +28 -0
  92. package/dist/tui/core/controller.d.ts.map +1 -0
  93. package/dist/tui/core/controller.js +78 -0
  94. package/dist/tui/core/controller.js.map +1 -0
  95. package/dist/tui/core/data.d.ts +4 -2
  96. package/dist/tui/core/data.d.ts.map +1 -1
  97. package/dist/tui/core/data.js +14 -3
  98. package/dist/tui/core/data.js.map +1 -1
  99. package/dist/tui/core/host.d.ts +5 -11
  100. package/dist/tui/core/host.d.ts.map +1 -1
  101. package/dist/tui/core/intent.d.ts +18 -3
  102. package/dist/tui/core/intent.d.ts.map +1 -1
  103. package/dist/tui/core/keymap.d.ts +2 -1
  104. package/dist/tui/core/keymap.d.ts.map +1 -1
  105. package/dist/tui/core/keymap.js +38 -6
  106. package/dist/tui/core/keymap.js.map +1 -1
  107. package/dist/tui/core/model.d.ts +18 -6
  108. package/dist/tui/core/model.d.ts.map +1 -1
  109. package/dist/tui/core/model.js +4 -3
  110. package/dist/tui/core/model.js.map +1 -1
  111. package/dist/tui/core/selection.d.ts +12 -0
  112. package/dist/tui/core/selection.d.ts.map +1 -0
  113. package/dist/tui/core/selection.js +42 -0
  114. package/dist/tui/core/selection.js.map +1 -0
  115. package/dist/tui/core/update.d.ts.map +1 -1
  116. package/dist/tui/core/update.js +140 -126
  117. package/dist/tui/core/update.js.map +1 -1
  118. package/dist/tui/core/view.d.ts.map +1 -1
  119. package/dist/tui/core/view.js +43 -31
  120. package/dist/tui/core/view.js.map +1 -1
  121. package/dist/tui/core/viewport.d.ts +5 -0
  122. package/dist/tui/core/viewport.d.ts.map +1 -0
  123. package/dist/tui/core/viewport.js +33 -0
  124. package/dist/tui/core/viewport.js.map +1 -0
  125. package/dist/tui/core/viewspec.d.ts +5 -0
  126. package/dist/tui/core/viewspec.d.ts.map +1 -1
  127. package/dist/tui/hosts/pi/embed-entry.d.ts.map +1 -1
  128. package/dist/tui/hosts/pi/embed-entry.js +74 -197
  129. package/dist/tui/hosts/pi/embed-entry.js.map +1 -1
  130. package/dist/tui/hosts/pi/inject.d.ts +46 -29
  131. package/dist/tui/hosts/pi/inject.d.ts.map +1 -1
  132. package/dist/tui/hosts/pi/inject.js +25 -47
  133. package/dist/tui/hosts/pi/inject.js.map +1 -1
  134. package/dist/tui/hosts/standalone.d.ts.map +1 -1
  135. package/dist/tui/hosts/standalone.js +75 -111
  136. package/dist/tui/hosts/standalone.js.map +1 -1
  137. package/dist/tui/skins/pi-tui/input.js +4 -0
  138. package/dist/tui/skins/pi-tui/input.js.map +1 -1
  139. package/dist/tui/skins/pi-tui/render.d.ts +6 -3
  140. package/dist/tui/skins/pi-tui/render.d.ts.map +1 -1
  141. package/dist/tui/skins/pi-tui/render.js +32 -24
  142. package/dist/tui/skins/pi-tui/render.js.map +1 -1
  143. package/docs/archive/opencode-v2-runtime-beta-18707.md +813 -0
  144. package/docs/authoring.md +47 -44
  145. package/docs/commands.md +21 -1
  146. package/docs/compatibility.md +2 -2
  147. package/docs/concepts.md +2 -2
  148. package/docs/opencode-v2-probes.md +253 -0
  149. package/docs/opencode-v2-runtime.md +129 -0
  150. package/docs/registry.md +1366 -0
  151. package/docs/runtime.md +112 -82
  152. package/docs/troubleshooting.md +17 -15
  153. package/docs/tui-architecture.md +10 -8
  154. package/package.json +12 -7
  155. package/bundled/opencode/commands/loadouts.md +0 -3
  156. package/bundled/opencode/plugins/loadouts-runtime-tui.tsx +0 -14461
  157. package/bundled/opencode/plugins/loadouts-runtime.ts +0 -533
  158. package/bundled/opencode/tui.jsonc +0 -5
  159. package/dist/builtins/kinds/opencode-tui-config.d.ts +0 -3
  160. package/dist/builtins/kinds/opencode-tui-config.d.ts.map +0 -1
  161. package/dist/builtins/kinds/opencode-tui-config.js +0 -8
  162. package/dist/builtins/kinds/opencode-tui-config.js.map +0 -1
  163. package/dist/integrations/opencode-runtime/bridge.d.ts +0 -17
  164. package/dist/integrations/opencode-runtime/bridge.d.ts.map +0 -1
  165. package/dist/integrations/opencode-runtime/bridge.js +0 -60
  166. package/dist/integrations/opencode-runtime/bridge.js.map +0 -1
  167. package/dist/integrations/opencode-runtime/command.d.ts +0 -4
  168. package/dist/integrations/opencode-runtime/command.d.ts.map +0 -1
  169. package/dist/integrations/opencode-runtime/command.js +0 -200
  170. package/dist/integrations/opencode-runtime/command.js.map +0 -1
  171. package/dist/integrations/opencode-runtime/index.d.ts +0 -6
  172. package/dist/integrations/opencode-runtime/index.d.ts.map +0 -1
  173. package/dist/integrations/opencode-runtime/index.js +0 -5
  174. package/dist/integrations/opencode-runtime/index.js.map +0 -1
  175. package/dist/integrations/opencode-runtime/plugin.d.ts +0 -59
  176. package/dist/integrations/opencode-runtime/plugin.d.ts.map +0 -1
  177. package/dist/integrations/opencode-runtime/plugin.js +0 -238
  178. package/dist/integrations/opencode-runtime/plugin.js.map +0 -1
  179. package/dist/integrations/opencode-runtime/state.d.ts +0 -8
  180. package/dist/integrations/opencode-runtime/state.d.ts.map +0 -1
  181. package/dist/integrations/opencode-runtime/state.js +0 -27
  182. package/dist/integrations/opencode-runtime/state.js.map +0 -1
  183. package/dist/integrations/opencode-runtime/types.d.ts +0 -38
  184. package/dist/integrations/opencode-runtime/types.d.ts.map +0 -1
  185. package/dist/integrations/opencode-runtime/types.js +0 -2
  186. package/dist/integrations/opencode-runtime/types.js.map +0 -1
  187. package/dist/tui/hosts/_probe/embed-entry.d.ts +0 -5
  188. package/dist/tui/hosts/_probe/embed-entry.d.ts.map +0 -1
  189. package/dist/tui/hosts/_probe/embed-entry.js +0 -8
  190. package/dist/tui/hosts/_probe/embed-entry.js.map +0 -1
package/docs/runtime.md CHANGED
@@ -1,107 +1,137 @@
1
1
  # Runtime Activation (OpenCode First)
2
2
 
3
- `loadouts runtime` compiles loadouts into a session-time bundle without touching activated outputs on disk. Runtime v1 is designed as an OpenCode-first integration path and a reference surface for other tools.
4
-
5
- ## Why Runtime Exists
6
-
7
- - Keep activation side-effect free for agent sessions.
8
- - Reuse the existing resolver and include semantics from standard loadout compilation.
9
- - Make instruction/rule injection explicit and auditable in one JSON payload.
10
- - Expose skill directories as references (path discovery only), without claiming native skill hot-swap.
11
-
12
- ## Architecture
13
-
14
- Runtime activation follows a resolver-backed bundle compiler:
15
-
16
- 1. Resolve loadouts exactly like normal activation (`include`, source imports, bundled/global fallback, tool filtering).
17
- 2. Compile supported artifacts into a `RuntimeBundle`.
18
- 3. Return bundle JSON (`--json`) or a model-ready block (`--system-block`).
19
-
20
- Key properties:
3
+ Equip loadouts globally, for a project, or for **one OpenCode session**.
4
+ Session switching uses OpenCode V2's durable instruction entries and permission
5
+ rules, so another session at the same directory is unaffected.
6
+
7
+ ## CLI
8
+
9
+ ```sh
10
+ loadouts session list
11
+ loadouts session status --session ses_...
12
+ loadouts session equip backend review --session ses_... -p
13
+ loadouts session equip caveman --session ses_... -g
14
+ loadouts session unequip --session ses_...
15
+ ```
21
16
 
22
- - Session-local state: caller owns lifecycle in memory/process state.
23
- - No persistent activation changes: runtime commands do not mutate `.loadouts/.state.json`.
24
- - No output rendering: runtime does not write `.opencode/`, `AGENTS.md`, or other tool target files.
25
- - Deterministic fingerprinting: `fingerprint` is stable across `generatedAt` changes for equivalent content.
17
+ `-g` and `-p` choose the **loadout source scope**; the destination is always the
18
+ named session. Omit `--session` to use the most recently updated root session at
19
+ the current directory. `--json` is available on every subcommand.
20
+ The CLI discovers an already-running authenticated service; start OpenCode first.
26
21
 
27
- ## OpenCode-First Flow
22
+ Session equips inject only instruction/rule content not already rendered by
23
+ intact Global/Project OpenCode outputs. Skill gates restrict native catalog skill
24
+ access to the selected loadout set while retaining pre-existing restrictions.
25
+ Unsupported session artifacts (commands, MCP, references, plugins) are reported
26
+ as diagnostics; equip those at Global/Project scope.
28
27
 
29
- Use OpenCode as the primary runtime consumer in v1:
28
+ ## OpenCode dashboard
30
29
 
31
- ```bash
32
- # JSON bridge for plugin/session adapters
33
- loadouts runtime base backend --tool opencode --json
30
+ Install the bundled integration at either filesystem scope:
34
31
 
35
- # Pre-rendered system block text
36
- loadouts runtime base backend --tool opencode --system-block
32
+ ```sh
33
+ loadouts activate opencode-runtime -g
34
+ # or: loadouts activate opencode-runtime -l
37
35
  ```
38
36
 
39
- Recommended integration pattern:
37
+ This renders the package directory `plugins/loadouts/`, containing the server and
38
+ TUI entries. Build from source with `npm run build` before activating a checkout.
40
39
 
41
- - Compile once when a session starts or active runtime loadouts change.
42
- - Cache by `fingerprint`.
43
- - Inject `instructions` and `rules` into model/system context.
44
- - Register `skills[*].path` for discovery only.
45
-
46
- ### Slash Command UX (`/loadouts`)
47
-
48
- The OpenCode runtime path is designed around a deterministic plugin-backed slash command:
40
+ Inside OpenCode:
49
41
 
50
42
  ```text
51
- /loadouts activate base
52
- /loadouts a base -l
53
- /loadouts a release -g
43
+ /loadouts dashboard (also ctrl+l)
44
+ /loadouts quick multi-select session equip
45
+ /loadouts equip caveman -g replace this session's set
46
+ /loadouts equip backend -p
47
+ /loadouts unequip
48
+ /loadouts status
54
49
  /loadouts list
55
- /loadouts info base
56
- /loadouts clear
57
50
  ```
58
51
 
59
- Expected behavior:
60
-
61
- - The server plugin maps `/loadouts activate|a|use <names...>` to `loadouts runtime ...` (or equivalent runtime adapter path) and computes session runtime state deterministically.
62
- - The TUI plugin listens for server plugin events and renders status/results in a TUI-only dialog that is not appended to chat and is not visible to the assistant.
63
- - `-l/--local` and `-g/--global` are supported as direct scope selectors for runtime compilation.
64
- - Runtime JSON and intermediate plugin outputs stay hidden from the model-facing response.
65
- - The server and TUI plugins share persisted runtime state through `~/.cache/loadouts/opencode-runtime/<cwd-hash>.json`; the server plugin uses that state during system-message injection.
66
- - A bundled scaffold loadout (`opencode-runtime`) renders `.opencode/plugins/loadouts-runtime.ts`, `.opencode/plugins/loadouts-runtime-tui.tsx`, and `.opencode/tui.jsonc`.
52
+ The dashboard shows **G / P / S** equipment and **All / Global / Project**
53
+ scope tabs. It opens on **All**. Tabs filter the catalog; in filesystem mode,
54
+ each row automatically equips into its own scope. The action target appears in
55
+ the detail pane. `m` switches **filesystem ↔ session** when a session is selected;
56
+ embedded dashboards open in session mode.
57
+
58
+ | Keys | Action |
59
+ |---|---|
60
+ | `j` / `k`, `↓` / `↑` | Move within a section |
61
+ | `h` / `l`, `←` / `→`, `Tab` / `Shift+Tab` | Previous / next section |
62
+ | `1` / `2` / `3` | Jump to Active / Available / Issues |
63
+ | `[` / `]` | Previous / next scope tab |
64
+ | `gg` / `G`, `Home` / `End` | First / last row |
65
+ | `Space`, `a` / `d` | Toggle, activate / deactivate the selected row |
66
+ | `m` | Switch filesystem / session mode |
67
+ | `s` / `x` / `D` | Sync / clear / diff the current target |
68
+ | `/`, `t` | Search, cycle tool filter |
69
+ | `Enter`, `e` | Expand artifacts, edit definition |
70
+ | `PgUp` / `PgDn` | Scroll artifact details (or the open overlay) |
71
+ | `u`, `r` | Undo last mutation, refresh |
72
+ | `?` | Help (`j` / `k` scroll) |
73
+ | `Esc` | Close overlay → clear filters → collapse detail → All tab → exit |
74
+ | `q` | Exit (or close the current overlay) |
75
+
76
+ Filesystem bulk operations use the selected tab. In **All**, a scope chooser
77
+ asks Global or Project (`h/l` or `j/k`, then `Enter`; `Esc` cancels). Search and
78
+ tool filters do not narrow bulk operations. In session mode, bulk actions target
79
+ the session's equipped set; a tab for the other source scope has no session
80
+ equipment to change. Equipping a session loadout from a different scope replaces
81
+ its previous source-scope set, and undo restores that set and scope.
82
+
83
+ Long sections keep the selected row visible, with row ranges in their headings.
84
+ The footer shows contextual shortcuts and updates from persisted session state
85
+ and native events.
86
+
87
+ The server plugin also filters skill advertisements (session permission denies
88
+ alone do not hide them on 2.0.3), provides off-disk skills through a catalog
89
+ transform, and supports headless equips.
90
+
91
+ Optional loadout selections:
92
+
93
+ ```yaml
94
+ name: review
95
+ include:
96
+ - instructions/AGENTS.review.md
97
+ opencode:
98
+ agent: reviewer
99
+ model:
100
+ providerID: anthropic
101
+ id: claude-sonnet-4-5
102
+ ```
67
103
 
68
- ### Known OpenCode Runtime Semantics
104
+ For automatic project session equips, add to `.loadouts/loadouts.yaml`:
69
105
 
70
- - The runtime plugin's `command.execute.before` hook is deterministic for parsing `/loadouts` arguments and updating runtime state.
71
- - In interactive OpenCode, the server plugin owns `/loadouts` command handling and the TUI plugin owns user-visible feedback. If the TUI plugin is not loaded, the server plugin remains the headless/fallback path.
72
- - OpenCode may still route server slash command text through model-facing flows when the TUI plugin is absent. Treat user-visible server acknowledgment text as host-dependent.
73
- - OpenCode loads server plugins and TUI plugins at startup. Restart OpenCode after changing or activating runtime plugin or TUI config artifacts.
74
- - The plugin bridge shells out to `loadouts runtime ...`. Ensure the `loadouts` binary available on OpenCode's `PATH` includes runtime support.
75
- - The bundled TUI config is whole-file managed like other Loadouts config artifacts. Existing unmanaged `.opencode/tui.jsonc` files are protected by normal shadowing; add `./plugins/loadouts-runtime-tui.tsx` to your existing TUI config if needed.
106
+ ```yaml
107
+ opencode:
108
+ defaultSession: [backend]
109
+ ```
76
110
 
77
- ## Tool Capability Matrix (Runtime v1)
111
+ ## Standalone and Pi
78
112
 
79
- The bundle always includes resolved instructions, rules, and skill references. Capability flags tell consumers what should be treated as native runtime behavior for each tool.
113
+ `loadouts tui` uses pi-tui and works without OpenCode. If a running service is
114
+ available, press `S` to select a conversation at the current directory, then use
115
+ session mode. Global/Project activation works independently of the service.
116
+ The standalone dashboard requires Node 22.19+.
80
117
 
81
- | Tool | Runtime mode | Instruction/rule model injection | Skill path discovery | Native skill hot-swap |
82
- |------|--------------|----------------------------------|----------------------|-----------------------|
83
- | OpenCode | `experimental-runtime` | Yes | Yes | No |
84
- | Pi | `native-runtime` | Yes | Yes | No |
85
- | Codex | `experimental-runtime` | Yes | Yes | No |
86
- | Claude Code | `filesystem-activation` | No | No | No |
87
- | Cursor | `filesystem-activation` | No (not native) | No | No |
118
+ Pi's bundled `loadouts-runtime` extension uses the same dashboard and layers.
119
+ Session equipment is persisted in Pi custom entries, keyed by the actual session
120
+ ID, and injected through `before_agent_start`. Resuming/switching a Pi session
121
+ reconstructs its own equipment. Pi skills remain path-discovery references.
88
122
 
89
- For filesystem-first tools, use standard `activate/sync` as the primary path and treat runtime output as inspection/debugging data.
123
+ ## Inspect compiled bundles
90
124
 
91
- ## Runtime v1 Limits
125
+ The existing compiler command remains useful independently of activation:
92
126
 
93
- - Supported kinds: `instruction`, `rule`, `skill`.
94
- - Agents are filesystem-rendered native definitions for supported harnesses; they are not injected through runtime v1.
95
- - Unsupported kinds are reported as diagnostics, not hard failures.
96
- - Skills require a `SKILL.md` entrypoint for runtime discovery metadata.
97
- - Runtime v1 does not implement native skill hot-swap.
127
+ ```sh
128
+ loadouts runtime base --tool opencode --json
129
+ loadouts runtime base --tool pi --system-block
130
+ ```
98
131
 
99
- ## Reference Scaffold
132
+ OpenCode supports native per-session instruction entries and skill gating, plus
133
+ location-wide skill hot reload. Pi supports session system-prompt injection.
134
+ Other tools retain their existing compiler/filesystem capability flags.
100
135
 
101
- - Bundled OpenCode server runtime plugin: `bundled/opencode/plugins/loadouts-runtime.ts`
102
- - Bundled OpenCode TUI runtime plugin: `bundled/opencode/plugins/loadouts-runtime-tui.tsx`
103
- - Bundled OpenCode TUI config: `bundled/opencode/tui.jsonc`
104
- - Bundled scaffold loadout: `bundled/loadouts/opencode-runtime.yaml`
105
- - Historical/reference plugin scaffold: `docs/examples/opencode-runtime-plugin.ts`
106
- - Core compiler implementation: `src/core/runtime.ts`
107
- - CLI command surface: `src/cli/commands/runtime.ts`
136
+ See [OpenCode V2 implementation details](opencode-v2-runtime.md) for ownership,
137
+ rollback, concurrency limits, cache behavior, probes and verification scripts.
@@ -51,24 +51,26 @@ loadouts sync # Re-render if needed
51
51
 
52
52
  **Cursor:** Rules need `.mdc` extension — loadouts handles this automatically. Restart Cursor if rules don't appear immediately.
53
53
 
54
- **OpenCode:** Rules render to `.opencode/rules/`, commands to `.opencode/commands/`, local plugins to `.opencode/plugins/`, and NPM plugins are configured with the `plugin` array in `opencode.json(c)`.
54
+ **OpenCode V2:** Rules render to `.opencode/rules/`, commands to `.opencode/commands/`, local plugins to `.opencode/plugins/`, and NPM plugins are configured with the `plugins` array in `opencode.json(c)`. Global instructions render to `~/.config/opencode/AGENTS.md`. OpenCode hot-reloads these sources.
55
55
 
56
56
  ### `/loadouts` not working in OpenCode runtime
57
57
 
58
- If `/loadouts` exists but does not activate runtime behavior, verify the full chain:
59
-
60
- 1. Runtime artifacts are rendered in the expected scope:
61
- - Local server plugin: `.opencode/plugins/loadouts-runtime.ts`
62
- - Local TUI plugin/config: `.opencode/plugins/loadouts-runtime-tui.tsx` and `.opencode/tui.jsonc`
63
- - Global server plugin: `~/.config/opencode/plugins/loadouts-runtime.ts`
64
- - Global TUI plugin/config: `~/.config/opencode/plugins/loadouts-runtime-tui.tsx` and `~/.config/opencode/tui.jsonc`
65
- 2. Runtime scaffold is active in the same scope (`loadouts info -l` or `loadouts info -g`).
66
- 3. Restart OpenCode after activation or plugin/TUI config changes (startup-time plugin loading).
67
- 4. Check the `loadouts` binary on OpenCode's `PATH` supports runtime:
68
- ```bash
69
- loadouts runtime base --tool opencode --json
70
- ```
71
- 5. In interactive OpenCode, the server plugin owns `/loadouts` and the TUI plugin listens for server events to render a user-only dialog. If command acknowledgment text looks model-generated, the TUI plugin is probably not loaded; the deterministic fallback is still server plugin state update and runtime system injection.
58
+ 1. Verify `plugins/loadouts/{package.json,index.js,tui.js}` exists under the
59
+ project's `.opencode/` or global `~/.config/opencode/` directory.
60
+ 2. Check `loadouts info -l` or `loadouts info -g` for `opencode-runtime` and
61
+ `loadouts status` for shadowed/missing output. A source checkout needs
62
+ `npm run build` before activation.
63
+ 3. Open OpenCode's Plugins dialog and inspect the server/TUI entries. Local
64
+ plugin directories do not install server dependencies; use the built,
65
+ self-contained artifact rather than copying `src/tui/hosts/opencode/`.
66
+ 4. Test the independent HTTP path with
67
+ `loadouts session status --session ses_...`.
68
+ 5. `/loadouts` and `ctrl+l` are client-side commands. The server entry is needed
69
+ for clean per-session skill advertisements; native permission denies alone
70
+ still leave skills listed on OpenCode 2.0.3.
71
+
72
+ If permissions were edited after equip, unequip preserves those edits and reports
73
+ it. See [runtime ownership and recovery](opencode-v2-runtime.md#persistence-and-ownership).
72
74
 
73
75
  **Claude Code:** Verify rules exist in `.claude/rules/`. May require restarting the session.
74
76
 
@@ -1,6 +1,8 @@
1
1
  # Loadouts TUI Architecture
2
2
 
3
- Status: **Design / RFC** (no implementation yet)
3
+ Status: **Historical design / RFC**. The three-layer core/skin/host architecture is
4
+ implemented. V1 runtime wiring and command names below are superseded by
5
+ [the OpenCode V2 runtime](opencode-v2-runtime.md) and [usage](runtime.md).
4
6
  Author: design pass, June 2026
5
7
 
6
8
  A plan for turning the loadouts TUI from a passive popup into a beautiful, ergonomic,
@@ -133,14 +135,14 @@ src/tui/
133
135
  extension.ts # default ExtensionAPI factory: command + inject + mount
134
136
  inject.ts # before_agent_start system-prompt block
135
137
  opencode/
136
- route.ts # api.route.register("loadouts") mounting opentui skin
137
- (reuses src/integrations/opencode-runtime/* for command + injection)
138
+ index.ts # server entry: Plugin.define({ id, setup })
139
+ tui.tsx # TUI entry: router page, slash, slots
138
140
  ```
139
141
 
140
- The existing `src/integrations/opencode-runtime/` (bridge, command parser, state,
141
- system-block injection) is reused as-is by the OpenCode host; the new TUI route is layered
142
- on top. A parallel `src/integrations/pi-runtime/` (or the `hosts/pi/` module above) provides
143
- the Pi equivalent.
142
+ The V1-shaped `src/integrations/opencode-runtime/` was replaced by
143
+ `src/integrations/opencode/` (session activator, instruction delta, service client,
144
+ advertisement filter). The Pi equivalent lives in `hosts/pi/` and the shared
145
+ `core/controller.ts` lifecycle.
144
146
 
145
147
  ---
146
148
 
@@ -300,7 +302,7 @@ skills/prompts/themes at runtime — a cleaner injection path than OpenCode's sy
300
302
 
301
303
  ### 6.2 OpenCode host (existing plugin, upgraded)
302
304
 
303
- Reuse `src/integrations/opencode-runtime/` (command parsing, session state, system-block
305
+ Reuse the shared controller/lifecycle in `src/tui/core/controller.ts` (command parsing, session state, system-block
304
306
  injection). Add a TUI route:
305
307
 
306
308
  | Need | OpenCode API |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loadouts",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Composable configuration bundles for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  "dev": "tsc --watch",
18
18
  "test": "vitest run",
19
19
  "test:watch": "vitest",
20
- "lint": "tsc --noEmit",
20
+ "lint": "tsc --noEmit -p tsconfig.lint.json && tsc --noEmit -p tsconfig.tui.json",
21
21
  "loadouts": "node dist/index.js"
22
22
  },
23
23
  "keywords": [
@@ -37,20 +37,25 @@
37
37
  "url": "https://github.com/evatths/loadouts.git"
38
38
  },
39
39
  "devDependencies": {
40
+ "@babel/core": "7.28.0",
41
+ "@babel/preset-typescript": "7.27.1",
40
42
  "@earendil-works/pi-coding-agent": "^0.79.7",
41
- "@opencode-ai/plugin": "^1.17.8",
42
- "@opentui/core": "^0.4.1",
43
- "@opentui/keymap": "^0.4.1",
44
- "@opentui/solid": "^0.4.1",
43
+ "@opencode/plugin": "2.0.3",
44
+ "@opentui/core": "0.5.11",
45
+ "@opentui/keymap": "0.5.11",
46
+ "@opentui/solid": "0.5.11",
47
+ "@opencode/theme": "2.0.3",
45
48
  "@types/node": "^20.12.0",
46
49
  "@types/update-notifier": "^6.0.8",
50
+ "babel-preset-solid": "1.9.12",
47
51
  "esbuild": "^0.23.1",
48
- "solid-js": "^1.9.12",
52
+ "solid-js": "1.9.15",
49
53
  "typescript": "^5.4.0",
50
54
  "vitest": "^1.5.0"
51
55
  },
52
56
  "dependencies": {
53
57
  "@earendil-works/pi-tui": "^0.79.7",
58
+ "@opencode/client": "2.0.3",
54
59
  "chalk": "^5.3.0",
55
60
  "commander": "^12.0.0",
56
61
  "update-notifier": "^7.3.1",
@@ -1,3 +0,0 @@
1
- ---
2
- description: Manage session-local Loadouts runtime activation
3
- ---