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.
- package/.agents/skills/btca-cli/SKILL.md +64 -0
- package/.agents/skills/btca-cli/agents/openai.yaml +3 -0
- package/.agents/skills/frontend-design/SKILL.md +42 -0
- package/.agents/skills/frontend-design/agents/openai.yaml +3 -0
- package/.env.example +36 -0
- package/.githooks/pre-commit +33 -0
- package/.github/workflows/ci.yml +309 -0
- package/.opencode/bun.lock +18 -0
- package/.opencode/package.json +5 -0
- package/.opencode/tools/agent_type_manager.ts +100 -0
- package/.opencode/tools/config_manager.ts +87 -0
- package/.opencode/tools/cron_manager.ts +145 -0
- package/.opencode/tools/memory_get.ts +43 -0
- package/.opencode/tools/memory_remember.ts +53 -0
- package/.opencode/tools/memory_search.ts +48 -0
- package/AGENTS.md +126 -0
- package/MEMORY.md +2 -0
- package/README.md +451 -0
- package/THIRD_PARTY_NOTICES.md +11 -0
- package/agent-mockingbird.config.example.json +135 -0
- package/apps/server/package.json +32 -0
- package/apps/server/src/backend/agents/bootstrapContext.ts +362 -0
- package/apps/server/src/backend/agents/openclawImport.test.ts +133 -0
- package/apps/server/src/backend/agents/openclawImport.ts +797 -0
- package/apps/server/src/backend/agents/opencodeConfig.ts +428 -0
- package/apps/server/src/backend/agents/service.ts +10 -0
- package/apps/server/src/backend/config/example-config.test.ts +20 -0
- package/apps/server/src/backend/config/orchestration.ts +243 -0
- package/apps/server/src/backend/config/policy.ts +158 -0
- package/apps/server/src/backend/config/schema.test.ts +15 -0
- package/apps/server/src/backend/config/schema.ts +391 -0
- package/apps/server/src/backend/config/semantic.test.ts +34 -0
- package/apps/server/src/backend/config/semantic.ts +149 -0
- package/apps/server/src/backend/config/service.test.ts +75 -0
- package/apps/server/src/backend/config/service.ts +207 -0
- package/apps/server/src/backend/config/smoke.ts +77 -0
- package/apps/server/src/backend/config/store.test.ts +123 -0
- package/apps/server/src/backend/config/store.ts +581 -0
- package/apps/server/src/backend/config/testFixtures.ts +5 -0
- package/apps/server/src/backend/config/types.ts +56 -0
- package/apps/server/src/backend/contracts/events.ts +320 -0
- package/apps/server/src/backend/contracts/runtime.ts +111 -0
- package/apps/server/src/backend/cron/executor.ts +435 -0
- package/apps/server/src/backend/cron/repository.ts +170 -0
- package/apps/server/src/backend/cron/service.ts +660 -0
- package/apps/server/src/backend/cron/storage.ts +92 -0
- package/apps/server/src/backend/cron/types.ts +138 -0
- package/apps/server/src/backend/cron/utils.ts +351 -0
- package/apps/server/src/backend/db/client.ts +20 -0
- package/apps/server/src/backend/db/migrate.ts +40 -0
- package/apps/server/src/backend/db/repository.ts +1762 -0
- package/apps/server/src/backend/db/schema.ts +113 -0
- package/apps/server/src/backend/db/usageDashboard.test.ts +102 -0
- package/apps/server/src/backend/db/wipe.ts +13 -0
- package/apps/server/src/backend/defaults.ts +32 -0
- package/apps/server/src/backend/env.ts +48 -0
- package/apps/server/src/backend/heartbeat/activeHours.ts +45 -0
- package/apps/server/src/backend/heartbeat/defaultJob.ts +88 -0
- package/apps/server/src/backend/heartbeat/heartbeat.test.ts +110 -0
- package/apps/server/src/backend/heartbeat/runtimeService.ts +190 -0
- package/apps/server/src/backend/heartbeat/service.ts +176 -0
- package/apps/server/src/backend/heartbeat/state.test.ts +63 -0
- package/apps/server/src/backend/heartbeat/state.ts +167 -0
- package/apps/server/src/backend/heartbeat/types.ts +54 -0
- package/apps/server/src/backend/http/boundedQueue.test.ts +49 -0
- package/apps/server/src/backend/http/boundedQueue.ts +92 -0
- package/apps/server/src/backend/http/parsers.ts +40 -0
- package/apps/server/src/backend/http/router.ts +61 -0
- package/apps/server/src/backend/http/routes/agentRoutes.ts +67 -0
- package/apps/server/src/backend/http/routes/backgroundRoutes.ts +203 -0
- package/apps/server/src/backend/http/routes/chatRoutes.ts +107 -0
- package/apps/server/src/backend/http/routes/configRoutes.ts +602 -0
- package/apps/server/src/backend/http/routes/cronRoutes.ts +221 -0
- package/apps/server/src/backend/http/routes/dashboardRoutes.ts +308 -0
- package/apps/server/src/backend/http/routes/eventRoutes.ts +7 -0
- package/apps/server/src/backend/http/routes/heartbeatRoutes.test.ts +41 -0
- package/apps/server/src/backend/http/routes/heartbeatRoutes.ts +28 -0
- package/apps/server/src/backend/http/routes/index.ts +101 -0
- package/apps/server/src/backend/http/routes/mcpRoutes.ts +213 -0
- package/apps/server/src/backend/http/routes/memoryRoutes.ts +154 -0
- package/apps/server/src/backend/http/routes/runRoutes.ts +310 -0
- package/apps/server/src/backend/http/routes/runtimeRoutes.ts +197 -0
- package/apps/server/src/backend/http/routes/skillRoutes.ts +112 -0
- package/apps/server/src/backend/http/routes/uiRoutes.test.ts +161 -0
- package/apps/server/src/backend/http/routes/uiRoutes.ts +177 -0
- package/apps/server/src/backend/http/routes/usageRoutes.test.ts +104 -0
- package/apps/server/src/backend/http/routes/usageRoutes.ts +767 -0
- package/apps/server/src/backend/http/schemas.ts +64 -0
- package/apps/server/src/backend/http/sse.ts +144 -0
- package/apps/server/src/backend/integration/backend-core.test.ts +2316 -0
- package/apps/server/src/backend/logging/logger.ts +64 -0
- package/apps/server/src/backend/mcp/service.ts +326 -0
- package/apps/server/src/backend/memory/cli.ts +170 -0
- package/apps/server/src/backend/memory/conceptExpansion.test.ts +28 -0
- package/apps/server/src/backend/memory/conceptExpansion.ts +80 -0
- package/apps/server/src/backend/memory/qmdPort.test.ts +54 -0
- package/apps/server/src/backend/memory/qmdPort.ts +61 -0
- package/apps/server/src/backend/memory/records.test.ts +66 -0
- package/apps/server/src/backend/memory/records.ts +229 -0
- package/apps/server/src/backend/memory/service.ts +2012 -0
- package/apps/server/src/backend/memory/sqliteVec.ts +58 -0
- package/apps/server/src/backend/memory/types.ts +104 -0
- package/apps/server/src/backend/opencode/agentMockingbirdPlugin.test.ts +396 -0
- package/apps/server/src/backend/opencode/client.ts +98 -0
- package/apps/server/src/backend/opencode/models.ts +41 -0
- package/apps/server/src/backend/opencode/systemPrompt.test.ts +146 -0
- package/apps/server/src/backend/opencode/systemPrompt.ts +284 -0
- package/apps/server/src/backend/paths.ts +57 -0
- package/apps/server/src/backend/prompts/service.ts +100 -0
- package/apps/server/src/backend/queue/queue.test.ts +189 -0
- package/apps/server/src/backend/queue/service.ts +177 -0
- package/apps/server/src/backend/queue/types.ts +39 -0
- package/apps/server/src/backend/run/service.ts +576 -0
- package/apps/server/src/backend/run/storage.ts +47 -0
- package/apps/server/src/backend/run/types.ts +44 -0
- package/apps/server/src/backend/runtime/errors.ts +61 -0
- package/apps/server/src/backend/runtime/index.ts +72 -0
- package/apps/server/src/backend/runtime/memoryPromptDedup.test.ts +153 -0
- package/apps/server/src/backend/runtime/memoryPromptDedup.ts +76 -0
- package/apps/server/src/backend/runtime/opencodeRuntime/backgroundMethods.ts +765 -0
- package/apps/server/src/backend/runtime/opencodeRuntime/coreMethods.ts +705 -0
- package/apps/server/src/backend/runtime/opencodeRuntime/eventMethods.ts +503 -0
- package/apps/server/src/backend/runtime/opencodeRuntime/memoryMethods.ts +462 -0
- package/apps/server/src/backend/runtime/opencodeRuntime/promptMethods.ts +1167 -0
- package/apps/server/src/backend/runtime/opencodeRuntime/shared.ts +254 -0
- package/apps/server/src/backend/runtime/opencodeRuntime.test.ts +2899 -0
- package/apps/server/src/backend/runtime/opencodeRuntime.ts +135 -0
- package/apps/server/src/backend/runtime/sessionScope.ts +45 -0
- package/apps/server/src/backend/skills/service.ts +442 -0
- package/apps/server/src/backend/workspace/resolve.ts +27 -0
- package/apps/server/src/cli/agent-mockingbird.mjs +2522 -0
- package/apps/server/src/cli/agent-mockingbird.test.ts +68 -0
- package/apps/server/src/cli/runtime-assets.mjs +269 -0
- package/apps/server/src/cli/runtime-assets.test.ts +52 -0
- package/apps/server/src/cli/runtime-layout.mjs +75 -0
- package/apps/server/src/cli/standaloneBuild.test.ts +19 -0
- package/apps/server/src/cli/standaloneBuild.ts +19 -0
- package/apps/server/src/cli/standaloneCronBinary.test.ts +187 -0
- package/apps/server/src/index.ts +178 -0
- package/apps/server/tsconfig.json +12 -0
- package/backlog.md +5 -0
- package/bin/agent-mockingbird +2522 -0
- package/bin/runtime-layout.mjs +75 -0
- package/build-bin.ts +34 -0
- package/build-cli.mjs +37 -0
- package/build.ts +40 -0
- package/bun-env.d.ts +11 -0
- package/bun.lock +888 -0
- package/bunfig.toml +2 -0
- package/components.json +21 -0
- package/config.json +130 -0
- package/deploy/RELEASE_INSTALL.md +112 -0
- package/deploy/docker-compose.yml +42 -0
- package/deploy/systemd/README.md +46 -0
- package/deploy/systemd/agent-mockingbird.service +28 -0
- package/deploy/systemd/opencode.service +25 -0
- package/docs/legacy-config-ui-reference.md +51 -0
- package/docs/memory-e2e-trace-2026-03-04.md +63 -0
- package/docs/memory-ops.md +96 -0
- package/docs/memory-runtime-contract.md +42 -0
- package/docs/memory-tuning-remote-2026-03-04.md +59 -0
- package/docs/opencode-rebase-workflow-plan.md +614 -0
- package/docs/opencode-startup-sync-plan.md +94 -0
- package/docs/vendor-opencode.md +41 -0
- package/drizzle/0000_famous_turbo.sql +49 -0
- package/drizzle/0001_cron_memory_aux.sql +160 -0
- package/drizzle/0002_runtime_session_bindings.sql +28 -0
- package/drizzle/0003_background_runs.sql +27 -0
- package/drizzle/0004_memory_open_write.sql +63 -0
- package/drizzle/0005_signal_channel.sql +47 -0
- package/drizzle/0006_usage_event_dimensions.sql +7 -0
- package/drizzle/meta/0000_snapshot.json +341 -0
- package/drizzle/meta/_journal.json +55 -0
- package/drizzle.config.ts +14 -0
- package/eslint.config.mjs +77 -0
- package/knip.json +18 -0
- package/memory/2026-03-04.md +4 -0
- package/opencode.lock.json +16 -0
- package/package.json +67 -0
- package/packages/agent-mockingbird-installer/README.md +31 -0
- package/packages/agent-mockingbird-installer/bin/agent-mockingbird-installer.mjs +44 -0
- package/packages/agent-mockingbird-installer/opencode.lock.json +16 -0
- package/packages/agent-mockingbird-installer/package.json +23 -0
- package/packages/contracts/package.json +19 -0
- package/packages/contracts/src/agentTypes.ts +122 -0
- package/packages/contracts/src/cron.ts +146 -0
- package/packages/contracts/src/dashboard.ts +378 -0
- package/packages/contracts/src/index.ts +3 -0
- package/packages/contracts/tsconfig.json +4 -0
- package/patches/opencode/0001-Wafflebot-OpenCode-baseline.patch +2341 -0
- package/patches/opencode/0002-Fix-OpenCode-web-entry-and-settings-icons.patch +104 -0
- package/patches/opencode/0003-fix-app-remove-duplicate-sidebar-mount.patch +32 -0
- package/patches/opencode/0004-Add-heartbeat-settings-and-usage-nav.patch +506 -0
- package/patches/opencode/0005-Use-chart-icon-for-usage-nav.patch +38 -0
- package/patches/opencode/0006-Modernize-cron-settings.patch +399 -0
- package/patches/opencode/0007-Rename-waffle-namespaces-to-mockingbird.patch +1110 -0
- package/patches/opencode/0008-Remove-cron-contract-section.patch +178 -0
- package/patches/opencode/0009-Rework-cron-tab-as-operations-console.patch +414 -0
- package/patches/opencode/0010-Refine-heartbeat-settings-controls.patch +208 -0
- package/runtime-assets/opencode-config/opencode.jsonc +25 -0
- package/runtime-assets/opencode-config/package.json +5 -0
- package/runtime-assets/opencode-config/plugins/agent-mockingbird.ts +715 -0
- package/runtime-assets/workspace/.agents/skills/config-auditor/SKILL.md +25 -0
- package/runtime-assets/workspace/.agents/skills/config-editor/SKILL.md +24 -0
- package/runtime-assets/workspace/.agents/skills/cron-manager/SKILL.md +57 -0
- package/runtime-assets/workspace/.agents/skills/memory-ops/SKILL.md +120 -0
- package/runtime-assets/workspace/.agents/skills/runtime-diagnose/SKILL.md +25 -0
- package/runtime-assets/workspace/AGENTS.md +56 -0
- package/runtime-assets/workspace/MEMORY.md +4 -0
- package/scripts/build-release-bundle.sh +66 -0
- package/scripts/check-ship.ts +383 -0
- package/scripts/dev-opencode.sh +17 -0
- package/scripts/dev-stack-opencode.sh +15 -0
- package/scripts/dev-stack.sh +61 -0
- package/scripts/install-systemd.sh +87 -0
- package/scripts/memory-e2e.sh +76 -0
- package/scripts/memory-trace-e2e.sh +141 -0
- package/scripts/migrate-opencode-env.ts +108 -0
- package/scripts/onboard/bootstrap.sh +32 -0
- package/scripts/opencode-swap.ts +78 -0
- package/scripts/opencode-sync.ts +715 -0
- package/scripts/runtime-assets-sync.mjs +83 -0
- package/scripts/setup-git-hooks.ts +39 -0
- package/tsconfig.json +45 -0
- package/tui.json +98 -0
- package/turbo.json +36 -0
- package/vendor/OPENCODE_VENDOR.md +13 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: btca-cli
|
|
3
|
+
description: Operate the btca CLI for local resources and source-first answers. Use when setting up btca in a project, connecting a provider, adding or managing resources, and asking questions via btca commands. Invoke this skill when the user says "use btca" or needs to do more detailed research on a specific library or framework.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# btca CLI
|
|
7
|
+
|
|
8
|
+
`btca` is a source-first research CLI. It hydrates resources (git, local, npm) into searchable context, then answers questions grounded in those sources. Use configured resources for ongoing work, or one-off anonymous resources directly in `btca ask`.
|
|
9
|
+
|
|
10
|
+
Full CLI reference: https://docs.btca.dev/guides/cli-reference
|
|
11
|
+
|
|
12
|
+
Add resources:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Git resource
|
|
16
|
+
btca add -n svelte-dev https://github.com/sveltejs/svelte.dev
|
|
17
|
+
|
|
18
|
+
# Local directory
|
|
19
|
+
btca add -n my-docs -t local /absolute/path/to/docs
|
|
20
|
+
|
|
21
|
+
# npm package
|
|
22
|
+
btca add npm:@types/node@22.10.1 -n node-types -t npm
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Verify resources:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
btca resources
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Ask a question:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
btca ask -r svelte-dev -q "How do I define remote functions?"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Common Tasks
|
|
38
|
+
|
|
39
|
+
- Ask with multiple resources:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
btca ask -r react -r typescript -q "How do I type useState?"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- Ask with anonymous one-off resources (not saved to config):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# One-off git repo
|
|
49
|
+
btca ask -r https://github.com/sveltejs/svelte -q "Where is the implementation of writable stores?"
|
|
50
|
+
|
|
51
|
+
# One-off npm package
|
|
52
|
+
btca ask -r npm:react@19.0.0 -q "How is useTransition exported?"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Config Overview
|
|
56
|
+
|
|
57
|
+
- Config lives in `btca.config.jsonc` (project) and `~/.config/btca/btca.config.jsonc` (global).
|
|
58
|
+
- Project config overrides global and controls provider/model and resources.
|
|
59
|
+
|
|
60
|
+
## Troubleshooting
|
|
61
|
+
|
|
62
|
+
- "No resources configured": add resources with `btca add ...` and re-run `btca resources`.
|
|
63
|
+
- "Provider not connected": run `btca connect` and follow the prompts.
|
|
64
|
+
- "Unknown resource": use `btca resources` for configured names, or pass a valid HTTPS git URL / `npm:<package>` as an anonymous one-off in `btca ask`.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: frontend-design
|
|
3
|
+
description: Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
|
|
4
|
+
license: Complete terms in LICENSE.txt
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices.
|
|
8
|
+
|
|
9
|
+
The user provides frontend requirements: a component, page, application, or interface to build. They may include context about the purpose, audience, or technical constraints.
|
|
10
|
+
|
|
11
|
+
## Design Thinking
|
|
12
|
+
|
|
13
|
+
Before coding, understand the context and commit to a BOLD aesthetic direction:
|
|
14
|
+
- **Purpose**: What problem does this interface solve? Who uses it?
|
|
15
|
+
- **Tone**: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction.
|
|
16
|
+
- **Constraints**: Technical requirements (framework, performance, accessibility).
|
|
17
|
+
- **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember?
|
|
18
|
+
|
|
19
|
+
**CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity.
|
|
20
|
+
|
|
21
|
+
Then implement working code (HTML/CSS/JS, React, Vue, etc.) that is:
|
|
22
|
+
- Production-grade and functional
|
|
23
|
+
- Visually striking and memorable
|
|
24
|
+
- Cohesive with a clear aesthetic point-of-view
|
|
25
|
+
- Meticulously refined in every detail
|
|
26
|
+
|
|
27
|
+
## Frontend Aesthetics Guidelines
|
|
28
|
+
|
|
29
|
+
Focus on:
|
|
30
|
+
- **Typography**: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font.
|
|
31
|
+
- **Color & Theme**: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes.
|
|
32
|
+
- **Motion**: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise.
|
|
33
|
+
- **Spatial Composition**: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density.
|
|
34
|
+
- **Backgrounds & Visual Details**: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays.
|
|
35
|
+
|
|
36
|
+
NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character.
|
|
37
|
+
|
|
38
|
+
Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations.
|
|
39
|
+
|
|
40
|
+
**IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well.
|
|
41
|
+
|
|
42
|
+
Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision.
|
package/.env.example
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# SQLite + runtime config path
|
|
2
|
+
# AGENT_MOCKINGBIRD_DB_PATH=./data/agent-mockingbird.db
|
|
3
|
+
# AGENT_MOCKINGBIRD_CONFIG_PATH=./data/agent-mockingbird.config.json
|
|
4
|
+
|
|
5
|
+
# OpenCode runtime settings are sourced from agent-mockingbird config file (`runtime.opencode.*`).
|
|
6
|
+
# To migrate old env-based settings into config once:
|
|
7
|
+
# bun run config:migrate-opencode-env
|
|
8
|
+
|
|
9
|
+
# OpenCode auth (optional)
|
|
10
|
+
# AGENT_MOCKINGBIRD_OPENCODE_AUTH_HEADER=Bearer your-token
|
|
11
|
+
# AGENT_MOCKINGBIRD_OPENCODE_USERNAME=opencode
|
|
12
|
+
# AGENT_MOCKINGBIRD_OPENCODE_PASSWORD=your-password
|
|
13
|
+
|
|
14
|
+
# Tiered cron subsystem
|
|
15
|
+
# AGENT_MOCKINGBIRD_CRON_ENABLED=true
|
|
16
|
+
# AGENT_MOCKINGBIRD_CRON_SCHEDULER_POLL_MS=1000
|
|
17
|
+
# AGENT_MOCKINGBIRD_CRON_WORKER_POLL_MS=1000
|
|
18
|
+
# AGENT_MOCKINGBIRD_CRON_LEASE_MS=30000
|
|
19
|
+
# AGENT_MOCKINGBIRD_CRON_MAX_ENQUEUE_PER_JOB_TICK=25
|
|
20
|
+
# AGENT_MOCKINGBIRD_CRON_API_BASE_URL=http://127.0.0.1:3001
|
|
21
|
+
|
|
22
|
+
# Memory subsystem defaults (used on first config bootstrap and as explicit missing-field defaults)
|
|
23
|
+
# AGENT_MOCKINGBIRD_MEMORY_ENABLED=true
|
|
24
|
+
# AGENT_MOCKINGBIRD_MEMORY_WORKSPACE_DIR=./data/workspace
|
|
25
|
+
# AGENT_MOCKINGBIRD_MEMORY_EMBED_PROVIDER=ollama
|
|
26
|
+
# AGENT_MOCKINGBIRD_MEMORY_EMBED_MODEL=qwen3-embedding:4b
|
|
27
|
+
# AGENT_MOCKINGBIRD_MEMORY_OLLAMA_BASE_URL=http://127.0.0.1:11434
|
|
28
|
+
# AGENT_MOCKINGBIRD_MEMORY_CHUNK_TOKENS=400
|
|
29
|
+
# AGENT_MOCKINGBIRD_MEMORY_CHUNK_OVERLAP=80
|
|
30
|
+
# AGENT_MOCKINGBIRD_MEMORY_MAX_RESULTS=4
|
|
31
|
+
# AGENT_MOCKINGBIRD_MEMORY_MIN_SCORE=0.35
|
|
32
|
+
# AGENT_MOCKINGBIRD_MEMORY_SYNC_COOLDOWN_MS=10000
|
|
33
|
+
# AGENT_MOCKINGBIRD_MEMORY_TOOL_MODE=tool_only
|
|
34
|
+
|
|
35
|
+
# Tool API base URLs used by OpenCode tools
|
|
36
|
+
# AGENT_MOCKINGBIRD_MEMORY_API_BASE_URL=http://127.0.0.1:3001
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT_DIR="$(git rev-parse --show-toplevel)"
|
|
5
|
+
cd "${ROOT_DIR}"
|
|
6
|
+
|
|
7
|
+
staged_files="$(git diff --cached --name-only --diff-filter=ACMR)"
|
|
8
|
+
if [[ -z "${staged_files}" ]]; then
|
|
9
|
+
exit 0
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
should_build="false"
|
|
13
|
+
while IFS= read -r path; do
|
|
14
|
+
case "${path}" in
|
|
15
|
+
apps/*|packages/*|vendor/opencode/*|runtime-assets/*|drizzle/*|build.ts|build-bin.ts|build-cli.mjs|package.json|bun.lock|turbo.json|tsconfig.json|scripts/*|eslint.config.mjs)
|
|
16
|
+
should_build="true"
|
|
17
|
+
break
|
|
18
|
+
;;
|
|
19
|
+
esac
|
|
20
|
+
done <<< "${staged_files}"
|
|
21
|
+
|
|
22
|
+
if [[ "${should_build}" != "true" ]]; then
|
|
23
|
+
exit 0
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
echo "[pre-commit] Running lint, typecheck, and artifact builds..."
|
|
27
|
+
bun run build:cli
|
|
28
|
+
bun run lint
|
|
29
|
+
bun run typecheck
|
|
30
|
+
bun run build
|
|
31
|
+
bun run build:bin
|
|
32
|
+
|
|
33
|
+
git add bin/agent-mockingbird bin/runtime-layout.mjs
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- "**"
|
|
8
|
+
tags:
|
|
9
|
+
- "v*"
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
pipeline:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
env:
|
|
19
|
+
NPM_REGISTRY_URL: https://registry.npmjs.org/
|
|
20
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Setup Bun
|
|
27
|
+
uses: oven-sh/setup-bun@v2
|
|
28
|
+
with:
|
|
29
|
+
bun-version: latest
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: bun install --frozen-lockfile
|
|
33
|
+
|
|
34
|
+
- name: Ship Check
|
|
35
|
+
run: bun run check:ship
|
|
36
|
+
|
|
37
|
+
- name: Resolve publish metadata
|
|
38
|
+
id: meta
|
|
39
|
+
run: |
|
|
40
|
+
set -euo pipefail
|
|
41
|
+
event="${GITHUB_EVENT_NAME:-}"
|
|
42
|
+
ref="${GITHUB_REF:-}"
|
|
43
|
+
ref_name="${GITHUB_REF_NAME:-}"
|
|
44
|
+
package_version="$(bun -e 'const p=require("./package.json"); if(!p.version){process.exit(2)}; console.log(p.version)')"
|
|
45
|
+
base_version="${package_version}"
|
|
46
|
+
build_number="${GITHUB_RUN_NUMBER:-}"
|
|
47
|
+
branch_slug="$(printf '%s' "${ref_name}" | tr '[:upper:]' '[:lower:]' | sed 's#[^a-z0-9-]#-#g; s#--*#-#g; s#^-##; s#-$##')"
|
|
48
|
+
branch_slug="${branch_slug:0:48}"
|
|
49
|
+
if [[ -z "${branch_slug}" ]]; then
|
|
50
|
+
branch_slug="preview"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
should_publish="false"
|
|
54
|
+
npm_tag="latest"
|
|
55
|
+
bootstrap_ref="main"
|
|
56
|
+
bootstrap_tag="${package_version}"
|
|
57
|
+
|
|
58
|
+
if [[ "${event}" == "pull_request" ]]; then
|
|
59
|
+
should_publish="false"
|
|
60
|
+
elif [[ "${event}" == "push" && "${ref}" == refs/tags/v* ]]; then
|
|
61
|
+
should_publish="true"
|
|
62
|
+
expected_tag="v${base_version}"
|
|
63
|
+
if [[ "${ref_name}" != "${expected_tag}" ]]; then
|
|
64
|
+
echo "Tag ${ref_name} does not match package.json version ${base_version} (${expected_tag})."
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
bootstrap_tag="${package_version}"
|
|
68
|
+
elif [[ "${event}" == "push" && "${ref}" == refs/heads/* && "${ref}" != "refs/heads/main" ]]; then
|
|
69
|
+
should_publish="true"
|
|
70
|
+
npm_tag="next"
|
|
71
|
+
bootstrap_ref="${ref_name}"
|
|
72
|
+
if [[ -z "${build_number}" ]]; then
|
|
73
|
+
build_number="$(date +%s)"
|
|
74
|
+
fi
|
|
75
|
+
package_version="${base_version}-next.${branch_slug}.${build_number}"
|
|
76
|
+
bootstrap_tag="${package_version}"
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
echo "should_publish=${should_publish}" >> "${GITHUB_OUTPUT}"
|
|
80
|
+
echo "package_version=${package_version}" >> "${GITHUB_OUTPUT}"
|
|
81
|
+
echo "build_number=${build_number}" >> "${GITHUB_OUTPUT}"
|
|
82
|
+
echo "npm_tag=${npm_tag}" >> "${GITHUB_OUTPUT}"
|
|
83
|
+
echo "branch_slug=${branch_slug}" >> "${GITHUB_OUTPUT}"
|
|
84
|
+
echo "bootstrap_ref=${bootstrap_ref}" >> "${GITHUB_OUTPUT}"
|
|
85
|
+
echo "bootstrap_tag=${bootstrap_tag}" >> "${GITHUB_OUTPUT}"
|
|
86
|
+
|
|
87
|
+
- name: Validate publish secrets
|
|
88
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
89
|
+
run: |
|
|
90
|
+
set -euo pipefail
|
|
91
|
+
token="${NPM_TOKEN:-}"
|
|
92
|
+
: "${token:?Missing NPM_TOKEN}"
|
|
93
|
+
token="$(printf '%s' "${token}" | tr -d '\r\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
|
94
|
+
echo "::add-mask::${token}"
|
|
95
|
+
echo "NODE_AUTH_TOKEN=${token}" >> "${GITHUB_ENV}"
|
|
96
|
+
|
|
97
|
+
- name: Build package metadata for publish
|
|
98
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
99
|
+
run: |
|
|
100
|
+
set -euo pipefail
|
|
101
|
+
PKG_VERSION="${{ steps.meta.outputs.package_version }}" bun -e '
|
|
102
|
+
const fs = require("fs");
|
|
103
|
+
const version = process.env.PKG_VERSION;
|
|
104
|
+
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
|
105
|
+
pkg.name = "agent-mockingbird";
|
|
106
|
+
pkg.private = false;
|
|
107
|
+
pkg.version = version;
|
|
108
|
+
delete pkg.module;
|
|
109
|
+
delete pkg.main;
|
|
110
|
+
pkg.publishConfig = {
|
|
111
|
+
access: "public",
|
|
112
|
+
registry: process.env.NPM_REGISTRY_URL,
|
|
113
|
+
};
|
|
114
|
+
pkg.files = [
|
|
115
|
+
"bin",
|
|
116
|
+
"runtime-assets",
|
|
117
|
+
"dist",
|
|
118
|
+
"deploy",
|
|
119
|
+
"scripts",
|
|
120
|
+
"README.md",
|
|
121
|
+
"bun.lock",
|
|
122
|
+
"agent-mockingbird.config.example.json"
|
|
123
|
+
];
|
|
124
|
+
fs.writeFileSync("package.json", `${JSON.stringify(pkg, null, 2)}\n`);
|
|
125
|
+
'
|
|
126
|
+
|
|
127
|
+
- name: Build installer package metadata for publish
|
|
128
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
129
|
+
run: |
|
|
130
|
+
set -euo pipefail
|
|
131
|
+
PKG_VERSION="${{ steps.meta.outputs.package_version }}" bun -e '
|
|
132
|
+
const fs = require("fs");
|
|
133
|
+
const path = require("path");
|
|
134
|
+
const version = process.env.PKG_VERSION;
|
|
135
|
+
const pkgPath = path.join("packages", "agent-mockingbird-installer", "package.json");
|
|
136
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
137
|
+
pkg.name = "@waffleophagus/agent-mockingbird-installer";
|
|
138
|
+
pkg.private = false;
|
|
139
|
+
pkg.version = version;
|
|
140
|
+
pkg.publishConfig = {
|
|
141
|
+
access: "public",
|
|
142
|
+
registry: process.env.NPM_REGISTRY_URL,
|
|
143
|
+
};
|
|
144
|
+
fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
145
|
+
'
|
|
146
|
+
|
|
147
|
+
- name: Pack agent-mockingbird artifact
|
|
148
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
149
|
+
run: |
|
|
150
|
+
set -euo pipefail
|
|
151
|
+
tarball="agent-mockingbird-${{ steps.meta.outputs.package_version }}.tgz"
|
|
152
|
+
bun pm pack --filename "${tarball}" --quiet >/dev/null
|
|
153
|
+
test -f "${tarball}"
|
|
154
|
+
tar_contents="$(tar -tzf "${tarball}")"
|
|
155
|
+
grep -Fqx -- "package/package.json" <<<"${tar_contents}"
|
|
156
|
+
grep -Fqx -- "package/bin/agent-mockingbird" <<<"${tar_contents}"
|
|
157
|
+
grep -Fqx -- "package/bin/runtime-assets.mjs" <<<"${tar_contents}"
|
|
158
|
+
grep -Fqx -- "package/bin/runtime-layout.mjs" <<<"${tar_contents}"
|
|
159
|
+
grep -Fqx -- "package/dist/agent-mockingbird" <<<"${tar_contents}"
|
|
160
|
+
grep -Fqx -- "package/dist/app/index.html" <<<"${tar_contents}"
|
|
161
|
+
grep -Fqx -- "package/dist/drizzle/meta/_journal.json" <<<"${tar_contents}"
|
|
162
|
+
grep -Fqx -- "package/runtime-assets/workspace/AGENTS.md" <<<"${tar_contents}"
|
|
163
|
+
grep -Fqx -- "package/runtime-assets/opencode-config/opencode.jsonc" <<<"${tar_contents}"
|
|
164
|
+
grep -Fqx -- "package/runtime-assets/opencode-config/plugins/agent-mockingbird.ts" <<<"${tar_contents}"
|
|
165
|
+
! grep -Fqx -- "package/runtime-assets/workspace/.opencode/plugins/agent-mockingbird.ts" <<<"${tar_contents}"
|
|
166
|
+
! grep -Fqx -- "package/runtime-assets/workspace/.opencode/tools/memory_search.ts" <<<"${tar_contents}"
|
|
167
|
+
! grep -Fqx -- "package/runtime-assets/workspace/.opencode/tools/memory_get.ts" <<<"${tar_contents}"
|
|
168
|
+
! grep -Fqx -- "package/runtime-assets/workspace/.opencode/tools/memory_remember.ts" <<<"${tar_contents}"
|
|
169
|
+
! grep -Fqx -- "package/runtime-assets/workspace/.opencode/tools/cron_manager.ts" <<<"${tar_contents}"
|
|
170
|
+
! grep -Fqx -- "package/runtime-assets/workspace/.opencode/tools/config_manager.ts" <<<"${tar_contents}"
|
|
171
|
+
! grep -Fqx -- "package/runtime-assets/workspace/.opencode/tools/agent_type_manager.ts" <<<"${tar_contents}"
|
|
172
|
+
grep -Fqx -- "package/deploy/systemd/agent-mockingbird.service" <<<"${tar_contents}"
|
|
173
|
+
grep -Fqx -- "package/scripts/onboard/bootstrap.sh" <<<"${tar_contents}"
|
|
174
|
+
echo "AGENT_MOCKINGBIRD_TARBALL=${tarball}" >> "${GITHUB_ENV}"
|
|
175
|
+
ls -lh -- "${tarball}"
|
|
176
|
+
|
|
177
|
+
- name: Verify packaged compiled app bundle
|
|
178
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
179
|
+
run: |
|
|
180
|
+
set -euo pipefail
|
|
181
|
+
tmpdir="$(mktemp -d)"
|
|
182
|
+
trap 'rm -rf "${tmpdir}"' EXIT
|
|
183
|
+
tar -xzf "${AGENT_MOCKINGBIRD_TARBALL}" -C "${tmpdir}"
|
|
184
|
+
PACKAGE_ROOT="${tmpdir}/package" bun -e '
|
|
185
|
+
const path = require("path");
|
|
186
|
+
const fs = require("fs");
|
|
187
|
+
const pkgRoot = process.env.PACKAGE_ROOT;
|
|
188
|
+
const indexPath = path.join(pkgRoot, "dist", "app", "index.html");
|
|
189
|
+
const indexHtml = fs.readFileSync(indexPath, "utf8");
|
|
190
|
+
if (!indexHtml.includes("/assets/")) {
|
|
191
|
+
throw new Error("Packaged app index does not reference compiled assets.");
|
|
192
|
+
}
|
|
193
|
+
const assetDir = path.join(pkgRoot, "dist", "app", "assets");
|
|
194
|
+
const assetEntries = fs.readdirSync(assetDir);
|
|
195
|
+
if (assetEntries.length === 0) {
|
|
196
|
+
throw new Error("Packaged app assets directory is empty.");
|
|
197
|
+
}
|
|
198
|
+
console.log("Packaged compiled app bundle validated.");
|
|
199
|
+
'
|
|
200
|
+
|
|
201
|
+
- name: Verify packaged runtime prefers compiled bundle
|
|
202
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
203
|
+
run: |
|
|
204
|
+
set -euo pipefail
|
|
205
|
+
tmpdir="$(mktemp -d)"
|
|
206
|
+
trap 'rm -rf "${tmpdir}"' EXIT
|
|
207
|
+
tar -xzf "${AGENT_MOCKINGBIRD_TARBALL}" -C "${tmpdir}"
|
|
208
|
+
RUNTIME_IMPL_PATH="${tmpdir}/package/bin/agent-mockingbird" bun -e '
|
|
209
|
+
const fs = require("fs");
|
|
210
|
+
const path = process.env.RUNTIME_IMPL_PATH;
|
|
211
|
+
if (!path || !fs.existsSync(path)) {
|
|
212
|
+
throw new Error("Packaged CLI missing from tarball.");
|
|
213
|
+
}
|
|
214
|
+
const text = fs.readFileSync(path, "utf8");
|
|
215
|
+
const start = text.indexOf("function resolveAgentMockingbirdRuntimeCommand");
|
|
216
|
+
const end = text.indexOf("\nfunction unitContents", start);
|
|
217
|
+
if (start < 0 || end < 0) {
|
|
218
|
+
throw new Error("Could not locate packaged runtime resolver.");
|
|
219
|
+
}
|
|
220
|
+
const snippet = text.slice(start, end);
|
|
221
|
+
const compiledIndex = snippet.indexOf("const compiledBinary = path.join");
|
|
222
|
+
const compiledModeIndex = snippet.indexOf("mode: \"compiled\"");
|
|
223
|
+
const sourceIndex = snippet.indexOf("const entrypoint = resolveAgentMockingbirdServiceEntrypoint");
|
|
224
|
+
if (compiledIndex < 0 || compiledModeIndex < 0) {
|
|
225
|
+
throw new Error("Packaged runtime resolver is missing compiled bundle support.");
|
|
226
|
+
}
|
|
227
|
+
if (sourceIndex >= 0 && sourceIndex < compiledIndex) {
|
|
228
|
+
throw new Error("Packaged runtime still prefers source mode.");
|
|
229
|
+
}
|
|
230
|
+
console.log("Packaged runtime prefers compiled bundle.");
|
|
231
|
+
'
|
|
232
|
+
|
|
233
|
+
- name: Pack agent-mockingbird-installer artifact
|
|
234
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
235
|
+
run: |
|
|
236
|
+
set -euo pipefail
|
|
237
|
+
tarball="agent-mockingbird-installer-${{ steps.meta.outputs.package_version }}.tgz"
|
|
238
|
+
packed_tarball="$(
|
|
239
|
+
cd packages/agent-mockingbird-installer
|
|
240
|
+
bun pm pack --destination ../.. --quiet
|
|
241
|
+
)"
|
|
242
|
+
packed_tarball="$(printf '%s' "${packed_tarball}" | tail -n 1)"
|
|
243
|
+
test -f "${packed_tarball}"
|
|
244
|
+
mv -- "${packed_tarball}" "${tarball}"
|
|
245
|
+
test -f "${tarball}"
|
|
246
|
+
echo "AGENT_MOCKINGBIRD_INSTALLER_TARBALL=${tarball}" >> "${GITHUB_ENV}"
|
|
247
|
+
ls -lh -- "${tarball}"
|
|
248
|
+
|
|
249
|
+
- name: Configure npm auth
|
|
250
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
251
|
+
run: |
|
|
252
|
+
set -euo pipefail
|
|
253
|
+
{
|
|
254
|
+
printf "registry=%s\n" "${NPM_REGISTRY_URL}"
|
|
255
|
+
printf "//registry.npmjs.org/:_authToken=%s\n" "${NODE_AUTH_TOKEN}"
|
|
256
|
+
} > "${HOME}/.npmrc"
|
|
257
|
+
|
|
258
|
+
- name: Publish package tarball
|
|
259
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
260
|
+
run: |
|
|
261
|
+
set -euo pipefail
|
|
262
|
+
package_name="agent-mockingbird"
|
|
263
|
+
package_version="${{ steps.meta.outputs.package_version }}"
|
|
264
|
+
if bunx npm view "${package_name}@${package_version}" version --registry "${NPM_REGISTRY_URL}" >/dev/null 2>&1; then
|
|
265
|
+
echo "Version ${package_name}@${package_version} already exists; skipping publish."
|
|
266
|
+
exit 0
|
|
267
|
+
fi
|
|
268
|
+
bunx npm publish "${AGENT_MOCKINGBIRD_TARBALL}" --registry "${NPM_REGISTRY_URL}" --access public --tag "${{ steps.meta.outputs.npm_tag }}"
|
|
269
|
+
|
|
270
|
+
- name: Publish installer package tarball
|
|
271
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
272
|
+
run: |
|
|
273
|
+
set -euo pipefail
|
|
274
|
+
package_name="@waffleophagus/agent-mockingbird-installer"
|
|
275
|
+
package_version="${{ steps.meta.outputs.package_version }}"
|
|
276
|
+
if bunx npm view "${package_name}@${package_version}" version --registry "${NPM_REGISTRY_URL}" >/dev/null 2>&1; then
|
|
277
|
+
echo "Version ${package_name}@${package_version} already exists; skipping publish."
|
|
278
|
+
exit 0
|
|
279
|
+
fi
|
|
280
|
+
bunx npm publish "${AGENT_MOCKINGBIRD_INSTALLER_TARBALL}" --registry "${NPM_REGISTRY_URL}" --access public --tag "${{ steps.meta.outputs.npm_tag }}"
|
|
281
|
+
|
|
282
|
+
- name: Verify published dist-tags
|
|
283
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
284
|
+
run: |
|
|
285
|
+
set -euo pipefail
|
|
286
|
+
package_name="agent-mockingbird"
|
|
287
|
+
installer_name="@waffleophagus/agent-mockingbird-installer"
|
|
288
|
+
expected_version="${{ steps.meta.outputs.package_version }}"
|
|
289
|
+
npm_tag="${{ steps.meta.outputs.npm_tag }}"
|
|
290
|
+
bunx npm view "${package_name}" dist-tags version --registry "${NPM_REGISTRY_URL}" --json
|
|
291
|
+
bunx npm view "${installer_name}" dist-tags version --registry "${NPM_REGISTRY_URL}" --json
|
|
292
|
+
actual_pkg_tag="$(bunx npm view "${package_name}" "dist-tags.${npm_tag}" --registry "${NPM_REGISTRY_URL}")"
|
|
293
|
+
actual_installer_tag="$(bunx npm view "${installer_name}" "dist-tags.${npm_tag}" --registry "${NPM_REGISTRY_URL}")"
|
|
294
|
+
test "${actual_pkg_tag}" = "${expected_version}"
|
|
295
|
+
test "${actual_installer_tag}" = "${expected_version}"
|
|
296
|
+
|
|
297
|
+
- name: Publish install command summary
|
|
298
|
+
if: steps.meta.outputs.should_publish == 'true'
|
|
299
|
+
run: |
|
|
300
|
+
set -euo pipefail
|
|
301
|
+
bootstrap_ref="${{ steps.meta.outputs.bootstrap_ref }}"
|
|
302
|
+
bootstrap_tag="${{ steps.meta.outputs.bootstrap_tag }}"
|
|
303
|
+
{
|
|
304
|
+
echo "## Install command"
|
|
305
|
+
echo
|
|
306
|
+
echo '```bash'
|
|
307
|
+
echo "AGENT_MOCKINGBIRD_TAG=${bootstrap_tag} curl -fsSL \"https://raw.githubusercontent.com/waffleophagus/agent-mockingbird/${bootstrap_ref}/scripts/onboard/bootstrap.sh\" | bash"
|
|
308
|
+
echo '```'
|
|
309
|
+
} >> "${GITHUB_STEP_SUMMARY}"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@opencode-ai/plugin": "1.2.27",
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
"packages": {
|
|
12
|
+
"@opencode-ai/plugin": ["@opencode-ai/plugin@1.2.27", "", { "dependencies": { "@opencode-ai/sdk": "1.2.27", "zod": "4.1.8" } }, "sha512-h+8Bw9v9nghMg7T+SUCTzxlIhOrsTqXW7U0HVLGQST5DjbN7uyCUM51roZWZ8LRjGxzbzFhvPnY1bj8i+ioZyw=="],
|
|
13
|
+
|
|
14
|
+
"@opencode-ai/sdk": ["@opencode-ai/sdk@1.2.27", "", {}, "sha512-Wk0o/I+Fo+wE3zgvlJDs8Fb67KlKqX0PrV8dK5adSDkANq6r4Z25zXJg2iOir+a8ntg3rAcpel1OY4FV/TwRUA=="],
|
|
15
|
+
|
|
16
|
+
"zod": ["zod@4.1.8", "", {}, "sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ=="],
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
function resolveApiBaseUrl() {
|
|
5
|
+
const explicit = process.env.AGENT_MOCKINGBIRD_CONFIG_API_BASE_URL?.trim();
|
|
6
|
+
if (explicit) return explicit.replace(/\/+$/, "");
|
|
7
|
+
const port = process.env.AGENT_MOCKINGBIRD_PORT?.trim() || process.env.PORT?.trim() || "3001";
|
|
8
|
+
return `http://127.0.0.1:${port}`;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async function requestJson(pathname: string, init?: RequestInit) {
|
|
12
|
+
const response = await fetch(`${resolveApiBaseUrl()}${pathname}`, init);
|
|
13
|
+
const payload = (await response.json()) as Record<string, unknown>;
|
|
14
|
+
if (!response.ok) {
|
|
15
|
+
const error = typeof payload.error === "string" ? payload.error : `Request failed (${response.status})`;
|
|
16
|
+
throw new Error(error);
|
|
17
|
+
}
|
|
18
|
+
return payload;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const agentTypeSchema = z.object({
|
|
22
|
+
id: z.string().min(1),
|
|
23
|
+
name: z.string().min(1).optional(),
|
|
24
|
+
description: z.string().min(1).optional(),
|
|
25
|
+
prompt: z.string().min(1).optional(),
|
|
26
|
+
model: z.string().min(1).optional(),
|
|
27
|
+
variant: z.string().min(1).optional(),
|
|
28
|
+
mode: z.enum(["subagent", "primary", "all"]).optional(),
|
|
29
|
+
hidden: z.boolean().optional(),
|
|
30
|
+
disable: z.boolean().optional(),
|
|
31
|
+
temperature: z.number().optional(),
|
|
32
|
+
topP: z.number().optional(),
|
|
33
|
+
steps: z.number().int().positive().optional(),
|
|
34
|
+
permission: z.unknown().optional(),
|
|
35
|
+
options: z.record(z.string(), z.unknown()).optional(),
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const argsSchema = z.discriminatedUnion("action", [
|
|
39
|
+
z.object({
|
|
40
|
+
action: z.literal("list"),
|
|
41
|
+
}),
|
|
42
|
+
z.object({
|
|
43
|
+
action: z.literal("validate_patch"),
|
|
44
|
+
upserts: z.array(agentTypeSchema).default([]),
|
|
45
|
+
deletes: z.array(z.string().min(1)).default([]),
|
|
46
|
+
}),
|
|
47
|
+
z.object({
|
|
48
|
+
action: z.literal("apply_patch"),
|
|
49
|
+
upserts: z.array(agentTypeSchema).default([]),
|
|
50
|
+
deletes: z.array(z.string().min(1)).default([]),
|
|
51
|
+
expectedHash: z.string().min(1),
|
|
52
|
+
}),
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
export default tool({
|
|
56
|
+
description:
|
|
57
|
+
"Manage OpenCode agent definitions through Agent Mockingbird's OpenCode-backed APIs with validation and hash conflict detection.",
|
|
58
|
+
args: {
|
|
59
|
+
action: tool.schema.enum(["list", "validate_patch", "apply_patch"]),
|
|
60
|
+
upserts: tool.schema.array(tool.schema.unknown()).optional(),
|
|
61
|
+
deletes: tool.schema.array(tool.schema.string().min(1)).optional(),
|
|
62
|
+
expectedHash: tool.schema.string().min(1).optional(),
|
|
63
|
+
},
|
|
64
|
+
async execute(rawArgs: {
|
|
65
|
+
action: "list" | "validate_patch" | "apply_patch";
|
|
66
|
+
upserts?: unknown[];
|
|
67
|
+
deletes?: string[];
|
|
68
|
+
expectedHash?: string;
|
|
69
|
+
}) {
|
|
70
|
+
const args = argsSchema.parse(rawArgs);
|
|
71
|
+
|
|
72
|
+
if (args.action === "list") {
|
|
73
|
+
const payload = await requestJson("/api/waffle/agents");
|
|
74
|
+
return JSON.stringify({ ok: true, ...payload });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (args.action === "validate_patch") {
|
|
78
|
+
const payload = await requestJson("/api/waffle/agents/validate", {
|
|
79
|
+
method: "POST",
|
|
80
|
+
headers: { "Content-Type": "application/json" },
|
|
81
|
+
body: JSON.stringify({
|
|
82
|
+
upserts: args.upserts,
|
|
83
|
+
deletes: args.deletes,
|
|
84
|
+
}),
|
|
85
|
+
});
|
|
86
|
+
return JSON.stringify({ ok: true, ...payload });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const payload = await requestJson("/api/waffle/agents", {
|
|
90
|
+
method: "PATCH",
|
|
91
|
+
headers: { "Content-Type": "application/json" },
|
|
92
|
+
body: JSON.stringify({
|
|
93
|
+
upserts: args.upserts,
|
|
94
|
+
deletes: args.deletes,
|
|
95
|
+
expectedHash: args.expectedHash,
|
|
96
|
+
}),
|
|
97
|
+
});
|
|
98
|
+
return JSON.stringify({ ok: true, ...payload });
|
|
99
|
+
},
|
|
100
|
+
});
|