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,141 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ cd "${ROOT_DIR}"
6
+
7
+ if ! command -v curl >/dev/null 2>&1; then
8
+ echo "[memory:trace:e2e] curl is required but not found in PATH."
9
+ exit 1
10
+ fi
11
+
12
+ if ! command -v bun >/dev/null 2>&1; then
13
+ echo "[memory:trace:e2e] bun is required but not found in PATH."
14
+ exit 1
15
+ fi
16
+
17
+ AGENT_MOCKINGBIRD_BASE_URL="${AGENT_MOCKINGBIRD_BASE_URL:-http://127.0.0.1:${AGENT_MOCKINGBIRD_PORT:-3001}}"
18
+ MARKER="trace-e2e-$(date +%s)-$RANDOM"
19
+ MEMORY_TEXT="Durable trace marker ${MARKER} should be recalled for E2E verification."
20
+ SESSION_MODEL="${AGENT_MOCKINGBIRD_E2E_MODEL:-}"
21
+
22
+ echo "[memory:trace:e2e] base URL: ${AGENT_MOCKINGBIRD_BASE_URL}"
23
+ echo "[memory:trace:e2e] marker: ${MARKER}"
24
+
25
+ echo "[memory:trace:e2e] health check"
26
+ curl -fsS "${AGENT_MOCKINGBIRD_BASE_URL}/api/health" >/dev/null
27
+
28
+ echo "[memory:trace:e2e] writing durable memory seed"
29
+ curl -fsS "${AGENT_MOCKINGBIRD_BASE_URL}/api/memory/remember" \
30
+ -H "Content-Type: application/json" \
31
+ -d "{\"type\":\"fact\",\"source\":\"system\",\"content\":\"${MEMORY_TEXT}\"}" >/tmp/agent-mockingbird-memory-trace-remember.json
32
+
33
+ if [[ -z "${SESSION_MODEL}" ]]; then
34
+ echo "[memory:trace:e2e] resolving model from existing sessions"
35
+ if SESSIONS_JSON="$(curl -fsS "${AGENT_MOCKINGBIRD_BASE_URL}/api/sessions" 2>/dev/null)"; then
36
+ SESSION_MODEL="$(
37
+ printf '%s\n' "${SESSIONS_JSON}" \
38
+ | bun -e '
39
+ const payload = JSON.parse(await new Response(Bun.stdin.stream()).text());
40
+ const sessions = Array.isArray(payload.sessions) ? payload.sessions : [];
41
+ const mainModel =
42
+ sessions.find((session) => session?.id === "main" && typeof session?.model === "string")?.model ?? "";
43
+ if (mainModel.trim()) {
44
+ console.log(mainModel.trim());
45
+ process.exit(0);
46
+ }
47
+ const firstModel =
48
+ sessions.find((session) => typeof session?.model === "string" && session.model.trim())?.model ?? "";
49
+ console.log(firstModel.trim());
50
+ '
51
+ )"
52
+ fi
53
+ fi
54
+
55
+ if [[ -z "${SESSION_MODEL}" ]]; then
56
+ echo "[memory:trace:e2e] resolving model from /api/opencode/models"
57
+ if MODELS_JSON="$(curl -fsS "${AGENT_MOCKINGBIRD_BASE_URL}/api/opencode/models" 2>/dev/null)"; then
58
+ SESSION_MODEL="$(
59
+ printf '%s\n' "${MODELS_JSON}" \
60
+ | bun -e '
61
+ const payload = JSON.parse(await new Response(Bun.stdin.stream()).text());
62
+ const models = Array.isArray(payload.models) ? payload.models : [];
63
+ const firstId = models.find((model) => typeof model?.id === "string" && model.id.trim())?.id ?? "";
64
+ console.log(firstId);
65
+ '
66
+ )"
67
+ fi
68
+ fi
69
+
70
+ if [[ -z "${SESSION_MODEL}" ]]; then
71
+ echo "[memory:trace:e2e] no model available. Configure OpenCode models or set AGENT_MOCKINGBIRD_E2E_MODEL."
72
+ exit 1
73
+ fi
74
+
75
+ echo "[memory:trace:e2e] model: ${SESSION_MODEL}"
76
+ SESSION_CREATE_PAYLOAD="$(
77
+ SESSION_MODEL="${SESSION_MODEL}" bun -e '
78
+ const model = (process.env.SESSION_MODEL ?? "").trim();
79
+ const payload = { title: "Memory Trace E2E", model };
80
+ console.log(JSON.stringify(payload));
81
+ '
82
+ )"
83
+
84
+ echo "[memory:trace:e2e] creating session"
85
+ SESSION_ID="$(
86
+ curl -fsS "${AGENT_MOCKINGBIRD_BASE_URL}/api/sessions" \
87
+ -H "Content-Type: application/json" \
88
+ -d "${SESSION_CREATE_PAYLOAD}" \
89
+ | bun -e 'const data=JSON.parse(await new Response(Bun.stdin.stream()).text()); console.log(data.session?.id ?? "");'
90
+ )"
91
+
92
+ if [[ -z "${SESSION_ID}" ]]; then
93
+ echo "[memory:trace:e2e] failed to create session."
94
+ exit 1
95
+ fi
96
+
97
+ echo "[memory:trace:e2e] session: ${SESSION_ID}"
98
+ echo "[memory:trace:e2e] sending chat prompt through runtime"
99
+ curl -fsS "${AGENT_MOCKINGBIRD_BASE_URL}/api/chat" \
100
+ -H "Content-Type: application/json" \
101
+ -d "{\"sessionId\":\"${SESSION_ID}\",\"content\":\"Please answer briefly. Use any relevant memory for this marker: ${MARKER}\"}" \
102
+ >/tmp/agent-mockingbird-memory-trace-chat.json
103
+
104
+ echo "[memory:trace:e2e] loading session messages"
105
+ MESSAGES_JSON="$(curl -fsS "${AGENT_MOCKINGBIRD_BASE_URL}/api/sessions/${SESSION_ID}/messages")"
106
+ printf '%s\n' "${MESSAGES_JSON}" >/tmp/agent-mockingbird-memory-trace-messages.json
107
+
108
+ TRACE_SUMMARY="$(
109
+ printf '%s\n' "${MESSAGES_JSON}" \
110
+ | bun -e '
111
+ const payload = JSON.parse(await new Response(Bun.stdin.stream()).text());
112
+ const messages = Array.isArray(payload.messages) ? payload.messages : [];
113
+ const assistant = [...messages].reverse().find((message) => message.role === "assistant");
114
+ if (!assistant) {
115
+ console.log("NO_ASSISTANT");
116
+ process.exit(0);
117
+ }
118
+ const trace = assistant.memoryTrace;
119
+ if (!trace) {
120
+ console.log("NO_TRACE");
121
+ process.exit(0);
122
+ }
123
+ const injected = Number(trace.injectedContextResults ?? 0);
124
+ const toolCalls = Array.isArray(trace.toolCalls) ? trace.toolCalls.length : 0;
125
+ console.log(`TRACE injected=${injected} toolCalls=${toolCalls}`);
126
+ if (injected < 1) process.exit(2);
127
+ '
128
+ )"
129
+
130
+ if [[ "${TRACE_SUMMARY}" == "NO_ASSISTANT" ]]; then
131
+ echo "[memory:trace:e2e] no assistant message found."
132
+ exit 1
133
+ fi
134
+
135
+ if [[ "${TRACE_SUMMARY}" == "NO_TRACE" ]]; then
136
+ echo "[memory:trace:e2e] no memoryTrace found on assistant message."
137
+ exit 1
138
+ fi
139
+
140
+ echo "[memory:trace:e2e] ${TRACE_SUMMARY}"
141
+ echo "[memory:trace:e2e] PASS"
@@ -0,0 +1,108 @@
1
+ import { applyConfigPatch, getConfigSnapshot } from "../apps/server/src/backend/config/service";
2
+
3
+ const LEGACY_OPENCODE_ENV_KEYS = [
4
+ "AGENT_MOCKINGBIRD_OPENCODE_BASE_URL",
5
+ "AGENT_MOCKINGBIRD_OPENCODE_PROVIDER_ID",
6
+ "AGENT_MOCKINGBIRD_OPENCODE_MODEL_ID",
7
+ "AGENT_MOCKINGBIRD_OPENCODE_MODEL_FALLBACKS",
8
+ "AGENT_MOCKINGBIRD_OPENCODE_SMALL_MODEL",
9
+ "AGENT_MOCKINGBIRD_OPENCODE_TIMEOUT_MS",
10
+ "AGENT_MOCKINGBIRD_OPENCODE_PROMPT_TIMEOUT_MS",
11
+ "AGENT_MOCKINGBIRD_OPENCODE_RUN_WAIT_TIMEOUT_MS",
12
+ "AGENT_MOCKINGBIRD_OPENCODE_DIRECTORY",
13
+ ] as const;
14
+
15
+ function listLegacyOpencodeRuntimeEnvVars(source: Record<string, string | undefined> = process.env) {
16
+ return LEGACY_OPENCODE_ENV_KEYS.filter((key) => {
17
+ const value = source[key];
18
+ return typeof value === "string" && value.trim().length > 0;
19
+ });
20
+ }
21
+
22
+ function parseStringList(raw: string | undefined) {
23
+ if (!raw) return [];
24
+ const normalized = raw
25
+ .split(",")
26
+ .map((value) => value.trim())
27
+ .filter(Boolean);
28
+ return [...new Set(normalized)];
29
+ }
30
+
31
+ function parsePositiveInt(raw: string | undefined) {
32
+ if (!raw) return null;
33
+ const parsed = Number(raw);
34
+ if (!Number.isInteger(parsed) || parsed <= 0) return null;
35
+ return parsed;
36
+ }
37
+
38
+ function trimOrNull(raw: string | undefined) {
39
+ if (!raw) return null;
40
+ const trimmed = raw.trim();
41
+ return trimmed.length > 0 ? trimmed : null;
42
+ }
43
+
44
+ async function main() {
45
+ const present = listLegacyOpencodeRuntimeEnvVars();
46
+ if (present.length === 0) {
47
+ console.log("[config:migrate-opencode-env] No deprecated AGENT_MOCKINGBIRD_OPENCODE_* runtime vars found.");
48
+ return;
49
+ }
50
+
51
+ const patch: Record<string, unknown> = {};
52
+
53
+ const baseUrl = trimOrNull(process.env.AGENT_MOCKINGBIRD_OPENCODE_BASE_URL);
54
+ if (baseUrl) patch.baseUrl = baseUrl;
55
+ const providerId = trimOrNull(process.env.AGENT_MOCKINGBIRD_OPENCODE_PROVIDER_ID);
56
+ if (providerId) patch.providerId = providerId;
57
+ const modelId = trimOrNull(process.env.AGENT_MOCKINGBIRD_OPENCODE_MODEL_ID);
58
+ if (modelId) patch.modelId = modelId;
59
+ const fallbackModels = parseStringList(process.env.AGENT_MOCKINGBIRD_OPENCODE_MODEL_FALLBACKS);
60
+ if (fallbackModels.length > 0) patch.fallbackModels = fallbackModels;
61
+ const smallModel = trimOrNull(process.env.AGENT_MOCKINGBIRD_OPENCODE_SMALL_MODEL);
62
+ if (smallModel) patch.smallModel = smallModel;
63
+ const timeoutMs = parsePositiveInt(process.env.AGENT_MOCKINGBIRD_OPENCODE_TIMEOUT_MS);
64
+ if (timeoutMs) patch.timeoutMs = timeoutMs;
65
+ const promptTimeoutMs = parsePositiveInt(process.env.AGENT_MOCKINGBIRD_OPENCODE_PROMPT_TIMEOUT_MS);
66
+ if (promptTimeoutMs) patch.promptTimeoutMs = promptTimeoutMs;
67
+ const runWaitTimeoutMs = parsePositiveInt(process.env.AGENT_MOCKINGBIRD_OPENCODE_RUN_WAIT_TIMEOUT_MS);
68
+ if (runWaitTimeoutMs) patch.runWaitTimeoutMs = runWaitTimeoutMs;
69
+ const directory = trimOrNull(process.env.AGENT_MOCKINGBIRD_OPENCODE_DIRECTORY);
70
+ if (directory) patch.directory = directory;
71
+
72
+ if (Object.keys(patch).length === 0) {
73
+ console.log("[config:migrate-opencode-env] Deprecated vars are present but no valid values were parsed.");
74
+ return;
75
+ }
76
+
77
+ const snapshot = getConfigSnapshot();
78
+ const result = await applyConfigPatch({
79
+ expectedHash: snapshot.hash,
80
+ runSmokeTest: false,
81
+ patch: {
82
+ runtime: {
83
+ opencode: patch,
84
+ },
85
+ },
86
+ });
87
+
88
+ console.log("[config:migrate-opencode-env] Migrated values into agent-mockingbird config.");
89
+ console.log(
90
+ JSON.stringify(
91
+ {
92
+ configPath: result.snapshot.path,
93
+ previousHash: snapshot.hash,
94
+ nextHash: result.snapshot.hash,
95
+ appliedFields: Object.keys(patch).sort(),
96
+ migratedEnvVars: present,
97
+ },
98
+ null,
99
+ 2,
100
+ ),
101
+ );
102
+ console.log("[config:migrate-opencode-env] Remove deprecated AGENT_MOCKINGBIRD_OPENCODE_* runtime vars before starting agent-mockingbird.");
103
+ }
104
+
105
+ void main().catch((error) => {
106
+ console.error("[config:migrate-opencode-env] Failed:", error instanceof Error ? error.message : error);
107
+ process.exitCode = 1;
108
+ });
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ REGISTRY_URL="${AGENT_MOCKINGBIRD_REGISTRY_URL:-https://registry.npmjs.org/}"
5
+ AGENT_MOCKINGBIRD_TAG="${AGENT_MOCKINGBIRD_TAG:-latest}"
6
+ PUBLIC_NPM_REGISTRY_URL="${AGENT_MOCKINGBIRD_PUBLIC_REGISTRY_URL:-https://registry.npmjs.org/}"
7
+
8
+ if ! command -v npm >/dev/null 2>&1; then
9
+ echo "npm is required. Please install npm and run again."
10
+ exit 1
11
+ fi
12
+
13
+ if [[ $# -eq 0 ]]; then
14
+ set -- install
15
+ fi
16
+
17
+ tmp_npmrc="$(mktemp)"
18
+ cleanup() {
19
+ rm -f "${tmp_npmrc}"
20
+ }
21
+ trap cleanup EXIT
22
+
23
+ {
24
+ printf "registry=%s\n" "${REGISTRY_URL}"
25
+ } > "${tmp_npmrc}"
26
+
27
+ exec npm exec \
28
+ --yes \
29
+ --userconfig "${tmp_npmrc}" \
30
+ --package "@waffleophagus/agent-mockingbird-installer@${AGENT_MOCKINGBIRD_TAG}" \
31
+ agent-mockingbird-installer \
32
+ -- "$@"
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env bun
2
+ import path from "node:path";
3
+ import process from "node:process";
4
+ import readline from "node:readline/promises";
5
+ import { spawnSync } from "node:child_process";
6
+
7
+ const repoRoot = path.resolve(import.meta.dir, "..");
8
+
9
+ type ParsedArgs = {
10
+ ref?: string;
11
+ yes: boolean;
12
+ };
13
+
14
+ function parseArgs(argv: string[]): ParsedArgs {
15
+ const parsed: ParsedArgs = { yes: false };
16
+ for (let index = 0; index < argv.length; index += 1) {
17
+ const arg = argv[index];
18
+ if (arg === "--yes" || arg === "-y") {
19
+ parsed.yes = true;
20
+ continue;
21
+ }
22
+ if (arg === "--ref") {
23
+ const value = argv[index + 1];
24
+ if (!value) {
25
+ throw new Error("Missing value after --ref.");
26
+ }
27
+ parsed.ref = value;
28
+ index += 1;
29
+ continue;
30
+ }
31
+ if (!parsed.ref) {
32
+ parsed.ref = arg;
33
+ continue;
34
+ }
35
+ throw new Error(`Unknown argument: ${arg}`);
36
+ }
37
+ return parsed;
38
+ }
39
+
40
+ async function promptForRef(current?: string) {
41
+ const rl = readline.createInterface({
42
+ input: process.stdin,
43
+ output: process.stdout,
44
+ });
45
+ try {
46
+ const answer = (await rl.question(`OpenCode version/tag to hard swap to${current ? ` [${current}]` : ""}: `)).trim();
47
+ return answer || current || "";
48
+ } finally {
49
+ rl.close();
50
+ }
51
+ }
52
+
53
+ function run(ref: string) {
54
+ const result = spawnSync("bun", ["run", "./scripts/opencode-sync.ts", "--hard-ref", ref], {
55
+ cwd: repoRoot,
56
+ stdio: "inherit",
57
+ env: process.env,
58
+ });
59
+ process.exit(result.status ?? 1);
60
+ }
61
+
62
+ async function main() {
63
+ const args = parseArgs(process.argv.slice(2));
64
+ const ref = args.ref || (await promptForRef());
65
+ if (!ref) {
66
+ throw new Error("No version/tag provided.");
67
+ }
68
+
69
+ if (!args.yes) {
70
+ console.log(`Hard-swapping OpenCode to ${ref}. This discards current vendor/opencode state before rebuilding.`);
71
+ }
72
+ run(ref);
73
+ }
74
+
75
+ await main().catch((error) => {
76
+ console.error(error instanceof Error ? error.message : String(error));
77
+ process.exit(1);
78
+ });