diff --git a/.project-docs/30-worklog/tasks/20261013-hide-home-robot-6c1f8a3d.md b/.project-docs/30-worklog/tasks/20261013-hide-home-robot-6c1f8a3d.md
new file mode 100644
index 00000000..5a8ee659
--- /dev/null
+++ b/.project-docs/30-worklog/tasks/20261013-hide-home-robot-6c1f8a3d.md
@@ -0,0 +1,67 @@
+# Task: Hide Robot home entry and arrange three modules
+
+## Identity
+
+- Task ID: 20261013-hide-home-robot-6c1f8a3d
+- Mode: Feature
+- Branch: codex/20261013-hide-home-robot-6c1f8a3d-hide-home-robot
+- Worktree: /Users/chillishark/Makelore 麦洛/.codex-worktrees/makelore/20261013-hide-home-robot-6c1f8a3d
+- Base commit: 23ddce11da5c4c7aa31af81213a5aafd474cdad0
+- Owner: codex
+- Status: Ready for Integration
+
+## Scope
+
+- Hide Robot only from the home module selection. Arrange Agents, Code and Canvas as three equal desktop cards and single-column compact cards, preserving existing artwork and navigation contracts.
+
+## Intent And Constraints
+
+- User explicitly requests Robot home-entry hiding and remaining-entry re-layout. Prior direction still defers temporary-app updates. Preserve global Robot definition, routes, permissions and capabilities; do not restart existing apps, publish, push, merge main or adopt peer changes.
+
+## Outcome
+
+- Robot is filtered only in home selection; global module definitions, Robot routes/APIs and policy access are unchanged. Agents, Code and Canvas share an equal-width desktop row beneath the centered welcome heading, with proportional card heights; below 768px they use a single vertical column of horizontal image/text cards. Existing artwork, click hit areas, disabled states and hover/focus behavior are preserved. README and navigation regressions match.
+
+## Verification
+
+- Module navigation unit tests: 9/9 passed, including hidden Robot with enabled permission, Canvas/Code routing, disabled policy, login/profile gates and Robot sidebar identity.
+- Pinned pnpm 10.33.4: typecheck, scoped ESLint and production build:vite passed. Build repeated after visual review reduced extra card whitespace at 768px.
+- Targeted Electron navigation fixtures: 3/3 passed (layout, retired Learning route, sidebar return plus direct Robot route); layout fixture rechecked after final CSS refinement, 1/1 passed.
+- Layout geometry and screenshots checked at 1440, 1024, 768 and 375px: equal columns/gaps, compact stack, loaded artwork, text/page overflow checks, whole-card click area and stable hover/focus.
+- git diff --check and task-aware project document drift check passed. Test Electron instances use independent temporary profiles; existing temporary/installed applications are unchanged.
+- Dependencies reused through an ignored node_modules symlink. No runtime data, dependencies, build/test output or secrets included in commits.
+
+## Follow-ups
+
+- Integrate this source commit into the code chosen for the next temporary-app update. No current temporary-app update/restart, main merge, push or publication was performed.
+
+## Promotion Candidates
+
+- Target: integrated module-selection/current-state documentation.
+- Proposal: home offers Agents, Code and Canvas only, with an equal desktop row and compact vertical stack. Robot remains a supported guarded route/capability whose home card is hidden.
+- Evidence: explicit screenshot request, focused source diff, 9 unit tests, 3 Electron cases and four-size visual/geometry review.
+- Future impact: later home UI work should preserve three visible entries unless explicitly changed. This supersedes historical four-card home presentation only; module policies and Robot capability remain unchanged. Human confirmation is already supplied; canonical promotion remains serialized integration work.
+
+## Project Context Loaded
+
+- Task ID: 20261013-hide-home-robot-6c1f8a3d; feature mode.
+- Branch: codex/20261013-hide-home-robot-6c1f8a3d-hide-home-robot.
+- Worktree: /Users/chillishark/Makelore 麦洛/.codex-worktrees/makelore/20261013-hide-home-robot-6c1f8a3d.
+- Base: 23ddce11da5c4c7aa31af81213a5aafd474cdad0 (latest locally fetched origin/main). start exited 0; status JSON confirms identity, branch, root, mode and reservation.
+- Read: AGENTS; entry/read-before-planning, memory-index and planning-gate; this task; positioning, current-state, decision-index/system-overview; business-rules and success-criteria; related accepted navigation/permission context. Same-task read-only subagent reviewed required context and every peer Scope/Intent/Promotion.
+- Project goal: student/creator desktop creation with Main-owned authentication/service access and a single light visual system.
+- Current integrated focus: combined personal Agent UI and runtime release, separate homepage module display.
+- Active scope/constraints: only hide one home choice and balance the other three; keep underlying Robot access and module-policy denial semantics.
+- Other active tasks: Canvas session diagnosis and knowledge workspace; retained teacher/docs tasks, including a legacy child-language task with undefined scope. No concrete homepage dependency or semantic conflict. All other worktrees remain read-only.
+- Decisions: older four-card vertical home layout is superseded only by this user's explicit hide/re-layout instruction. Robot remains a supported guarded module; missing/denied permissions keep existing handling.
+- Evidence/commitments: existing module-navigation unit tests and main-navigation Electron fixtures available; no external or timed obligation.
+- Modules: ModuleSelection/index.tsx, scoped module card CSS in globals.css, navigation tests and README.
+- Unknown/stale context: older AGENTS/module counts and integrated memory include historical three/four-module summaries; feature mode records promotion candidates instead of rewriting accepted docs.
+- Gate result: Passed.
+
+## Plan
+
+- Filter Robot only in home rendering; center the greeting above a three-column desktop grid and use horizontal single-column cards below 768px.
+- Preserve artwork, hover/focus stability, policy-disabled states, login/profile gates and navigation destinations.
+- Adapt focused unit/Electron regressions and check actual layout at wide/narrow windows, typecheck, lint and production build.
+- Update README and this task record; commit a tested source handoff without changing current app runtime.
diff --git a/README.md b/README.md
index 9447b4ef..ef527d5f 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
Code 会话保存的模型被下架后,会提示重新选择可用模型;用户可在原会话中切换,恢复时使用新选择并保留会话与历史消息。切换不会自动重发消息或自动选择替代模型。
-Makelore 是一个面向软件、视觉创作、智能机器人与个人云智能体的 AI 桌面工作台。当前版本为 `2.0.0`,源码提供四个模块入口;云智能体需配套配置 WS/Yuxi 服务。模块入口页按 Agents、Code、Canvas、Robot 排列,统一采用横向插画卡片;Agents 标语为“打造你想象中的AI助手”。工作区左上角入口点击后返回模块入口页:
+Makelore 是一个面向软件、视觉创作、智能机器人与个人云智能体的 AI 桌面工作台。当前版本为 `2.0.0`,首页展示 Agents、Code、Canvas 三个模块入口,Robot 入口隐藏;云智能体需配套配置 WS/Yuxi 服务。三个入口在桌面等宽并排、插画在上文字在下,小窗口改为纵向排列的横向插画卡片;Agents 标语为“打造你想象中的AI助手”。工作区左上角入口点击后返回模块入口页:
- `Makelore Code|AI 编程`:管理本地项目、项目智能体、对话、文件上下文、代码变更和运行时。
会话工作台采用浅蓝项目栏、彩色通用手柄图标与卡片选中态;中间对话/作品使用圆角标签,作品预览的后退、前进、刷新与网址输入统一放在标签右侧;只在作品页显示,窄窗口自动换行。右侧智能体咨询使用奶油色标题区。沿用真实项目和会话入口、侧栏伸缩与账户菜单,样式只作用于 Code 会话工作台。可编辑的空对话在输入区上方的可用区域中央显示童趣欢迎语;「去作品广场逛逛」入口紧贴输入框上方,两者一起位于底部。老师介绍以固定宽度浮在右上角,不占用中间布局;欢迎语和底部输入区始终相对项目栏右侧的整个内容区域居中;小窗口的欢迎内容独立滚动;发送首条消息后收起欢迎区。侧栏保留「作品广场」入口,只有点击后才在系统浏览器打开公共广场,不请求、摘取或内嵌展示广场作品。打开广场保留当前项目、对话、草稿和附件,不自动发送消息;老师求助按钮保留临时应用的最新文案「帮我整体看🧠」。
diff --git a/src/pages/ModuleSelection/index.tsx b/src/pages/ModuleSelection/index.tsx
index 91989e4a..80fe3c57 100644
--- a/src/pages/ModuleSelection/index.tsx
+++ b/src/pages/ModuleSelection/index.tsx
@@ -57,8 +57,8 @@ export function ModuleSelection({ authRequired = true }: { authRequired?: boolea
-
{userDisplayName ? `${userDisplayName},欢迎回来!` : '欢迎回来!'}
@@ -70,7 +70,7 @@ export function ModuleSelection({ authRequired = true }: { authRequired?: boolea aria-label="AI 模块列表" className="module-selection-options" > - {aiModules.map((module) => { + {aiModules.filter((module) => module.id !== 'robot').map((module) => { const content = moduleSelectionContent[module.id]; const enabledByPolicy = isAiModuleAllowed(module.id, moduleAccess); const enabled = module.enabled && enabledByPolicy; diff --git a/src/styles/globals.css b/src/styles/globals.css index ce9b88c4..46051094 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -423,7 +423,8 @@ display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--module-option-gap); - width: min(100%, 43rem); + width: min(100%, 69rem); + margin-inline: auto; min-width: 0; justify-self: center; align-items: stretch; @@ -497,7 +498,7 @@ flex-direction: column; justify-content: center; padding: clamp(0.75rem, 1.6vw, 1.25rem); - padding-right: clamp(2.75rem, 5vw, 4rem); + padding-right: clamp(0.75rem, 1.6vw, 1.25rem); } .module-option-card-title { @@ -517,6 +518,38 @@ line-height: 1.25; } +@media (min-width: 768px) { + .module-selection-options { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .module-selection-options .module-option-card { + height: auto; + min-height: clamp(17.5rem, 24vw, 21rem); + } + + .module-selection-options .module-option-card-surface { + position: relative; + flex-direction: column; + overflow: hidden; + height: 100%; + } + + .module-selection-options .module-option-card-image { + flex: 0 0 auto; + width: calc(100% - 0.125rem); + height: auto; + aspect-ratio: 16 / 10; + margin: 0.0625rem 0.0625rem 0; + border-radius: 0.75rem 0.75rem 0 0; + } + + .module-selection-options .module-option-card-content { + justify-content: flex-start; + padding: 1.25rem; + } +} + .module-option-card.module-option-card-disabled::before, .module-option-card.module-option-card-disabled::after { display: none; diff --git a/tests/e2e/main-navigation.spec.ts b/tests/e2e/main-navigation.spec.ts index cf9f9590..974eed21 100644 --- a/tests/e2e/main-navigation.spec.ts +++ b/tests/e2e/main-navigation.spec.ts @@ -200,7 +200,7 @@ test.describe('Makelore module navigation without setup flow', () => { } }); - test('keeps the four module entries in a proportional vertical stack while resizing the window', async ({ launchElectronApp }) => { + test('lays out three module cards in a desktop row and a compact mobile stack', async ({ launchElectronApp }) => { const app = await launchElectronApp({ skipSetup: true }); try { @@ -209,17 +209,18 @@ test.describe('Makelore module navigation without setup flow', () => { const moduleCards = page.locator('[data-testid^="ai-module-option-"]'); await expect(moduleCards.locator('.module-option-card-title')).toHaveText([ - 'Agents 智能体', 'Code 编程', 'Canvas 设计', 'Robot 机器', + 'Agents 智能体', 'Code 编程', 'Canvas 设计', ]); + await expect(page.getByTestId('ai-module-option-robot')).toHaveCount(0); await expect(moduleCards.first().locator('.module-option-card-description')).toHaveText('打造你想象中的AI助手'); - await expect(moduleCards.locator('img')).toHaveCount(4); + await expect(moduleCards.locator('img')).toHaveCount(3); await expect.poll(async () => await moduleCards.locator('img').evaluateAll((images) => images.every((image) => image.complete && image.naturalWidth > 0), )).toBe(true); - await page.screenshot({ path: test.info().outputPath('module-entry-artwork.png') }); const readCardMetrics = async () => await moduleCards.evaluateAll((elements) => elements.map((element) => { const bounds = element.getBoundingClientRect(); const image = element.querySelector('.module-option-card-image')?.getBoundingClientRect(); + const content = element.querySelector('.module-option-card-content')?.getBoundingClientRect(); return { left: bounds.left, top: bounds.top, @@ -227,70 +228,59 @@ test.describe('Makelore module navigation without setup flow', () => { height: bounds.height, imageWidth: image?.width ?? 0, imageHeight: image?.height ?? 0, + imageLeft: image?.left ?? 0, + imageTop: image?.top ?? 0, + contentLeft: content?.left ?? 0, + contentTop: content?.top ?? 0, }; })); - const initialMetrics = await readCardMetrics(); - expect(initialMetrics).toHaveLength(4); await expect(moduleCards.first().locator('.module-option-card-arrow')).toHaveCount(0); await expect(moduleCards.first().locator('.module-option-artwork')).toHaveCount(0); - await expect.poll(async () => await moduleCards.first().evaluate((element) => { - const surface = element.querySelector