Skip to content

Commit 7568a65

Browse files
MelvinBotikevin127
andcommitted
Merge remote-tracking branch 'origin/main' into claude-iosFocusDescriptionOnCancel
Co-authored-by: Kevin Brian Bader <ikevin127@users.noreply.github.com>
2 parents 5fa7db0 + 23778fa commit 7568a65

1,013 files changed

Lines changed: 18815 additions & 11482 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/coding-standards/SKILL.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ Coding standards for the Expensify App. Each standard is a standalone file in `r
5353
- [CONSISTENCY-12](rules/consistency-12-callback-named-for-action.md) — Name callbacks for what they do, not the event they handle
5454
- [CONSISTENCY-13](rules/consistency-13-document-props.md) — Document component props with a JSDoc block comment
5555
- [CONSISTENCY-14](rules/consistency-14-new-file-header.md) — Non-trivial new files start with a header description
56+
- [CONSISTENCY-15](rules/consistency-15-comment-why.md) — Comments explain why the code exists, not what it does
57+
- [CONSISTENCY-16](rules/consistency-16-plain-comment-style.md) — Write comments as plain, natural sentences
5658

5759
### Clean React Patterns
5860
- [CLEAN-REACT-PATTERNS-0](rules/clean-react-0-compiler.md) — React Compiler compliance
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
ruleId: CONSISTENCY-15
3+
title: Commenting "Why"
4+
---
5+
6+
## [CONSISTENCY-15] Commenting "Why"
7+
8+
### Reasoning
9+
10+
Comments should explain *why* the code exists, not what it does. Well-named identifiers already say what the code does, so a comment that only restates the code is dead weight.
11+
12+
### Incorrect
13+
14+
```tsx
15+
// loop through users
16+
users.forEach(processUser);
17+
```
18+
19+
### Correct
20+
21+
```tsx
22+
// We only include active users to avoid reprocessing deactivated ones
23+
users.forEach(processUser);
24+
```
25+
26+
---
27+
28+
### Review Metadata
29+
30+
Flag ONLY when BOTH of these are true:
31+
32+
- The changed code adds or modifies a comment
33+
- The comment restates what the code does instead of explaining why it exists
34+
35+
**DO NOT flag if:**
36+
37+
- The comment is a JSDoc `@param` or `@returns` description, where stating what the parameter or return value is is the expected content, not a why explanation
38+
- Stating what the code does is genuinely the only way to orient a reader, such as documenting a regex or a bit-flag mask
39+
40+
**Search Patterns** (hints for reviewers):
41+
- Any newly added or modified `//` or `/* */` comment that only restates the code below it
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
ruleId: CONSISTENCY-16
3+
title: Write comments as plain, natural sentences
4+
---
5+
6+
## [CONSISTENCY-16] Write comments as plain, natural sentences
7+
8+
### Reasoning
9+
10+
Comments should read like something a person actually wrote: plain sentences without the stylistic tics that make prose harder to read, such as em dashes, redundant parentheticals, stacked hyphenated modifiers, arrows, semicolons, and trailing placement on the same line as the code.
11+
12+
### Incorrect
13+
14+
```tsx
15+
doThing(); // cache the result
16+
17+
// Set the pendingAction to ADD — this exercises the optimistic-update branch before the API responds
18+
19+
// When the assigned guide (who is not a policy admin) comments, then it succeeds
20+
21+
// the not-yet-validated user-supplied bank-account number
22+
23+
// persisted -> processing transition
24+
25+
// retry once; the token had expired
26+
```
27+
28+
### Correct
29+
30+
```tsx
31+
// Cache the result to avoid reading from the database every time
32+
doThing();
33+
34+
// Set the pendingAction to ADD to go through the optimistic-update branch before the API responds
35+
36+
// The assigned guide isn't a policy admin, but the comment still succeeds
37+
38+
// The bank account number the user supplied, before validation
39+
40+
// SequentialQueue moves the request from persisted to processing
41+
42+
// Retry once because the token had expired
43+
```
44+
45+
---
46+
47+
### Review Metadata
48+
49+
Flag ONLY when BOTH of these are true:
50+
51+
- The changed code adds or modifies a comment
52+
- In its own sentence, not inside a quoted code snippet or string literal it's documenting, the comment does at least one of the following:
53+
- Uses an em dash or en dash
54+
- Uses a redundant parenthetical that just repeats what the surrounding sentence already says
55+
- Stacks more than one hyphenated compound modifier in front of a noun
56+
- Uses `->` instead of writing the relationship in words
57+
- Uses a semicolon instead of two separate sentences
58+
- Trails at the end of a code line instead of sitting on its own line directly above it
59+
60+
**DO NOT flag if:**
61+
62+
- The dash, arrow, or semicolon appears inside a quoted code example, string literal, or file path the comment is documenting, rather than in the comment's own sentence
63+
- A single, ordinary compound modifier like "well-known" or "high-risk" is used. Only a stacked chain of several modifiers in front of one noun is a violation
64+
65+
**Search Patterns** (hints for reviewers):
66+
- Any newly added or modified `//` or `/* */` comment

.github/actions/javascript/getPullRequestIncrementalChanges/index.js

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12887,7 +12887,7 @@ exports["default"] = Git;
1288712887
"use strict";
1288812888

1288912889
Object.defineProperty(exports, "__esModule", ({ value: true }));
12890-
exports.bold = exports.formatLink = exports.success = exports.errorDetail = exports.error = exports.note = exports.warn = exports.info = void 0;
12890+
exports.setOutputStream = exports.bold = exports.formatLink = exports.success = exports.errorDetail = exports.error = exports.note = exports.warn = exports.info = void 0;
1289112891
const COLOR_DIM = '\x1b[2m';
1289212892
const COLOR_RESET = '\x1b[0m';
1289312893
const COLOR_YELLOW = '\x1b[33m';
@@ -12902,32 +12902,58 @@ const EMOJIS = {
1290212902
SUCCESS: '✅',
1290312903
ERROR: '🔴',
1290412904
};
12905+
/** Mirrors the console API: informational levels on stdout, warnings and errors on stderr. */
12906+
const outputStreams = {
12907+
info: 'stdout',
12908+
bold: 'stdout',
12909+
success: 'stdout',
12910+
note: 'stdout',
12911+
warn: 'stderr',
12912+
error: 'stderr',
12913+
errorDetail: 'stderr',
12914+
};
12915+
/**
12916+
* Redirects individual levels; levels left out keep whatever they are set to. Call this at startup
12917+
* from a script whose stdout carries machine-readable output (e.g. JSON parsed by another process),
12918+
* where a stray log line would corrupt the payload: `setOutputStream({info: 'stderr'})`.
12919+
*/
12920+
const setOutputStream = (streams) => {
12921+
Object.assign(outputStreams, streams);
12922+
};
12923+
exports.setOutputStream = setOutputStream;
12924+
const write = (level, ...args) => {
12925+
if (outputStreams[level] === 'stderr') {
12926+
console.error(...args);
12927+
return;
12928+
}
12929+
console.log(...args);
12930+
};
1290512931
const info = (...args) => {
12906-
console.log(EMOJIS.INFO, ...args);
12932+
write('info', EMOJIS.INFO, ...args);
1290712933
};
1290812934
exports.info = info;
1290912935
const bold = (...args) => {
12910-
console.log(COLOR_BOLD, ...args, COLOR_RESET);
12936+
write('bold', COLOR_BOLD, ...args, COLOR_RESET);
1291112937
};
1291212938
exports.bold = bold;
1291312939
const success = (...args) => {
12914-
console.log(`${EMOJIS.SUCCESS}${COLOR_GREEN}`, ...args, COLOR_RESET);
12940+
write('success', `${EMOJIS.SUCCESS}${COLOR_GREEN}`, ...args, COLOR_RESET);
1291512941
};
1291612942
exports.success = success;
1291712943
const warn = (...args) => {
12918-
console.warn(`${EMOJIS.WARN}${COLOR_YELLOW}`, ...args, COLOR_RESET);
12944+
write('warn', `${EMOJIS.WARN}${COLOR_YELLOW}`, ...args, COLOR_RESET);
1291912945
};
1292012946
exports.warn = warn;
1292112947
const note = (...args) => {
12922-
console.log(COLOR_DIM, ...args, COLOR_RESET);
12948+
write('note', COLOR_DIM, ...args, COLOR_RESET);
1292312949
};
1292412950
exports.note = note;
1292512951
const error = (...args) => {
12926-
console.error(`${EMOJIS.ERROR}${COLOR_RED}`, ...args, COLOR_RESET);
12952+
write('error', `${EMOJIS.ERROR}${COLOR_RED}`, ...args, COLOR_RESET);
1292712953
};
1292812954
exports.error = error;
1292912955
const errorDetail = (...args) => {
12930-
console.error(` ${COLOR_RED}↳`, ...args, COLOR_RESET);
12956+
write('errorDetail', ` ${COLOR_RED}↳`, ...args, COLOR_RESET);
1293112957
};
1293212958
exports.errorDetail = errorDetail;
1293312959
const formatLink = (name, url) => `\x1b]8;;${url}\x1b\\${name}\x1b]8;;\x1b\\`;

.github/workflows/publishReactNativeAndroidArtifacts.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ jobs:
5959
id: computePatchesHash
6060
run: |
6161
if [[ '${{ matrix.is_hybrid }}' == 'true' ]]; then
62-
echo "PATCHES_HASH=$(./scripts/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
62+
echo "PATCHES_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
6363
else
64-
echo "PATCHES_HASH=$(./scripts/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
64+
echo "PATCHES_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
6565
fi
6666
6767
- name: Setup Node

.github/workflows/publishReactNativeArtifacts.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ on:
3838
- patches/react-native/react-native+*.patch
3939
- patches/react-native/@react-native+*.patch
4040
- Mobile-Expensify
41-
- scripts/compute-patches-hash.sh
41+
- scripts/artifacts-utils/compute-patches-hash.sh
4242

4343
jobs:
4444
verifyPatches:
@@ -62,8 +62,8 @@ jobs:
6262
if: ${{ github.event.after != '' }}
6363
id: getOldPatchesHash
6464
run: |
65-
echo "HYBRID_APP_HASH=$(./scripts/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
66-
echo "STANDALONE_APP_HASH=$(./scripts/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
65+
echo "HYBRID_APP_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
66+
echo "STANDALONE_APP_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
6767
6868
- name: Get previous react-native version
6969
if: ${{ github.event.after != '' }}
@@ -80,8 +80,8 @@ jobs:
8080
- name: Get new patches hash
8181
id: getNewPatchesHash
8282
run: |
83-
echo "HYBRID_APP_HASH=$(./scripts/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
84-
echo "STANDALONE_APP_HASH=$(./scripts/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
83+
echo "HYBRID_APP_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
84+
echo "STANDALONE_APP_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
8585
8686
- name: Get new react-native version
8787
if: ${{ github.event.after != '' }}

.github/workflows/publishReactNativeiOSArtifacts.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,9 @@ jobs:
211211
id: computePatchesHash
212212
run: |
213213
if [[ '${{ matrix.is_hybrid }}' == 'true' ]]; then
214-
echo "PATCHES_HASH=$(./scripts/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
214+
echo "PATCHES_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
215215
else
216-
echo "PATCHES_HASH=$(./scripts/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
216+
echo "PATCHES_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
217217
fi
218218
219219
- name: Determine new patched RN version

Mobile-Expensify

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ android {
111111
minSdkVersion rootProject.ext.minSdkVersion
112112
targetSdkVersion rootProject.ext.targetSdkVersion
113113
multiDexEnabled rootProject.ext.multiDexEnabled
114-
versionCode 1009044902
115-
versionName "9.4.49-2"
114+
versionCode 1009045101
115+
versionName "9.4.51-1"
116116
// Supported language variants must be declared here to avoid from being removed during the compilation.
117117
// This also helps us to not include unnecessary language variants in the APK.
118118
resConfigs "en", "es"

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ buildscript {
1616
// "mapbox" indicates the usage of the Mapbox SDK.
1717
RNMapboxMapsImpl = "mapbox"
1818
reactNativeIncludedBuild = gradle.getIncludedBuilds().find { it.name == 'react-native' }
19-
// This is our custom extension that we defined in gradleUtils/PatchedArtifactsSettings.gradle
19+
// This is our custom extension that we defined in scripts/artifacts-utils/android/PatchedArtifactsSettings.gradle
2020
// It enables us to use custom artifacts of patched react-native
2121
patchedArtifactsConfig = project.gradle.settings.extensions.findByName('patchedArtifacts')
2222
}

0 commit comments

Comments
 (0)