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,1110 @@
1
+ From aa99a5bc6827bc92d46194cf9b1fd0b8c05f3181 Mon Sep 17 00:00:00 2001
2
+ From: Matt Campbell <matt@battleshopper.com>
3
+ Date: Thu, 19 Mar 2026 15:30:30 -0500
4
+ Subject: [PATCH 07/10] Rename waffle namespaces to mockingbird
5
+
6
+ ---
7
+ .../app/src/components/settings-agents.tsx | 38 +++---
8
+ .../src/components/settings-cron-data.test.ts | 12 +-
9
+ .../app/src/components/settings-cron-data.ts | 12 +-
10
+ packages/app/src/components/settings-cron.tsx | 52 ++++-----
11
+ .../app/src/components/settings-heartbeat.tsx | 108 +++++++++---------
12
+ packages/app/src/components/settings-mcp.tsx | 36 +++---
13
+ ...ed.tsx => settings-mockingbird-shared.tsx} | 16 +--
14
+ .../app/src/components/settings-runtime.tsx | 38 +++---
15
+ .../app/src/components/settings-skills.tsx | 50 ++++----
16
+ packages/app/src/i18n/en.ts | 2 +-
17
+ packages/app/src/pages/directory-layout.tsx | 2 +-
18
+ packages/app/src/pages/home.tsx | 2 +-
19
+ packages/app/src/pages/layout.tsx | 2 +-
20
+ .../src/utils/{waffle.ts => mockingbird.ts} | 12 +-
21
+ 14 files changed, 191 insertions(+), 191 deletions(-)
22
+ rename packages/app/src/components/{settings-waffle-shared.tsx => settings-mockingbird-shared.tsx} (85%)
23
+ rename packages/app/src/utils/{waffle.ts => mockingbird.ts} (75%)
24
+
25
+ diff --git a/packages/app/src/components/settings-agents.tsx b/packages/app/src/components/settings-agents.tsx
26
+ index dda48a075..81b547fb4 100644
27
+ --- a/packages/app/src/components/settings-agents.tsx
28
+ +++ b/packages/app/src/components/settings-agents.tsx
29
+ @@ -2,8 +2,8 @@ import { Button } from "@opencode-ai/ui/button"
30
+ import { showToast } from "@opencode-ai/ui/toast"
31
+ import { onMount, Show, type Component } from "solid-js"
32
+ import { createStore } from "solid-js/store"
33
+ -import { prettyJson, waffleJson } from "@/utils/waffle"
34
+ -import { WaffleCard, WaffleMetaRow, WaffleNotice, WaffleSettingsPage, WaffleSettingsSection, WaffleTextArea, WaffleToolbar } from "./settings-waffle-shared"
35
+ +import { prettyJson, mockingbirdJson } from "@/utils/mockingbird"
36
+ +import { MockingbirdCard, MockingbirdMetaRow, MockingbirdNotice, MockingbirdSettingsPage, MockingbirdSettingsSection, MockingbirdTextArea, MockingbirdToolbar } from "./settings-mockingbird-shared"
37
+
38
+ type AgentType = {
39
+ id: string
40
+ @@ -45,7 +45,7 @@ export const SettingsAgents: Component = () => {
41
+ setState("loading", true)
42
+ setState("error", "")
43
+ try {
44
+ - const payload = await waffleJson<AgentsPayload>("/api/waffle/agents")
45
+ + const payload = await mockingbirdJson<AgentsPayload>("/api/mockingbird/agents")
46
+ setState("payload", payload)
47
+ setState("text", prettyJson(payload.agentTypes))
48
+ } catch (error) {
49
+ @@ -77,7 +77,7 @@ export const SettingsAgents: Component = () => {
50
+ setState("saving", true)
51
+ setState("error", "")
52
+ try {
53
+ - const payload = await waffleJson<AgentsPayload>("/api/waffle/agents", {
54
+ + const payload = await mockingbirdJson<AgentsPayload>("/api/mockingbird/agents", {
55
+ method: "PATCH",
56
+ body: JSON.stringify({
57
+ upserts: parsed,
58
+ @@ -104,44 +104,44 @@ export const SettingsAgents: Component = () => {
59
+ })
60
+
61
+ return (
62
+ - <WaffleSettingsPage
63
+ + <MockingbirdSettingsPage
64
+ title="Agents"
65
+ description="Manage OpenCode agent definitions stored in the pinned workspace's .opencode/opencode.jsonc."
66
+ actions={
67
+ - <WaffleToolbar>
68
+ + <MockingbirdToolbar>
69
+ <Button variant="ghost" size="large" onClick={() => void load()} disabled={state.loading || state.saving}>
70
+ Refresh
71
+ </Button>
72
+ <Button size="large" onClick={() => void save()} disabled={state.loading || state.saving}>
73
+ Save
74
+ </Button>
75
+ - </WaffleToolbar>
76
+ + </MockingbirdToolbar>
77
+ }
78
+ >
79
+ <Show when={state.error}>
80
+ - <WaffleNotice tone="error">{state.error}</WaffleNotice>
81
+ + <MockingbirdNotice tone="error">{state.error}</MockingbirdNotice>
82
+ </Show>
83
+
84
+ <Show when={state.payload?.storage}>
85
+ {(storage) => (
86
+ - <WaffleSettingsSection title="Storage">
87
+ - <WaffleMetaRow label="Workspace directory" value={storage().directory} />
88
+ - <WaffleMetaRow label="Config file" value={storage().configFilePath} />
89
+ - <WaffleMetaRow label="Persistence mode" value={storage().persistenceMode} />
90
+ - </WaffleSettingsSection>
91
+ + <MockingbirdSettingsSection title="Storage">
92
+ + <MockingbirdMetaRow label="Workspace directory" value={storage().directory} />
93
+ + <MockingbirdMetaRow label="Config file" value={storage().configFilePath} />
94
+ + <MockingbirdMetaRow label="Persistence mode" value={storage().persistenceMode} />
95
+ + </MockingbirdSettingsSection>
96
+ )}
97
+ </Show>
98
+
99
+ - <WaffleSettingsSection title="Agent editor" description="Edit the current agent type array as JSON.">
100
+ - <WaffleCard>
101
+ - <WaffleTextArea
102
+ + <MockingbirdSettingsSection title="Agent editor" description="Edit the current agent type array as JSON.">
103
+ + <MockingbirdCard>
104
+ + <MockingbirdTextArea
105
+ rows={22}
106
+ value={state.text}
107
+ onInput={(event) => setState("text", event.currentTarget.value)}
108
+ spellcheck={false}
109
+ />
110
+ - </WaffleCard>
111
+ - </WaffleSettingsSection>
112
+ - </WaffleSettingsPage>
113
+ + </MockingbirdCard>
114
+ + </MockingbirdSettingsSection>
115
+ + </MockingbirdSettingsPage>
116
+ )
117
+ }
118
+ diff --git a/packages/app/src/components/settings-cron-data.test.ts b/packages/app/src/components/settings-cron-data.test.ts
119
+ index faf702691..c1ec8fcd3 100644
120
+ --- a/packages/app/src/components/settings-cron-data.test.ts
121
+ +++ b/packages/app/src/components/settings-cron-data.test.ts
122
+ @@ -6,13 +6,13 @@ describe("loadCronSettings", () => {
123
+ const calls: Array<{ path: string; init?: RequestInit }> = []
124
+ const requestJson = async <T>(path: string, init?: RequestInit) => {
125
+ calls.push({ path, init })
126
+ - if (path === "/api/waffle/cron/jobs") {
127
+ + if (path === "/api/mockingbird/cron/jobs") {
128
+ return { jobs: [] } as T
129
+ }
130
+ - if (path === "/api/waffle/cron/health") {
131
+ + if (path === "/api/mockingbird/cron/health") {
132
+ return { health: { enabled: true, jobs: { total: 0, enabled: 0 } } } as T
133
+ }
134
+ - if (path === "/api/waffle/cron/manage") {
135
+ + if (path === "/api/mockingbird/cron/manage") {
136
+ return {
137
+ contract: {
138
+ runModes: {
139
+ @@ -36,10 +36,10 @@ describe("loadCronSettings", () => {
140
+ },
141
+ })
142
+ expect(calls).toEqual([
143
+ - { path: "/api/waffle/cron/jobs", init: undefined },
144
+ - { path: "/api/waffle/cron/health", init: undefined },
145
+ + { path: "/api/mockingbird/cron/jobs", init: undefined },
146
+ + { path: "/api/mockingbird/cron/health", init: undefined },
147
+ {
148
+ - path: "/api/waffle/cron/manage",
149
+ + path: "/api/mockingbird/cron/manage",
150
+ init: {
151
+ method: "POST",
152
+ body: JSON.stringify({ action: "describe_contract" }),
153
+ diff --git a/packages/app/src/components/settings-cron-data.ts b/packages/app/src/components/settings-cron-data.ts
154
+ index c747ce06f..2eeab5f94 100644
155
+ --- a/packages/app/src/components/settings-cron-data.ts
156
+ +++ b/packages/app/src/components/settings-cron-data.ts
157
+ @@ -1,4 +1,4 @@
158
+ -import { prettyJson, waffleJson } from "@/utils/waffle"
159
+ +import { prettyJson, mockingbirdJson } from "@/utils/mockingbird"
160
+
161
+ export type CronJobDefinition = {
162
+ id: string
163
+ @@ -49,7 +49,7 @@ type CronContractResponse = {
164
+ contract: CronContract
165
+ }
166
+
167
+ -type WaffleJson = <T>(path: string, init?: RequestInit) => Promise<T>
168
+ +type MockingbirdJson = <T>(path: string, init?: RequestInit) => Promise<T>
169
+
170
+ const DEFAULT_AGENT_JOB = {
171
+ name: "Hourly review",
172
+ @@ -63,11 +63,11 @@ const DEFAULT_AGENT_JOB = {
173
+
174
+ export const DEFAULT_JOB = prettyJson(DEFAULT_AGENT_JOB)
175
+
176
+ -export async function loadCronSettings(requestJson: WaffleJson = waffleJson) {
177
+ +export async function loadCronSettings(requestJson: MockingbirdJson = mockingbirdJson) {
178
+ const [jobs, health, contract] = await Promise.all([
179
+ - requestJson<CronJobsResponse>("/api/waffle/cron/jobs"),
180
+ - requestJson<CronHealthResponse>("/api/waffle/cron/health"),
181
+ - requestJson<CronContractResponse>("/api/waffle/cron/manage", {
182
+ + requestJson<CronJobsResponse>("/api/mockingbird/cron/jobs"),
183
+ + requestJson<CronHealthResponse>("/api/mockingbird/cron/health"),
184
+ + requestJson<CronContractResponse>("/api/mockingbird/cron/manage", {
185
+ method: "POST",
186
+ body: JSON.stringify({ action: "describe_contract" }),
187
+ }),
188
+ diff --git a/packages/app/src/components/settings-cron.tsx b/packages/app/src/components/settings-cron.tsx
189
+ index a5b15cb11..67f282245 100644
190
+ --- a/packages/app/src/components/settings-cron.tsx
191
+ +++ b/packages/app/src/components/settings-cron.tsx
192
+ @@ -2,9 +2,9 @@ import { Button } from "@opencode-ai/ui/button"
193
+ import { showToast } from "@opencode-ai/ui/toast"
194
+ import { For, onMount, Show, type Component } from "solid-js"
195
+ import { createStore } from "solid-js/store"
196
+ -import { waffleJson } from "@/utils/waffle"
197
+ +import { mockingbirdJson } from "@/utils/mockingbird"
198
+ import { DEFAULT_JOB, loadCronSettings, serializeCronJobForEdit, type CronContract, type CronHealthSnapshot, type CronJobDefinition } from "./settings-cron-data"
199
+ -import { WaffleCard, WaffleMetaRow, WaffleNotice, WaffleSettingsPage, WaffleSettingsSection, WaffleTextArea, WaffleToolbar } from "./settings-waffle-shared"
200
+ +import { MockingbirdCard, MockingbirdMetaRow, MockingbirdNotice, MockingbirdSettingsPage, MockingbirdSettingsSection, MockingbirdTextArea, MockingbirdToolbar } from "./settings-mockingbird-shared"
201
+
202
+ export const SettingsCron: Component = () => {
203
+ const [state, setState] = createStore({
204
+ @@ -51,7 +51,7 @@ export const SettingsCron: Component = () => {
205
+ setState("saving", true)
206
+ setState("error", "")
207
+ try {
208
+ - await waffleJson("/api/waffle/cron/jobs", {
209
+ + await mockingbirdJson("/api/mockingbird/cron/jobs", {
210
+ method: "POST",
211
+ body: JSON.stringify(payload),
212
+ })
213
+ @@ -82,7 +82,7 @@ export const SettingsCron: Component = () => {
214
+ setState("busyId", state.editingId)
215
+ setState("error", "")
216
+ try {
217
+ - await waffleJson(`/api/waffle/cron/jobs/${encodeURIComponent(state.editingId)}`, {
218
+ + await mockingbirdJson(`/api/mockingbird/cron/jobs/${encodeURIComponent(state.editingId)}`, {
219
+ method: "PATCH",
220
+ body: JSON.stringify(payload),
221
+ })
222
+ @@ -99,7 +99,7 @@ export const SettingsCron: Component = () => {
223
+ async function runNow(id: string) {
224
+ setState("busyId", id)
225
+ try {
226
+ - await waffleJson(`/api/waffle/cron/jobs/${encodeURIComponent(id)}/run`, {
227
+ + await mockingbirdJson(`/api/mockingbird/cron/jobs/${encodeURIComponent(id)}/run`, {
228
+ method: "POST",
229
+ })
230
+ showToast({
231
+ @@ -117,7 +117,7 @@ export const SettingsCron: Component = () => {
232
+ async function remove(id: string) {
233
+ setState("busyId", id)
234
+ try {
235
+ - await waffleJson(`/api/waffle/cron/jobs/${encodeURIComponent(id)}`, {
236
+ + await mockingbirdJson(`/api/mockingbird/cron/jobs/${encodeURIComponent(id)}`, {
237
+ method: "DELETE",
238
+ })
239
+ await refresh()
240
+ @@ -133,34 +133,34 @@ export const SettingsCron: Component = () => {
241
+ })
242
+
243
+ return (
244
+ - <WaffleSettingsPage
245
+ + <MockingbirdSettingsPage
246
+ title="Cron"
247
+ description="Inspect cron health, create jobs, update jobs with JSON patches, and run them immediately."
248
+ actions={
249
+ - <WaffleToolbar>
250
+ + <MockingbirdToolbar>
251
+ <Button variant="ghost" size="large" onClick={() => void refresh()} disabled={state.loading || state.saving}>
252
+ Refresh
253
+ </Button>
254
+ - </WaffleToolbar>
255
+ + </MockingbirdToolbar>
256
+ }
257
+ >
258
+ <Show when={state.error}>
259
+ - <WaffleNotice tone="error">{state.error}</WaffleNotice>
260
+ + <MockingbirdNotice tone="error">{state.error}</MockingbirdNotice>
261
+ </Show>
262
+
263
+ <Show when={state.health}>
264
+ {(health) => (
265
+ - <WaffleSettingsSection title="Cron health">
266
+ - <WaffleMetaRow label="Enabled" value={health().enabled ? "Yes" : "No"} />
267
+ - <WaffleMetaRow label="Total jobs" value={String(health().jobs.total)} />
268
+ - <WaffleMetaRow label="Enabled jobs" value={String(health().jobs.enabled)} />
269
+ - </WaffleSettingsSection>
270
+ + <MockingbirdSettingsSection title="Cron health">
271
+ + <MockingbirdMetaRow label="Enabled" value={health().enabled ? "Yes" : "No"} />
272
+ + <MockingbirdMetaRow label="Total jobs" value={String(health().jobs.total)} />
273
+ + <MockingbirdMetaRow label="Enabled jobs" value={String(health().jobs.enabled)} />
274
+ + </MockingbirdSettingsSection>
275
+ )}
276
+ </Show>
277
+
278
+ <Show when={state.contract}>
279
+ {(contract) => (
280
+ - <WaffleSettingsSection title="Run mode contract" description="Current backend requirements for each cron run mode.">
281
+ + <MockingbirdSettingsSection title="Run mode contract" description="Current backend requirements for each cron run mode.">
282
+ <For each={Object.entries(contract().runModes)}>
283
+ {([mode, details]) => (
284
+ <div class="px-4 py-4 border-b border-border-weak-base last:border-none flex flex-col gap-1">
285
+ @@ -177,11 +177,11 @@ export const SettingsCron: Component = () => {
286
+ </div>
287
+ )}
288
+ </For>
289
+ - </WaffleSettingsSection>
290
+ + </MockingbirdSettingsSection>
291
+ )}
292
+ </Show>
293
+
294
+ - <WaffleSettingsSection title="Jobs">
295
+ + <MockingbirdSettingsSection title="Jobs">
296
+ <Show
297
+ when={state.jobs.length > 0}
298
+ fallback={<div class="px-4 py-4 text-14-regular text-text-weak">No cron jobs configured.</div>}
299
+ @@ -231,7 +231,7 @@ export const SettingsCron: Component = () => {
300
+
301
+ <Show when={state.editingId === job.id}>
302
+ <div class="flex flex-col gap-3">
303
+ - <WaffleTextArea
304
+ + <MockingbirdTextArea
305
+ rows={12}
306
+ value={state.editText}
307
+ onInput={(event) => setState("editText", event.currentTarget.value)}
308
+ @@ -247,10 +247,10 @@ export const SettingsCron: Component = () => {
309
+ )}
310
+ </For>
311
+ </Show>
312
+ - </WaffleSettingsSection>
313
+ + </MockingbirdSettingsSection>
314
+
315
+ - <WaffleSettingsSection title="Create job" description="Post a complete cron job definition as JSON using the current run mode contract.">
316
+ - <WaffleCard
317
+ + <MockingbirdSettingsSection title="Create job" description="Post a complete cron job definition as JSON using the current run mode contract.">
318
+ + <MockingbirdCard
319
+ footer={
320
+ <div class="flex justify-end">
321
+ <Button size="large" onClick={() => void createJob()} disabled={state.saving}>
322
+ @@ -259,9 +259,9 @@ export const SettingsCron: Component = () => {
323
+ </div>
324
+ }
325
+ >
326
+ - <WaffleTextArea rows={16} value={state.createText} onInput={(event) => setState("createText", event.currentTarget.value)} />
327
+ - </WaffleCard>
328
+ - </WaffleSettingsSection>
329
+ - </WaffleSettingsPage>
330
+ + <MockingbirdTextArea rows={16} value={state.createText} onInput={(event) => setState("createText", event.currentTarget.value)} />
331
+ + </MockingbirdCard>
332
+ + </MockingbirdSettingsSection>
333
+ + </MockingbirdSettingsPage>
334
+ )
335
+ }
336
+ diff --git a/packages/app/src/components/settings-heartbeat.tsx b/packages/app/src/components/settings-heartbeat.tsx
337
+ index 95a1770cc..628fda355 100644
338
+ --- a/packages/app/src/components/settings-heartbeat.tsx
339
+ +++ b/packages/app/src/components/settings-heartbeat.tsx
340
+ @@ -3,17 +3,17 @@ import { Switch } from "@opencode-ai/ui/switch"
341
+ import { showToast } from "@opencode-ai/ui/toast"
342
+ import { onMount, Show, type Component } from "solid-js"
343
+ import { createStore } from "solid-js/store"
344
+ -import { waffleJson } from "@/utils/waffle"
345
+ +import { mockingbirdJson } from "@/utils/mockingbird"
346
+ import {
347
+ - WaffleCard,
348
+ - WaffleInput,
349
+ - WaffleMetaRow,
350
+ - WaffleNotice,
351
+ - WaffleSettingsPage,
352
+ - WaffleSettingsSection,
353
+ - WaffleTextArea,
354
+ - WaffleToolbar,
355
+ -} from "./settings-waffle-shared"
356
+ + MockingbirdCard,
357
+ + MockingbirdInput,
358
+ + MockingbirdMetaRow,
359
+ + MockingbirdNotice,
360
+ + MockingbirdSettingsPage,
361
+ + MockingbirdSettingsSection,
362
+ + MockingbirdTextArea,
363
+ + MockingbirdToolbar,
364
+ +} from "./settings-mockingbird-shared"
365
+
366
+ type HeartbeatActiveHours = {
367
+ start: string
368
+ @@ -168,8 +168,8 @@ export const SettingsHeartbeat: Component = () => {
369
+ setState("error", "")
370
+ try {
371
+ const [heartbeat, runtime] = await Promise.all([
372
+ - waffleJson<HeartbeatStatusPayload>("/api/waffle/heartbeat"),
373
+ - waffleJson<RuntimePayload>("/api/waffle/runtime/config"),
374
+ + mockingbirdJson<HeartbeatStatusPayload>("/api/mockingbird/heartbeat"),
375
+ + mockingbirdJson<RuntimePayload>("/api/mockingbird/runtime/config"),
376
+ ])
377
+ setState("status", heartbeat.heartbeat)
378
+ setState("runtimeHash", runtime.hash)
379
+ @@ -194,7 +194,7 @@ export const SettingsHeartbeat: Component = () => {
380
+ setState("saving", true)
381
+ setState("error", "")
382
+ try {
383
+ - const runtime = await waffleJson<RuntimePayload>("/api/waffle/runtime/config", {
384
+ + const runtime = await mockingbirdJson<RuntimePayload>("/api/mockingbird/runtime/config", {
385
+ method: "PATCH",
386
+ body: JSON.stringify({
387
+ patch: {
388
+ @@ -224,7 +224,7 @@ export const SettingsHeartbeat: Component = () => {
389
+ setState("running", true)
390
+ setState("error", "")
391
+ try {
392
+ - const payload = await waffleJson<HeartbeatStatusPayload>("/api/waffle/heartbeat/run", {
393
+ + const payload = await mockingbirdJson<HeartbeatStatusPayload>("/api/mockingbird/heartbeat/run", {
394
+ method: "POST",
395
+ })
396
+ setState("status", payload.heartbeat)
397
+ @@ -246,11 +246,11 @@ export const SettingsHeartbeat: Component = () => {
398
+ })
399
+
400
+ return (
401
+ - <WaffleSettingsPage
402
+ + <MockingbirdSettingsPage
403
+ title="Heartbeat"
404
+ description="Monitor the dedicated heartbeat session, control its schedule, and choose its model explicitly."
405
+ actions={
406
+ - <WaffleToolbar>
407
+ + <MockingbirdToolbar>
408
+ <Button variant="ghost" size="large" onClick={() => void load()} disabled={state.loading || state.saving || state.running}>
409
+ Refresh
410
+ </Button>
411
+ @@ -260,46 +260,46 @@ export const SettingsHeartbeat: Component = () => {
412
+ <Button size="large" onClick={() => void save()} disabled={state.loading || state.saving || state.running}>
413
+ Save
414
+ </Button>
415
+ - </WaffleToolbar>
416
+ + </MockingbirdToolbar>
417
+ }
418
+ >
419
+ <Show when={state.error}>
420
+ - <WaffleNotice tone="error">{state.error}</WaffleNotice>
421
+ + <MockingbirdNotice tone="error">{state.error}</MockingbirdNotice>
422
+ </Show>
423
+
424
+ <Show when={state.status}>
425
+ {(status) => (
426
+ <>
427
+ - <WaffleSettingsSection title="Status" description="Current scheduler state for the dedicated Heartbeat session.">
428
+ - <WaffleMetaRow label="Config file" value={state.runtimePath || "Unavailable"} />
429
+ - <WaffleMetaRow label="Enabled" value={status().config.enabled ? "Yes" : "No"} />
430
+ - <WaffleMetaRow label="Session id" value={status().state.sessionId ?? "Not created yet"} />
431
+ - <WaffleMetaRow label="Currently running" value={status().state.running ? "Yes" : "No"} />
432
+ - <WaffleMetaRow label="Last run" value={formatTimestamp(status().state.lastRunAt)} />
433
+ - <WaffleMetaRow label="Next due" value={formatTimestamp(status().nextDueAt)} />
434
+ - <WaffleMetaRow label="Last result" value={formatResult(status().state.lastResult)} />
435
+ - <WaffleMetaRow label="Last updated" value={formatTimestamp(status().state.updatedAt)} />
436
+ - </WaffleSettingsSection>
437
+ + <MockingbirdSettingsSection title="Status" description="Current scheduler state for the dedicated Heartbeat session.">
438
+ + <MockingbirdMetaRow label="Config file" value={state.runtimePath || "Unavailable"} />
439
+ + <MockingbirdMetaRow label="Enabled" value={status().config.enabled ? "Yes" : "No"} />
440
+ + <MockingbirdMetaRow label="Session id" value={status().state.sessionId ?? "Not created yet"} />
441
+ + <MockingbirdMetaRow label="Currently running" value={status().state.running ? "Yes" : "No"} />
442
+ + <MockingbirdMetaRow label="Last run" value={formatTimestamp(status().state.lastRunAt)} />
443
+ + <MockingbirdMetaRow label="Next due" value={formatTimestamp(status().nextDueAt)} />
444
+ + <MockingbirdMetaRow label="Last result" value={formatResult(status().state.lastResult)} />
445
+ + <MockingbirdMetaRow label="Last updated" value={formatTimestamp(status().state.updatedAt)} />
446
+ + </MockingbirdSettingsSection>
447
+
448
+ <Show when={status().state.lastError}>
449
+ - <WaffleNotice tone="error">{status().state.lastError ?? ""}</WaffleNotice>
450
+ + <MockingbirdNotice tone="error">{status().state.lastError ?? ""}</MockingbirdNotice>
451
+ </Show>
452
+
453
+ <Show when={status().state.lastResponse}>
454
+ - <WaffleSettingsSection title="Last response" description="Most recent heartbeat response captured from the dedicated session.">
455
+ - <WaffleCard>
456
+ + <MockingbirdSettingsSection title="Last response" description="Most recent heartbeat response captured from the dedicated session.">
457
+ + <MockingbirdCard>
458
+ <div class="text-13-regular text-text-strong whitespace-pre-wrap break-words">
459
+ {status().state.lastResponse}
460
+ </div>
461
+ - </WaffleCard>
462
+ - </WaffleSettingsSection>
463
+ + </MockingbirdCard>
464
+ + </MockingbirdSettingsSection>
465
+ </Show>
466
+ </>
467
+ )}
468
+ </Show>
469
+
470
+ - <WaffleSettingsSection title="Controls" description="Choose whether heartbeat runs, how often it runs, and which model it uses.">
471
+ - <WaffleCard>
472
+ + <MockingbirdSettingsSection title="Controls" description="Choose whether heartbeat runs, how often it runs, and which model it uses.">
473
+ + <MockingbirdCard>
474
+ <div class="flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border-weak-base bg-surface-base px-4 py-3">
475
+ <div class="flex flex-col gap-1">
476
+ <div class="text-13-medium text-text-strong">Heartbeat enabled</div>
477
+ @@ -313,7 +313,7 @@ export const SettingsHeartbeat: Component = () => {
478
+ <div class="grid gap-4 sm:grid-cols-2">
479
+ <div class="flex flex-col gap-2">
480
+ <span class="text-12-medium text-text-weak">Model</span>
481
+ - <WaffleInput
482
+ + <MockingbirdInput
483
+ value={state.form.model}
484
+ placeholder="openai/gpt-5.4"
485
+ onInput={(event) => setState("form", "model", event.currentTarget.value)}
486
+ @@ -321,7 +321,7 @@ export const SettingsHeartbeat: Component = () => {
487
+ </div>
488
+ <div class="flex flex-col gap-2">
489
+ <span class="text-12-medium text-text-weak">Interval</span>
490
+ - <WaffleInput
491
+ + <MockingbirdInput
492
+ value={state.form.interval}
493
+ placeholder="15m"
494
+ onInput={(event) => setState("form", "interval", event.currentTarget.value)}
495
+ @@ -329,7 +329,7 @@ export const SettingsHeartbeat: Component = () => {
496
+ </div>
497
+ <div class="flex flex-col gap-2">
498
+ <span class="text-12-medium text-text-weak">Agent id</span>
499
+ - <WaffleInput
500
+ + <MockingbirdInput
501
+ value={state.form.agentId}
502
+ placeholder="build"
503
+ onInput={(event) => setState("form", "agentId", event.currentTarget.value)}
504
+ @@ -337,7 +337,7 @@ export const SettingsHeartbeat: Component = () => {
505
+ </div>
506
+ <div class="flex flex-col gap-2">
507
+ <span class="text-12-medium text-text-weak">Ack max chars</span>
508
+ - <WaffleInput
509
+ + <MockingbirdInput
510
+ type="number"
511
+ min="1"
512
+ value={state.form.ackMaxChars}
513
+ @@ -345,11 +345,11 @@ export const SettingsHeartbeat: Component = () => {
514
+ />
515
+ </div>
516
+ </div>
517
+ - </WaffleCard>
518
+ - </WaffleSettingsSection>
519
+ + </MockingbirdCard>
520
+ + </MockingbirdSettingsSection>
521
+
522
+ - <WaffleSettingsSection title="Active hours" description="Optionally restrict heartbeat runs to a daily time window.">
523
+ - <WaffleCard>
524
+ + <MockingbirdSettingsSection title="Active hours" description="Optionally restrict heartbeat runs to a daily time window.">
525
+ + <MockingbirdCard>
526
+ <div class="flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border-weak-base bg-surface-base px-4 py-3">
527
+ <div class="flex flex-col gap-1">
528
+ <div class="text-13-medium text-text-strong">Restrict to active hours</div>
529
+ @@ -368,7 +368,7 @@ export const SettingsHeartbeat: Component = () => {
530
+ <div class="grid gap-4 sm:grid-cols-3">
531
+ <div class="flex flex-col gap-2">
532
+ <span class="text-12-medium text-text-weak">Start</span>
533
+ - <WaffleInput
534
+ + <MockingbirdInput
535
+ value={state.form.activeStart}
536
+ placeholder="09:00"
537
+ onInput={(event) => setState("form", "activeStart", event.currentTarget.value)}
538
+ @@ -376,7 +376,7 @@ export const SettingsHeartbeat: Component = () => {
539
+ </div>
540
+ <div class="flex flex-col gap-2">
541
+ <span class="text-12-medium text-text-weak">End</span>
542
+ - <WaffleInput
543
+ + <MockingbirdInput
544
+ value={state.form.activeEnd}
545
+ placeholder="17:00"
546
+ onInput={(event) => setState("form", "activeEnd", event.currentTarget.value)}
547
+ @@ -384,7 +384,7 @@ export const SettingsHeartbeat: Component = () => {
548
+ </div>
549
+ <div class="flex flex-col gap-2">
550
+ <span class="text-12-medium text-text-weak">Timezone</span>
551
+ - <WaffleInput
552
+ + <MockingbirdInput
553
+ value={state.form.activeTimezone}
554
+ placeholder="America/Chicago"
555
+ onInput={(event) => setState("form", "activeTimezone", event.currentTarget.value)}
556
+ @@ -392,18 +392,18 @@ export const SettingsHeartbeat: Component = () => {
557
+ </div>
558
+ </div>
559
+ </Show>
560
+ - </WaffleCard>
561
+ - </WaffleSettingsSection>
562
+ + </MockingbirdCard>
563
+ + </MockingbirdSettingsSection>
564
+
565
+ - <WaffleSettingsSection title="Prompt" description="This prompt runs in the visible Heartbeat session whenever the scheduler fires.">
566
+ - <WaffleCard>
567
+ - <WaffleTextArea
568
+ + <MockingbirdSettingsSection title="Prompt" description="This prompt runs in the visible Heartbeat session whenever the scheduler fires.">
569
+ + <MockingbirdCard>
570
+ + <MockingbirdTextArea
571
+ rows={12}
572
+ value={state.form.prompt}
573
+ onInput={(event) => setState("form", "prompt", event.currentTarget.value)}
574
+ />
575
+ - </WaffleCard>
576
+ - </WaffleSettingsSection>
577
+ - </WaffleSettingsPage>
578
+ + </MockingbirdCard>
579
+ + </MockingbirdSettingsSection>
580
+ + </MockingbirdSettingsPage>
581
+ )
582
+ }
583
+ diff --git a/packages/app/src/components/settings-mcp.tsx b/packages/app/src/components/settings-mcp.tsx
584
+ index 88abc0a06..26bc59c19 100644
585
+ --- a/packages/app/src/components/settings-mcp.tsx
586
+ +++ b/packages/app/src/components/settings-mcp.tsx
587
+ @@ -2,8 +2,8 @@ import { Button } from "@opencode-ai/ui/button"
588
+ import { showToast } from "@opencode-ai/ui/toast"
589
+ import { For, onMount, Show, type Component } from "solid-js"
590
+ import { createStore } from "solid-js/store"
591
+ -import { prettyJson, waffleJson } from "@/utils/waffle"
592
+ -import { WaffleCard, WaffleNotice, WaffleSettingsPage, WaffleSettingsSection, WaffleTextArea, WaffleToolbar } from "./settings-waffle-shared"
593
+ +import { prettyJson, mockingbirdJson } from "@/utils/mockingbird"
594
+ +import { MockingbirdCard, MockingbirdNotice, MockingbirdSettingsPage, MockingbirdSettingsSection, MockingbirdTextArea, MockingbirdToolbar } from "./settings-mockingbird-shared"
595
+
596
+ type McpServer =
597
+ | {
598
+ @@ -51,7 +51,7 @@ export const SettingsMcp: Component = () => {
599
+ setState("loading", true)
600
+ setState("error", "")
601
+ try {
602
+ - const payload = await waffleJson<McpPayload>("/api/waffle/mcp")
603
+ + const payload = await mockingbirdJson<McpPayload>("/api/mockingbird/mcp")
604
+ setState("payload", payload)
605
+ setState("text", prettyJson(payload.servers))
606
+ } catch (error) {
607
+ @@ -78,7 +78,7 @@ export const SettingsMcp: Component = () => {
608
+ setState("saving", true)
609
+ setState("error", "")
610
+ try {
611
+ - const payload = await waffleJson<McpPayload>("/api/waffle/mcp", {
612
+ + const payload = await mockingbirdJson<McpPayload>("/api/mockingbird/mcp", {
613
+ method: "PUT",
614
+ body: JSON.stringify({ servers: parsed }),
615
+ })
616
+ @@ -99,8 +99,8 @@ export const SettingsMcp: Component = () => {
617
+ async function runAction(id: string, action: "connect" | "disconnect" | "auth/start" | "auth/remove") {
618
+ setState("busyId", id)
619
+ try {
620
+ - const payload = await waffleJson<{ status: McpStatusMap; authorizationUrl?: string }>(
621
+ - `/api/waffle/mcp/${encodeURIComponent(id)}/${action}`,
622
+ + const payload = await mockingbirdJson<{ status: McpStatusMap; authorizationUrl?: string }>(
623
+ + `/api/mockingbird/mcp/${encodeURIComponent(id)}/${action}`,
624
+ {
625
+ method: "POST",
626
+ },
627
+ @@ -123,25 +123,25 @@ export const SettingsMcp: Component = () => {
628
+ const statusFor = (id: string) => state.payload?.status?.[id]?.status ?? "unknown"
629
+
630
+ return (
631
+ - <WaffleSettingsPage
632
+ + <MockingbirdSettingsPage
633
+ title="MCP"
634
+ description="Edit MCP server definitions and drive connection or auth flows through Agent Mockingbird's same-origin APIs."
635
+ actions={
636
+ - <WaffleToolbar>
637
+ + <MockingbirdToolbar>
638
+ <Button variant="ghost" size="large" onClick={() => void load()} disabled={state.loading || state.saving}>
639
+ Refresh
640
+ </Button>
641
+ <Button size="large" onClick={() => void save()} disabled={state.loading || state.saving}>
642
+ Save
643
+ </Button>
644
+ - </WaffleToolbar>
645
+ + </MockingbirdToolbar>
646
+ }
647
+ >
648
+ <Show when={state.error}>
649
+ - <WaffleNotice tone="error">{state.error}</WaffleNotice>
650
+ + <MockingbirdNotice tone="error">{state.error}</MockingbirdNotice>
651
+ </Show>
652
+
653
+ - <WaffleSettingsSection title="Configured servers" description="Connection status and auth actions for configured MCP servers.">
654
+ + <MockingbirdSettingsSection title="Configured servers" description="Connection status and auth actions for configured MCP servers.">
655
+ <Show
656
+ when={(state.payload?.servers.length ?? 0) > 0}
657
+ fallback={<div class="px-4 py-4 text-14-regular text-text-weak">No MCP servers configured.</div>}
658
+ @@ -186,18 +186,18 @@ export const SettingsMcp: Component = () => {
659
+ )}
660
+ </For>
661
+ </Show>
662
+ - </WaffleSettingsSection>
663
+ + </MockingbirdSettingsSection>
664
+
665
+ - <WaffleSettingsSection title="Server editor" description="Edit the full MCP server array as JSON.">
666
+ - <WaffleCard>
667
+ - <WaffleTextArea
668
+ + <MockingbirdSettingsSection title="Server editor" description="Edit the full MCP server array as JSON.">
669
+ + <MockingbirdCard>
670
+ + <MockingbirdTextArea
671
+ rows={22}
672
+ value={state.text}
673
+ onInput={(event) => setState("text", event.currentTarget.value)}
674
+ spellcheck={false}
675
+ />
676
+ - </WaffleCard>
677
+ - </WaffleSettingsSection>
678
+ - </WaffleSettingsPage>
679
+ + </MockingbirdCard>
680
+ + </MockingbirdSettingsSection>
681
+ + </MockingbirdSettingsPage>
682
+ )
683
+ }
684
+ diff --git a/packages/app/src/components/settings-waffle-shared.tsx b/packages/app/src/components/settings-mockingbird-shared.tsx
685
+ similarity index 85%
686
+ rename from packages/app/src/components/settings-waffle-shared.tsx
687
+ rename to packages/app/src/components/settings-mockingbird-shared.tsx
688
+ index 64ece4b04..6955f903c 100644
689
+ --- a/packages/app/src/components/settings-waffle-shared.tsx
690
+ +++ b/packages/app/src/components/settings-mockingbird-shared.tsx
691
+ @@ -1,6 +1,6 @@
692
+ import { type JSX, type ParentProps, Show } from "solid-js"
693
+
694
+ -export function WaffleSettingsPage(
695
+ +export function MockingbirdSettingsPage(
696
+ props: ParentProps<{
697
+ title: string
698
+ description?: string
699
+ @@ -28,7 +28,7 @@ export function WaffleSettingsPage(
700
+ )
701
+ }
702
+
703
+ -export function WaffleSettingsSection(
704
+ +export function MockingbirdSettingsSection(
705
+ props: ParentProps<{
706
+ title: string
707
+ description?: string
708
+ @@ -53,7 +53,7 @@ export function WaffleSettingsSection(
709
+ )
710
+ }
711
+
712
+ -export function WaffleMetaRow(props: { label: string; value: string | JSX.Element }) {
713
+ +export function MockingbirdMetaRow(props: { label: string; value: string | JSX.Element }) {
714
+ return (
715
+ <div class="flex flex-col gap-1 px-4 py-3 border-b border-border-weak-base last:border-none">
716
+ <span class="text-12-medium text-text-weak">{props.label}</span>
717
+ @@ -62,11 +62,11 @@ export function WaffleMetaRow(props: { label: string; value: string | JSX.Elemen
718
+ )
719
+ }
720
+
721
+ -export function WaffleToolbar(props: ParentProps) {
722
+ +export function MockingbirdToolbar(props: ParentProps) {
723
+ return <div class="flex flex-wrap items-center gap-2">{props.children}</div>
724
+ }
725
+
726
+ -export function WaffleNotice(props: { tone?: "error" | "success" | "info"; children: JSX.Element }) {
727
+ +export function MockingbirdNotice(props: { tone?: "error" | "success" | "info"; children: JSX.Element }) {
728
+ const tone = () => props.tone ?? "info"
729
+ return (
730
+ <div
731
+ @@ -82,7 +82,7 @@ export function WaffleNotice(props: { tone?: "error" | "success" | "info"; child
732
+ )
733
+ }
734
+
735
+ -export function WaffleInput(props: JSX.InputHTMLAttributes<HTMLInputElement>) {
736
+ +export function MockingbirdInput(props: JSX.InputHTMLAttributes<HTMLInputElement>) {
737
+ return (
738
+ <input
739
+ {...props}
740
+ @@ -93,7 +93,7 @@ export function WaffleInput(props: JSX.InputHTMLAttributes<HTMLInputElement>) {
741
+ )
742
+ }
743
+
744
+ -export function WaffleTextArea(props: JSX.TextareaHTMLAttributes<HTMLTextAreaElement>) {
745
+ +export function MockingbirdTextArea(props: JSX.TextareaHTMLAttributes<HTMLTextAreaElement>) {
746
+ return (
747
+ <textarea
748
+ {...props}
749
+ @@ -104,7 +104,7 @@ export function WaffleTextArea(props: JSX.TextareaHTMLAttributes<HTMLTextAreaEle
750
+ )
751
+ }
752
+
753
+ -export function WaffleCard(props: ParentProps<{ footer?: JSX.Element }>) {
754
+ +export function MockingbirdCard(props: ParentProps<{ footer?: JSX.Element }>) {
755
+ return (
756
+ <div class="rounded-lg border border-border-weak-base bg-background-base overflow-hidden">
757
+ <div class="p-4 flex flex-col gap-4">{props.children}</div>
758
+ diff --git a/packages/app/src/components/settings-runtime.tsx b/packages/app/src/components/settings-runtime.tsx
759
+ index fd091697e..808430278 100644
760
+ --- a/packages/app/src/components/settings-runtime.tsx
761
+ +++ b/packages/app/src/components/settings-runtime.tsx
762
+ @@ -2,8 +2,8 @@ import { Button } from "@opencode-ai/ui/button"
763
+ import { showToast } from "@opencode-ai/ui/toast"
764
+ import { onMount, Show, type Component } from "solid-js"
765
+ import { createStore } from "solid-js/store"
766
+ -import { prettyJson, waffleJson } from "@/utils/waffle"
767
+ -import { WaffleCard, WaffleMetaRow, WaffleNotice, WaffleSettingsPage, WaffleSettingsSection, WaffleTextArea, WaffleToolbar } from "./settings-waffle-shared"
768
+ +import { prettyJson, mockingbirdJson } from "@/utils/mockingbird"
769
+ +import { MockingbirdCard, MockingbirdMetaRow, MockingbirdNotice, MockingbirdSettingsPage, MockingbirdSettingsSection, MockingbirdTextArea, MockingbirdToolbar } from "./settings-mockingbird-shared"
770
+
771
+ type RuntimePayload = {
772
+ hash: string
773
+ @@ -29,7 +29,7 @@ export const SettingsRuntime: Component = () => {
774
+ setState("loading", true)
775
+ setState("error", "")
776
+ try {
777
+ - const payload = await waffleJson<RuntimePayload>("/api/waffle/runtime/config")
778
+ + const payload = await mockingbirdJson<RuntimePayload>("/api/mockingbird/runtime/config")
779
+ setState("payload", payload)
780
+ setState("text", prettyJson(payload.config))
781
+ } catch (error) {
782
+ @@ -51,7 +51,7 @@ export const SettingsRuntime: Component = () => {
783
+ setState("saving", true)
784
+ setState("error", "")
785
+ try {
786
+ - const payload = await waffleJson<RuntimePayload>("/api/waffle/runtime/config/replace", {
787
+ + const payload = await mockingbirdJson<RuntimePayload>("/api/mockingbird/runtime/config/replace", {
788
+ method: "POST",
789
+ body: JSON.stringify({
790
+ config: parsed,
791
+ @@ -77,44 +77,44 @@ export const SettingsRuntime: Component = () => {
792
+ })
793
+
794
+ return (
795
+ - <WaffleSettingsPage
796
+ + <MockingbirdSettingsPage
797
+ title="Runtime"
798
+ description="Edit Agent Mockingbird runtime settings owned outside OpenCode's workspace config."
799
+ actions={
800
+ - <WaffleToolbar>
801
+ + <MockingbirdToolbar>
802
+ <Button variant="ghost" size="large" onClick={() => void load()} disabled={state.loading || state.saving}>
803
+ Refresh
804
+ </Button>
805
+ <Button size="large" onClick={() => void save()} disabled={state.loading || state.saving}>
806
+ Save
807
+ </Button>
808
+ - </WaffleToolbar>
809
+ + </MockingbirdToolbar>
810
+ }
811
+ >
812
+ <Show when={state.error}>
813
+ - <WaffleNotice tone="error">{state.error}</WaffleNotice>
814
+ + <MockingbirdNotice tone="error">{state.error}</MockingbirdNotice>
815
+ </Show>
816
+
817
+ <Show when={state.payload}>
818
+ {(payload) => (
819
+ - <WaffleSettingsSection title="Config metadata">
820
+ - <WaffleMetaRow label="Config file" value={payload().path} />
821
+ - <WaffleMetaRow label="Pinned workspace" value={payload().config.workspace.pinnedDirectory} />
822
+ - <WaffleMetaRow label="Revision hash" value={payload().hash} />
823
+ - </WaffleSettingsSection>
824
+ + <MockingbirdSettingsSection title="Config metadata">
825
+ + <MockingbirdMetaRow label="Config file" value={payload().path} />
826
+ + <MockingbirdMetaRow label="Pinned workspace" value={payload().config.workspace.pinnedDirectory} />
827
+ + <MockingbirdMetaRow label="Revision hash" value={payload().hash} />
828
+ + </MockingbirdSettingsSection>
829
+ )}
830
+ </Show>
831
+
832
+ - <WaffleSettingsSection title="Config editor" description="Replace the current Agent Mockingbird config payload with JSON.">
833
+ - <WaffleCard>
834
+ - <WaffleTextArea
835
+ + <MockingbirdSettingsSection title="Config editor" description="Replace the current Agent Mockingbird config payload with JSON.">
836
+ + <MockingbirdCard>
837
+ + <MockingbirdTextArea
838
+ rows={22}
839
+ value={state.text}
840
+ onInput={(event) => setState("text", event.currentTarget.value)}
841
+ spellcheck={false}
842
+ />
843
+ - </WaffleCard>
844
+ - </WaffleSettingsSection>
845
+ - </WaffleSettingsPage>
846
+ + </MockingbirdCard>
847
+ + </MockingbirdSettingsSection>
848
+ + </MockingbirdSettingsPage>
849
+ )
850
+ }
851
+ diff --git a/packages/app/src/components/settings-skills.tsx b/packages/app/src/components/settings-skills.tsx
852
+ index 2254d384c..ca7c7b3cf 100644
853
+ --- a/packages/app/src/components/settings-skills.tsx
854
+ +++ b/packages/app/src/components/settings-skills.tsx
855
+ @@ -3,8 +3,8 @@ import { Switch } from "@opencode-ai/ui/switch"
856
+ import { showToast } from "@opencode-ai/ui/toast"
857
+ import { createSignal, For, onMount, Show, type Component } from "solid-js"
858
+ import { createStore } from "solid-js/store"
859
+ -import { WaffleCard, WaffleInput, WaffleMetaRow, WaffleNotice, WaffleSettingsPage, WaffleSettingsSection, WaffleTextArea, WaffleToolbar } from "./settings-waffle-shared"
860
+ -import { waffleJson } from "@/utils/waffle"
861
+ +import { MockingbirdCard, MockingbirdInput, MockingbirdMetaRow, MockingbirdNotice, MockingbirdSettingsPage, MockingbirdSettingsSection, MockingbirdTextArea, MockingbirdToolbar } from "./settings-mockingbird-shared"
862
+ +import { mockingbirdJson } from "@/utils/mockingbird"
863
+
864
+ type SkillEntry = {
865
+ id: string
866
+ @@ -48,7 +48,7 @@ export const SettingsSkills: Component = () => {
867
+ setState("loading", true)
868
+ setState("error", "")
869
+ try {
870
+ - const catalog = await waffleJson<SkillsPayload>("/api/waffle/skills")
871
+ + const catalog = await mockingbirdJson<SkillsPayload>("/api/mockingbird/skills")
872
+ setState("catalog", catalog)
873
+ } catch (error) {
874
+ const message = error instanceof Error ? error.message : "Failed to load skills"
875
+ @@ -66,7 +66,7 @@ export const SettingsSkills: Component = () => {
876
+ async function toggleSkill(id: string, enabled: boolean) {
877
+ setState("busyId", id)
878
+ try {
879
+ - const next = await waffleJson<SkillsPayload>(`/api/waffle/skills/${encodeURIComponent(id)}`, {
880
+ + const next = await mockingbirdJson<SkillsPayload>(`/api/mockingbird/skills/${encodeURIComponent(id)}`, {
881
+ method: "PATCH",
882
+ body: JSON.stringify({ enabled }),
883
+ })
884
+ @@ -84,7 +84,7 @@ export const SettingsSkills: Component = () => {
885
+ async function removeSkill(id: string) {
886
+ setState("busyId", id)
887
+ try {
888
+ - const next = await waffleJson<SkillsPayload>(`/api/waffle/skills/${encodeURIComponent(id)}`, {
889
+ + const next = await mockingbirdJson<SkillsPayload>(`/api/mockingbird/skills/${encodeURIComponent(id)}`, {
890
+ method: "DELETE",
891
+ })
892
+ setState("catalog", next)
893
+ @@ -107,7 +107,7 @@ export const SettingsSkills: Component = () => {
894
+ setState("error", "")
895
+ setState("busyId", "import")
896
+ try {
897
+ - await waffleJson("/api/waffle/skills/import", {
898
+ + await mockingbirdJson("/api/mockingbird/skills/import", {
899
+ method: "POST",
900
+ body: JSON.stringify({
901
+ id: state.importId,
902
+ @@ -135,30 +135,30 @@ export const SettingsSkills: Component = () => {
903
+ })
904
+
905
+ return (
906
+ - <WaffleSettingsPage
907
+ + <MockingbirdSettingsPage
908
+ title="Skills"
909
+ description="Manage the workspace skill catalog and import managed skills for the pinned workspace."
910
+ actions={
911
+ - <WaffleToolbar>
912
+ + <MockingbirdToolbar>
913
+ <Button variant="ghost" size="large" onClick={() => void refresh()} disabled={state.loading}>
914
+ Refresh
915
+ </Button>
916
+ - </WaffleToolbar>
917
+ + </MockingbirdToolbar>
918
+ }
919
+ >
920
+ <Show when={state.error}>
921
+ - <WaffleNotice tone="error">{state.error}</WaffleNotice>
922
+ + <MockingbirdNotice tone="error">{state.error}</MockingbirdNotice>
923
+ </Show>
924
+
925
+ <Show when={state.catalog}>
926
+ {(catalog) => (
927
+ <>
928
+ - <WaffleSettingsSection title="Catalog paths">
929
+ - <WaffleMetaRow label="Managed skills path" value={catalog().managedPath} />
930
+ - <WaffleMetaRow label="Disabled skills path" value={catalog().disabledPath} />
931
+ - </WaffleSettingsSection>
932
+ + <MockingbirdSettingsSection title="Catalog paths">
933
+ + <MockingbirdMetaRow label="Managed skills path" value={catalog().managedPath} />
934
+ + <MockingbirdMetaRow label="Disabled skills path" value={catalog().disabledPath} />
935
+ + </MockingbirdSettingsSection>
936
+
937
+ - <WaffleSettingsSection title="Installed skills" description="Enable, disable, or remove managed skills.">
938
+ + <MockingbirdSettingsSection title="Installed skills" description="Enable, disable, or remove managed skills.">
939
+ <Show
940
+ when={catalog().skills.length > 0}
941
+ fallback={<div class="px-4 py-4 text-14-regular text-text-weak">No managed skills found.</div>}
942
+ @@ -193,10 +193,10 @@ export const SettingsSkills: Component = () => {
943
+ )}
944
+ </For>
945
+ </Show>
946
+ - </WaffleSettingsSection>
947
+ + </MockingbirdSettingsSection>
948
+
949
+ <Show when={catalog().invalid.length > 0}>
950
+ - <WaffleSettingsSection title="Invalid skills">
951
+ + <MockingbirdSettingsSection title="Invalid skills">
952
+ <For each={catalog().invalid}>
953
+ {(issue) => (
954
+ <div class="px-4 py-3 border-b border-border-weak-base last:border-none">
955
+ @@ -206,17 +206,17 @@ export const SettingsSkills: Component = () => {
956
+ </div>
957
+ )}
958
+ </For>
959
+ - </WaffleSettingsSection>
960
+ + </MockingbirdSettingsSection>
961
+ </Show>
962
+ </>
963
+ )}
964
+ </Show>
965
+
966
+ - <WaffleSettingsSection
967
+ + <MockingbirdSettingsSection
968
+ title="Import skill"
969
+ description="Paste a managed SKILL.md and import it into the pinned workspace."
970
+ >
971
+ - <WaffleCard
972
+ + <MockingbirdCard
973
+ footer={
974
+ <div class="flex flex-wrap items-center justify-between gap-3">
975
+ <label class="flex items-center gap-2 text-13-regular text-text-strong">
976
+ @@ -235,7 +235,7 @@ export const SettingsSkills: Component = () => {
977
+ >
978
+ <div class="flex flex-col gap-2">
979
+ <span class="text-12-medium text-text-weak">Skill id</span>
980
+ - <WaffleInput
981
+ + <MockingbirdInput
982
+ value={state.importId}
983
+ placeholder="example-skill"
984
+ onInput={(event) => setState("importId", event.currentTarget.value)}
985
+ @@ -243,14 +243,14 @@ export const SettingsSkills: Component = () => {
986
+ </div>
987
+ <div class="flex flex-col gap-2">
988
+ <span class="text-12-medium text-text-weak">SKILL.md content</span>
989
+ - <WaffleTextArea
990
+ + <MockingbirdTextArea
991
+ rows={14}
992
+ value={state.importContent}
993
+ onInput={(event) => setState("importContent", event.currentTarget.value)}
994
+ />
995
+ </div>
996
+ - </WaffleCard>
997
+ - </WaffleSettingsSection>
998
+ - </WaffleSettingsPage>
999
+ + </MockingbirdCard>
1000
+ + </MockingbirdSettingsSection>
1001
+ + </MockingbirdSettingsPage>
1002
+ )
1003
+ }
1004
+ diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts
1005
+ index 0bb31bab0..5c6e30b68 100644
1006
+ --- a/packages/app/src/i18n/en.ts
1007
+ +++ b/packages/app/src/i18n/en.ts
1008
+ @@ -703,7 +703,7 @@ export const dict = {
1009
+
1010
+ "settings.section.desktop": "Desktop",
1011
+ "settings.section.server": "Server",
1012
+ - "settings.section.wafflebot": "Wafflebot",
1013
+ + "settings.section.agent-mockingbird": "Agent Mockingbird",
1014
+ "settings.tab.general": "General",
1015
+ "settings.tab.shortcuts": "Shortcuts",
1016
+ "settings.desktop.section.wsl": "WSL",
1017
+ diff --git a/packages/app/src/pages/directory-layout.tsx b/packages/app/src/pages/directory-layout.tsx
1018
+ index 50b6fa5ad..f6c5b7b23 100644
1019
+ --- a/packages/app/src/pages/directory-layout.tsx
1020
+ +++ b/packages/app/src/pages/directory-layout.tsx
1021
+ @@ -11,7 +11,7 @@ import { base64Encode } from "@opencode-ai/util/encode"
1022
+ import { decode64 } from "@/utils/base64"
1023
+ import { showToast } from "@opencode-ai/ui/toast"
1024
+ import { useLanguage } from "@/context/language"
1025
+ -import { readPinnedWorkspace, workspaceHref } from "@/utils/waffle"
1026
+ +import { readPinnedWorkspace, workspaceHref } from "@/utils/mockingbird"
1027
+ function DirectoryDataProvider(props: ParentProps<{ directory: string }>) {
1028
+ const navigate = useNavigate()
1029
+ const sync = useSync()
1030
+ diff --git a/packages/app/src/pages/home.tsx b/packages/app/src/pages/home.tsx
1031
+ index ab5c84329..a556507cb 100644
1032
+ --- a/packages/app/src/pages/home.tsx
1033
+ +++ b/packages/app/src/pages/home.tsx
1034
+ @@ -1,6 +1,6 @@
1035
+ import { useNavigate } from "@solidjs/router"
1036
+ import { createSignal, onMount, Show } from "solid-js"
1037
+ -import { readPinnedWorkspace, workspaceHref } from "@/utils/waffle"
1038
+ +import { readPinnedWorkspace, workspaceHref } from "@/utils/mockingbird"
1039
+
1040
+ export default function Home() {
1041
+ const navigate = useNavigate()
1042
+ diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx
1043
+ index 86cfb0b9b..3246eaebc 100644
1044
+ --- a/packages/app/src/pages/layout.tsx
1045
+ +++ b/packages/app/src/pages/layout.tsx
1046
+ @@ -91,7 +91,7 @@ import {
1047
+ } from "./layout/sidebar-workspace"
1048
+ import { ProjectDragOverlay, SortableProject, type ProjectSidebarContext } from "./layout/sidebar-project"
1049
+ import { SidebarContent } from "./layout/sidebar-shell"
1050
+ -import { readPinnedWorkspace } from "@/utils/waffle"
1051
+ +import { readPinnedWorkspace } from "@/utils/mockingbird"
1052
+
1053
+ export default function Layout(props: ParentProps) {
1054
+ const [store, setStore, , ready] = persisted(
1055
+ diff --git a/packages/app/src/utils/waffle.ts b/packages/app/src/utils/mockingbird.ts
1056
+ similarity index 75%
1057
+ rename from packages/app/src/utils/waffle.ts
1058
+ rename to packages/app/src/utils/mockingbird.ts
1059
+ index 79286f66b..c30e7aac8 100644
1060
+ --- a/packages/app/src/utils/waffle.ts
1061
+ +++ b/packages/app/src/utils/mockingbird.ts
1062
+ @@ -1,11 +1,11 @@
1063
+ import { base64Encode } from "@opencode-ai/util/encode"
1064
+
1065
+ -export class WaffleApiError extends Error {
1066
+ +export class MockingbirdApiError extends Error {
1067
+ status: number
1068
+
1069
+ constructor(message: string, status: number) {
1070
+ super(message)
1071
+ - this.name = "WaffleApiError"
1072
+ + this.name = "MockingbirdApiError"
1073
+ this.status = status
1074
+ }
1075
+ }
1076
+ @@ -13,13 +13,13 @@ export class WaffleApiError extends Error {
1077
+ async function parseJson<T>(response: Response): Promise<T> {
1078
+ const contentType = response.headers.get("content-type") ?? ""
1079
+ if (!contentType.includes("application/json")) {
1080
+ - throw new WaffleApiError(`Expected JSON response from ${response.url}`, response.status)
1081
+ + throw new MockingbirdApiError(`Expected JSON response from ${response.url}`, response.status)
1082
+ }
1083
+
1084
+ return (await response.json()) as T
1085
+ }
1086
+
1087
+ -export async function waffleJson<T>(path: string, init?: RequestInit): Promise<T> {
1088
+ +export async function mockingbirdJson<T>(path: string, init?: RequestInit): Promise<T> {
1089
+ const response = await fetch(path, {
1090
+ ...init,
1091
+ headers: {
1092
+ @@ -36,7 +36,7 @@ export async function waffleJson<T>(path: string, init?: RequestInit): Promise<T
1093
+ } catch {
1094
+ // Preserve the default HTTP status message when the error body is not JSON.
1095
+ }
1096
+ - throw new WaffleApiError(message, response.status)
1097
+ + throw new MockingbirdApiError(message, response.status)
1098
+ }
1099
+
1100
+ return parseJson<T>(response)
1101
+ @@ -57,5 +57,5 @@ export interface PinnedWorkspacePayload {
1102
+ }
1103
+
1104
+ export function readPinnedWorkspace() {
1105
+ - return waffleJson<PinnedWorkspacePayload>("/api/waffle/runtime/pinned-workspace")
1106
+ + return mockingbirdJson<PinnedWorkspacePayload>("/api/mockingbird/runtime/pinned-workspace")
1107
+ }
1108
+ --
1109
+ 2.53.0
1110
+