feat: improve project agent onboarding

This commit is contained in:
2026-09-06 13:54:20 +08:00
parent a4fc3a5251
commit df02680f9d
15 changed files with 826 additions and 74 deletions

View File

@@ -36,59 +36,72 @@
## Outcome
- Confirmed that the screenshot's “项目智能体” is a persisted project-owned parent Agent,
not a runtime child Agent. ADR-006 and ADR-008 deliberately keep child Agents ephemeral
and without inherited project Plugin resources.
- Confirmed a state-invariant gap: Project Configuration validates only the Agents that
exist, so an empty Agent array passes; `submit()` then saves `initialized: true`.
`ProjectChatRoute` and `MainLayout` gate only on that boolean, despite the gate copy
claiming that at least one manually configured Agent is required.
- Confirmed the resulting dead-end presentation: Coding chat has no selected Agent, clears
the Conversation selection, renders only a small “当前项目还没有可用智能体” sidebar
message, leaves the main canvas empty, and disables the Composer without a recovery CTA.
- Confirmed the navigation gap: Project Configuration uses history-relative
`navigate(-1)`. The destination depends on how the page was entered and can even be a
visually identical Project Configuration history entry; saving does not navigate to
the Conversation page.
- Confirmed an additional supported-path gap: first-run Setup does not configure a model.
With zero model options, the create-Agent icon shows a toast and opens a read-only model
drawer that contains no direct action to `/models`, so stronger Agent guidance alone
would still lead some users into a dead end.
- Recommended the “required but escapable” flow: an incomplete project may exist and the
user may leave, but completion/Conversation readiness requires at least one enabled,
unarchived, fully configured project Agent. In the empty state, replace the icon-only
instruction with a prominent text CTA; after the first Agent is valid, make the primary
action “保存并进入对话” with deterministic `/chat` navigation. Keep a full chat recovery
state for legacy/archived-all data and route it directly back to Agent creation.
- Recommended treating zero models as an explicit prerequisite state with a “先配置模型”
CTA and a return intent, and replacing history-relative back behavior with context-aware,
labelled destinations such as “返回对话” or “稍后设置”.
- No product behavior or source code was changed.
- Confirmed that the screenshot's “项目智能体” is the persisted project-owned parent
Agent, not an ephemeral runtime child Agent, and retained that terminology throughout.
- Added one shared Conversation-readiness rule: `initialized` must be true and the project
must contain at least one enabled, unarchived Agent with a non-empty name, avatar, role,
responsibility, and resolved model. Project list entry, direct `/chat` resolution,
the programming-module gate, and Coding chat now use the same rule instead of trusting
`initialized` alone.
- Reworked the zero-ready-Agent configuration state into a prominent required-step card.
With no model it offers “先配置模型” and a direct model-settings action; otherwise it
creates the first Agent or resumes an enabled incomplete Agent. Disabled-only state
intentionally offers a new Agent because the edit dialog has no enable control.
- The first Agent is persisted immediately and then navigates to `/chat`. Later Agent
additions and edits retain the existing page-draft plus explicit-save behavior.
- Replaced history-relative back navigation with labelled, deterministic “返回对话” or
“稍后设置” destinations. Unsaved Agent changes are confirmed before any page exit,
including the model-settings prerequisite path.
- Archiving the last ready Agent now explains that saving will return the project to a
pending state; saving that state clears `initialized` and leaves the unusable chat route.
- Added a full Coding chat recovery state with a direct project-configuration action and no
Composer or Conversation/runtime creation when no usable Agent exists.
- Updated README with the accepted readiness and onboarding behavior.
## Verification
- Inspected the supplied 1493×891 Project Configuration screenshot at original detail.
- Read the project memory startup set, relevant product/domain rules, ADR-006, ADR-008,
and related concurrent task scopes after passing the ownership and planning gates.
- Inspected `src/pages/ProjectConfiguration/index.tsx`, `src/App.tsx`,
`src/components/layout/MainLayout.tsx`, `src/components/layout/Sidebar.tsx`,
`src/pages/Chat/CodingChatPanel.tsx`, `CodingConversationSidebar.tsx`,
`AgentCreationDialog.tsx`, the project configuration schema/service, Setup, README,
focused tests, and relevant Git blame/history.
- Queried the UI/UX reference for onboarding, empty-state, primary-action, keyboard, and
predictable-back guidance. Its generated dark palette was rejected because Makelore's
repository contract requires the existing single light visual system.
- No automated test was run because this task intentionally made no behavior change; a
future implementation requires focused unit coverage and the shared Electron E2E flow.
- Focused Vitest: 5 files, 63 tests passed, covering readiness, App routing, MainLayout
gating, Project Configuration onboarding/navigation, and Coding chat recovery.
- Full `pnpm test`: 230 files / 1928 tests passed with 2 skipped, followed by the isolated
pressure test passing 1/1.
- `pnpm run typecheck`: passed after the final interaction changes.
- `pnpm run lint:check`: passed with 0 errors; it retained 5 pre-existing warnings in
`src/pages/Home/index.tsx` and `src/pages/Makelore/index.tsx`.
- `pnpm run build:vite`: passed after the final interaction changes; only the repository's
existing Browserslist, dynamic-import, and chunk-size warnings were emitted.
- Electron E2E `project-configuration-skills.spec.ts`: passed 1/1, including zero-model
guidance, legacy `initialized: true` plus zero-Agent recovery, and labelled return to chat.
- Playwright trace inspection showed an initial E2E failure was caused by that spec's later
restrictive Host API stub, not product navigation; the navigation assertion now runs
before the stub and passes.
- Independent read-only review found the disabled-only recovery loop; after the targeted
correction and test, the reviewer returned PASS.
- `git diff --check`: passed.
- Task Documentation Gate remains blocked because merging current `main` introduced the
unchanged foreign task record
`.project-docs/30-worklog/tasks/20260906-agent-browser-failure-a7c91e4d.md` relative to
this task's older recorded base. The record was not modified by this task.
## Follow-ups
- If the recommended direction is accepted, implement one shared readiness predicate and
cover zero Agents, all Agents archived, no configured model, first Agent completion,
deterministic return/continue navigation, unsaved changes, and chat recovery.
- Update README only with the accepted final interaction behavior, not this discussion or
a historical worklog.
- Obtain explicit human confirmation for the project-doc recovery required to adopt the
unchanged foreign task record brought in by the already-created, unpushed `main` merge;
then rerun `check_doc_drift.py`, set this record to Ready for Integration, commit the
result, and run `task_context.py complete`.
## Promotion Candidates
- None recorded.
- Target: `.project-docs/30-worklog/current-state.md`.
Proposal: record that Coding Conversation readiness requires both persisted
initialization and at least one enabled, unarchived, fully configured project Agent;
all project-entry and chat-recovery surfaces share this invariant, and the first Agent
setup is the explicit completion path.
Evidence: shared readiness tests, Project Configuration onboarding tests, App/MainLayout
route tests, Coding chat recovery tests, Electron E2E, successful full unit suite,
typecheck, lint, production build, and independent review.
Future impact: future project-entry, archival, or Agent-edit work must reuse the shared
predicate rather than treating `initialized` as sufficient on its own.
Semantic conflicts: none known; the rule preserves the existing no-default-Agent and
project-owned Agent decisions.
Human confirmation required: no, unless integration discovers a conflicting accepted
product decision.