Add a new built-in exercise to Liftosaur end-to-end — image (gymvisual.com → S3), catalog registration, description page, and the LLM/MCP exercise list. Use when adding one or more built-in exercises to the app catalog.
中文简介正在准备中。当前显示原文说明。
Create, run, debug and tear down an isolated dev worktree — its own branch, node_modules, domains, ports, SSL certs, DNS records, Metro and iOS simulator. Use when asked to set up/remove a worktree, when something in a worktree points at the wrong port/host/simulator, or when work should happen off the base checkout.
中文简介正在准备中。当前显示原文说明。
实测评分 未实测
查看安装方法安装前可以查看交给 AI 代理的指令内容。
A worktree here is a complete parallel dev environment, not just a second checkout. Each one
gets its own branch, node_modules, public domains, port block, SSL certs, Cloudflare DNS records,
Metro instance and cloned iOS simulator, so several can run at once without colliding.
Everything is keyed off one git-ignored file at the worktree root: localdomain.js. Read it
first whenever you need to know where anything in a checkout lives.
module.exports = {
main: "local2", api: "local2-api", streamingapi: "local2-streaming-api",
port: 8090, apiPort: 3010, streamingApiPort: 3011, metroPort: 8091,
};
scripts/worktree-create.sh:64 — OFFSET = (INDEX - 1) * 10:
| index | domains | web | api | streaming | metro | simulator |
|---|---|---|---|---|---|---|
| 1 (base repo, reserved) | local, local-api, local-streaming-api | 8080 | 3000 | 3001 | 8081 | iPhone 17e RNW |
| N (2..20) | localN, localN-api, localN-streaming-api | 8080+10(N-1) | 3000+10(N-1) | 3001+10(N-1) | 8081+10(N-1) | iPhone 17e RNW <dirname> |
Indices are capped at 2..20 and picked at random from the free ones (scripts/worktree-create.sh:50)
— deliberately a small reusable pool, because certs are never deleted, so the same handful of domains
get renewed rather than newly issued (Let's Encrypt rate-limits new certs, not renewals). Taken
indices are discovered by reading every worktrees/*/localdomain.js.
scripts/worktree-create.sh <name> [index] # run from the base repo root
Does, in order: git worktree add worktrees/<name> -b <name> → writes localdomain.js → npm ci
→ generators (build:theme, build:markdown, build:programs, build:exercises) → issues/renews
certs via lambda/scripts/update_liftosaur_dev_certs.sh (certbot + Cloudflare DNS-01, into
~/.secrets) → points localN*.liftosaur.com A records at this machine's LAN IP via
lambda/scripts/change_liftosaur_dev_api.sh.
It does not touch native — pods and the simulator are provisioned later, on demand.
worktrees/<name>)npm start # webpack-dev-server on localdomain.port, https from ~/.secrets certs
npm run start:server # api + streaming api on apiPort / streamingApiPort
npm run worktree:ios # pods (once) + clone sim (once) + boot + run-ios on the right Metro port
npm run worktree:metro # Metro alone (= rn:start), on this checkout's metroPort
npm test # fine in a fresh worktree — build:programs already wrote programdata/
npm start is not optional for native work: the RN app's __HOST__ is the web dev server
(src/App.native.tsx:30), so images and other assets come from it.
Nothing may assume 8080/3000/8081. The plumbing:
src/localdomain.ts re-exports localdomain.js; consumed by
webpack.config.js (devServer port, cert paths, __API_HOST__ defines, proxies) and
devserver.ts:250 (listens on apiPort, reads certs from ~/.secrets/live/<api domain>/).src/App.native.tsx:30-34 sets __HOST__ / __API_HOST__ / __STREAMING_API_HOST__
from localdomain.js under __DEV__, so a native build in a worktree talks to that worktree's servers.scripts/metro-port.sh ($RCT_METRO_PORT → localdomain.js → 8081);
used by the ios / android / rn:start npm scripts.RCT_METRO_PORT cannot work: React-Core is a prebuilt xcframework, so
its default 8081 is compiled upstream. Instead ios/scripts/write-metro-port.sh runs as an
always-out-of-date Debug build phase (project.pbxproj:933) and writes metro-port.txt into the
app bundle; MetroLocation in ios/Liftosaur/AppDelegate.swift:104 reads it and pins
jsLocation + packagerHost. Plain npm run ios and ⌘R in Xcode are both correct.android/app/build.gradle:95 parses metroPort out of
localdomain.js and emits resValue "integer", "react_native_dev_server_port".metro.config.js block-lists worktrees/ and .claude/worktrees/ (anchored
to the project root, so Metro still works when run from inside a worktree) to avoid haste-map
collisions between duplicate package.jsons.scripts/worktree-remove.sh <name> # run from anywhere
Kills whatever is bound to its four ports, deletes the DNS records (guarded: refuses when
main === "local"), deletes the cloned simulator, then git worktree remove --force and
git branch -D. Certs are kept on purpose — same reason the index pool is small.
xcrun simctl shutdown "iPhone 17e RNW", then re-run.sh lambda/scripts/change_liftosaur_dev_api.sh "$PWD/localdomain.js".~/.secrets/live/<domain>/, shared across checkouts. If they're missing,
webpack.config.js silently falls back to plain http while devserver.ts throws on readFileSync.-[RCTLogBoxView dealloc] → doesNotRecognizeSelector → SIGABRT.
It usually means the worktree's servers aren't running; start them (or temporarily point
localdomain.js at the base repo's local/8080/3000) instead of dismissing it.npm run pod-install dirties ios/Podfile.lock and ios/Liftosaur.xcodeproj/project.pbxproj —
revert before committing feature work.npm run worktree:ios from the worktree root — it resolves ./localdomain and names the
sim after basename $PWD, which must match the <name> worktree-remove.sh will be given.git worktree add -b <name> fails if the branch already exists. Create it from a fresh name,
or git worktree add manually and write localdomain.js by hand.lambda/scripts is a git submodule and worktree-create.sh does not initialise it, so inside a
worktree that directory is empty. Plans, codex transcripts and archdocs for the branch go in the
base repo's lambda/scripts/plans/ and lambda/scripts/archdocs/, as usual.
An archdoc's code links then have to reach into the worktree, because the base checkout does not
have the feature and the lint hook (grasp archdoc lint + scripts/lint-docs.ts, on every write
under lambda/scripts/archdocs/) reports a dead path for ../../../ios/Foo.swift. Write every
link as ../../../worktrees/<name>/ios/Foo.swift#L12 (relative to the doc's own directory), stamp
the header base <worktree HEAD sha> - head working, and lint resolves against the files on disk.
grasp finds the repo root through git rev-parse --git-common-dir, so lint and relink work
from either checkout. worktrees/ is git-ignored in the base repo, so relink routes every link to
the file view (no diff route) until the branch is committed.
After the branch is committed and merged, remove worktrees/<name>/ from every link, replace
working with the commit sha, and run grasp archdoc relink <doc> --write again.
liftosaur-local MCP is pinned to https://local.liftosaur.com:8080/mcp (in ~/.claude.json).
From a worktree it still talks to the base repo's server. Either run the base repo's
npm start/start:server too, or repoint the MCP URL at the worktree's port for the session.npm run build:dev once per worktree. Its start page is /app/, and the dev
server serves that directory index only from a physical dist/app/index.html (static: in
webpack.config.js); the in-memory bundle answers /app/index.html but not /app/. A fresh
worktree has no dist/app/, so every spec fails on the first page.waitForFunction with
"Refused to evaluate a string as JavaScript" — the 404 page's CSP, not the app. build:dev writes
the file; after that npx playwright test --reporter=line runs against the worktree's own port.lambda/utils/response.ts:7), as do the OAuth/MCP redirect
fallbacks (lambda/mcp/handler.ts, lambda/mcp/oauth.ts) and the dev CDK stack
(liftosaur-cdk/liftosaur-cdk.ts). Cross-origin/OAuth flows may need the base ports.com.liftosaur.www.twa), one
emulator, one install. Only the Metro port is worktree-aware. Two Android worktrees can't run
side by side..claude/worktrees/* are a different mechanism — created by the Claude Code harness
(EnterWorktree), with no localdomain.js, ports, DNS or simulator. These scripts don't apply
to them; they're only block-listed in Metro and excluded from copy:lambda.还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
Add a new built-in exercise to Liftosaur end-to-end — image (gymvisual.com → S3), catalog registration, description page, and the LLM/MCP exercise list. Use when adding one or more built-in exercises to the app catalog.
中文简介正在准备中。当前显示原文说明。
Add a new server-rendered page to the Liftosaur website. Use when creating new public-facing pages with routing, SSR, and client hydration.
中文简介正在准备中。当前显示原文说明。
Create a 30%-off coupon for an affiliate or creator on iOS and Android, and draft the reply that tells them how to use it. Use when asked to create, set up or send a coupon or promo code for an affiliate, influencer or creator.
中文简介正在准备中。当前显示原文说明。
Interactively investigate a production Rollbar error. Accepts an occurrence id, item id, item counter, or Rollbar URL. Fetches the error data, assesses how widespread it is, drills into affected users (events, logs, storage, captured state), and works with the developer toward a fix or ignore decision. Use for collaborative debugging; use /fix-rollbar for a straight fetch-and-fix of a single occurrence.
中文简介正在准备中。当前显示原文说明。
Investigate a user-reported issue using server logs, user events, storage snapshots, and Rollbar. Use when given a user id or email plus an issue description (e.g. from a support email).
中文简介正在准备中。当前显示原文说明。
Build a feature end to end — decide worktree vs here, design the architecture and debate it with codex, get the user's approval on a one-pass-readable plan, state the API/state contract, implement with visible diffs, then run two codex reviews (bugs + architecture) and document the result. Use when asked to build/implement/add a feature or do a refactor that involves design decisions.
中文简介正在准备中。当前显示原文说明。