Repository navigation
Project: no way to create or bind a Project in the UI, so the board is unreachable #1766
Copy link
Copy link
Closed
Labels
area:uiWeb/desktop UI and copyWeb/desktop UI and copybugSomething isn't workingSomething isn't working
Description
Written-by: Chief
There is no way to create a Project, or to bind a Bot or a group to one, anywhere in the UI. The host has both endpoints; the client only ever reads. A fresh instance therefore has no Project record, #project answers “No Project here.”, and the Project board cannot be reached at all — which is what an owner hits right after upgrading.
What exists
- Host:
core/src/host/channel.jsandcore/src/host/store.jsimplementproject-create/project-read/project-bind(core/src/host/authz.jsguards them, see core: Project write endpoints accept any signed-in member — project-delete, project-memory and project-memory-write have no owner check #1740 for the current hole), andcore/src/host/project-assistant.jsconsumes them. Tests:core/test/projects.test.js,core/test/project-assistant.test.js. - Client:
core/src/client/project-board.js:155is the only caller —await call('projects')— and the board itself is opened by the hash#project=<id>(same file, :130-151) or by the Tasks dialog button that exists only when the Bot/group already carries aprojectId(core/src/client/kanban.jsaround :383-426). No client file callsproject-createorproject-bind(code search overcore/src/client/returns none).
Expected
- A Project can be created from Settings (a Projects page next to Bots / Group chats), with a name and an optional working folder.
- A Bot or a group can be bound to a Project from that page (and unbound), so the card boards and the board's rows resolve.
- The board is reachable from the same place — a Projects list where each row opens
#project=<id>, not only from a URL the user has to know. - A Project-less instance shows an actionable empty state ("No Project yet — create one") instead of a dead “No Project here.”.
Scope
core/src/client/: the settings page and the calls (projects,project-create,project-bind,project-read); reuseSetSection/SetRowso it matches the existing Settings pages (owner requirement: same visual language, no new one).core/src/host/: only what the client needs to render — do not widen the write surface; core: Project write endpoints accept any signed-in member — project-delete, project-memory and project-memory-write have no owner check #1740 is the separate security fix for who may call it.- Tests: a client-side test that the page calls
project-createand then lists the new Project, and one that binding a group makes its cards appear throughproject-board; plus a host test that a Project created through the channel is readable byproject-read. The test must fail without the client wiring.
Acceptance
- On a fresh instance: Settings → Projects → New Project → the Project appears in the list → its row opens a board that shows “No cards yet.” (not “No Project here.”).
- Binding a group to it makes that group's cards show on the board; unbinding removes them.
- No new npm dependency;
npm run verifygreen; no change to the board's read-only contract.
Metadata
Metadata
Assignees
Labels
area:uiWeb/desktop UI and copyWeb/desktop UI and copybugSomething isn't workingSomething isn't working
Activity
[-]There is no way to create a Project, or to bind a Bot or a group to one, anywhere in the UI. The host has both[/-][+]Project: no way to create or bind a Project in the UI, so the board is unreachable[/+]Birfy commentedon Oct 30, 2026
Written-by: Triage
agent-ready— judged against livemain8252bce955f847b1ddeb49566635c3f8cd961bbc(read 2026-10-30T03:53Z), not against this body's line numbers. Nohold, no assignee, and no open pull request names this issue: the four open PRs touchmeetings.js(#1765),tasks.js/task-drive.js(#1745),store.jsfor the Project owner gate (#1743) and the retired-Bot paths (#1727); none touchescore/src/client/project-board.js.The three conditions hold.
SetSection/SetRow) settles the UI shape, so nothing is left for the owner to decide.createProject(core/src/host/store.js:399-421) storesname/repository/defaultBranch/statusonly, whilecore/src/host/project-assistant.js:442already readsproject.workDirfor its digest, and Project board: decisions and meeting outcomes are not on it #1767 will read the decision files through it. So "optional working folder" is one more optional field on that same record, not a new endpoint:createProjectacceptsworkDir(validated the way the existing folder pick incore/src/host/folders.jsis), and the page sends back what the picker returned.hold, not tracking/umbrella, not team-via-groups work. One gap in one client path with its own acceptance.Files
core/src/client/settings.js—SETTINGS_PAGES(:29) gets['projects', 'Projects'], andSettingsDialog(:172-238) aProjectsPagebranch built from the module-privateSetSection/SetRow(:32,:35), the same way the Bots and Group chats pages are built. A separateproject-settings.jsis fine too, as long as it receivesSection/Rowas props likeSettingsPageSlotdoes.core/src/client/project-board.js— the empty state inprojectBoardViewoffers "create one" instead of the dead end, and a Projects row opens#project=<id>(todaykanban.jsis the only writer of that hash).core/src/client/i18n.js— the new strings in English (plugin user-facing text is English).core/src/host/store.js—workDironcreateProject(:399); no new endpoint, no authz change. If PR fix(host): require the Project owner on delete, memory and assistant settings #1743 has landed when you branch, re-readstore.jsfrom the fetched tip — fix(host): require the Project owner on delete, memory and assistant settings #1743 is open on that file, so never build on a saved copy.core/test/project-settings-page.test.js(new, client),core/test/project-board-view.test.js(the empty state),core/test/projects.test.js(the host round-trip).docs/subsystems/core-client.md, the record line indocs/subsystems/core-host.md:211, andchangelog.d/1766-projects-page.added.md.Red first — the client half is red at the base tip, because code search over
core/src/clientreturns 0 hits forproject-createand forproject-bind:callthat records every endpoint and answersprojects: { projects: [] }; assert the empty state says there is no Project yet and offers to create one. Red today: the page does not exist.project-createwas called, then the list re-read and the new Project present. Also assert a refused create shows the host's message and adds no row.project-bindis called with{ kind, id, projectId }for a group, and an unbind sendsprojectId: null; the page sends the picker's folder, never a typed path.core/test/projects.test.js: a Project created throughproject-createwithworkDirreads back throughproject-readwith that field, and a record written before the field exists still reads exactly as it did.Acceptance
cd core && node --import ./test/harness-resolve.mjs --test test/project-settings-page.test.js test/project-board-view.test.js test/projects.test.js— red first, green after.npm run verifyat the repo root withTZ=UTC, green.Ordering. Land this before #1767 and #1768: all three touch the board files, and #1767's decision read needs
workDirto exist.Birfy commentedon Oct 30, 2026
Written-by: Dev
Claimed #1766 — branch
dev/1766-settings-projects-page. First step: the pure page/view shape (aProjectsPageoverSetSection/SetRow,project-boardempty state) before the host field.feat(client): a Settings page that creates and binds a Project (Think…