Add local iOS release pipeline, fix shortcuts, and improve invoice UX.

Enable App Store builds without EAS, iOS 18 App Intents plugins, and signing
fixes for distribution export. Add mobile invoice PDF preview, compact line
items, and more reliable shortcut deep-link handling.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-23 01:08:20 -04:00
parent 06bc91ac13
commit 355b14faef
35 changed files with 1915 additions and 502 deletions
+45 -3
View File
@@ -8,6 +8,7 @@ const fs = require("fs");
const path = require("path");
const SWIFT_FILES = [
"BeenVoiceIntentHelpers.swift",
"ClockInIntent.swift",
"ClockOutIntent.swift",
"OpenTimerIntent.swift",
@@ -25,8 +26,11 @@ function withAppIntents(config) {
config = withDangerousMod(config, [
"ios",
async (config) => {
const projectRoot = config.modRequest.projectRoot;
const platformRoot = config.modRequest.platformProjectRoot;
const projectName = IOSConfig.XcodeUtils.getProjectName(platformRoot);
const projectName =
config.modRequest.projectName ??
IOSConfig.XcodeUtils.getProjectName(projectRoot);
const targetDir = path.join(platformRoot, projectName);
fs.mkdirSync(targetDir, { recursive: true });
@@ -35,14 +39,50 @@ function withAppIntents(config) {
fs.copyFileSync(path.join(appIntentsSource, file), path.join(targetDir, file));
}
const appDelegatePath = path.join(targetDir, "AppDelegate.swift");
if (fs.existsSync(appDelegatePath)) {
let appDelegate = fs.readFileSync(appDelegatePath, "utf8");
const marker = "BeenVoiceShortcuts.updateAppShortcutParameters";
if (!appDelegate.includes("import AppIntents")) {
appDelegate = appDelegate.replace(
"internal import Expo",
"import AppIntents\ninternal import Expo",
);
}
if (appDelegate.includes(marker)) {
appDelegate = appDelegate.replace(
/if #available\(iOS 16\.0, \*\)/g,
"if #available(iOS 18.0, *)",
);
} else {
appDelegate = appDelegate.replace(
"return super.application(application, didFinishLaunchingWithOptions: launchOptions)",
`if #available(iOS 18.0, *) {
Task {
await BeenVoiceShortcuts.updateAppShortcutParameters()
}
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)`,
);
}
fs.writeFileSync(appDelegatePath, appDelegate);
}
return config;
},
]);
return withXcodeProject(config, (config) => {
const project = config.modResults;
const projectRoot = config.modRequest.projectRoot;
const platformRoot = config.modRequest.platformProjectRoot;
const projectName = IOSConfig.XcodeUtils.getProjectName(platformRoot);
const projectName =
config.modRequest.projectName ??
IOSConfig.XcodeUtils.getProjectName(projectRoot);
for (const file of SWIFT_FILES) {
const filepath = `${projectName}/${file}`;
@@ -56,7 +96,9 @@ function withAppIntents(config) {
entry &&
typeof entry === "object" &&
"path" in entry &&
entry.path === file,
(entry.path === file ||
entry.path === `${projectName}/${file}` ||
String(entry.path).endsWith(`/${file}`)),
);
if (!alreadyLinked) {