diff --git a/AGENTS.md b/AGENTS.md index 30686da7..56554507 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -158,14 +158,17 @@ pedantic, or style-only rule. Treat `packages/stim-cli/skill/SKILL.md` as a tiny discovery router. Its body only tells the agent to run `stim guide agent` and follow the version-matched -instructions. Keep every operational detail in that guide topic, including the -normal workflow, ownership and deletion rules, command notation, topic routing, -flags, payloads, settings, backends, caches, cleanup, and remedies. Do not add a +instructions. Keep operational guidance in the version-matched guides. +`guide agent` covers the normal workflow, safety, recovery actions, and topic +routing. Put transparent build optimizations and cache internals in the relevant +detailed topics, not the root agent guide. Detailed topics also own flag, +payload, setting, backend, cleanup, and remedy references. Do not add a version check, compatibility branch, migration path, or failure fallback to the static skill. Only one skill ships. -Update `guide agent`, the relevant detailed guide topics, and their contract -tests when commands, defaults, safety rules, or remedies change. The static +Update the affected guide topics and their contract tests when commands, +defaults, safety rules, or remedies change. Change `guide agent` when the agent's +actions, safety rules, or topic routing change. The static skill changes only when its activation description or single routing command changes. diff --git a/packages/stim-cli/src/__tests__/guide.test.ts b/packages/stim-cli/src/__tests__/guide.test.ts index aa205093..d52e6de7 100644 --- a/packages/stim-cli/src/__tests__/guide.test.ts +++ b/packages/stim-cli/src/__tests__/guide.test.ts @@ -308,7 +308,13 @@ test('the agent guide routes to every detailed topic', () => { expect(agent).toContain(`guide ${topicName}`); } expect(agent).toContain('stim guide errors '); - for (const route of ['guide errors sandbox', 'guide facts devmenu', 'guide cleanup collector']) { + for (const route of [ + 'guide errors sandbox', + 'guide facts devmenu', + 'guide cleanup collector', + 'guide lifecycle builds', + 'guide lifecycle concurrency', + ]) { expect(agent).toContain(route); } }); diff --git a/packages/stim-cli/src/guide/agent.ts b/packages/stim-cli/src/guide/agent.ts index 0bf8cd87..0e9a6f72 100644 --- a/packages/stim-cli/src/guide/agent.ts +++ b/packages/stim-cli/src/guide/agent.ts @@ -26,12 +26,6 @@ fix PATH or the installation before continuing so commands and guidance match. stim doctor --platform ios # or: --platform android - # In the main checkout, seed the shared build caches when more native - # worktrees are coming. Skip this for one-off or JavaScript-only work. - stim start - stim ios # or: stim android - stim stop - # Skip Git creation if the harness already created this linked worktree. git worktree add -b HEAD cd @@ -62,12 +56,6 @@ RULES DURING THE LOOP run stim start and retry. - Run ios or android again after a native input changes. A JavaScript-only change does not need one. -- If fingerprinting fails after native inputs change during the run, Stim - installs the build without caching it. A null fingerprint or cacheKey is - unavailable cache information, not an install failure. -- Android Debug builds target the owned emulator system-image ABI or the - physical device's primary ABI. Unknown targets and Release builds stay - universal. - Reload is not part of the normal workflow. Use stim reload on an owned local simulator or emulator after a failed first bundle load, when an error screen remains after the fix, or when you explicitly need an app restart. For a @@ -82,10 +70,8 @@ RULES DURING THE LOOP the error screen remains, follow the printed reload remedy instead of running ios or android again. If launch says FATAL because the app process exited, fix the crash and run the platform command again; Metro cannot restart it. -- A cold native build can outlive a shell timeout. Run the same command again: - the second call joins the active build or returns its result. If a builder - fails, one waiter takes over and the others keep waiting within the same - 90-minute limit. Follow the remedy if STIM_BUILD_WAIT_TIMEOUT is returned. +- A native build can outlive a shell timeout. Retry the same command and + follow its printed remedy if waiting times out. See guide lifecycle concurrency. - ios and android install the app, launch it, and check readiness. Trust the exact device, app, Metro, and launch facts in the final summary. Use the full reported device ID. Never assume a simulator named booted belongs to this @@ -171,7 +157,8 @@ LOAD ADVANCED GUIDANCE WHEN NEEDED stim guide errors fallbacks # swap, cache, and install notes on a release cache hit stim guide lifecycle # the ordered flow, consent rules, and capacity stim guide lifecycle verification # reproduce, edit, verify the UI, and retain proof - stim guide lifecycle builds # cache hits, misses, fingerprints, .fingerprintignore + stim guide lifecycle builds # build optimizations, optional cache warm-up, fingerprints + stim guide lifecycle concurrency # shared builds, wait timeouts, capacity limits stim guide lifecycle options # every flag, Android variants, --device-type, --system-image stim guide lifecycle devices # ios --device and android --device on a physical phone stim guide lifecycle release # Release configurations and ...Release variants diff --git a/packages/stim-cli/src/guide/lifecycle.ts b/packages/stim-cli/src/guide/lifecycle.ts index 06105ff2..1fa5ca03 100644 --- a/packages/stim-cli/src/guide/lifecycle.ts +++ b/packages/stim-cli/src/guide/lifecycle.ts @@ -306,8 +306,21 @@ result as proof instead of requiring an unrelated screenshot.`, }, builds: { summary: - 'cache hits, misses, the fingerprint shift, .fingerprintignore, install unchanged, where runtime state lives', - body: () => `AN ARTIFACT THE DEVICE ALREADY HOLDS IS NOT INSTALLED AGAIN + 'optional cache warm-up, build optimizations, fingerprints, .fingerprintignore, install unchanged, runtime state', + body: () => `OPTIONAL CACHE WARM-UP FOR REPEATED NATIVE WORK + When several native worktrees are coming, build the main checkout once to + seed the shared caches before warming the linked worktrees. Skip this extra + build for one-off or JavaScript-only work. For local simulator or emulator + work, run these commands in the main checkout's app directory: + + stim doctor --platform ios # or: --platform android + stim start + stim ios # or: stim android + stim stop + + Follow the normal ownership and consent rules in guide agent. + +AN ARTIFACT THE DEVICE ALREADY HOLDS IS NOT INSTALLED AGAIN Both platforms store the artifact verbatim, so its hash is its identity. Before installing, Stim hashes the artifact it is about to install and the one the device already has -- \`pm path\` then \`sha256sum\` on Android, the @@ -351,8 +364,9 @@ committing. The shared caches need no project-file edits: when the project configured ccache (the two defeat each other). android gradlew carries --build-cache, so task outputs cross worktrees with no org.gradle.caching=true in gradle.properties. Debug builds also - carry -PreactNativeArchitectures= when Stim can prove - the emulator or physical-device ABI; otherwise they stay universal. + carry -PreactNativeArchitectures=, using the owned + emulator system-image ABI or the physical device's primary ABI. + Unknown targets and Release builds stay universal. ccache the same gradlew run carries an absolute CMAKE_C_COMPILER_LAUNCHER / CMAKE_CXX_COMPILER_LAUNCHER plus CCACHE_DIR, CCACHE_BASEDIR, CCACHE_NOHASHDIR, CCACHE_SLOPPINESS @@ -457,6 +471,8 @@ THE BUILD CACHE HAS THREE LEVELS If the iOS fingerprint after prebuild or pod install is unavailable, Stim installs the build but skips local storage and remote uploads. fingerprint and cacheKey are null in the result and lastBuild; the old key is not reused. + Android does the same if its post-Gradle fingerprint cannot be computed. + These null fields mean unavailable cache information, not an install failure. WHAT MAKES THE CACHE ACTUALLY HIT: .FINGERPRINTIGNORE Every entry is keyed on what the tree hashes, so two workspaces share an