Add source-backed serving quantities, preparation checklists, cooking progress and supplementary step links. Preserve the adaptive tabletop layout and conservative fallbacks for unresolved recipe quantities.
Validate 232 annotated recipes, Web and CookCore tests, and 25 local iPad tests. Record unresolved source questions in docs/dev/recipe-amount-review.md.
Keep private Support feedback receipts, drafts, retries and demand-wall links while adding category presets and optional mail fallback.
Complete native recipe contribution and verify failure recovery on iPhone and iPad. Select Xcode-compatible simulator pairs and test devices sequentially in CI.
* feat(feedback): route private app feedback through Support SDK
* fix(feedback): load shared light and dark design tokens
* build(feedback): pin documented Support SDK release archive
* build(feedback): bundle SDK dependencies for CloudBase deployment
* docs(feedback): use the verified deployment bundle in data guide
* fix(feedback): route signed-out web submissions through guest HTTP
Add seven requested ingredients, common aliases, 20 recipes, and persistent ingredient expansion on Web and iOS.
Exclude recipes with unsupported main ingredients and refresh shared fixtures. Verified recipe validation, 282 tests, lint, typecheck, production build, and CookCore CI.
* feat(feedback): app feedback and an HTTP entry for the native app
- cook-feedback: new `feedback` action (category, note, optional contact,
platform) stored in cook_app_feedback; POST bodies over the HTTP trigger
run report / signal / feedback for the iOS app, GET stays the token export
- web: 我的 → 问题反馈 submits in the app, falls back to GitHub Issues
- feedback:pull lists app feedback in summary.md without contact details
- docs: CloudBase setup, decision 0006 on iOS analytics
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EFHDCs6oQeD2M9BhyKbnn9
* docs: renumber the iOS analytics decision to 0008 (#109 takes 0007)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EFHDCs6oQeD2M9BhyKbnn9
* feat(feedback): record platform and version on reports and signals
Reports and search signals take the same `platform` / `version` fields as
app feedback (missing = web). Signals are counted per platform: web keeps
its original key so existing rows keep counting, iOS gets its own. The
feedback summary splits recipe reports, app feedback and signals by
platform; eval cases add both platforms up and merge the same recipe.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EFHDCs6oQeD2M9BhyKbnn9
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat(ios): CookCore Swift package, data versions and shared search/incompatible fixtures
- recipe-meta.json gains schemaVersion (DATA_SCHEMA_VERSION) and dataVersion (content hash)
- JSON Schemas for every file in packages/data, checked by test/data-schema.test.ts
- findIncompatibleRules shared by the web composable and the fixtures
- packages/data/fixtures adds search.json and incompatible.json
- apps/ios/CookCore ports recommend, search and incompatible logic to Swift and runs the
shared fixtures; CI runs swift test on Linux
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fas1deZ1VtGhZCjh1VLfVC
* docs(ios): record the iOS app name in the M2 plan
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fas1deZ1VtGhZCjh1VLfVC
* docs(ios): M2 implementation plan
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fas1deZ1VtGhZCjh1VLfVC
* feat(ios): 云食册 SwiftUI app skeleton with cook flow, library, random and settings
- XcodeGen project (apps/ios/project.yml) depending on the local CookCore package;
a pre-build script bundles packages/data into the app
- Tabs: 做菜 (ingredient/tool/method/difficulty chips, pantry/avoid/no-spicy,
incompatible warning, grouped results), 菜谱 (all/favorites/recent with search),
随机, 我的
- Recipe detail with have/missing/pantry groups, Bilibili app/web link, share, feedback
- SwiftData favorites and history, synced through CloudKit when iCloud is available
- CookTests for bundled data, session preferences and favorites/history
- CI job builds and tests the app on an iOS simulator (macos-26)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fas1deZ1VtGhZCjh1VLfVC
* fix(ios): keep the in-memory container alive in tests, create Application Support before opening the store
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fas1deZ1VtGhZCjh1VLfVC
* fix(ios): keep the cook button readable over the list and always show library search
The disabled 先选几样食材 button is translucent, so section headers scrolling
under it showed through; give the bottom inset an opaque fade. The 菜谱 tab's
search field only appeared after pulling down, so pin it in the navigation bar.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(ios): only promise iCloud sync when signed in
Without an iCloud account (or entitlement) SwiftData falls back to a local
store, so the settings footer should not claim sync unconditionally.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* docs(ios): mark CookCore verified on a Mac
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(ios): polish detail title, random card and results search
- Detail: show the dish name once, as a large title that collapses into the nav bar
- Random: make the card read as tappable (看做法 >) and lift it off a grouped background
- Results: keep the 按菜名筛选 field visible instead of hiding it until pull-down
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fas1deZ1VtGhZCjh1VLfVC
* perf(ios): match the launch screen to the first page and signpost launch work
Measured on the iPhone 18 Pro simulator: loading the bundled data takes about
20 ms and opening the SwiftData store about 25 ms. Time to first frame (about
2.1 s) is the same as an app whose only view is a Text, so the remaining time
is simulator overhead, not app work. The visible problem was the white launch
screen switching to the grouped grey background, so the launch screen now uses
a LaunchBackground colour (#F2F2F7, black in dark mode). Data loading and store
creation are wrapped in signposts so they can be checked on a device in
Instruments (Points of Interest).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(ios): SwiftData preferences, soft-deleted favorites and history, filter sheet, iPad library split view and a11y
- Favorite / HistoryEntry carry updatedAt and deletedAt (soft delete, tombstones purged after 30 days)
- Preferences (pantry, avoid, no-spicy, recommendation mode) move from UserDefaults into SwiftData so they sync via iCloud; duplicates from several devices merge into one
- 做菜: 做法, 难度 and 调料和忌口 move into a 筛选 sheet; the toolbar button shows when filters are on
- 菜谱: NavigationSplitView (list + detail on iPad, a stack on iPhone) and a 清空 action for history
- VoiceOver reads chip and ingredient names without emoji names; chip grid scales with Dynamic Type
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fas1deZ1VtGhZCjh1VLfVC
* feat(ios): new 蒸汽成云 app icon
Adds the Icon Composer layered AppIcon.icon for iOS 26 and replaces the
AppIcon.appiconset fallback with light, dark and tinted 1024px images.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fas1deZ1VtGhZCjh1VLfVC
* fix(ios): opaque filter sheet, show active filters on results, large 菜谱 title
- At the medium detent the 筛选 sheet was translucent glass, so a selected
ingredient chip behind it glowed through and looked like a selected 做法.
- The results footer now lists the active filters (厨具, 做法, 难度, 不吃辣),
since they are set in a sheet and otherwise explain fewer results silently.
- The split-view sidebar defaulted to an inline title on iPhone; use the
large title like the other tabs.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(ios): walk the cook flow by accessibility labels
CookUITests finds every control by the label VoiceOver reads: pick 土豆,
番茄 and 鸡蛋 (checking the selected trait), open 筛选 and pick 炒菜,
看看能做什么, open 番茄炒蛋, then 收藏 → 取消收藏. It runs in the same
scheme, so the macOS CI job covers it. Passes on iPhone 18 Pro and
iPad Pro 11-inch (M5) simulators.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* chore(ios): use fun.yunle.cook as the bundle id
The Capacitor app under cn.yunyoujun.cook was never released, so the
native app takes the 云乐坊 domain id and iCloud.fun.yunle.cook before
the first TestFlight build. Recorded in docs/decisions/0006.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fas1deZ1VtGhZCjh1VLfVC
* test(ios): let the UI test start from an already favorited recipe
Favorites persist in the app's store on the simulator, so a second run on the
same device found 取消收藏 instead of 收藏 and failed. Unfavorite first when
needed, then check that 收藏 flips to 取消收藏.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Move the food/tool dictionary, pantry defaults and ingredient aliases to
JSON in packages/data so the iOS app can read the same files, and add
packages/data/fixtures/recommend.json (pnpm fixtures) as the shared
recommendation cases both implementations must match.
Claude-Session: https://claude.ai/code/session_01Fas1deZ1VtGhZCjh1VLfVC
Co-authored-by: Claude <noreply@anthropic.com>
* feat(data): add 18 fish recipes and recipe-sourcing skill
- Enable the 鱼 ingredient (was 鱼(Todo)) and map common fish names
(鲈鱼、带鱼、三文鱼…) to it.
- Add 18 fish recipes, each with a verified Bilibili video, covering
wok, air fryer, microwave and oven.
- Add a recipe-sourcing skill describing how to collect recipes by topic
from Bilibili / Xiaohongshu.
Closes#38
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lu334SCfiQb1M4q5B2hdAc
* feat(data): add 12 more fish recipes
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lu334SCfiQb1M4q5B2hdAc
---------
Co-authored-by: Claude <noreply@anthropic.com>
- pnpm validate in CI (dictionary, values, video ids; --base guards ids on PRs), weekly dead-video check
- permanent recipe id column; IndexedDB keyed on it
- in-app feedback and anonymous search signals via cook-feedback cloud function
- feedback:pull / eval:search and a local recipe-data-review skill
- docs/dev/data.md and docs/decisions
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJEQjfVTadrjmNrZfxfnHd