Add Runtime v2 implementation skeleton - #5
Merged
likun666661 merged 1 commit intoJun 14, 2026
Conversation
jackwener
pushed a commit
that referenced
this pull request
Jun 21, 2026
Add Runtime v2 implementation skeleton
jackwener
added a commit
that referenced
this pull request
Jun 21, 2026
…doc-merge) 1. **iframe sandbox/CSP language tightened** (@kenji #1): - Remove the "separate webContents partition + permissive CSP for iframe" promise — DOM `<iframe>` doesn't get an independent partition without `<webview>` / BrowserView. Don't promise what the DOM can't deliver. - Add `allow-forms` and `allow-modals` to the not-allowed list - Switch from `src="file://..."` to `srcdoc={await readText()}` so content delivery goes through the path-guard read helper - Note that global CSP `default-src 'self'` stays locked — sandbox attribute carries all isolation 2. **Symlink-aware path guard** (@kenji #2): - Both `realpath(artifactRoot)` AND `realpath(target)` required, then containment check - Mirror PR56 open-path-guard which already has symlink-escape + `..` + URL-scheme test coverage 3. **readBinary MIME allow-list** (@kenji #3): - Allowlist: image/png/jpeg/gif/webp/svg+xml, application/pdf - MIME sniffed at read time, NOT trusted from record.kind or record.mimeType - Unknown → `reason: 'unsupported_mime'` + UI shows metadata + "在 Finder 中打开" / "另存为" actions (no raw bytes to renderer) 4. **Deleted tombstone blocks reads** (@kenji #4): - `status: 'deleted'` records immediately return `reason: 'deleted'` from readText / readBinary — even if the underlying file still exists on disk - Surface table updated: deleted row preview shows "此 artifact 已 删除,预览已停止" - Permanent path purge is a separate Settings · 数据 flow 5. **PR108c runtime hook scope** (@kenji #5): - First version does NOT do LLM extractor - Only deterministic outputs: Write→file record, Edit→diff record, Bash with explicit redirect → file record - stdout/stderr NOT auto-promoted (noise) - LLM extractor (parse ```html``` from assistant message) deferred to PR109+ Also: type rename `storagePath` → `relativePath` to enforce contract in the type system; full reason union widened on both read helpers. doc total: 1416 lines.
jackwener
added a commit
that referenced
this pull request
Jun 21, 2026
…inese-first labels, stub views for non-implemented modules Implements the IA refactor WAWQAQ locked in msg `b86b47d1`: the sidebar's second part is now a top-level 5-module nav (会话 / 搜索 / 计划 / 技能 / 每日回顾) rather than session filter tabs. Pinned / Archived / Chats become internal Sessions filters. Settings stays at the bottom; a placeholder 版本更新 button sits above it. Per xuan `47e204f2` priorities applied directly: - #2 IA: top-level modules; filters moved into Sessions. - #4 visual hierarchy: nav rows reuse `.maka-nav-row` (transparent bg, accent-tinted selected state, no card stacking). - #5 Chinese-first naming throughout the surface; English stays as accessible keywords in the command palette. - #7 Search nav item placeholder for Phase 4 modal; clicking now switches the section to `'search'` and renders an empty-state stub. Phase 4 will swap the section switch for an `onOpenSearchModal()` callback (already plumbed through props). - #8 disabled / hover / focus states pinned for the Update placeholder (aria-disabled + data-disabled + CSS dim). == Type-level changes == `packages/ui/src/components.tsx`: export type NavSelection = | { section: 'sessions'; filter: SessionFilter } | { section: 'search' } | { section: 'automations' } | { section: 'skills' } | { section: 'daily-review' }; // New module label map (Chinese-first): const MODULE_NAV_LABEL: Record<NavSelection['section'], string> = { sessions: '会话', search: '搜索', automations: '计划', skills: '技能', 'daily-review': '每日回顾', }; == SessionListPanel JSX shape == <aside> <header>新建对话 button</header> <nav.maka-sidebar-modules> 5 module nav rows (NEW) <div.maka-session-filter hidden={!sessions}> Pinned/Chats/Archived <div.maka-session-search hidden={!sessions}> session-name search <section.maka-session-list> ├ skills view (existing, reused for `selection.section==='skills'`) ├ sessions view (existing, when 'sessions') └ STUB_VIEWS[section] (search / automations / daily-review) <footer.maka-session-panel-footer> ├ 版本更新 button (NEW; UI placeholder, aria-disabled by default) └ 设置 button (existing; renamed from "Settings") </aside> Skills no longer appears in the footer — it lives in the top-level module nav alongside the other 4. The chat surface (`ChatPanel`) shows a neutral "从 会话 选择对话" message when the active section is `search` / `automations` / `daily-review`. == Persistence == `apps/desktop/src/renderer/main.tsx readNavSelection`: recognizes `search` / `automations` / `daily-review` as valid section variants when restoring from localStorage. Corrupted entries fall back to `{ section: 'sessions', filter: 'chats' }`. == CSS == `apps/desktop/src/renderer/styles.css`: .maka-session-panel grid-template-rows: auto auto auto auto minmax(0, 1fr) auto; /* Row 2 is the new module nav. Phase 1's `.maka-session-list` grid * fix (auto + minmax(0, 1fr)) and `.maka-list-stack` overflow:auto * are preserved verbatim. */ .maka-sidebar-modules { display: grid; gap: 2px; padding: 4px 8px; } /* Disabled nav-row dimming (used by 版本更新 placeholder). */ .maka-nav-row[aria-disabled="true"], .maka-nav-row[data-disabled="true"] { cursor: not-allowed; opacity: 0.55; } .maka-nav-row[aria-disabled="true"]:hover, .maka-nav-row[data-disabled="true"]:hover { background: transparent; } == Tests == core 392 / storage 50 / runtime 103 / desktop 645 = 1190 pass. Typecheck + build green across all workspaces. Phase 1's CSS contract test still passes (grid + min-height + overflow pins survive the IA refactor). == Out of scope (Phase 3 / 4) == - Session row slimming (~85px → ~32px). Phase 3. - Search modal implementation. Phase 4 (resurrects `useThreadSearch` from `yuejing/pr-search-2.6`; swaps current Search stub for modal trigger). - Real auto-update wiring (Electron updater). Future PR-AUTOUPDATE-0. - Automations / Daily Review feature implementation. Future PR-TIME-* / PR-DAILY-*. Anchors: WAWQAQ msg `b86b47d1` + `f5f6f834` (IA + Skills inclusion + Update button). xuan msg `47e204f2` (8-point priority list); `dc790a54` (Phase 1 scope refinement); `adcf0c95` (per-phase gate workflow). kenji msg `fcd9c54f` (consolidated packet design); `0f7bb872` (scroll P0 architecture). Branch base: `655a09f` (Phase 1 + fixup, on top of main `809875a`).
jackwener
added a commit
that referenced
this pull request
Jun 21, 2026
…l + 版本更新 passive (4 nits + capability state CSS) WAWQAQ msg `1893c08e` 没动静 → starting PR-UX-POLISH-1 in parallel with kenji's PR-DESKTOP-SMOKE-0 instead of waiting on the Sidebar resize verdict. Commit lands on top of `yuejing/pr-sidebar-ia-0` so it merges as a stack once Sidebar is greenlit. Per ratified scope (yuejing UX audit msg `9c779b56` + xuan + kenji boundary 1 closed-state enum): 1. Filter input shortcut hint corrected: `筛选会话… F 聚焦` → `筛选会话… ⌘F 聚焦` The actual binding is ⌘F (Meta+F) via the existing `useEffect` in `SessionListPanel`; the lone `F` placeholder was misdocumenting the chord. 2. Composer streaming hint disambiguated from reasoning stream: `Maka 正在思考…` → `Maka 正在回答…` (zh) `Maka is thinking…` → `Maka is responding…` (en) ReasoningPanel still uses `正在思考…` / `Thinking…` for the model's extended-thinking stream. Distinct signals now have distinct copy — composer = output-streaming; ReasoningPanel = reasoning-streaming. 3. Sidebar group label visual gap: Without `display: flex; gap` on `.maka-list-group-label`, the `<span>label</span><span>count</span>` rendered as `会话65` (no separator). Added `display: flex; align-items: baseline; gap: 6px` so the rendered form is `会话 65` (or with future bullet separator: `会话 · 65`). 4. 版本更新 footer entry switched from aria-disabled fake-button to passive `data-state="coming_soon"` informational tag with small `即将推出` badge. Removes the "looks tappable but does nothing" affordance. When `onOpenUpdate` IS wired (future PR-AUTOUPDATE-0), the button form returns automatically. This is the first integration of the capability presentation enum (kenji boundary 1, msg `88a9f29d`): UI consumes the state via props, never derives `operational` from token/config presence. CSS adds `.maka-nav-row[data-state="coming_soon"]` styling + `.maka-nav-row-state-badge` pill for the "即将推出" chip. The closed enum (`available / coming_soon / needs_config / blocked_by_permission / disabled_by_policy / unsupported_platform`) is documented in `notes/pr-ux-polish-1-gate.md`. Eyebrow icon variety (audit P2 #5) skipped — re-examined source and setup heroes already use varied icons (SettingsIcon, KeyRound, Cpu, AlertCircle via SetupHero); only NeedsConnectionHero and ReadyEmptyHero still use Sparkles which is correct for those states. Stale pill tone (audit P1 #4) skipped — already amber-toned (`--warning` token at 0.18 alpha + warning-text); the only weak signal is the 0.7 opacity row dim, which is the intentional secondary signal. Gates: - typecheck clean, UI + renderer build clean - desktop tests: 643 pass / 0 fail (no test additions yet — capability enum contract test arrives in commit 2 alongside the search-service rename + daily-review consolidation + permission-center cleanup + modal backdrop token unification) - core tests: 392 pass Subsequent commits in this PR (commit 2+): - Permission Center "即将可用" hide / change to passive copy - Settings · 搜索服务 → 联网搜索 rename - Daily Review Settings sub-page consolidation - Modal backdrop token unification - `? 快捷键` sidebar chip (small a11y discoverability add) - Extend visible-copy-hygiene-contract with capability enum presentation gate (no `coming_soon` should render as <button> without explicit `data-state="coming_soon"`)
jackwener
pushed a commit
that referenced
this pull request
Jun 21, 2026
Add Runtime v2 implementation skeleton
jackwener
added a commit
that referenced
this pull request
Jun 21, 2026
…doc-merge) 1. **iframe sandbox/CSP language tightened** (@kenji #1): - Remove the "separate webContents partition + permissive CSP for iframe" promise — DOM `<iframe>` doesn't get an independent partition without `<webview>` / BrowserView. Don't promise what the DOM can't deliver. - Add `allow-forms` and `allow-modals` to the not-allowed list - Switch from `src="file://..."` to `srcdoc={await readText()}` so content delivery goes through the path-guard read helper - Note that global CSP `default-src 'self'` stays locked — sandbox attribute carries all isolation 2. **Symlink-aware path guard** (@kenji #2): - Both `realpath(artifactRoot)` AND `realpath(target)` required, then containment check - Mirror PR56 open-path-guard which already has symlink-escape + `..` + URL-scheme test coverage 3. **readBinary MIME allow-list** (@kenji #3): - Allowlist: image/png/jpeg/gif/webp/svg+xml, application/pdf - MIME sniffed at read time, NOT trusted from record.kind or record.mimeType - Unknown → `reason: 'unsupported_mime'` + UI shows metadata + "在 Finder 中打开" / "另存为" actions (no raw bytes to renderer) 4. **Deleted tombstone blocks reads** (@kenji #4): - `status: 'deleted'` records immediately return `reason: 'deleted'` from readText / readBinary — even if the underlying file still exists on disk - Surface table updated: deleted row preview shows "此 artifact 已 删除,预览已停止" - Permanent path purge is a separate Settings · 数据 flow 5. **PR108c runtime hook scope** (@kenji #5): - First version does NOT do LLM extractor - Only deterministic outputs: Write→file record, Edit→diff record, Bash with explicit redirect → file record - stdout/stderr NOT auto-promoted (noise) - LLM extractor (parse ```html``` from assistant message) deferred to PR109+ Also: type rename `storagePath` → `relativePath` to enforce contract in the type system; full reason union widened on both read helpers. doc total: 1416 lines.
jackwener
pushed a commit
that referenced
this pull request
Jun 21, 2026
Add Runtime v2 implementation skeleton
jackwener
added a commit
that referenced
this pull request
Jun 24, 2026
…ts (#211) Kenji aesthetic-audit reminder 9 (msg `bacde601` 2026-06-24, finding #5): three streaming-state indicator dots have the same semantic ("live work happening") but their pulse amplitudes drifted: - `.maka-list-row-streaming-dot` keyframe at styles.css:2231 — `scale(1.1)` - `.maka-reasoning-panel-dot` keyframe at styles.css:11645 — `scale(1.15)` - `.maka-tool-output-stream-pulse` keyframe at styles.css:12634 — `scale(1.18)` The amplitudes pile up when more than one is visible at the same time (e.g. user in a turn that's streaming text AND a tool call is in flight) and the screen reads as agitated. Fix: settle all three to `scale(1.1)` — the calmest of the three because these dots run continuously while a turn is streaming and the larger pulses are visually loud at that frequency. List-row dot was already at 1.1 so this is a unification at the existing low end, not a raise. Single file, two keyframe value tweaks. Existing PR-202 styles.css edits are in different regions (onboarding rules + cubic-bezier sweep on transition values, not @Keyframes scale values), so no overlap.
This was referenced Jun 24, 2026
jackwener
added a commit
that referenced
this pull request
Jun 25, 2026
Per @kenji audit `26a221be` against #237 main `4e0247f6`: **#1 — bottom 「想先看看效果?」 hero buttons left-aligned.** PR #236 right-aligned the top 「打开每日回顾」 button via `.settingsFeatureStatusHeroActions` but the bottom 「生成每日回顾 / 生成深度分析」 row still used inline `style={{ display: 'flex', gap: 8, marginTop: 8 }}`, so it stayed glued to the paragraph margin. Route the bottom row through the same class. Add `gap: 8px` to the class so multi-button clusters keep proper spacing. **#2 — 执行时间 disabled when the master switch is off.** The disable condition was `formDisabled || savingKey === 'executeTime' || !(effectiveConfig?.enabled ?? false)`. That last clause blocked the common UX of "pick a time first, then turn it on". Drop it — the time value is harmless to edit while disabled (it doesn't fire until the switch flips), and the disabled state was misread as "broken UI". **#3 — 分析模型 default-row label still verbose.** WAWQAQ's directive: "所有模型选择只用模型名". PR #236 went from `使用对话默认模型(Codex OAuth · email · gpt-5.5)` to `对话默认(gpt-5.5)` — better, but the model id parenthetical still mixes "selectable model" with "follow chat default". Per @kenji's "don't conflate the two semantics", the default row becomes plain `跟随对话默认`; the explicit options carry the model id. **#4 — duplicate model ids across connections looked unselectable.** When two enabled connections both expose `gpt-5.5`, the flat `model`-only labels read as two identical entries. Detect the collision at build time and append `· ${connection.name}` ONLY to the colliding entries; unique model ids stay terse per WAWQAQ's directive. Deferred (with @kenji concurrence): - **#5** (`data-control-width` semantic API replacing CSS-selector width patches) — pure refactor, no end-result change. WAWQAQ explicitly said 「只看最后的结果」. - **#6** (collapse Daily Review hero card pile into a single grouped settings surface) — bigger visual restructure judgment call; needs WAWQAQ sign-off before swinging at the whole page layout.
5 tasks
jackwener
added a commit
that referenced
this pull request
Jun 25, 2026
…#244) Bundled response to @kenji audit findings #5 + #6 (msg `26a221be`) plus the page-restructure WAWQAQ explicitly authorized (thread msg `afbe542d`: 「一次性多改,别他妈分这么多轮」). **Finding #6 — Daily Review settings page restructure.** Removed the two `.settingsFeatureStatusHero` cards (intro + 「想先看看 效果?」). They were promo chrome on a workbench settings surface and duplicated information the section banner already carries. The 「打开每日回顾」 / 「生成每日回顾」 / 「生成深度分析」 actions are now folded into a single right-aligned `.settingsPageFooterActions` toolbar rendered below the rows. Net: one banner, one grouped rows surface, one action footer — no card pile. The `.settingsFeatureStatusHero*` CSS rules stay because the voice settings page still uses them; this PR just drops Daily Review's dependency on them. **Finding #5 — semantic width attr instead of class-selector patches.** `.settingsRow > .settingsTimeInput` and `.settingsRow > .settingsBaseSelectTrigger` were globally-scoped selectors that implicitly assumed the row contained one specific control type. Move the contract to a `data-control-width="compact| select"` attribute on the row itself; mark the 执行时间 and 分析模型 rows accordingly. The old global rules are gone — only the data-attr rules survive. Verified the 4 other `SettingsSelect` call sites (proxy host, gateway host, bot domain, usage filter) are inside `.settingsField`, not `.settingsRow`, so they aren't affected by the dropped rule.
6 tasks
jackwener
added a commit
that referenced
this pull request
Jun 25, 2026
@kenji audit thread `#my-ai:4821a792` msg `e4cfbfb0` vs main `71d88454`. WAWQAQ msg `782a1663` + `继续`: bundle these, don't split. **#1 — Memory page top control rows had no outer card surface.** The three control rows (本地 MEMORY.md / 模型上下文可读取 / 项目指令 文件) were direct children of `.settingsStructuredPage`, which is transparent. `.settingsFormRow` only carries a hairline bottom border, so users saw three floating rows without the grouped-card visual every other settings surface uses. Wrap them in `.settingsRows` so they inherit the 12px outer border + radius + overflow:hidden treatment. **#2 — Plan Reminder delivery picker showed text-only IM channels.** Settings → 机器人对话 switched to real brand logos (Iconify simple-icons) in #BOT-SETTINGS-UI-0, but the chat-side Plan Reminder delivery flow's `平台` select was still rendering plain Chinese labels. Same channels should read the same everywhere. - Move `BOT_BRAND` to `packages/ui/src/bot-brand.ts` so both surfaces share a single brand-metadata source instead of one duplicating the other. - Extend `PlanReminderSelect` to accept a third tuple slot (optional `ReactNode` icon); `PlanReminderPanel` now passes an `<IconifyIcon icon={brand.iconifyId}>` per provider with the existing offline glyph fallback. - Update `SettingsModal.tsx` to import `BOT_BRAND` from `@maka/ui` instead of declaring a local copy. **#5 — Two inline `style={{ marginTop }}` spacing patches.** - `Alert variant="error" style={{ marginTop: 12 }}` → `className= "settingsSurfaceAlert"`. - `<div className="settingsActionRow" style={{ marginTop: 8 }}>` → `className="settingsActionRow settingsNoticeAction"`. The new classes pin the spacing decision in CSS where the design tokens live, instead of inline JSX. Deferred per kenji's own scope note + WAWQAQ 「只看最后的结果」: - **#3** (`RadioCard` / `ChoiceCard` primitive for theme/palette picker) — pure design-system refactor, no visible delta on Settings → 外观. - **#4** (`SettingsSelect` uplift to rich-option contract) — bigger cross-cutting refactor; current fix covers the immediate model-name and disambiguation issues kenji raised in round 1. - **#6** (layout-property transitions in sidebar/tabs/accordion) — kenji explicitly flagged these as visual-smoke-gated; will land alongside the smoke config in a separate PR.
4 tasks
jackwener
added a commit
that referenced
this pull request
Jun 25, 2026
… dvh (#250) @kenji audit msg `232aec0f` (`#my-ai:c28a6293`). Round 3 against `af66ebb7` post-#249. **#2 — Plan Reminder select collapsed state was text-only.** PR #247 added a brand icon to each `<SelectItem>`, but `<SelectValue />` defaulted to rendering just the label string — open dropdown showed a logo, collapsed trigger showed plain text. Build a `value → { label, icon }` lookup inside `PlanReminderSelect` and pass a function-child to `SelectValue` so the picked state renders the same icon + label row the dropdown items render. **#6 — `100vh` residue in renderer CSS.** Four sites still on `100vh`: - `maka-tokens.css:760` `.maka-shell` `height` - `maka-tokens.css:1941` `.maka-modal` `max-height: calc(100vh - 80px)` - `styles.css:5028` `.maka-help-modal` `max-height: calc(100vh - 96px)` - `styles.css:13121` `.maka-onboarding-stack` `min-height: calc(100vh - 84px)` Replace each with `100dvh` so Electron browser frames with dynamic chrome (or a future mobile-style viewport) don't get half a viewport of height calculation drift. Other renderer surfaces already use `100dvh`; this brings the legacy four into line. Deferred per kenji's own scope: - **#1** feishu/dingtalk official-brand-kit sourcing — separate PR. - **#3 / #4** SettingsSelect / Segmented / ChoiceCard primitive unification — design-system refactor; no end-result delta on its own. - **#5** layout-property transitions in sidebar/tabs/accordion — kenji explicitly gated on visual smoke harness.
7 tasks
anaconda110
added a commit
to anaconda110/maka-agent
that referenced
this pull request
Aug 3, 2026
… (P1 apache#5) The previous MainApplication.kt diverged from the RN 0.79.7 official template (@react-native-community/template@0.79.7) in ways that risk compile/runtime failure under the bridgeless ReactHost path: - reactNativeHost was a plain ReactNativeHost anonymous object. The getDefaultReactHost(context, reactNativeHost) overload (DefaultReactHost.kt:287) requires a DefaultReactNativeHost (it does `require(reactNativeHost is DefaultReactNativeHost)`), so this would throw at runtime. Switched to DefaultReactNativeHost, overriding isNewArchEnabled/isHermesEnabled from BuildConfig so the host reports the correct engine/arch flags. - getReactHost() was declared as `override fun getReactHost(): ReactHost`, but ReactApplication#reactHost is a property (`val reactHost: ReactHost?`). Changed to `override val reactHost: ReactHost` (Kotlin property form), matching the template and the interface. - MainApplication did not implement ReactApplication. Added the interface so the RN gradle plugin / tooling can locate the host via the standard contract. - SoLoader.init used the legacy 2-arg SoLoader.init(this, false). Switched to the template's SoLoader.init(this, OpenSourceMergedSoMapping), which is the 0.79.7 public API for so-merging JNI_OnLoad registration. - DefaultNewArchitectureEntryPoint.load() is now imported statically and called as load(), matching the template; the IS_NEW_ARCHITECTURE_ENABLED gate is preserved (P0 apache#4). Aligns with .hive/android-code-review.md P1 apache#5.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Verification
Notes
This PR is intentionally stacked on runtime-v2-architecture-doc to keep the architecture document PR separate from the implementation skeleton.