From 32cc853d10f9a5fc41f6f5d3d9cd686ed3a5bfc6 Mon Sep 17 00:00:00 2001 From: ben Date: Sat, 14 Feb 2026 20:53:06 -0800 Subject: [PATCH] refactor(router): rename owpenbot to opencode-router (#567) --- .github/workflows/release-macos-aarch64.yml | 20 +- AGENTS.md | 2 +- INFRASTRUCTURE.md | 2 +- README.md | 8 +- RELEASE.md | 2 +- packages/agent-lab/src/cli.ts | 2 +- packages/app/scripts/bump-version.mjs | 14 +- packages/app/src/app/app.tsx | 16 +- .../app/src/app/components/status-bar.tsx | 22 +- packages/app/src/app/lib/openwork-server.ts | 162 +++--- packages/app/src/app/lib/tauri.ts | 60 +-- packages/app/src/app/pages/dashboard.tsx | 6 +- packages/app/src/app/pages/identities.tsx | 64 +-- packages/app/src/app/pages/settings.tsx | 106 ++-- packages/desktop/package.json | 2 +- packages/desktop/scripts/prepare-sidecar.mjs | 110 ++-- packages/desktop/src-tauri/build.rs | 20 +- .../desktop/src-tauri/src/commands/engine.rs | 42 +- .../desktop/src-tauri/src/commands/mod.rs | 2 +- .../{owpenbot.rs => opencode_router.rs} | 86 ++-- .../desktop/src-tauri/src/commands/openwrk.rs | 2 +- packages/desktop/src-tauri/src/lib.rs | 24 +- .../{owpenbot => opencode_router}/manager.rs | 16 +- .../src/{owpenbot => opencode_router}/mod.rs | 0 .../{owpenbot => opencode_router}/spawn.rs | 22 +- .../src-tauri/src/openwork_server/mod.rs | 4 +- .../src-tauri/src/openwork_server/spawn.rs | 6 +- packages/desktop/src-tauri/src/types.rs | 2 +- packages/desktop/src-tauri/tauri.conf.json | 2 +- packages/headless/README.md | 16 +- packages/headless/package.json | 2 +- packages/headless/scripts/build-bin.ts | 18 +- ...owpenbot.mjs => build-opencode-router.mjs} | 14 +- packages/headless/scripts/build-sidecars.mjs | 32 +- packages/headless/scripts/publish-npm.mjs | 2 +- packages/headless/src/cli.ts | 446 ++++++++-------- packages/headless/src/tui/app.tsx | 4 +- .../.env.example | 10 +- .../{owpenbot => opencode-router}/README.md | 34 +- packages/opencode-router/install.sh | 147 ++++++ .../package.json | 14 +- .../script/build.ts | 4 +- .../scripts/setup.mjs | 0 .../scripts/smoke.mjs | 2 +- .../scripts/test-cli.mjs | 8 +- .../scripts/test-npx.mjs | 2 +- .../src/bridge.ts | 24 +- .../{owpenbot => opencode-router}/src/cli.ts | 22 +- .../src/config.ts | 31 +- .../{owpenbot => opencode-router}/src/db.ts | 0 .../src/events.ts | 0 .../src/health.ts | 4 +- .../src/logger.ts | 0 .../src/opencode.ts | 0 .../src/slack.ts | 0 .../src/telegram.ts | 0 .../{owpenbot => opencode-router}/src/text.ts | 0 .../test/bridge-e2e.test.js | 8 +- .../test/bridge-multiworkspace.test.js | 16 +- .../test/db.test.js | 4 +- .../test/health-send.test.js | 24 +- .../test/slack.test.js | 0 .../tsconfig.json | 0 packages/owpenbot/install.sh | 157 ------ packages/server/README.md | 10 +- packages/server/src/server.ts | 478 +++++++++--------- packages/server/src/types.ts | 2 +- packaging/docker/Dockerfile | 6 +- packaging/docker/docker-compose.dev.yml | 12 +- pnpm-lock.yaml | 4 +- ...oke.png => opencode-router-send-smoke.png} | Bin scripts/dev-headless-web.ts | 36 +- scripts/release/review.mjs | 28 +- scripts/release/verify-tag.mjs | 4 +- 74 files changed, 1218 insertions(+), 1233 deletions(-) rename packages/desktop/src-tauri/src/commands/{owpenbot.rs => opencode_router.rs} (77%) rename packages/desktop/src-tauri/src/{owpenbot => opencode_router}/manager.rs (79%) rename packages/desktop/src-tauri/src/{owpenbot => opencode_router}/mod.rs (100%) rename packages/desktop/src-tauri/src/{owpenbot => opencode_router}/spawn.rs (66%) rename packages/headless/scripts/{build-owpenbot.mjs => build-opencode-router.mjs} (67%) rename packages/{owpenbot => opencode-router}/.env.example (54%) rename packages/{owpenbot => opencode-router}/README.md (73%) create mode 100644 packages/opencode-router/install.sh rename packages/{owpenbot => opencode-router}/package.json (63%) rename packages/{owpenbot => opencode-router}/script/build.ts (96%) rename packages/{owpenbot => opencode-router}/scripts/setup.mjs (100%) rename packages/{owpenbot => opencode-router}/scripts/smoke.mjs (94%) rename packages/{owpenbot => opencode-router}/scripts/test-cli.mjs (91%) rename packages/{owpenbot => opencode-router}/scripts/test-npx.mjs (93%) rename packages/{owpenbot => opencode-router}/src/bridge.ts (98%) rename packages/{owpenbot => opencode-router}/src/cli.ts (95%) rename packages/{owpenbot => opencode-router}/src/config.ts (90%) rename packages/{owpenbot => opencode-router}/src/db.ts (100%) rename packages/{owpenbot => opencode-router}/src/events.ts (100%) rename packages/{owpenbot => opencode-router}/src/health.ts (99%) rename packages/{owpenbot => opencode-router}/src/logger.ts (100%) rename packages/{owpenbot => opencode-router}/src/opencode.ts (100%) rename packages/{owpenbot => opencode-router}/src/slack.ts (100%) rename packages/{owpenbot => opencode-router}/src/telegram.ts (100%) rename packages/{owpenbot => opencode-router}/src/text.ts (100%) rename packages/{owpenbot => opencode-router}/test/bridge-e2e.test.js (88%) rename packages/{owpenbot => opencode-router}/test/bridge-multiworkspace.test.js (90%) rename packages/{owpenbot => opencode-router}/test/db.test.js (86%) rename packages/{owpenbot => opencode-router}/test/health-send.test.js (87%) rename packages/{owpenbot => opencode-router}/test/slack.test.js (100%) rename packages/{owpenbot => opencode-router}/tsconfig.json (100%) delete mode 100644 packages/owpenbot/install.sh rename pr/{owpenbot-send-smoke.png => opencode-router-send-smoke.png} (100%) diff --git a/.github/workflows/release-macos-aarch64.yml b/.github/workflows/release-macos-aarch64.yml index 2c0e85c2..ec3f8b64 100644 --- a/.github/workflows/release-macos-aarch64.yml +++ b/.github/workflows/release-macos-aarch64.yml @@ -620,7 +620,7 @@ jobs: id: sidecar-versions shell: bash run: | - node -e "const fs=require('fs'); const headless=JSON.parse(fs.readFileSync('packages/headless/package.json','utf8')); const server=JSON.parse(fs.readFileSync('packages/server/package.json','utf8')); const owpenbot=JSON.parse(fs.readFileSync('packages/owpenbot/package.json','utf8')); console.log('openwrk=' + headless.version); console.log('server=' + server.version); console.log('owpenbot=' + owpenbot.version);" >> "$GITHUB_OUTPUT" + node -e "const fs=require('fs'); const headless=JSON.parse(fs.readFileSync('packages/headless/package.json','utf8')); const server=JSON.parse(fs.readFileSync('packages/server/package.json','utf8')); const opencodeRouter=JSON.parse(fs.readFileSync('packages/opencode-router/package.json','utf8')); console.log('openwrk=' + headless.version); console.log('server=' + server.version); console.log('opencodeRouter=' + opencodeRouter.version);" >> "$GITHUB_OUTPUT" - name: Resolve SOURCE_DATE_EPOCH id: source-date @@ -660,7 +660,7 @@ jobs: run: | version="${{ steps.sidecar-versions.outputs.openwrk }}" tag="openwrk-v${version}" - notes="Sidecar bundle for openwrk v${version}.\n\nopenwork-server: ${{ steps.sidecar-versions.outputs.server }}\nowpenbot: ${{ steps.sidecar-versions.outputs.owpenbot }}" + notes="Sidecar bundle for openwrk v${version}.\n\nopenwork-server: ${{ steps.sidecar-versions.outputs.server }}\nopencodeRouter: ${{ steps.sidecar-versions.outputs.opencodeRouter }}" gh release create "$tag" \ --repo "$GITHUB_REPOSITORY" \ --title "openwrk v${version}" \ @@ -729,7 +729,7 @@ jobs: id: package-versions shell: bash run: | - node -e "const fs=require('fs'); const headless=JSON.parse(fs.readFileSync('packages/headless/package.json','utf8')); const server=JSON.parse(fs.readFileSync('packages/server/package.json','utf8')); const owpenbot=JSON.parse(fs.readFileSync('packages/owpenbot/package.json','utf8')); console.log('openwrk=' + headless.version); console.log('server=' + server.version); console.log('owpenbot=' + owpenbot.version);" >> "$GITHUB_OUTPUT" + node -e "const fs=require('fs'); const headless=JSON.parse(fs.readFileSync('packages/headless/package.json','utf8')); const server=JSON.parse(fs.readFileSync('packages/server/package.json','utf8')); const opencodeRouter=JSON.parse(fs.readFileSync('packages/opencode-router/package.json','utf8')); console.log('openwrk=' + headless.version); console.log('server=' + server.version); console.log('opencodeRouter=' + opencodeRouter.version);" >> "$GITHUB_OUTPUT" - name: Check npm versions id: npm-versions @@ -737,12 +737,12 @@ jobs: env: OPENWRK_VERSION: ${{ steps.package-versions.outputs.openwrk }} SERVER_VERSION: ${{ steps.package-versions.outputs.server }} - OWPENBOT_VERSION: ${{ steps.package-versions.outputs.owpenbot }} + OPENCODE_ROUTER_VERSION: ${{ steps.package-versions.outputs.opencodeRouter }} run: | set -euo pipefail openwrk_current=$(npm view openwrk version) server_current=$(npm view openwork-server version) - owpenbot_current=$(npm view owpenwork version) + opencodeRouter_current=$(npm view owpenwork version) if [ "$openwrk_current" = "$OPENWRK_VERSION" ]; then echo "publish_openwrk=false" >> "$GITHUB_OUTPUT" @@ -756,14 +756,14 @@ jobs: echo "publish_server=true" >> "$GITHUB_OUTPUT" fi - if [ "$owpenbot_current" = "$OWPENBOT_VERSION" ]; then - echo "publish_owpenbot=false" >> "$GITHUB_OUTPUT" + if [ "$opencodeRouter_current" = "$OPENCODE_ROUTER_VERSION" ]; then + echo "publish_opencodeRouter=false" >> "$GITHUB_OUTPUT" else - echo "publish_owpenbot=true" >> "$GITHUB_OUTPUT" + echo "publish_opencodeRouter=true" >> "$GITHUB_OUTPUT" fi publish_any=false - if [ "$openwrk_current" != "$OPENWRK_VERSION" ] || [ "$server_current" != "$SERVER_VERSION" ] || [ "$owpenbot_current" != "$OWPENBOT_VERSION" ]; then + if [ "$openwrk_current" != "$OPENWRK_VERSION" ] || [ "$server_current" != "$SERVER_VERSION" ] || [ "$opencodeRouter_current" != "$OPENCODE_ROUTER_VERSION" ]; then publish_any=true fi echo "publish_any=$publish_any" >> "$GITHUB_OUTPUT" @@ -796,7 +796,7 @@ jobs: run: pnpm --filter openwork-server publish --access public --no-git-checks - name: Publish owpenwork - if: steps.npm-auth.outputs.enabled == 'true' && steps.npm-versions.outputs.publish_owpenbot == 'true' + if: steps.npm-auth.outputs.enabled == 'true' && steps.npm-versions.outputs.publish_opencodeRouter == 'true' run: pnpm --filter owpenwork publish --access public --no-git-checks - name: Publish openwrk diff --git a/AGENTS.md b/AGENTS.md index b9cd0c1b..2dfccbac 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,7 +22,7 @@ Read INFRASTRUCTURE.md ## Why OpenWork Exists **Cowork is closed-source and locked to Claude Max.** We need an open alternative. -**Mobile-first matters.** People want to run tasks from their phones, including via messaging surfaces like WhatsApp and Telegram through owpenbot. +**Mobile-first matters.** People want to run tasks from their phones, including via messaging surfaces like WhatsApp and Telegram through OpenCode Router. **Slick UI is non-negotiable.** The experience must feel premium, not utilitarian. ## Agent Guidelines for development diff --git a/INFRASTRUCTURE.md b/INFRASTRUCTURE.md index 7f582c78..a7ba2ea0 100644 --- a/INFRASTRUCTURE.md +++ b/INFRASTRUCTURE.md @@ -74,7 +74,7 @@ But what you can do is: * Provides filesystem-backed config surfaces (skills, plugins, MCP, commands). * Sidecar lifecycle is described in `packages/app/pr/openwork-server.md`. -### Owpenbot +### OpenCode Router * Runs standalone via `owpenwork` CLI. * Must be able to use OpenWork server for config and approvals. diff --git a/README.md b/README.md index 78b315ea..d29e215f 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,10 @@ OpenWork is designed around the idea that you can easily ship your agentic workf ## Alternate UIs -- **Owpenbot (WhatsApp bot)**: a lightweight WhatsApp bridge for a running OpenCode server. Install with: - - `curl -fsSL https://raw.githubusercontent.com/different-ai/owpenbot/dev/install.sh | bash` - - run `owpenbot setup`, then `owpenbot whatsapp login`, then `owpenbot start` - - full setup: https://github.com/different-ai/owpenbot/blob/dev/README.md +- **OpenCode Router (WhatsApp bot)**: a lightweight WhatsApp bridge for a running OpenCode server. Install with: + - `curl -fsSL https://raw.githubusercontent.com/different-ai/opencode-router/dev/install.sh | bash` + - run `opencode-router setup`, then `opencode-router whatsapp login`, then `opencode-router start` + - full setup: https://github.com/different-ai/opencode-router/blob/dev/README.md - **Openwrk (CLI host)**: run OpenCode + OpenWork server without the desktop UI. Install with `npm install -g openwrk`. - docs: [packages/headless/README.md](./packages/headless/README.md) diff --git a/RELEASE.md b/RELEASE.md index 7d3ef222..ef23e2b0 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -31,7 +31,7 @@ OpenWork releases should be deterministic, easy to reproduce, and fully verifiab 4. Publish the package: - `pnpm --filter openwrk publish --access public` -## openwork-server + owpenbot (if version changed) +## openwork-server + opencode-router (if version changed) - `pnpm --filter openwork-server publish --access public` - `pnpm --filter owpenwork publish --access public` diff --git a/packages/agent-lab/src/cli.ts b/packages/agent-lab/src/cli.ts index 6c3a03d9..a2aac9e3 100644 --- a/packages/agent-lab/src/cli.ts +++ b/packages/agent-lab/src/cli.ts @@ -598,7 +598,7 @@ async function runOpenwrkStart(options: { options.hostToken, "--approval", options.approval, - "--no-owpenbot", + "--no-opencode-router", ]; return await new Promise((resolveResult, reject) => { diff --git a/packages/app/scripts/bump-version.mjs b/packages/app/scripts/bump-version.mjs index eecb5a5f..e2eadfa7 100755 --- a/packages/app/scripts/bump-version.mjs +++ b/packages/app/scripts/bump-version.mjs @@ -60,16 +60,16 @@ const updatePackageJson = async (nextVersion) => { const tauriPath = path.join(REPO_ROOT, "packages", "desktop", "package.json"); const headlessPath = path.join(REPO_ROOT, "packages", "headless", "package.json"); const serverPath = path.join(REPO_ROOT, "packages", "server", "package.json"); - const owpenbotPath = path.join(REPO_ROOT, "packages", "owpenbot", "package.json"); + const opencodeRouterPath = path.join(REPO_ROOT, "packages", "opencode-router", "package.json"); const uiData = await readJson(uiPath); const tauriData = await readJson(tauriPath); const headlessData = await readJson(headlessPath); const serverData = await readJson(serverPath); - const owpenbotData = await readJson(owpenbotPath); + const opencodeRouterData = await readJson(opencodeRouterPath); uiData.version = nextVersion; tauriData.version = nextVersion; - // Desktop pins owpenbotVersion for sidecar bundling; keep it aligned. - tauriData.owpenbotVersion = nextVersion; + // Desktop pins opencodeRouterVersion for sidecar bundling; keep it aligned. + tauriData.opencodeRouterVersion = nextVersion; headlessData.version = nextVersion; // Ensure openwrk uses the same openwork-server/owpenwork versions. @@ -78,13 +78,13 @@ const updatePackageJson = async (nextVersion) => { headlessData.dependencies.owpenwork = nextVersion; serverData.version = nextVersion; - owpenbotData.version = nextVersion; + opencodeRouterData.version = nextVersion; if (!isDryRun) { await writeFile(uiPath, JSON.stringify(uiData, null, 2) + "\n"); await writeFile(tauriPath, JSON.stringify(tauriData, null, 2) + "\n"); await writeFile(headlessPath, JSON.stringify(headlessData, null, 2) + "\n"); await writeFile(serverPath, JSON.stringify(serverData, null, 2) + "\n"); - await writeFile(owpenbotPath, JSON.stringify(owpenbotData, null, 2) + "\n"); + await writeFile(opencodeRouterPath, JSON.stringify(opencodeRouterData, null, 2) + "\n"); } }; @@ -140,7 +140,7 @@ const main = async () => { "packages/desktop/package.json", "packages/headless/package.json", "packages/server/package.json", - "packages/owpenbot/package.json", + "packages/opencode-router/package.json", "packages/desktop/src-tauri/Cargo.toml", "packages/desktop/src-tauri/tauri.conf.json", ], diff --git a/packages/app/src/app/app.tsx b/packages/app/src/app/app.tsx index d3e4984c..34006f98 100644 --- a/packages/app/src/app/app.tsx +++ b/packages/app/src/app/app.tsx @@ -124,11 +124,11 @@ import { schedulerListJobs, openworkServerInfo, openwrkStatus, - owpenbotInfo, + opencodeRouterInfo, setWindowDecorations, type OpenwrkStatus, type OpenworkServerInfo, - type OwpenbotInfo, + type OpenCodeRouterInfo, } from "./lib/tauri"; import { parseOpenworkWorkspaceIdFromUrl, @@ -268,7 +268,7 @@ export default function App() { const [openworkServerHostInfo, setOpenworkServerHostInfo] = createSignal(null); const [openworkServerDiagnostics, setOpenworkServerDiagnostics] = createSignal(null); const [openworkReconnectBusy, setOpenworkReconnectBusy] = createSignal(false); - const [owpenbotInfoState, setOwpenbotInfoState] = createSignal(null); + const [opencodeRouterInfoState, setOpenCodeRouterInfoState] = createSignal(null); const [openwrkStatusState, setOpenwrkStatusState] = createSignal(null); const [openworkAuditEntries, setOpenworkAuditEntries] = createSignal([]); const [openworkAuditStatus, setOpenworkAuditStatus] = createSignal<"idle" | "loading" | "error">("idle"); @@ -511,7 +511,7 @@ export default function App() { createEffect(() => { if (!isTauriRuntime()) return; if (!developerMode()) { - setOwpenbotInfoState(null); + setOpenCodeRouterInfoState(null); return; } if (!documentVisible()) return; @@ -520,10 +520,10 @@ export default function App() { const run = async () => { try { - const info = await owpenbotInfo(); - if (active) setOwpenbotInfoState(info); + const info = await opencodeRouterInfo(); + if (active) setOpenCodeRouterInfoState(info); } catch { - if (active) setOwpenbotInfoState(null); + if (active) setOpenCodeRouterInfoState(null); } }; @@ -4335,7 +4335,7 @@ export default function App() { opencodeConnectStatus: opencodeConnectStatus(), engineInfo: workspaceStore.engine(), openwrkStatus: openwrkStatusState(), - owpenbotInfo: owpenbotInfoState(), + opencodeRouterInfo: opencodeRouterInfoState(), engineDoctorVersion: workspaceStore.engineDoctorResult()?.version ?? null, updateOpenworkServerSettings, resetOpenworkServerSettings, diff --git a/packages/app/src/app/components/status-bar.tsx b/packages/app/src/app/components/status-bar.tsx index 692765d0..a8938917 100644 --- a/packages/app/src/app/components/status-bar.tsx +++ b/packages/app/src/app/components/status-bar.tsx @@ -2,9 +2,9 @@ import { Show, createEffect, createMemo, createSignal, onCleanup, onMount } from import { Cpu, MessageCircle, Server, Settings } from "lucide-solid"; import type { OpenworkServerStatus } from "../lib/openwork-server"; -import type { OwpenbotStatus } from "../lib/tauri"; +import type { OpenCodeRouterStatus } from "../lib/tauri"; import type { McpStatusMap } from "../types"; -import { getOwpenbotStatus } from "../lib/tauri"; +import { getOpenCodeRouterStatus } from "../lib/tauri"; import Button from "./button"; @@ -21,7 +21,7 @@ type StatusBarProps = { }; export default function StatusBar(props: StatusBarProps) { - const [owpenbotStatus, setOwpenbotStatus] = createSignal(null); + const [opencodeRouterStatus, setOpenCodeRouterStatus] = createSignal(null); const [documentVisible, setDocumentVisible] = createSignal(true); const opencodeStatusMeta = createMemo(() => ({ @@ -42,7 +42,7 @@ export default function StatusBar(props: StatusBarProps) { }); const messagingMeta = createMemo(() => { - const status = owpenbotStatus(); + const status = opencodeRouterStatus(); if (!status) { return { dot: "bg-gray-6", text: "text-gray-10", label: "Messaging bridge unavailable" }; } @@ -81,7 +81,7 @@ export default function StatusBar(props: StatusBarProps) { id: "slack", label: "Connect Slack", enabled: () => { - const status = owpenbotStatus(); + const status = opencodeRouterStatus(); return Boolean(status && (status.slack.items?.length ?? 0) === 0); }, action: () => runAction(props.onOpenMessaging), @@ -90,7 +90,7 @@ export default function StatusBar(props: StatusBarProps) { id: "telegram", label: "Connect Telegram", enabled: () => { - const status = owpenbotStatus(); + const status = opencodeRouterStatus(); return Boolean(status && (status.telegram.items?.length ?? 0) === 0); }, action: () => runAction(props.onOpenMessaging), @@ -159,9 +159,9 @@ export default function StatusBar(props: StatusBarProps) { setTipCursor(1); }); - const refreshOwpenbot = async () => { - const next = await getOwpenbotStatus(); - setOwpenbotStatus(next); + const refreshOpenCodeRouter = async () => { + const next = await getOpenCodeRouterStatus(); + setOpenCodeRouterStatus(next); }; createEffect(() => { @@ -174,8 +174,8 @@ export default function StatusBar(props: StatusBarProps) { createEffect(() => { if (!documentVisible()) return; - refreshOwpenbot(); - const interval = window.setInterval(refreshOwpenbot, 15_000); + refreshOpenCodeRouter(); + const interval = window.setInterval(refreshOpenCodeRouter, 15_000); onCleanup(() => window.clearInterval(interval)); }); diff --git a/packages/app/src/app/lib/openwork-server.ts b/packages/app/src/app/lib/openwork-server.ts index ad42b1c7..00aea0a2 100644 --- a/packages/app/src/app/lib/openwork-server.ts +++ b/packages/app/src/app/lib/openwork-server.ts @@ -16,7 +16,7 @@ export type OpenworkServerCapabilities = { commands: { read: boolean; write: boolean }; config: { read: boolean; write: boolean }; sandbox?: { enabled: boolean; backend: "none" | "docker" | "container" }; - proxy?: { opencode: boolean; owpenbot: boolean }; + proxy?: { opencode: boolean; opencodeRouter: boolean }; toolProviders?: { browser?: { enabled: boolean; @@ -139,7 +139,7 @@ export type OpenworkMcpItem = { disabledByTools?: boolean; }; -export type OpenworkOwpenbotTelegramResult = { +export type OpenworkOpenCodeRouterTelegramResult = { ok: boolean; persisted?: boolean; applied?: boolean; @@ -154,7 +154,7 @@ export type OpenworkOwpenbotTelegramResult = { }; }; -export type OpenworkOwpenbotSlackResult = { +export type OpenworkOpenCodeRouterSlackResult = { ok: boolean; persisted?: boolean; applied?: boolean; @@ -169,20 +169,20 @@ export type OpenworkOwpenbotSlackResult = { }; }; -export type OpenworkOwpenbotTelegramBotInfo = { +export type OpenworkOpenCodeRouterTelegramBotInfo = { id: number; username?: string; name?: string; }; -export type OpenworkOwpenbotTelegramInfo = { +export type OpenworkOpenCodeRouterTelegramInfo = { ok: boolean; configured: boolean; enabled: boolean; - bot: OpenworkOwpenbotTelegramBotInfo | null; + bot: OpenworkOpenCodeRouterTelegramBotInfo | null; }; -export type OpenworkOwpenbotTelegramEnabledResult = { +export type OpenworkOpenCodeRouterTelegramEnabledResult = { ok: boolean; persisted?: boolean; enabled: boolean; @@ -191,7 +191,7 @@ export type OpenworkOwpenbotTelegramEnabledResult = { applyStatus?: number; }; -export type OpenworkOwpenbotHealthSnapshot = { +export type OpenworkOpenCodeRouterHealthSnapshot = { ok: boolean; opencode: { url: string; @@ -222,7 +222,7 @@ export type OpenworkOwpenbotHealthSnapshot = { }; }; -export type OpenworkOwpenbotBindingItem = { +export type OpenworkOpenCodeRouterBindingItem = { channel: string; identityId: string; peerId: string; @@ -230,16 +230,16 @@ export type OpenworkOwpenbotBindingItem = { updatedAt?: number; }; -export type OpenworkOwpenbotBindingsResult = { +export type OpenworkOpenCodeRouterBindingsResult = { ok: boolean; - items: OpenworkOwpenbotBindingItem[]; + items: OpenworkOpenCodeRouterBindingItem[]; }; -export type OpenworkOwpenbotBindingUpdateResult = { +export type OpenworkOpenCodeRouterBindingUpdateResult = { ok: boolean; }; -export type OpenworkOwpenbotSendResult = { +export type OpenworkOpenCodeRouterSendResult = { ok: boolean; channel: string; identityId?: string; @@ -251,23 +251,23 @@ export type OpenworkOwpenbotSendResult = { reason?: string; }; -export type OpenworkOwpenbotIdentityItem = { +export type OpenworkOpenCodeRouterIdentityItem = { id: string; enabled: boolean; running: boolean; }; -export type OpenworkOwpenbotTelegramIdentitiesResult = { +export type OpenworkOpenCodeRouterTelegramIdentitiesResult = { ok: boolean; - items: OpenworkOwpenbotIdentityItem[]; + items: OpenworkOpenCodeRouterIdentityItem[]; }; -export type OpenworkOwpenbotSlackIdentitiesResult = { +export type OpenworkOpenCodeRouterSlackIdentitiesResult = { ok: boolean; - items: OpenworkOwpenbotIdentityItem[]; + items: OpenworkOpenCodeRouterIdentityItem[]; }; -export type OpenworkOwpenbotTelegramIdentityUpsertResult = { +export type OpenworkOpenCodeRouterTelegramIdentityUpsertResult = { ok: boolean; persisted?: boolean; applied?: boolean; @@ -279,11 +279,11 @@ export type OpenworkOwpenbotTelegramIdentityUpsertResult = { applied?: boolean; starting?: boolean; error?: string; - bot?: OpenworkOwpenbotTelegramBotInfo | null; + bot?: OpenworkOpenCodeRouterTelegramBotInfo | null; }; }; -export type OpenworkOwpenbotSlackIdentityUpsertResult = { +export type OpenworkOpenCodeRouterSlackIdentityUpsertResult = { ok: boolean; persisted?: boolean; applied?: boolean; @@ -298,7 +298,7 @@ export type OpenworkOwpenbotSlackIdentityUpsertResult = { }; }; -export type OpenworkOwpenbotTelegramIdentityDeleteResult = { +export type OpenworkOpenCodeRouterTelegramIdentityDeleteResult = { ok: boolean; persisted?: boolean; deleted?: boolean; @@ -311,7 +311,7 @@ export type OpenworkOwpenbotTelegramIdentityDeleteResult = { }; }; -export type OpenworkOwpenbotSlackIdentityDeleteResult = { +export type OpenworkOpenCodeRouterSlackIdentityDeleteResult = { ok: boolean; persisted?: boolean; deleted?: boolean; @@ -802,7 +802,7 @@ export function createOpenworkServerClient(options: { baseUrl: string; token?: s deleteSession: 12_000, status: 6_000, config: 10_000, - owpenbot: 10_000, + opencodeRouter: 10_000, workspaceExport: 30_000, workspaceImport: 30_000, binary: 60_000, @@ -815,20 +815,20 @@ export function createOpenworkServerClient(options: { baseUrl: string; token?: s requestJson<{ ok: boolean; version: string; uptimeMs: number }>(baseUrl, "/health", { token, hostToken, timeoutMs: timeouts.health }), status: () => requestJson(baseUrl, "/status", { token, hostToken, timeoutMs: timeouts.status }), capabilities: () => requestJson(baseUrl, "/capabilities", { token, hostToken, timeoutMs: timeouts.capabilities }), - owpenbotHealth: () => - requestJsonRaw(baseUrl, "/owpenbot/health", { token, hostToken, timeoutMs: timeouts.owpenbot }), - owpenbotBindings: (filters?: { channel?: string; identityId?: string }) => { + opencodeRouterHealth: () => + requestJsonRaw(baseUrl, "/opencode-router/health", { token, hostToken, timeoutMs: timeouts.opencodeRouter }), + opencodeRouterBindings: (filters?: { channel?: string; identityId?: string }) => { const search = new URLSearchParams(); if (filters?.channel?.trim()) search.set("channel", filters.channel.trim()); if (filters?.identityId?.trim()) search.set("identityId", filters.identityId.trim()); const suffix = search.toString(); - const path = suffix ? `/owpenbot/bindings?${suffix}` : "/owpenbot/bindings"; - return requestJsonRaw(baseUrl, path, { token, hostToken, timeoutMs: timeouts.owpenbot }); + const path = suffix ? `/opencode-router/bindings?${suffix}` : "/opencode-router/bindings"; + return requestJsonRaw(baseUrl, path, { token, hostToken, timeoutMs: timeouts.opencodeRouter }); }, - owpenbotTelegramIdentities: () => - requestJsonRaw(baseUrl, "/owpenbot/identities/telegram", { token, hostToken, timeoutMs: timeouts.owpenbot }), - owpenbotSlackIdentities: () => - requestJsonRaw(baseUrl, "/owpenbot/identities/slack", { token, hostToken, timeoutMs: timeouts.owpenbot }), + opencodeRouterTelegramIdentities: () => + requestJsonRaw(baseUrl, "/opencode-router/identities/telegram", { token, hostToken, timeoutMs: timeouts.opencodeRouter }), + opencodeRouterSlackIdentities: () => + requestJsonRaw(baseUrl, "/opencode-router/identities/slack", { token, hostToken, timeoutMs: timeouts.opencodeRouter }), listWorkspaces: () => requestJson(baseUrl, "/workspaces", { token, hostToken, timeoutMs: timeouts.listWorkspaces }), activateWorkspace: (workspaceId: string) => requestJson<{ activeId: string; workspace: OpenworkWorkspaceInfo }>( @@ -868,61 +868,61 @@ export function createOpenworkServerClient(options: { baseUrl: string; token?: s `/workspace/${workspaceId}/config`, { token, hostToken, timeoutMs: timeouts.config }, ), - setOwpenbotTelegramToken: ( + setOpenCodeRouterTelegramToken: ( workspaceId: string, tokenValue: string, healthPort?: number | null, ) => - requestJson( + requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/telegram-token`, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/telegram-token`, { token, hostToken, method: "POST", body: { token: tokenValue, healthPort }, - timeoutMs: timeouts.owpenbot, + timeoutMs: timeouts.opencodeRouter, }, ), - setOwpenbotSlackTokens: ( + setOpenCodeRouterSlackTokens: ( workspaceId: string, botToken: string, appToken: string, healthPort?: number | null, ) => - requestJson( + requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/slack-tokens`, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/slack-tokens`, { token, hostToken, method: "POST", body: { botToken, appToken, healthPort }, - timeoutMs: timeouts.owpenbot, + timeoutMs: timeouts.opencodeRouter, }, ), - getOwpenbotTelegram: (workspaceId: string) => - requestJson( + getOpenCodeRouterTelegram: (workspaceId: string) => + requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/telegram`, - { token, hostToken, timeoutMs: timeouts.owpenbot }, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/telegram`, + { token, hostToken, timeoutMs: timeouts.opencodeRouter }, ), - getOwpenbotTelegramIdentities: (workspaceId: string, options?: { healthPort?: number | null }) => { + getOpenCodeRouterTelegramIdentities: (workspaceId: string, options?: { healthPort?: number | null }) => { const query = typeof options?.healthPort === "number" ? `?healthPort=${encodeURIComponent(String(options.healthPort))}` : ""; - return requestJson( + return requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/identities/telegram${query}`, - { token, hostToken, timeoutMs: timeouts.owpenbot }, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/identities/telegram${query}`, + { token, hostToken, timeoutMs: timeouts.opencodeRouter }, ); }, - upsertOwpenbotTelegramIdentity: ( + upsertOpenCodeRouterTelegramIdentity: ( workspaceId: string, input: { id?: string; token: string; enabled?: boolean }, options?: { healthPort?: number | null }, ) => - requestJson( + requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/identities/telegram`, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/identities/telegram`, { token, hostToken, @@ -935,30 +935,30 @@ export function createOpenworkServerClient(options: { baseUrl: string; token?: s }, }, ), - deleteOwpenbotTelegramIdentity: (workspaceId: string, identityId: string, options?: { healthPort?: number | null }) => { + deleteOpenCodeRouterTelegramIdentity: (workspaceId: string, identityId: string, options?: { healthPort?: number | null }) => { const query = typeof options?.healthPort === "number" ? `?healthPort=${encodeURIComponent(String(options.healthPort))}` : ""; - return requestJson( + return requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/identities/telegram/${encodeURIComponent(identityId)}${query}`, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/identities/telegram/${encodeURIComponent(identityId)}${query}`, { token, hostToken, method: "DELETE" }, ); }, - getOwpenbotSlackIdentities: (workspaceId: string, options?: { healthPort?: number | null }) => { + getOpenCodeRouterSlackIdentities: (workspaceId: string, options?: { healthPort?: number | null }) => { const query = typeof options?.healthPort === "number" ? `?healthPort=${encodeURIComponent(String(options.healthPort))}` : ""; - return requestJson( + return requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/identities/slack${query}`, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/identities/slack${query}`, { token, hostToken }, ); }, - upsertOwpenbotSlackIdentity: ( + upsertOpenCodeRouterSlackIdentity: ( workspaceId: string, input: { id?: string; botToken: string; appToken: string; enabled?: boolean }, options?: { healthPort?: number | null }, ) => - requestJson( + requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/identities/slack`, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/identities/slack`, { token, hostToken, @@ -972,15 +972,15 @@ export function createOpenworkServerClient(options: { baseUrl: string; token?: s }, }, ), - deleteOwpenbotSlackIdentity: (workspaceId: string, identityId: string, options?: { healthPort?: number | null }) => { + deleteOpenCodeRouterSlackIdentity: (workspaceId: string, identityId: string, options?: { healthPort?: number | null }) => { const query = typeof options?.healthPort === "number" ? `?healthPort=${encodeURIComponent(String(options.healthPort))}` : ""; - return requestJson( + return requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/identities/slack/${encodeURIComponent(identityId)}${query}`, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/identities/slack/${encodeURIComponent(identityId)}${query}`, { token, hostToken, method: "DELETE" }, ); }, - getOwpenbotBindings: ( + getOpenCodeRouterBindings: ( workspaceId: string, filters?: { channel?: string; identityId?: string; healthPort?: number | null }, ) => { @@ -989,20 +989,20 @@ export function createOpenworkServerClient(options: { baseUrl: string; token?: s if (filters?.identityId?.trim()) search.set("identityId", filters.identityId.trim()); if (typeof filters?.healthPort === "number") search.set("healthPort", String(filters.healthPort)); const suffix = search.toString(); - return requestJson( + return requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/bindings${suffix ? `?${suffix}` : ""}`, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/bindings${suffix ? `?${suffix}` : ""}`, { token, hostToken }, ); }, - setOwpenbotBinding: ( + setOpenCodeRouterBinding: ( workspaceId: string, input: { channel: string; identityId?: string; peerId: string; directory?: string }, options?: { healthPort?: number | null }, ) => - requestJson( + requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/bindings`, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/bindings`, { token, hostToken, @@ -1016,7 +1016,7 @@ export function createOpenworkServerClient(options: { baseUrl: string; token?: s }, }, ), - sendOwpenbotMessage: ( + sendOpenCodeRouterMessage: ( workspaceId: string, input: { channel: "telegram" | "slack"; @@ -1038,40 +1038,40 @@ export function createOpenworkServerClient(options: { baseUrl: string; token?: s healthPort: options?.healthPort ?? null, }; - const primaryPath = `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/send`; + const primaryPath = `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/send`; const mountedWorkspaceId = parseOpenworkWorkspaceIdFromUrl(baseUrl); const fallbackPath = mountedWorkspaceId && mountedWorkspaceId === workspaceId - ? `/owpenbot/send` - : `/w/${encodeURIComponent(workspaceId)}/owpenbot/send`; + ? `/opencode-router/send` + : `/w/${encodeURIComponent(workspaceId)}/opencode-router/send`; - return requestJson(baseUrl, primaryPath, { + return requestJson(baseUrl, primaryPath, { token, hostToken, method: "POST", body: payload, - timeoutMs: timeouts.owpenbot, + timeoutMs: timeouts.opencodeRouter, }).catch(async (error) => { if (!(error instanceof OpenworkServerError) || error.status !== 404) { throw error; } - return requestJson(baseUrl, fallbackPath, { + return requestJson(baseUrl, fallbackPath, { token, hostToken, method: "POST", body: payload, - timeoutMs: timeouts.owpenbot, + timeoutMs: timeouts.opencodeRouter, }); }); }, - setOwpenbotTelegramEnabled: ( + setOpenCodeRouterTelegramEnabled: ( workspaceId: string, enabled: boolean, options?: { clearToken?: boolean; healthPort?: number | null }, ) => - requestJson( + requestJson( baseUrl, - `/workspace/${encodeURIComponent(workspaceId)}/owpenbot/telegram-enabled`, + `/workspace/${encodeURIComponent(workspaceId)}/opencode-router/telegram-enabled`, { token, hostToken, diff --git a/packages/app/src/app/lib/tauri.ts b/packages/app/src/app/lib/tauri.ts index 68d4c177..0e483691 100644 --- a/packages/app/src/app/lib/tauri.ts +++ b/packages/app/src/app/lib/tauri.ts @@ -651,31 +651,31 @@ export async function schedulerDeleteJob(name: string, scopeRoot?: string): Prom return invoke("scheduler_delete_job", { name, scopeRoot }); } -// Owpenbot types -export type OwpenbotIdentityItem = { +// OpenCodeRouter types +export type OpenCodeRouterIdentityItem = { id: string; enabled: boolean; running?: boolean; }; -export type OwpenbotChannelStatus = { - items: OwpenbotIdentityItem[]; +export type OpenCodeRouterChannelStatus = { + items: OpenCodeRouterIdentityItem[]; }; -export type OwpenbotStatus = { +export type OpenCodeRouterStatus = { running: boolean; config: string; healthPort?: number | null; - telegram: OwpenbotChannelStatus; - slack: OwpenbotChannelStatus; + telegram: OpenCodeRouterChannelStatus; + slack: OpenCodeRouterChannelStatus; opencode: { url: string; directory?: string }; }; -export type OwpenbotStatusResult = - | { ok: true; status: OwpenbotStatus } +export type OpenCodeRouterStatusResult = + | { ok: true; status: OpenCodeRouterStatus } | { ok: false; error: string }; -export type OwpenbotInfo = { +export type OpenCodeRouterInfo = { running: boolean; version: string | null; workspacePath: string | null; @@ -685,31 +685,31 @@ export type OwpenbotInfo = { lastStderr: string | null; }; -// Owpenbot functions - call Tauri commands that wrap owpenbot CLI -export async function getOwpenbotStatus(): Promise { +// OpenCodeRouter functions - call Tauri commands that wrap opencodeRouter CLI +export async function getOpenCodeRouterStatus(): Promise { try { - return await invoke("owpenbot_status"); + return await invoke("opencodeRouter_status"); } catch { return null; } } -export async function getOwpenbotStatusDetailed(): Promise { +export async function getOpenCodeRouterStatusDetailed(): Promise { try { - const status = await invoke("owpenbot_status"); + const status = await invoke("opencodeRouter_status"); return { ok: true, status }; } catch (error) { return { ok: false, error: String(error) }; } } -export async function owpenbotInfo(): Promise { - return invoke("owpenbot_info"); +export async function opencodeRouterInfo(): Promise { + return invoke("opencodeRouter_info"); } -export async function getOwpenbotGroupsEnabled(): Promise { +export async function getOpenCodeRouterGroupsEnabled(): Promise { try { - const status = await getOwpenbotStatus(); + const status = await getOpenCodeRouterStatus(); const healthPort = status?.healthPort ?? 3005; const response = await (isTauriRuntime() ? tauriFetch : fetch)(`http://127.0.0.1:${healthPort}/config/groups`, { method: "GET", @@ -725,9 +725,9 @@ export async function getOwpenbotGroupsEnabled(): Promise { } } -export async function setOwpenbotGroupsEnabled(enabled: boolean): Promise { +export async function setOpenCodeRouterGroupsEnabled(enabled: boolean): Promise { try { - const status = await getOwpenbotStatus(); + const status = await getOpenCodeRouterStatus(); const healthPort = status?.healthPort ?? 3005; const response = await (isTauriRuntime() ? tauriFetch : fetch)(`http://127.0.0.1:${healthPort}/config/groups`, { method: "POST", @@ -761,18 +761,18 @@ export async function opencodeMcpAuth( }); } -export async function owpenbotStop(): Promise { - return invoke("owpenbot_stop"); +export async function opencodeRouterStop(): Promise { + return invoke("opencodeRouter_stop"); } -export async function owpenbotStart(options: { +export async function opencodeRouterStart(options: { workspacePath: string; opencodeUrl?: string; opencodeUsername?: string; opencodePassword?: string; healthPort?: number; -}): Promise { - return invoke("owpenbot_start", { +}): Promise { + return invoke("opencodeRouter_start", { workspacePath: options.workspacePath, opencodeUrl: options.opencodeUrl ?? null, opencodeUsername: options.opencodeUsername ?? null, @@ -781,15 +781,15 @@ export async function owpenbotStart(options: { }); } -export async function owpenbotRestart(options: { +export async function opencodeRouterRestart(options: { workspacePath: string; opencodeUrl?: string; opencodeUsername?: string; opencodePassword?: string; healthPort?: number; -}): Promise { - await owpenbotStop(); - return owpenbotStart(options); +}): Promise { + await opencodeRouterStop(); + return opencodeRouterStart(options); } /** diff --git a/packages/app/src/app/pages/dashboard.tsx b/packages/app/src/app/pages/dashboard.tsx index e4ffd70b..39c6989d 100644 --- a/packages/app/src/app/pages/dashboard.tsx +++ b/packages/app/src/app/pages/dashboard.tsx @@ -25,7 +25,7 @@ import type { OpenworkServerSettings, OpenworkServerStatus, } from "../lib/openwork-server"; -import type { EngineInfo, OpenwrkStatus, OpenworkServerInfo, OwpenbotInfo, WorkspaceInfo } from "../lib/tauri"; +import type { EngineInfo, OpenwrkStatus, OpenworkServerInfo, OpenCodeRouterInfo, WorkspaceInfo } from "../lib/tauri"; import Button from "../components/button"; import ExtensionsView from "./extensions"; @@ -94,7 +94,7 @@ export type DashboardViewProps = { engineInfo: EngineInfo | null; engineDoctorVersion: string | null; openwrkStatus: OpenwrkStatus | null; - owpenbotInfo: OwpenbotInfo | null; + opencodeRouterInfo: OpenCodeRouterInfo | null; updateOpenworkServerSettings: (next: OpenworkServerSettings) => void; resetOpenworkServerSettings: () => void; testOpenworkServerConnection: (next: OpenworkServerSettings) => Promise; @@ -1283,7 +1283,7 @@ export default function DashboardView(props: DashboardViewProps) { opencodeConnectStatus={props.opencodeConnectStatus} engineInfo={props.engineInfo} openwrkStatus={props.openwrkStatus} - owpenbotInfo={props.owpenbotInfo} + opencodeRouterInfo={props.opencodeRouterInfo} engineDoctorVersion={props.engineDoctorVersion} developerMode={props.developerMode} toggleDeveloperMode={props.toggleDeveloperMode} diff --git a/packages/app/src/app/pages/identities.tsx b/packages/app/src/app/pages/identities.tsx index ca5c321e..fcf682cc 100644 --- a/packages/app/src/app/pages/identities.tsx +++ b/packages/app/src/app/pages/identities.tsx @@ -16,9 +16,9 @@ import { } from "../lib/openwork-server"; import type { OpenworkServerClient, - OpenworkOwpenbotHealthSnapshot, - OpenworkOwpenbotIdentityItem, - OpenworkOwpenbotSendResult, + OpenworkOpenCodeRouterHealthSnapshot, + OpenworkOpenCodeRouterIdentityItem, + OpenworkOpenCodeRouterSendResult, OpenworkServerStatus, OpenworkWorkspaceFileContent, } from "../lib/openwork-server"; @@ -35,8 +35,8 @@ export type IdentitiesViewProps = { developerMode: boolean; }; -const OWPENBOT_AGENT_FILE_PATH = ".opencode/agents/owpenbot.md"; -const OWPENBOT_AGENT_FILE_TEMPLATE = `# Owpenbot Messaging Agent +const OPENCODE_ROUTER_AGENT_FILE_PATH = ".opencode/agents/opencode-router.md"; +const OPENCODE_ROUTER_AGENT_FILE_TEMPLATE = `# OpenCodeRouter Messaging Agent Use this file to define how the assistant responds in Slack/Telegram for this workspace. @@ -53,7 +53,7 @@ function formatRequestError(error: unknown): string { return error instanceof Error ? error.message : String(error); } -function isOwpenbotSnapshot(value: unknown): value is OpenworkOwpenbotHealthSnapshot { +function isOpenCodeRouterSnapshot(value: unknown): value is OpenworkOpenCodeRouterHealthSnapshot { if (!value || typeof value !== "object") return false; const record = value as Record; return ( @@ -64,7 +64,7 @@ function isOwpenbotSnapshot(value: unknown): value is OpenworkOwpenbotHealthSnap ); } -function isOwpenbotIdentities(value: unknown): value is { ok: boolean; items: OpenworkOwpenbotIdentityItem[] } { +function isOpenCodeRouterIdentities(value: unknown): value is { ok: boolean; items: OpenworkOpenCodeRouterIdentityItem[] } { if (!value || typeof value !== "object") return false; const record = value as Record; return typeof record.ok === "boolean" && Array.isArray(record.items); @@ -126,13 +126,13 @@ function StatusPill(props: { label: string; value: string; ok: boolean }) { export default function IdentitiesView(props: IdentitiesViewProps) { const [refreshing, setRefreshing] = createSignal(false); - const [health, setHealth] = createSignal(null); + const [health, setHealth] = createSignal(null); const [healthError, setHealthError] = createSignal(null); - const [telegramIdentities, setTelegramIdentities] = createSignal([]); + const [telegramIdentities, setTelegramIdentities] = createSignal([]); const [telegramIdentitiesError, setTelegramIdentitiesError] = createSignal(null); - const [slackIdentities, setSlackIdentities] = createSignal([]); + const [slackIdentities, setSlackIdentities] = createSignal([]); const [slackIdentitiesError, setSlackIdentitiesError] = createSignal(null); const [telegramToken, setTelegramToken] = createSignal(""); @@ -169,7 +169,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) { const [sendBusy, setSendBusy] = createSignal(false); const [sendStatus, setSendStatus] = createSignal(null); const [sendError, setSendError] = createSignal(null); - const [sendResult, setSendResult] = createSignal(null); + const [sendResult, setSendResult] = createSignal(null); const [reconnectStatus, setReconnectStatus] = createSignal(null); const [reconnectError, setReconnectError] = createSignal(null); @@ -284,7 +284,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) { setAgentLoading(true); setAgentError(null); try { - const result = (await client.readWorkspaceFile(id, OWPENBOT_AGENT_FILE_PATH)) as OpenworkWorkspaceFileContent; + const result = (await client.readWorkspaceFile(id, OPENCODE_ROUTER_AGENT_FILE_PATH)) as OpenworkWorkspaceFileContent; const nextContent = result.content ?? ""; setAgentExists(true); setAgentContent(nextContent); @@ -317,12 +317,12 @@ export default function IdentitiesView(props: IdentitiesViewProps) { setAgentError(null); try { const result = await client.writeWorkspaceFile(id, { - path: OWPENBOT_AGENT_FILE_PATH, - content: OWPENBOT_AGENT_FILE_TEMPLATE, + path: OPENCODE_ROUTER_AGENT_FILE_PATH, + content: OPENCODE_ROUTER_AGENT_FILE_TEMPLATE, }); setAgentExists(true); - setAgentContent(OWPENBOT_AGENT_FILE_TEMPLATE); - setAgentDraft(OWPENBOT_AGENT_FILE_TEMPLATE); + setAgentContent(OPENCODE_ROUTER_AGENT_FILE_TEMPLATE); + setAgentDraft(OPENCODE_ROUTER_AGENT_FILE_TEMPLATE); setAgentBaseUpdatedAt(typeof result.updatedAt === "number" ? result.updatedAt : null); setAgentStatus("Created default messaging agent file."); } catch (error) { @@ -345,7 +345,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) { setAgentError(null); try { const result = await client.writeWorkspaceFile(id, { - path: OWPENBOT_AGENT_FILE_PATH, + path: OPENCODE_ROUTER_AGENT_FILE_PATH, content: agentDraft(), baseUpdatedAt: agentBaseUpdatedAt(), }); @@ -379,7 +379,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) { setSendError(null); setSendResult(null); try { - const result = await client.sendOwpenbotMessage(id, { + const result = await client.sendOpenCodeRouterMessage(id, { channel: sendChannel(), text, ...(sendDirectory().trim() ? { directory: sendDirectory().trim() } : {}), @@ -425,15 +425,15 @@ export default function IdentitiesView(props: IdentitiesViewProps) { } const [healthRes, tgRes, slackRes, telegramInfo] = await Promise.all([ - client.owpenbotHealth(), - client.getOwpenbotTelegramIdentities(id), - client.getOwpenbotSlackIdentities(id), - client.getOwpenbotTelegram(id).catch(() => null), + client.opencodeRouterHealth(), + client.getOpenCodeRouterTelegramIdentities(id), + client.getOpenCodeRouterSlackIdentities(id), + client.getOpenCodeRouterTelegram(id).catch(() => null), ]); setTelegramBotUsername(getTelegramUsernameFromResult(telegramInfo)); - if (isOwpenbotSnapshot(healthRes.json)) { + if (isOpenCodeRouterSnapshot(healthRes.json)) { setHealth(healthRes.json); } else { setHealth(null); @@ -441,19 +441,19 @@ export default function IdentitiesView(props: IdentitiesViewProps) { const message = (healthRes.json && typeof (healthRes.json as any).message === "string") ? String((healthRes.json as any).message) - : `Owpenbot health unavailable (${healthRes.status})`; + : `OpenCodeRouter health unavailable (${healthRes.status})`; setHealthError(message); } } - if (isOwpenbotIdentities(tgRes)) { + if (isOpenCodeRouterIdentities(tgRes)) { setTelegramIdentities(tgRes.items ?? []); } else { setTelegramIdentities([]); setTelegramIdentitiesError("Telegram identities unavailable."); } - if (isOwpenbotIdentities(slackRes)) { + if (isOpenCodeRouterIdentities(slackRes)) { setSlackIdentities(slackRes.items ?? []); } else { setSlackIdentities([]); @@ -508,7 +508,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) { setTelegramStatus(null); setTelegramError(null); try { - const result = await client.upsertOwpenbotTelegramIdentity(id, { token, enabled: telegramEnabled() }); + const result = await client.upsertOpenCodeRouterTelegramIdentity(id, { token, enabled: telegramEnabled() }); if (result.ok) { const username = (result.telegram as any)?.bot?.username; if (username) { @@ -546,7 +546,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) { setTelegramStatus(null); setTelegramError(null); try { - const result = await client.deleteOwpenbotTelegramIdentity(id, identityId); + const result = await client.deleteOpenCodeRouterTelegramIdentity(id, identityId); if (result.ok) { setTelegramBotUsername(null); setTelegramStatus(result.applied === false ? "Deleted (pending apply)." : "Deleted."); @@ -580,7 +580,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) { setSlackStatus(null); setSlackError(null); try { - const result = await client.upsertOwpenbotSlackIdentity(id, { botToken, appToken, enabled: slackEnabled() }); + const result = await client.upsertOpenCodeRouterSlackIdentity(id, { botToken, appToken, enabled: slackEnabled() }); if (result.ok) { setSlackStatus(result.applied === false ? "Saved (pending apply)." : "Saved."); } else { @@ -612,7 +612,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) { setSlackStatus(null); setSlackError(null); try { - const result = await client.deleteOwpenbotSlackIdentity(id, identityId); + const result = await client.deleteOpenCodeRouterSlackIdentity(id, identityId); if (result.ok) { setSlackStatus(result.applied === false ? "Deleted (pending apply)." : "Deleted."); } else { @@ -1244,7 +1244,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) { - {OWPENBOT_AGENT_FILE_PATH} + {OPENCODE_ROUTER_AGENT_FILE_PATH} @@ -1268,7 +1268,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) {