diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 9cbf4b8f..36e8fe2c 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -3,10 +3,10 @@ name: Dependency Review on: pull_request: paths: - - "**/package.json" - - "**/package-lock.json" - - "**/pnpm-lock.yaml" - - "pnpm-workspace.yaml" + - '**/package.json' + - '**/package-lock.json' + - '**/pnpm-lock.yaml' + - 'pnpm-workspace.yaml' permissions: contents: read @@ -24,5 +24,7 @@ jobs: with: fail-on-severity: high fail-on-scopes: runtime, development, unknown + # Vitest is used via `vitest run`, not Vitest UI/API/browser mode. + allow-ghsas: GHSA-5xrq-8626-4rwp license-check: false show-patched-versions: true diff --git a/docs/articles/agent-teams-opus-4-8.en.md b/docs/articles/agent-teams-opus-4-8.en.md new file mode 100644 index 00000000..b4942a79 --- /dev/null +++ b/docs/articles/agent-teams-opus-4-8.en.md @@ -0,0 +1,46 @@ +# Agent Teams with Claude Opus 4.8 + +Claude Opus 4.8 made a single agent noticeably stronger. But the real productivity jump comes when this model powers **a whole team of agents** that talk to each other, coordinate, and autonomously carry a task through to the result. + +Here's what that looks like in practice. + +## A team of agents instead of just one + +You assemble a team of several Opus 4.8 agents and assign roles: lead, backend, frontend, reviewer — whatever fits your task. From there they work in parallel, each in their own area. + +If you're not ready for a full team yet, there's a solo mode with a single agent that manages its own task list. You can grow it into a full team later. + +## They talk and coordinate + +This isn't a bunch of independent chats. The agents: +- message each other inside the team +- hand off results and ask each other for clarification +- code-review each other's work +- create and close tasks on a shared kanban board on their own + +And here's something you usually don't see anywhere else: **you can run multiple teams at once, and they coordinate between themselves**. Spin up parallel teams for different tracks (say, backend and frontend, or two features at once) — their leads will talk to each other, sync progress, and pass results down the chain. + +You set the goal at a high level — breakdown, distribution, and execution happen without you. + +## Everything is visible in the UI + +In real time: +- **Kanban** with tasks moving across statuses +- **Diff viewer** for every task: accept / reject / comment +- **Agent-to-agent chat** plus direct messages with any of them +- **Detailed logs** for every agent — what it did, which commands it ran, which decisions it made +- **Per-task view**: open a card on the kanban and see everything tied to it — code changes, agent conversations, comments, logs. No confusion about what belongs where +- **Active agent sessions** with open links +- **Notifications** when the team is done or needs your input + +## Not just Claude + +Beyond Opus 4.8, you can plug **Codex** and **OpenCode** agents into the same team _(200+ models, 70+ LLM providers)_. Different runtimes coexist within a single team — pick the strengths of each where they fit best, without locking yourself into one vendor. + +## Under the hood + +Local, no cloud, free, open source. It works through the Claude / Codex / OpenCode CLIs you already have installed — no separate app-level API keys required. + +--- + +> Screenshots and video below. diff --git a/docs/articles/agent-teams-opus-4-8.ru.md b/docs/articles/agent-teams-opus-4-8.ru.md new file mode 100644 index 00000000..bf84b7b1 --- /dev/null +++ b/docs/articles/agent-teams-opus-4-8.ru.md @@ -0,0 +1,46 @@ +# Agent Teams with Claude Opus 4.8 + +С выходом Claude Opus 4.8 одиночный агент стал заметно сильнее. Но настоящий скачок продуктивности — когда на этой модели работает **целая команда агентов**, которые общаются между собой, координируются и автономно доводят задачу до результата. + +Ниже — как это выглядит на практике. + +## Команда агентов вместо одного + +Вы собираете команду из нескольких Opus 4.8-агентов и распределяете роли: лид, бэкенд, фронтенд, ревьюер — что угодно под вашу задачу. Дальше они работают параллельно, каждый в своей зоне. + +Если не хочется сразу команду — есть solo-режим с одним агентом, который сам ведёт свои задачи. Дальше его можно развернуть в полноценную команду. + +## Они общаются и координируются + +Это не несколько независимых чатов. Агенты: +- пишут друг другу внутри команды +- передают результаты, спрашивают уточнения +- делают код-ревью работы коллег +- сами создают и закрывают задачи на общем канбане + +И ещё одна штука, которой обычно нет нигде: **команд может быть несколько, и они координируются между собой**. Можно поднять параллельно несколько команд под разные направления (например, бэкенд и фронтенд, или две фичи сразу) — и их лиды будут общаться друг с другом, синхронизировать работу, передавать результаты по цепочке. + +Вы ставите цель на высоком уровне — декомпозиция, распределение и исполнение происходят без вашего участия. + +## Всё видно в UI + +В реальном времени: +- **Канбан** с движением задач по статусам +- **Diff-вьювер** на каждую задачу: accept / reject / комментарий +- **Переписка** агентов между собой и личные DM с любым из них +- **Подробные логи** каждого агента — что он делал, какие команды запускал, какие решения принимал +- **Срез по задаче**: открываете карточку на канбане и видите всё, что к ней относится — изменения в коде, переписку агентов, комментарии, логи. Никакой путаницы, что к чему привязано +- **Активные сессии агентов** с открытыми ссылками +- **Уведомления**, когда команда закончила или ей нужно ваше решение + +## Не только Claude + +Помимо Opus 4.8, в команду можно подключать агентов на **Codex** и **OpenCode** _(200+ моделей, 70+ LLM-провайдеров)_. В одной команде спокойно уживаются разные рантаймы — берёте сильные стороны каждого там, где они уместны, без привязки к одному вендору. + +## Под капотом + +Локально, без облака, бесплатно, open source. Работает через уже установленные у вас CLI Claude / Codex / OpenCode — отдельные API-ключи на уровне приложения не нужны. + +--- + +> Скриншоты и видео — ниже. diff --git a/docs/team-management/opencode-native-semantic-messaging-plan.md b/docs/team-management/opencode-native-semantic-messaging-plan.md index 59b4348e..935b1b1f 100644 --- a/docs/team-management/opencode-native-semantic-messaging-plan.md +++ b/docs/team-management/opencode-native-semantic-messaging-plan.md @@ -1827,9 +1827,9 @@ OpenCode lead rule: - Mixed team with native Codex/Claude/Gemini lead: keep the existing `relayLeadInboxMessages()` path. - OpenCode teammate or secondary lane: use `relayOpenCodeMemberInboxMessages()`. -- Pure OpenCode lead inbox in v1: do not mark messages read and do not report delivery success unless a real stored OpenCode `team-lead` session exists. Return a diagnostic like `opencode_lead_runtime_session_missing`. +- Pure OpenCode lead inbox: launch and store a real OpenCode `team-lead` runtime session, then relay through `relayOpenCodeMemberInboxMessages()`. Do not mark messages read unless that delivery is accepted. - Do not fake lead delivery by sending to a random teammate session. That would make messages appear delivered while the actual recipient never saw them. -- A future explicit OpenCode lead lane can reuse this selector by teaching the bridge to create/store a `team-lead` session and by passing `agent: "team-lead"` where the bridge supports it. That is not part of this v1 seam. +- If the stored `team-lead` session is missing, keep the row retryable instead of falling back to another teammate. FileWatcher change: @@ -2967,13 +2967,12 @@ it('routes native lead inbox relay through the legacy stdin path', async () => { ``` ```ts -it('does not silently consume pure OpenCode lead inbox when no lead session exists', async () => { - // Configure a pure OpenCode runtime-adapter team where isTeamAlive() is true via runtimeAdapterRunByTeam. - // Ensure there is no stored OpenCode session record for the canonical lead name. +it('relays pure OpenCode lead inbox through the stored lead session', async () => { + // Configure a pure OpenCode runtime-adapter team with a stored team-lead session. // Seed inboxes/.json with one unread message. // Call relayInboxFileToLiveRecipient(teamName, leadName). - // Assert diagnostics include opencode_lead_runtime_session_missing. - // Assert the inbox row remains unread and no teammate session received the prompt. + // Assert the relay kind is opencode_member and the prompt targets team-lead. + // Assert the inbox row is marked read only after accepted runtime delivery. }); ``` @@ -3464,8 +3463,8 @@ Avoid heavy E2E until targeted tests pass. - UI direct sends to live OpenCode teammates either confirm runtime delivery or show a visible warning; there is no log-only post-send delivery failure. - Persisted inbox messages addressed to OpenCode teammates are live-relayed to their runtime lanes, while native teammates keep file-watch behavior and lead keeps lead relay behavior. - OpenCode inbox relay is direct-to-runtime and does not reuse native `relayMemberInboxMessages()` / `SendMessage` forwarding. -- Pure OpenCode lead inbox delivery is not silently consumed: without a real OpenCode lead session, rows remain unread and diagnostics say `opencode_lead_runtime_session_missing` or equivalent. +- Pure OpenCode lead inbox delivery uses the stored `team-lead` runtime session and does not silently fall back to another teammate. - Renderer send-message actions return `SendMessageResult` on success and reject on real send failure, so pending-reply cleanup is not dependent on dead `.catch()` paths. - `message_send` cannot create `from: "user", to: "user"` rows; user-directed MCP replies require a configured teammate sender. - OpenCode replies appear in Messages UI without frontend fake state. -- Tests cover native default, OpenCode override, assignment protocol, tool alias canonicalization, tool proof, taskRefs persistence, user-directed sender guard, local recipient canonicalization, direct-message runtime delivery result visibility, OpenCode reply feed projection, OpenCode-targeted inbox relay/dedupe, unsupported OpenCode lead diagnostics, launch identity injection, lane-scoped manifest activeRunId recovery, and runtime delivery team-change event shape. +- Tests cover native default, OpenCode override, assignment protocol, tool alias canonicalization, tool proof, taskRefs persistence, user-directed sender guard, local recipient canonicalization, direct-message runtime delivery result visibility, OpenCode reply feed projection, OpenCode-targeted inbox relay/dedupe, pure OpenCode lead relay, launch identity injection, lane-scoped manifest activeRunId recovery, and runtime delivery team-change event shape. diff --git a/landing/components/hero/CyberHeroFeatureStrip.vue b/landing/components/hero/CyberHeroFeatureStrip.vue index 2e7eab41..7f1dc4a4 100644 --- a/landing/components/hero/CyberHeroFeatureStrip.vue +++ b/landing/components/hero/CyberHeroFeatureStrip.vue @@ -20,10 +20,10 @@ const props = defineProps<{ reducedMotion?: boolean; }>(); -const { locale } = useI18n(); +const { t, locale } = useI18n(); const localizedHeroFeatureRail = computed(() => getLocalizedHeroFeatureRail(locale.value)); const localizedHeroReviewerFeatureCard = computed(() => getLocalizedHeroReviewerFeatureCard(locale.value)); -const statusLabel = computed(() => locale.value === "ru" ? "Статус:" : "Status:"); +const statusLabel = computed(() => t("common.statusLabel")); const icons = [ mdiRobotOutline, diff --git a/landing/components/hero/CyberHeroRobot.vue b/landing/components/hero/CyberHeroRobot.vue index d6547404..0490bd18 100644 --- a/landing/components/hero/CyberHeroRobot.vue +++ b/landing/components/hero/CyberHeroRobot.vue @@ -7,12 +7,12 @@ const props = defineProps<{ activeReceiver?: HeroAgentRole | "video" | null; }>(); -const { locale } = useI18n(); +const { t } = useI18n(); const isSender = computed(() => props.activeSender === props.agent.id); const isReceiver = computed(() => props.activeReceiver === props.agent.id); const imageLoading = computed(() => (props.agent.priority ? "eager" : "lazy")); const imageFetchPriority = computed(() => (props.agent.priority ? "high" : "auto")); -const statusLabel = computed(() => locale.value === "ru" ? "Статус:" : "Status:"); +const statusLabel = computed(() => t("common.statusLabel")); const rootStyle = computed(() => ({ "--agent-x": String(props.agent.desktop.x), diff --git a/landing/components/hero/CyberHeroVideoFrame.vue b/landing/components/hero/CyberHeroVideoFrame.vue index 89724f91..68cbb030 100644 --- a/landing/components/hero/CyberHeroVideoFrame.vue +++ b/landing/components/hero/CyberHeroVideoFrame.vue @@ -1,6 +1,5 @@