1
0
mirror of synced 2026-11-02 13:41:09 +08:00

16 Commits

Author SHA1 Message Date
云游君
c9fb1feffe fix(ci): replace video scans with offline checks and bounded reviews (#171) 2026-10-26 03:41:12 -07:00
云游君
f9d7b68ed9 feat(ios): scale recipe quantities and track cooking progress (#152)
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.
2026-10-24 11:26:30 -07:00
云游君
da110d6b34 feat(feedback): add recipe context and isolate test submissions 2026-10-24 06:55:10 -07:00
云游君
b24d389100 fix(feedback): distinguish video and text recipe reports 2026-10-24 06:10:40 -07:00
云游君
85df3a63fd feat(feedback): preserve Support and unify recipe submissions (#122)
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.
2026-10-23 12:00:51 -07:00
云游君
84bc20f4ec feat(feedback): unify Cook private feedback with Support SDK
* 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
2026-10-23 04:30:35 -07:00
云游君
0c9bcf96ed feat(recommend): 用视频质量分决定同组菜谱的先后 (#121)
推荐在缺料数、大杂烩、用上的食材数都相同时,按视频质量分从高到低排,再相同才看行号。分数由 pnpm check:videos --stats 拉取的 B 站数据在 pnpm convert 时算成 0~100 的整数,Web 和 iOS 共用。决策见 docs/decisions/0010-recipe-quality-score.md。

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qWLajDhEw82jwdrqfBcMu
2026-10-22 01:39:20 +08:00
云游君
05910e7a29 feat(data): add seven ingredients and collapsible selection
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.
2026-10-22 00:55:42 +08:00
云游君
476e072fb4 feat(cook): 支持图文做法并导入 HowToCook 菜谱 (#115)
导入 HowToCook 195 道新菜,并为 30 道已有菜补充图文链接;云食册内置 225 道菜的正文,支持离线阅读。

203 张配图压成 WebP 上传到 COS,通过 assets.yunle.fun 的 EdgeOne 加速加载。配置只允许 cook/ 前缀上传和查询的专用子账号与仓库 Secrets,并启用 Recipe Images 自动上传工作流。

Closes #67
2026-10-20 23:11:11 +08:00
云游君
8cfe4134cf feat(feedback): 应用内意见反馈,并为 iOS App 开放云函数 HTTP 上报入口 (#110)
* 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>
2026-10-20 00:41:36 +08:00
云游君
644c8b8c4b feat(cook): 做菜页输入框支持整句识别 (#109)
- parseCookQuery:按共享词表 packages/data/query.json 做最长匹配,识别食材、忌口、不辣、厨具、做法和难度
- 做菜页输入框接受整句,识别结果合进当前筛选
- query.json 的 JSON Schema,计入 dataVersion;共享用例 fixtures/query.json
- 决定记录 0007、使用指南「一句话找菜」(含截图)和应用内帮助

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ShQJTTWKu9dkJ6n4ws1Y4A
2026-10-19 23:19:07 +08:00
云游君
b156d91345 feat(ios): 云食册 SwiftUI App 第一版:CookCore、筛选、收藏同步、iPad 与无障碍 (#106)
* 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>
2026-10-19 22:08:01 +08:00
云游君
c8dfa7d81b refactor(data): share food dictionary, pantry, aliases and recommend fixtures via packages/data (#105)
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>
2026-10-19 17:18:31 +08:00
云游君
847189279a refactor: native iOS plan and monorepo layout (apps/web, packages/data) (#104)
Move the Nuxt app to apps/web and recipe data to packages/data (pure move, no logic changes), and add decision record 0003 plus the iOS roadmap.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fas1deZ1VtGhZCjh1VLfVC
2026-10-19 17:01:36 +08:00
云游君
045c5bae6c feat(data): add 30 fish recipes and recipe-sourcing skill (#103)
* 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>
2026-10-19 03:33:31 +08:00
云游君
4732b8e99a feat(data): recipe validation, stable ids, in-app feedback and AI review loop (#100)
- 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
2026-10-19 03:14:20 +08:00