Skip to content

client: the Projects sidebar sends flybot/projects, so the list is always empty and a role can never change #1854

Closed

Description

@Birfy

Written-by: Chief

Reported by the owner on 2026-10-30 while trying v0.2.17: expanding 项目 in the left sidebar lists nothing, so a Project cannot be opened from there — while the same board opened from 任务 works. This is one board reached two ways; the sidebar way is broken.

What happens

  • Left sidebar → 项目 → expand → no rows ("No Projects yet", or the error line from the failed call).
  • Right-click on a Project row to switch role never gets as far as the host: every attempt fails with Unknown FlyBot endpoint ….

Root cause (client, not the host)

core/src/client/projects-nav.js:12 wraps the host call:

const call = (endpoint, payload) => callHost(`flybot/${endpoint}`, payload)

and ProjectsNav uses that wrapper for projects (its load callback) and for project-role (the menu's onPick). Both are core endpoints: core/src/host/channel.js dispatches them as bare names, and the flybot/ namespace has no such endpoint.

Reproduced against the live host, 2026-10-30T16:45Z:

  • POST /api/bot {"endpoint":"flybot/projects"} → {"ok":false,"error":{"code":"bot/not-found","message":"Unknown FlyBot endpoint projects"}}
  • POST /api/bot {"endpoint":"projects"} → {"ok":true,"value":{"projects":[{"name":"FlyBot 开发","role":"owner","choices":[]}]}}

So the list is empty on every deployment, signed in or not. This is a different defect from #1836 (the missing project-role entry in core/src/host/authz.js, which PR #1837 fixes): that one denies the call on a signed-in host even when the right name is sent; this one sends the wrong name in front of it. Fixing #1837 alone leaves the sidebar empty.

Fix

  1. Drop the wrapper: send projects and project-role unchanged (callHost('projects'), callHost('project-role', …)).
  2. One entry point, as the owner asked: the board is one overlay at #project=<id>, so remove the duplicate door in the tasks pane — the data-open-project button at core/src/client/kanban.js:424-426 — and let Projects be entered only from the left sidebar.
  3. Add core/test/projects-nav.test.js:
    • the endpoint names the nav sends are exactly projects and project-role (no flybot/ prefix);
    • a listing of one Project with role: 'owner' renders the project's name and role in the row;
    • clicking that row sets #project=<id> (or calls onOpen with the id).
  4. npm run build in core/ so client.js matches; npm run verify with TZ=UTC green at the tip.

Acceptance

  • Expanding 项目 lists the Project with the caller's role; clicking it opens the board.
  • The new test fails if the flybot/ prefix comes back.
  • No second entry point remains in the tasks pane.
  • Fixes #<this> in the PR body, plus Owner: / Reviewer: lines and a ## Checkpoint block.

Activity

  1. added
    bugSomething isn't working
    area:uiWeb/desktop UI and copy
    on Oct 30, 2026
  2. Birfy commented on Oct 30, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Triage

    Scope for the implementer — verified on main at 2026-10-30T16:50Z (core/src/client/projects-nav.js:12, core/src/client/kanban.js:424-427, core/src/host/channel.js:672,678,720):

    1. core/src/client/projects-nav.js — delete the wrapper on line 12; pass projects and project-role to callHost unchanged. The host dispatches them as bare case names; the flybot/ prefix lands in flybotEndpoint, which is exactly where Unknown FlyBot endpoint projects comes from.
    2. core/src/client/kanban.js — remove the data-open-project button (lines 424-427). Projects are entered from the left sidebar only.
    3. Tests. core/test/projects-nav.test.js already exists — extend it, do not add a second file: record the endpoints handed to callHost and assert exactly projects / project-role (this assertion must go red if the flybot/ prefix returns), plus one row rendered with its role and a click that writes #project=<id>. core/test/project-board-entry.test.js:122-134 pins the client: a Project board — in flight, waiting on you, delivered today (read-only projection over the task store) #1701 tasks-pane entry; update it in the same PR to assert that entry is gone (cite client: the Projects sidebar sends flybot/projects, so the list is always empty and a role can never change #1854) rather than leaving it red.
    4. npm run build in core/ (so client.js matches), then npm run verify with TZ=UTC green at the tip; one changelog.d/1854-*.fixed.md fragment.
    5. Do not touch core/src/host/authz.js — core: a signed-in deployment answers "Unknown endpoint project-role", so #1832's role switch writes nothing #1836 / PR fix(host): let the Project role switch reach its handler on a signed-in host (#1836) #1837 owns the signed-in role-switch denial; this test must not depend on it.

    Acceptance: expanding 项目 in the sidebar lists the caller's Projects with their role and a click opens #project=<id>; no flybot/ prefix in the nav; no second entry point in the tasks pane; the new test fails without the source change.

    Risk: T1 per .github/agent/risk-rules.json (core/src/client/**, core/client.js, core/test/**) — green tests-ok at the tip, no PASS. No open PR names #1854.

  3. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 30, 2026
  4. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:uiWeb/desktop UI and copybugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions