agent-mockingbird 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/.agents/skills/btca-cli/SKILL.md +64 -0
  2. package/.agents/skills/btca-cli/agents/openai.yaml +3 -0
  3. package/.agents/skills/frontend-design/SKILL.md +42 -0
  4. package/.agents/skills/frontend-design/agents/openai.yaml +3 -0
  5. package/.env.example +36 -0
  6. package/.githooks/pre-commit +33 -0
  7. package/.github/workflows/ci.yml +309 -0
  8. package/.opencode/bun.lock +18 -0
  9. package/.opencode/package.json +5 -0
  10. package/.opencode/tools/agent_type_manager.ts +100 -0
  11. package/.opencode/tools/config_manager.ts +87 -0
  12. package/.opencode/tools/cron_manager.ts +145 -0
  13. package/.opencode/tools/memory_get.ts +43 -0
  14. package/.opencode/tools/memory_remember.ts +53 -0
  15. package/.opencode/tools/memory_search.ts +48 -0
  16. package/AGENTS.md +126 -0
  17. package/MEMORY.md +2 -0
  18. package/README.md +451 -0
  19. package/THIRD_PARTY_NOTICES.md +11 -0
  20. package/agent-mockingbird.config.example.json +135 -0
  21. package/apps/server/package.json +32 -0
  22. package/apps/server/src/backend/agents/bootstrapContext.ts +362 -0
  23. package/apps/server/src/backend/agents/openclawImport.test.ts +133 -0
  24. package/apps/server/src/backend/agents/openclawImport.ts +797 -0
  25. package/apps/server/src/backend/agents/opencodeConfig.ts +428 -0
  26. package/apps/server/src/backend/agents/service.ts +10 -0
  27. package/apps/server/src/backend/config/example-config.test.ts +20 -0
  28. package/apps/server/src/backend/config/orchestration.ts +243 -0
  29. package/apps/server/src/backend/config/policy.ts +158 -0
  30. package/apps/server/src/backend/config/schema.test.ts +15 -0
  31. package/apps/server/src/backend/config/schema.ts +391 -0
  32. package/apps/server/src/backend/config/semantic.test.ts +34 -0
  33. package/apps/server/src/backend/config/semantic.ts +149 -0
  34. package/apps/server/src/backend/config/service.test.ts +75 -0
  35. package/apps/server/src/backend/config/service.ts +207 -0
  36. package/apps/server/src/backend/config/smoke.ts +77 -0
  37. package/apps/server/src/backend/config/store.test.ts +123 -0
  38. package/apps/server/src/backend/config/store.ts +581 -0
  39. package/apps/server/src/backend/config/testFixtures.ts +5 -0
  40. package/apps/server/src/backend/config/types.ts +56 -0
  41. package/apps/server/src/backend/contracts/events.ts +320 -0
  42. package/apps/server/src/backend/contracts/runtime.ts +111 -0
  43. package/apps/server/src/backend/cron/executor.ts +435 -0
  44. package/apps/server/src/backend/cron/repository.ts +170 -0
  45. package/apps/server/src/backend/cron/service.ts +660 -0
  46. package/apps/server/src/backend/cron/storage.ts +92 -0
  47. package/apps/server/src/backend/cron/types.ts +138 -0
  48. package/apps/server/src/backend/cron/utils.ts +351 -0
  49. package/apps/server/src/backend/db/client.ts +20 -0
  50. package/apps/server/src/backend/db/migrate.ts +40 -0
  51. package/apps/server/src/backend/db/repository.ts +1762 -0
  52. package/apps/server/src/backend/db/schema.ts +113 -0
  53. package/apps/server/src/backend/db/usageDashboard.test.ts +102 -0
  54. package/apps/server/src/backend/db/wipe.ts +13 -0
  55. package/apps/server/src/backend/defaults.ts +32 -0
  56. package/apps/server/src/backend/env.ts +48 -0
  57. package/apps/server/src/backend/heartbeat/activeHours.ts +45 -0
  58. package/apps/server/src/backend/heartbeat/defaultJob.ts +88 -0
  59. package/apps/server/src/backend/heartbeat/heartbeat.test.ts +110 -0
  60. package/apps/server/src/backend/heartbeat/runtimeService.ts +190 -0
  61. package/apps/server/src/backend/heartbeat/service.ts +176 -0
  62. package/apps/server/src/backend/heartbeat/state.test.ts +63 -0
  63. package/apps/server/src/backend/heartbeat/state.ts +167 -0
  64. package/apps/server/src/backend/heartbeat/types.ts +54 -0
  65. package/apps/server/src/backend/http/boundedQueue.test.ts +49 -0
  66. package/apps/server/src/backend/http/boundedQueue.ts +92 -0
  67. package/apps/server/src/backend/http/parsers.ts +40 -0
  68. package/apps/server/src/backend/http/router.ts +61 -0
  69. package/apps/server/src/backend/http/routes/agentRoutes.ts +67 -0
  70. package/apps/server/src/backend/http/routes/backgroundRoutes.ts +203 -0
  71. package/apps/server/src/backend/http/routes/chatRoutes.ts +107 -0
  72. package/apps/server/src/backend/http/routes/configRoutes.ts +602 -0
  73. package/apps/server/src/backend/http/routes/cronRoutes.ts +221 -0
  74. package/apps/server/src/backend/http/routes/dashboardRoutes.ts +308 -0
  75. package/apps/server/src/backend/http/routes/eventRoutes.ts +7 -0
  76. package/apps/server/src/backend/http/routes/heartbeatRoutes.test.ts +41 -0
  77. package/apps/server/src/backend/http/routes/heartbeatRoutes.ts +28 -0
  78. package/apps/server/src/backend/http/routes/index.ts +101 -0
  79. package/apps/server/src/backend/http/routes/mcpRoutes.ts +213 -0
  80. package/apps/server/src/backend/http/routes/memoryRoutes.ts +154 -0
  81. package/apps/server/src/backend/http/routes/runRoutes.ts +310 -0
  82. package/apps/server/src/backend/http/routes/runtimeRoutes.ts +197 -0
  83. package/apps/server/src/backend/http/routes/skillRoutes.ts +112 -0
  84. package/apps/server/src/backend/http/routes/uiRoutes.test.ts +161 -0
  85. package/apps/server/src/backend/http/routes/uiRoutes.ts +177 -0
  86. package/apps/server/src/backend/http/routes/usageRoutes.test.ts +104 -0
  87. package/apps/server/src/backend/http/routes/usageRoutes.ts +767 -0
  88. package/apps/server/src/backend/http/schemas.ts +64 -0
  89. package/apps/server/src/backend/http/sse.ts +144 -0
  90. package/apps/server/src/backend/integration/backend-core.test.ts +2316 -0
  91. package/apps/server/src/backend/logging/logger.ts +64 -0
  92. package/apps/server/src/backend/mcp/service.ts +326 -0
  93. package/apps/server/src/backend/memory/cli.ts +170 -0
  94. package/apps/server/src/backend/memory/conceptExpansion.test.ts +28 -0
  95. package/apps/server/src/backend/memory/conceptExpansion.ts +80 -0
  96. package/apps/server/src/backend/memory/qmdPort.test.ts +54 -0
  97. package/apps/server/src/backend/memory/qmdPort.ts +61 -0
  98. package/apps/server/src/backend/memory/records.test.ts +66 -0
  99. package/apps/server/src/backend/memory/records.ts +229 -0
  100. package/apps/server/src/backend/memory/service.ts +2012 -0
  101. package/apps/server/src/backend/memory/sqliteVec.ts +58 -0
  102. package/apps/server/src/backend/memory/types.ts +104 -0
  103. package/apps/server/src/backend/opencode/agentMockingbirdPlugin.test.ts +396 -0
  104. package/apps/server/src/backend/opencode/client.ts +98 -0
  105. package/apps/server/src/backend/opencode/models.ts +41 -0
  106. package/apps/server/src/backend/opencode/systemPrompt.test.ts +146 -0
  107. package/apps/server/src/backend/opencode/systemPrompt.ts +284 -0
  108. package/apps/server/src/backend/paths.ts +57 -0
  109. package/apps/server/src/backend/prompts/service.ts +100 -0
  110. package/apps/server/src/backend/queue/queue.test.ts +189 -0
  111. package/apps/server/src/backend/queue/service.ts +177 -0
  112. package/apps/server/src/backend/queue/types.ts +39 -0
  113. package/apps/server/src/backend/run/service.ts +576 -0
  114. package/apps/server/src/backend/run/storage.ts +47 -0
  115. package/apps/server/src/backend/run/types.ts +44 -0
  116. package/apps/server/src/backend/runtime/errors.ts +61 -0
  117. package/apps/server/src/backend/runtime/index.ts +72 -0
  118. package/apps/server/src/backend/runtime/memoryPromptDedup.test.ts +153 -0
  119. package/apps/server/src/backend/runtime/memoryPromptDedup.ts +76 -0
  120. package/apps/server/src/backend/runtime/opencodeRuntime/backgroundMethods.ts +765 -0
  121. package/apps/server/src/backend/runtime/opencodeRuntime/coreMethods.ts +705 -0
  122. package/apps/server/src/backend/runtime/opencodeRuntime/eventMethods.ts +503 -0
  123. package/apps/server/src/backend/runtime/opencodeRuntime/memoryMethods.ts +462 -0
  124. package/apps/server/src/backend/runtime/opencodeRuntime/promptMethods.ts +1167 -0
  125. package/apps/server/src/backend/runtime/opencodeRuntime/shared.ts +254 -0
  126. package/apps/server/src/backend/runtime/opencodeRuntime.test.ts +2899 -0
  127. package/apps/server/src/backend/runtime/opencodeRuntime.ts +135 -0
  128. package/apps/server/src/backend/runtime/sessionScope.ts +45 -0
  129. package/apps/server/src/backend/skills/service.ts +442 -0
  130. package/apps/server/src/backend/workspace/resolve.ts +27 -0
  131. package/apps/server/src/cli/agent-mockingbird.mjs +2522 -0
  132. package/apps/server/src/cli/agent-mockingbird.test.ts +68 -0
  133. package/apps/server/src/cli/runtime-assets.mjs +269 -0
  134. package/apps/server/src/cli/runtime-assets.test.ts +52 -0
  135. package/apps/server/src/cli/runtime-layout.mjs +75 -0
  136. package/apps/server/src/cli/standaloneBuild.test.ts +19 -0
  137. package/apps/server/src/cli/standaloneBuild.ts +19 -0
  138. package/apps/server/src/cli/standaloneCronBinary.test.ts +187 -0
  139. package/apps/server/src/index.ts +178 -0
  140. package/apps/server/tsconfig.json +12 -0
  141. package/backlog.md +5 -0
  142. package/bin/agent-mockingbird +2522 -0
  143. package/bin/runtime-layout.mjs +75 -0
  144. package/build-bin.ts +34 -0
  145. package/build-cli.mjs +37 -0
  146. package/build.ts +40 -0
  147. package/bun-env.d.ts +11 -0
  148. package/bun.lock +888 -0
  149. package/bunfig.toml +2 -0
  150. package/components.json +21 -0
  151. package/config.json +130 -0
  152. package/deploy/RELEASE_INSTALL.md +112 -0
  153. package/deploy/docker-compose.yml +42 -0
  154. package/deploy/systemd/README.md +46 -0
  155. package/deploy/systemd/agent-mockingbird.service +28 -0
  156. package/deploy/systemd/opencode.service +25 -0
  157. package/docs/legacy-config-ui-reference.md +51 -0
  158. package/docs/memory-e2e-trace-2026-03-04.md +63 -0
  159. package/docs/memory-ops.md +96 -0
  160. package/docs/memory-runtime-contract.md +42 -0
  161. package/docs/memory-tuning-remote-2026-03-04.md +59 -0
  162. package/docs/opencode-rebase-workflow-plan.md +614 -0
  163. package/docs/opencode-startup-sync-plan.md +94 -0
  164. package/docs/vendor-opencode.md +41 -0
  165. package/drizzle/0000_famous_turbo.sql +49 -0
  166. package/drizzle/0001_cron_memory_aux.sql +160 -0
  167. package/drizzle/0002_runtime_session_bindings.sql +28 -0
  168. package/drizzle/0003_background_runs.sql +27 -0
  169. package/drizzle/0004_memory_open_write.sql +63 -0
  170. package/drizzle/0005_signal_channel.sql +47 -0
  171. package/drizzle/0006_usage_event_dimensions.sql +7 -0
  172. package/drizzle/meta/0000_snapshot.json +341 -0
  173. package/drizzle/meta/_journal.json +55 -0
  174. package/drizzle.config.ts +14 -0
  175. package/eslint.config.mjs +77 -0
  176. package/knip.json +18 -0
  177. package/memory/2026-03-04.md +4 -0
  178. package/opencode.lock.json +16 -0
  179. package/package.json +67 -0
  180. package/packages/agent-mockingbird-installer/README.md +31 -0
  181. package/packages/agent-mockingbird-installer/bin/agent-mockingbird-installer.mjs +44 -0
  182. package/packages/agent-mockingbird-installer/opencode.lock.json +16 -0
  183. package/packages/agent-mockingbird-installer/package.json +23 -0
  184. package/packages/contracts/package.json +19 -0
  185. package/packages/contracts/src/agentTypes.ts +122 -0
  186. package/packages/contracts/src/cron.ts +146 -0
  187. package/packages/contracts/src/dashboard.ts +378 -0
  188. package/packages/contracts/src/index.ts +3 -0
  189. package/packages/contracts/tsconfig.json +4 -0
  190. package/patches/opencode/0001-Wafflebot-OpenCode-baseline.patch +2341 -0
  191. package/patches/opencode/0002-Fix-OpenCode-web-entry-and-settings-icons.patch +104 -0
  192. package/patches/opencode/0003-fix-app-remove-duplicate-sidebar-mount.patch +32 -0
  193. package/patches/opencode/0004-Add-heartbeat-settings-and-usage-nav.patch +506 -0
  194. package/patches/opencode/0005-Use-chart-icon-for-usage-nav.patch +38 -0
  195. package/patches/opencode/0006-Modernize-cron-settings.patch +399 -0
  196. package/patches/opencode/0007-Rename-waffle-namespaces-to-mockingbird.patch +1110 -0
  197. package/patches/opencode/0008-Remove-cron-contract-section.patch +178 -0
  198. package/patches/opencode/0009-Rework-cron-tab-as-operations-console.patch +414 -0
  199. package/patches/opencode/0010-Refine-heartbeat-settings-controls.patch +208 -0
  200. package/runtime-assets/opencode-config/opencode.jsonc +25 -0
  201. package/runtime-assets/opencode-config/package.json +5 -0
  202. package/runtime-assets/opencode-config/plugins/agent-mockingbird.ts +715 -0
  203. package/runtime-assets/workspace/.agents/skills/config-auditor/SKILL.md +25 -0
  204. package/runtime-assets/workspace/.agents/skills/config-editor/SKILL.md +24 -0
  205. package/runtime-assets/workspace/.agents/skills/cron-manager/SKILL.md +57 -0
  206. package/runtime-assets/workspace/.agents/skills/memory-ops/SKILL.md +120 -0
  207. package/runtime-assets/workspace/.agents/skills/runtime-diagnose/SKILL.md +25 -0
  208. package/runtime-assets/workspace/AGENTS.md +56 -0
  209. package/runtime-assets/workspace/MEMORY.md +4 -0
  210. package/scripts/build-release-bundle.sh +66 -0
  211. package/scripts/check-ship.ts +383 -0
  212. package/scripts/dev-opencode.sh +17 -0
  213. package/scripts/dev-stack-opencode.sh +15 -0
  214. package/scripts/dev-stack.sh +61 -0
  215. package/scripts/install-systemd.sh +87 -0
  216. package/scripts/memory-e2e.sh +76 -0
  217. package/scripts/memory-trace-e2e.sh +141 -0
  218. package/scripts/migrate-opencode-env.ts +108 -0
  219. package/scripts/onboard/bootstrap.sh +32 -0
  220. package/scripts/opencode-swap.ts +78 -0
  221. package/scripts/opencode-sync.ts +715 -0
  222. package/scripts/runtime-assets-sync.mjs +83 -0
  223. package/scripts/setup-git-hooks.ts +39 -0
  224. package/tsconfig.json +45 -0
  225. package/tui.json +98 -0
  226. package/turbo.json +36 -0
  227. package/vendor/OPENCODE_VENDOR.md +13 -0
@@ -0,0 +1,59 @@
1
+ # Memory Retrieval Tuning (Remote Ollama)
2
+
3
+ Date: 2026-03-04
4
+ Endpoint: `http://172.16.1.100:11434`
5
+
6
+ ## Test Matrix
7
+
8
+ | Case | Model | conceptExpansionMaxTerms | semanticRescueMinVectorScore | semanticRescueMaxResults |
9
+ |---|---|---:|---:|---:|
10
+ | case1 | `qwen3-embedding:4b` | 10 | 0.75 | 2 |
11
+ | case2 | `qwen3-embedding:4b` | 12 | 0.72 | 2 |
12
+ | case3 | `qwen3-embedding:4b` | 12 | 0.70 | 3 |
13
+ | case4 | `granite-embedding:278m` | 10 | 0.75 | 2 |
14
+ | case5 | `embeddinggemma:latest` | 10 | 0.75 | 2 |
15
+
16
+ ## Query Set
17
+
18
+ Adjacent-recall queries:
19
+ - `portfolio`
20
+ - `how is my portfolio doing`
21
+ - `metals exposure`
22
+ - `silver price`
23
+ - `asset allocation`
24
+
25
+ Control precision queries:
26
+ - `what is my daughter's name`
27
+ - `how should I write a Bun script`
28
+
29
+ Noise probe:
30
+ - `favorite color`
31
+
32
+ ## Results
33
+
34
+ | case | model | adjacent_recall_hits | control_precision_hits | unrelated_noise | average_top_score | runtime_seconds |
35
+ |---|---|---:|---:|---:|---:|---:|
36
+ | case4 | `granite-embedding:278m` | 5 | 2 | 0 | 0.976600 | 9 |
37
+ | case3 | `qwen3-embedding:4b` | 4 | 2 | 1 | 0.972300 | 11 |
38
+ | case1 | `qwen3-embedding:4b` | 4 | 2 | 0 | 0.785720 | 11 |
39
+ | case2 | `qwen3-embedding:4b` | 4 | 2 | 0 | 0.785580 | 11 |
40
+ | case5 | `embeddinggemma:latest` | 4 | 2 | 0 | 0.783700 | 8 |
41
+
42
+ ## Recommendation
43
+
44
+ Use:
45
+ - `runtime.memory.embedModel = "granite-embedding:278m"`
46
+ - `runtime.memory.retrieval.conceptExpansionMaxTerms = 10`
47
+ - `runtime.memory.retrieval.semanticRescueMinVectorScore = 0.75`
48
+ - `runtime.memory.retrieval.semanticRescueMaxResults = 2`
49
+
50
+ Why:
51
+ - Best adjacent recall (5/5)
52
+ - No added unrelated noise
53
+ - Control queries still correct
54
+ - Fastest among high-quality candidates in this run
55
+
56
+ ## Artifacts
57
+
58
+ - Summary JSON: `/tmp/wb-tune-remote/summary.json`
59
+ - Per-case raw outputs: `/tmp/wb-tune-remote/{case}/`
@@ -0,0 +1,614 @@
1
+ # OpenCode Rebase Workflow Plan
2
+
3
+ ## Goal
4
+
5
+ Replace the current "copy upstream into `vendor/opencode` and hand-edit it" workflow with a release-tag-pinned, rebasable OpenCode workflow that gives us all of the following at once:
6
+
7
+ - a pristine local upstream reference checkout
8
+ - a reliable way to carry Agent Mockingbird patches forward onto newer OpenCode releases
9
+ - a generated shipped source tree instead of a permanently committed vendor tree
10
+ - a single source of truth for which OpenCode version we ship
11
+ - a pinned installed OpenCode CLI/sidecar version that matches the shipped UI version
12
+ - a path that will still work later if we start patching desktop packages in addition to the web UI
13
+
14
+ This is intentionally a breaking internal workflow change. That is acceptable for this repo.
15
+
16
+ ## Current State
17
+
18
+ Observed repo facts at planning time:
19
+
20
+ - `vendor/opencode` is a committed source tree.
21
+ - `cleanroom/opencode` is a separate local clone, not tracked by the main repo.
22
+ - both local trees currently report `1.2.24` in their OpenCode package metadata
23
+ - upstream has newer release tags available through `v1.2.27`
24
+ - `bin/agent-mockingbird` currently installs `opencode-ai@latest`, which allows the installed sidecar version to drift away from the vendored UI version
25
+ - the repo currently tracks roughly 4,408 files under `vendor/opencode`
26
+ - the published package artifact already ships compiled outputs like `dist/app`, not the full vendored source tree
27
+ - the current helper docs/scripts are inconsistent and partially stale
28
+
29
+ This means the main problem is not packaging the final artifact. The problem is maintaining the source-of-truth workflow for upstream sync, local patches, and shipped-version alignment.
30
+
31
+ ## Target Model
32
+
33
+ The target model is:
34
+
35
+ - `cleanroom/opencode`
36
+ - local-only upstream reference clone
37
+ - always pristine
38
+ - managed by repo scripts
39
+ - checked out to an exact release tag, not a moving branch
40
+ - `vendor/opencode`
41
+ - generated local worktree for the shipped OpenCode source
42
+ - gitignored by the main repo
43
+ - backed by a real git branch/worktree so rebases are native git operations, not file copies
44
+ - `patches/opencode`
45
+ - tracked serialized patch stack exported from the local OpenCode patch branch
46
+ - exists so the workflow is portable across machines and fresh clones
47
+ - `opencode.lock.json`
48
+ - tracked metadata file defining the shipped OpenCode version and workflow state
49
+ - authoritative source for the upstream ref and pinned npm package version
50
+
51
+ The shipped application remains built from `vendor/opencode/packages/app`, but that tree is no longer committed to the repo.
52
+
53
+ ## Decisions Already Made
54
+
55
+ - Track upstream by release tags, not by `origin/dev`.
56
+ - Use a git patch branch/worktree as the editing and rebase model.
57
+ - Move toward generated-on-demand `vendor/opencode` now, not later.
58
+ - Keep `cleanroom/opencode` as a local reference checkout, not a tracked repo artifact.
59
+ - Keep the current `vendor/opencode` path for compatibility so existing build code can be migrated with minimal churn.
60
+ - Treat desktop support as "workflow-ready but not fully productized in this pass". The patch system must work for desktop paths, but desktop packaging changes are not required unless needed by the current OpenCode patches.
61
+
62
+ ## Non-Goals
63
+
64
+ - Do not split the repo into multiple publishable packages in this pass.
65
+ - Do not redesign the Agent Mockingbird runtime architecture.
66
+ - Do not try to support old vendor workflows in parallel after the cutover.
67
+ - Do not keep installing `opencode-ai@latest` after this is complete.
68
+
69
+ ## Deliverables
70
+
71
+ The implementation is complete only when all of these exist and are wired up:
72
+
73
+ - a tracked `opencode.lock.json`
74
+ - a tracked `patches/opencode/` patch series
75
+ - a single scripted entrypoint for sync/rebase/rebuild/status
76
+ - a script-managed pristine `cleanroom/opencode`
77
+ - a script-managed generated `vendor/opencode`
78
+ - build/dev/package flows that no longer depend on a committed vendor tree
79
+ - installer/update flow pinned to the locked OpenCode version
80
+ - updated documentation replacing the stale vendor notes
81
+
82
+ ## File and Interface Additions
83
+
84
+ ### 1. `opencode.lock.json`
85
+
86
+ Add a new tracked lock file at repo root.
87
+
88
+ Recommended shape:
89
+
90
+ ```json
91
+ {
92
+ "upstream": {
93
+ "remote": "https://github.com/anomalyco/opencode.git",
94
+ "tag": "v1.2.27",
95
+ "commit": "<resolved-commit>"
96
+ },
97
+ "packageVersion": "1.2.27",
98
+ "paths": {
99
+ "cleanroom": "cleanroom/opencode",
100
+ "vendor": "vendor/opencode",
101
+ "patches": "patches/opencode"
102
+ },
103
+ "branch": {
104
+ "name": "agent-mockingbird/opencode"
105
+ }
106
+ }
107
+ ```
108
+
109
+ Rules:
110
+
111
+ - `tag` is the human-facing upstream ref.
112
+ - `commit` is the exact resolved upstream commit for that tag.
113
+ - `packageVersion` is what the installer must use for `opencode-ai@<version>`.
114
+ - the lock file only updates after rebase/apply and validation succeed.
115
+
116
+ ### 2. `patches/opencode/`
117
+
118
+ Add a tracked directory containing the serialized patch stack.
119
+
120
+ Recommended contents:
121
+
122
+ - `0001-...patch`
123
+ - `0002-...patch`
124
+ - etc
125
+ - optional `SERIES.md` or `series.json` if needed for metadata
126
+
127
+ Rules:
128
+
129
+ - export patches in a stable order from the patch branch relative to the locked upstream commit
130
+ - keep commits scoped and readable
131
+ - separate major areas when possible:
132
+ - app UI
133
+ - core/runtime integration
134
+ - console/docs
135
+ - desktop packages later if needed
136
+
137
+ ### 3. Script entrypoint
138
+
139
+ Add a single user-facing Bun script, for example:
140
+
141
+ ```json
142
+ "opencode:sync": "bun run ./scripts/opencode-sync.ts"
143
+ ```
144
+
145
+ The script should support:
146
+
147
+ - `--status`
148
+ - `--ref <tag>`
149
+ - `--rebuild-only`
150
+ - `--export-patches`
151
+ - `--check`
152
+
153
+ The script can internally call helper modules, but there should be one primary operator command.
154
+
155
+ ## Script Behavior
156
+
157
+ ### `bun run opencode:sync --status`
158
+
159
+ Must print:
160
+
161
+ - lock file tag and commit
162
+ - cleanroom path and current HEAD
163
+ - whether cleanroom is pristine
164
+ - patch branch/worktree current HEAD
165
+ - whether `vendor/opencode` is clean, dirty, conflicted, or missing
166
+ - whether the exported patch series matches the patch branch
167
+
168
+ This command must not mutate anything.
169
+
170
+ ### `bun run opencode:sync --rebuild-only`
171
+
172
+ Must:
173
+
174
+ - verify `opencode.lock.json`
175
+ - verify cleanroom exists and is pristine
176
+ - recreate or refresh `vendor/opencode` from the locked upstream commit
177
+ - reapply the tracked patch series or reset the worktree branch to the expected patch head
178
+ - stop before updating the lock file
179
+
180
+ This is the safe "make my local generated OpenCode tree exist again" command.
181
+
182
+ ### `bun run opencode:sync --ref vX.Y.Z`
183
+
184
+ This is the full upgrade flow.
185
+
186
+ Required steps:
187
+
188
+ 1. Validate preconditions.
189
+ 2. Ensure the cleanroom clone exists.
190
+ 3. Fetch the requested upstream tag.
191
+ 4. Resolve the exact upstream commit.
192
+ 5. Refuse to continue if cleanroom is dirty.
193
+ 6. Refuse to continue if `vendor/opencode` contains uncommitted/unexported work that would be lost.
194
+ 7. Move cleanroom to the target tag in a pristine state.
195
+ 8. Rebase or recreate the patch branch onto the new upstream commit.
196
+ 9. Stop loudly on merge conflict or failed patch apply.
197
+ 10. Run OpenCode validation steps.
198
+ 11. Export the patch series back into `patches/opencode/`.
199
+ 12. Verify exported patches reproduce the same resulting tree.
200
+ 13. Update `opencode.lock.json`.
201
+ 14. Rebuild the shipped app assets.
202
+
203
+ The lock file must not change before step 10 succeeds.
204
+
205
+ ### `bun run opencode:sync --export-patches`
206
+
207
+ Must:
208
+
209
+ - verify `vendor/opencode` exists as the OpenCode patch worktree
210
+ - verify worktree is clean
211
+ - export commits on top of the locked upstream commit into `patches/opencode`
212
+ - verify the export is reproducible
213
+
214
+ This is mainly for after making intentional OpenCode changes locally.
215
+
216
+ ### `bun run opencode:sync --check`
217
+
218
+ Must run non-mutating verification suitable for CI:
219
+
220
+ - lock file is valid
221
+ - cleanroom/vendor path expectations are sane when materialized
222
+ - patch series applies cleanly to the locked upstream commit
223
+ - generated tree passes required validation
224
+
225
+ If the implementation is simpler, `--check` may internally materialize a temporary worktree rather than using the persistent local one.
226
+
227
+ ## Daily Edit Workflow
228
+
229
+ This section defines the normal developer loop after the new workflow exists.
230
+
231
+ ### Editing OpenCode locally
232
+
233
+ When the goal is "change OpenCode code we ship", the expected loop is:
234
+
235
+ 1. Run `bun run opencode:sync --rebuild-only`.
236
+ 2. Edit files inside `vendor/opencode`.
237
+ 3. Run the relevant OpenCode-local validation.
238
+ 4. Commit the changes in the `vendor/opencode` worktree on the OpenCode patch branch.
239
+ 5. Run `bun run opencode:sync --export-patches`.
240
+ 6. Rebuild the shipped app bundle if the change affects the shipped UI.
241
+
242
+ Important rules:
243
+
244
+ - `vendor/opencode` is the editable patch worktree.
245
+ - `cleanroom/opencode` is never edited directly.
246
+ - `patches/opencode/*.patch` are exported artifacts of commits on the patch branch.
247
+ - the normal flow is commit-first, not "edit files and let the script guess".
248
+
249
+ ### What happens with uncommitted changes
250
+
251
+ If someone edits files in `vendor/opencode` and does not commit them:
252
+
253
+ - `bun run opencode:sync --status` must report the worktree as dirty
254
+ - `bun run opencode:sync --ref ...` must refuse to continue
255
+ - `bun run opencode:sync --export-patches` must refuse to continue
256
+
257
+ This prevents silent extraction, silent loss, or partially serialized state.
258
+
259
+ ### What the patch files represent
260
+
261
+ The tracked patch files are not the primary authoring surface.
262
+
263
+ They represent:
264
+
265
+ - the serialized commit stack on top of the locked upstream commit
266
+ - the portable form used to reconstruct the patch branch/worktree on another machine or fresh clone
267
+
268
+ This means the real authoring model is:
269
+
270
+ - edit in `vendor/opencode`
271
+ - commit in the patch branch
272
+ - export the branch to patch files
273
+
274
+ ## Git Topology
275
+
276
+ Use a real git-backed workflow instead of file copying.
277
+
278
+ Recommended shape:
279
+
280
+ - `cleanroom/opencode` is a normal git clone with `origin` set to upstream.
281
+ - `vendor/opencode` is a git worktree attached to a local branch in the cleanroom clone's object database.
282
+
283
+ Why:
284
+
285
+ - patch rebases are first-class git operations
286
+ - no more replacing directories with `cp -R`
287
+ - local history for OpenCode changes becomes inspectable
288
+ - object storage is shared instead of duplicated
289
+
290
+ Important invariant:
291
+
292
+ - `cleanroom/opencode` is never the patch worktree
293
+ - `cleanroom/opencode` must stay pristine so a diff between cleanroom and vendor represents our intentional changes
294
+
295
+ ## Validation and Failure Gates
296
+
297
+ The workflow must fail loudly and early.
298
+
299
+ ### Gate 1: cleanroom cleanliness
300
+
301
+ Fail if:
302
+
303
+ - `cleanroom/opencode` has tracked or untracked changes
304
+ - its current ref does not match the expected upstream ref after checkout/reset
305
+
306
+ Reason:
307
+
308
+ - cleanroom is meant to be the pristine upstream reference
309
+
310
+ ### Gate 2: patch worktree safety
311
+
312
+ Fail if:
313
+
314
+ - `vendor/opencode` contains uncommitted changes
315
+ - the patch branch has commits that are not represented by the tracked patch series when attempting a ref move
316
+
317
+ Reason:
318
+
319
+ - avoid silently discarding local OpenCode work
320
+
321
+ ### Gate 3: rebase/apply conflicts
322
+
323
+ Fail if:
324
+
325
+ - `git rebase` stops on conflict
326
+ - `git am` or equivalent patch apply fails
327
+
328
+ Required operator output:
329
+
330
+ - which commit/patch failed
331
+ - which files conflicted
332
+ - clear statement that the lock file was not updated
333
+
334
+ ### Gate 4: OpenCode build/type validation
335
+
336
+ After a successful rebase/apply, run validation in `vendor/opencode`.
337
+
338
+ Minimum required validation:
339
+
340
+ - `bun install --cwd vendor/opencode`
341
+ - web app build
342
+ - targeted typecheck/tests for touched OpenCode packages when practical
343
+
344
+ The exact commands can be refined during implementation, but the script must fail non-zero if any validation step fails.
345
+
346
+ Reason:
347
+
348
+ - a clean rebase is not enough
349
+ - upstream type or runtime changes can still break our patch stack
350
+
351
+ ### Gate 5: patch export reproducibility
352
+
353
+ After exporting `patches/opencode`, verify that applying the exported series onto the locked upstream commit yields the same resulting tree.
354
+
355
+ Fail if:
356
+
357
+ - export order is unstable
358
+ - local patch branch contains state not represented in the tracked series
359
+ - the reproduced tree does not match the current patch worktree
360
+
361
+ Reason:
362
+
363
+ - the tracked patch series must be portable and trustworthy
364
+
365
+ ### Gate 6: lock update
366
+
367
+ Only after all previous gates are green:
368
+
369
+ - update `opencode.lock.json`
370
+ - update any docs that echo the pinned version if we choose to keep them
371
+
372
+ ## One-Time Migration Plan
373
+
374
+ ### Phase A: Add metadata and scripts
375
+
376
+ 1. Add `opencode.lock.json` pinned to `v1.2.27`.
377
+ 2. Add the new sync script and helper modules.
378
+ 3. Add `patches/opencode/` directory.
379
+ 4. Add ignore rules for generated OpenCode paths.
380
+
381
+ ### Phase B: Capture current patch stack
382
+
383
+ 1. Create a pristine upstream cleanroom checkout at the current baseline.
384
+ 2. Recreate `vendor/opencode` as a git worktree.
385
+ 3. Port the current Agent Mockingbird changes from the committed vendor tree into the patch worktree.
386
+ 4. Commit those changes as a readable stack rather than one giant blob if feasible.
387
+ 5. Export that stack to `patches/opencode/`.
388
+
389
+ Important note:
390
+
391
+ - if splitting the existing vendor delta into multiple commits is too risky during migration, it is acceptable to land an initial single large baseline patch commit and improve patch granularity later
392
+ - correctness matters more than perfect history on day one
393
+
394
+ ### Phase C: Remove committed vendor source
395
+
396
+ 1. Remove `vendor/opencode` from git tracking.
397
+ 2. Keep the path itself available locally as a generated worktree.
398
+ 3. Update docs and scripts so `vendor/opencode` is understood as generated, not committed.
399
+
400
+ ### Phase D: Rebase to `v1.2.27`
401
+
402
+ 1. Run the full sync flow onto `v1.2.27`.
403
+ 2. Resolve conflicts if any.
404
+ 3. Rebuild the shipped web assets.
405
+ 4. Update the pinned installer version.
406
+
407
+ ## Build, Dev, and Packaging Changes
408
+
409
+ ### Build
410
+
411
+ Current `build.ts` already builds from `vendor/opencode/packages/app`.
412
+
413
+ Keep that path, but change the contract:
414
+
415
+ - before: source tree is committed and expected to exist
416
+ - after: source tree is generated locally and expected to be materialized by the sync workflow
417
+
418
+ Implementation options:
419
+
420
+ - make `build.ts` fail with a clear message if `vendor/opencode` is missing
421
+ - optionally add a small "ensure materialized" helper before build/dev scripts
422
+
423
+ ### Dev
424
+
425
+ Any dev flow that depends on the OpenCode source tree must either:
426
+
427
+ - require `bun run opencode:sync --rebuild-only` first
428
+ - or call a lightweight ensure step automatically
429
+
430
+ The error message must tell the operator exactly which command to run.
431
+
432
+ ### Packaging
433
+
434
+ The npm package and release bundle should continue shipping:
435
+
436
+ - compiled `dist/app`
437
+ - standalone runtime binary
438
+ - runtime assets
439
+ - installer scripts
440
+
441
+ They should not depend on the OpenCode source tree being committed to git.
442
+
443
+ ### CI
444
+
445
+ CI must evolve from "verify committed vendor-derived app bundle exists" to:
446
+
447
+ - materialize the generated OpenCode tree from lock + patch series
448
+ - build the app bundle
449
+ - verify packaged outputs
450
+
451
+ If we want to avoid larger CI churn immediately, an acceptable intermediate state is:
452
+
453
+ - keep verifying committed `dist/app`
454
+ - but stop assuming `vendor/opencode` itself is tracked
455
+
456
+ ## Agent and Tooling Guidance
457
+
458
+ The implementation should include explicit agent-facing guidance so future coding agents can follow the workflow without rediscovering it.
459
+
460
+ ### `AGENTS.md` changes
461
+
462
+ Add a short OpenCode workflow section to the repo `AGENTS.md`.
463
+
464
+ That section should state:
465
+
466
+ - do not edit `cleanroom/opencode`
467
+ - if the task requires changing shipped OpenCode code, materialize it with `bun run opencode:sync --rebuild-only`
468
+ - make OpenCode code changes only in `vendor/opencode`
469
+ - commit OpenCode changes in the patch worktree before exporting
470
+ - do not hand-edit `patches/opencode/*.patch` except for deliberate patch-series repair work
471
+ - use `bun run opencode:sync --export-patches` after committing OpenCode changes
472
+ - use `bun run opencode:sync --ref <tag>` for upstream bumps
473
+ - if the OpenCode worktree is dirty, do not attempt a ref bump or patch export
474
+
475
+ The AGENTS instructions should be short and behavioral, not a full re-explanation of the workflow.
476
+
477
+ ### Agent-readable status output
478
+
479
+ The sync tooling should support a machine-readable status mode, for example:
480
+
481
+ - `bun run opencode:sync --status --json`
482
+
483
+ Recommended JSON payload:
484
+
485
+ - locked upstream tag and commit
486
+ - cleanroom path and cleanliness
487
+ - patch branch name and HEAD
488
+ - vendor worktree status
489
+ - whether exported patches match current branch state
490
+
491
+ This gives agents and scripts a reliable way to check whether they are allowed to proceed.
492
+
493
+ ### Optional local skill
494
+
495
+ If we want a stronger agent experience, add a local skill such as:
496
+
497
+ - `.agents/skills/opencode-maintenance/SKILL.md`
498
+
499
+ The skill should contain:
500
+
501
+ - when to use the OpenCode workflow
502
+ - which command to run first
503
+ - what to edit and what not to edit
504
+ - how to export patches
505
+ - how to handle a dirty worktree
506
+ - how to bump upstream refs
507
+
508
+ This is optional, but recommended if OpenCode edits are going to be a recurring task.
509
+
510
+ ### Minimum tooling contract for agents
511
+
512
+ At minimum, agents need:
513
+
514
+ - one command to materialize the editable OpenCode worktree
515
+ - one command to report current workflow state
516
+ - one command to export committed OpenCode changes
517
+ - one command to perform an upstream ref bump
518
+
519
+ Without those, the workflow remains too implicit and future agent edits will drift back into ad hoc vendor changes.
520
+
521
+ ## Installer and Runtime Version Alignment
522
+
523
+ This is required. Do not leave the installer on `opencode-ai@latest`.
524
+
525
+ Change the installer/update flow so it installs:
526
+
527
+ - `opencode-ai@<packageVersion from opencode.lock.json>`
528
+
529
+ Reasons:
530
+
531
+ - the shipped UI version and sidecar version must match
532
+ - it removes silent drift
533
+ - it makes bug reports and upgrades reproducible
534
+
535
+ Acceptance rule:
536
+
537
+ - when the lock says `1.2.27`, install/update must install `opencode-ai@1.2.27`
538
+
539
+ ## Documentation Changes
540
+
541
+ Update or replace:
542
+
543
+ - `docs/vendor-opencode.md`
544
+ - `vendor/OPENCODE_VENDOR.md`
545
+ - any README references to `scripts/pull-opencode.sh` or copy-based vendor sync
546
+
547
+ The docs after the change must explain:
548
+
549
+ - what cleanroom is
550
+ - what `vendor/opencode` is
551
+ - where the patch series lives
552
+ - which command to run for status, rebuild, and upgrade
553
+ - how to resolve conflicts
554
+
555
+ ## Scripts That Need Review or Removal
556
+
557
+ At minimum, revisit:
558
+
559
+ - `scripts/vendor/sync-opencode.sh`
560
+ - `scripts/pull-opencode.sh`
561
+
562
+ The old copy-based sync scripts should either:
563
+
564
+ - be removed
565
+ - or become thin wrappers around the new workflow with updated behavior
566
+
567
+ Do not leave stale scripts around that still imply `cp -R` replacement is the supported model.
568
+
569
+ ## Desktop Readiness
570
+
571
+ This pass does not need to ship desktop deliverables.
572
+
573
+ It does need to ensure that the patch model can handle future desktop edits without redesign:
574
+
575
+ - patch commits may touch `packages/desktop*`
576
+ - validation can remain web-focused for now unless desktop patches are active
577
+ - docs should note that desktop-specific validation can be added later as an additional gate
578
+
579
+ ## Acceptance Criteria
580
+
581
+ The work is done when all of the following are true:
582
+
583
+ - `vendor/opencode` is no longer tracked by the main repo
584
+ - `cleanroom/opencode` is script-managed and pristine
585
+ - `bun run opencode:sync --status` reports valid workflow state
586
+ - `bun run opencode:sync --rebuild-only` can recreate the local shipped OpenCode tree
587
+ - `bun run opencode:sync --ref v1.2.27` works or fails loudly without partial lock updates
588
+ - `patches/opencode/` reproduces the shipped OpenCode tree from the locked upstream commit
589
+ - the installer pins `opencode-ai` to the locked version
590
+ - the app bundle still builds and packages successfully
591
+ - docs describe the new workflow instead of the old vendor-copy process
592
+
593
+ ## Recommended Implementation Order
594
+
595
+ 1. Add `opencode.lock.json`.
596
+ 2. Add the new sync script skeleton with `--status`.
597
+ 3. Add path/ignore changes for generated vendor and local cleanroom.
598
+ 4. Create cleanroom clone bootstrap logic.
599
+ 5. Create git worktree logic for `vendor/opencode`.
600
+ 6. Export/import patch series support.
601
+ 7. Port the current vendor delta into the new patch stack.
602
+ 8. Remove tracked `vendor/opencode`.
603
+ 9. Wire `build.ts` and developer flows to the generated tree contract.
604
+ 10. Pin installer OpenCode version from the lock file.
605
+ 11. Update docs and remove stale scripts.
606
+ 12. Run full validation and package checks.
607
+
608
+ ## Operator Notes for Future Me
609
+
610
+ - Expect the first migration to be the hardest part. Capturing the existing patch delta correctly matters more than perfect commit hygiene.
611
+ - If the existing delta is too large to split safely, take the initial baseline as one patch stack and improve granularity only after the workflow is working.
612
+ - The most important invariant is that the lock file is never advanced on a broken rebase.
613
+ - The second most important invariant is that `cleanroom/opencode` never becomes the place where local Agent Mockingbird changes live.
614
+ - If this gets messy, favor correctness and repeatability over elegance. The whole point of this work is to stop having an opaque hand-maintained vendor tree.