peachsim 0.1.899 → 0.1.908
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/cli/app-fonts.ts +27 -2
- package/cli/commands/box/bundle-plane.ts +13 -4
- package/cli/commands/box.ts +22 -1
- package/cli/commands/control.ts +29 -16
- package/cli/commands/flow.ts +8 -1
- package/cli/commands/platform.ts +15 -2
- package/cli/commands/skills.ts +125 -10
- package/cli/commands/upload.ts +53 -39
- package/cli/flow-live-status.ts +11 -6
- package/detox/expectations.ts +22 -15
- package/detox/index.ts +4 -19
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/bundle-channel.cjs +8 -5
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +15 -18
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +8 -5
- package/dist-lib/expo-swift-metadata.cjs +1 -1
- package/dist-lib/expo-swift-metadata.mjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +8 -5
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/native-app-identity.cjs +1 -1
- package/dist-lib/native-app-identity.mjs +1 -1
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/plist.cjs +1 -1
- package/dist-lib/plist.mjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +136 -25
- package/dist-lib/swift-compile.cjs +1 -1
- package/dist-lib/swift-compile.mjs +1 -1
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift-toolchain.cjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +1 -1
- package/dist-lib/vite.cjs +1 -1
- package/dist-lib/worklet-executable.cjs +1 -1
- package/dist-lib/worklet-executable.mjs +1 -1
- package/kotlin/fork/NOTICE +3 -0
- package/kotlin/fork/README.md +10 -2
- package/kotlin/fork/build.sh +14 -14
- package/kotlin/fork/compose-worker-globals.patch +105 -0
- package/kotlin/fork/fork.json +3 -3
- package/kotlin/fork/publish.ts +8 -1
- package/kotlin/fork/skia-android-shaping.patch +30 -0
- package/kotlin/fork/skiko-local.init.gradle +10 -0
- package/kotlin/fork/skiko-worker-clock.patch +17 -0
- package/kotlin/toolchain.json +9 -9
- package/package.json +1 -1
- package/skills/peach-debug/SKILL.md +15 -153
- package/skills/peach-debug/references/accessibility.md +102 -0
- package/skills/peach-debug/references/commands.md +56 -0
- package/src/expo-swift-host.ts +15 -4
- package/src/vite-plugin.ts +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/plist.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/plist.mjs
CHANGED
package/dist-lib/profiles.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/render-mode.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/sdk.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/sdk.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -4370,6 +4370,8 @@ var init_supported_native_packages = __esm({
|
|
|
4370
4370
|
// coverage
|
|
4371
4371
|
"@callstack/liquid-glass",
|
|
4372
4372
|
// preset+seam
|
|
4373
|
+
"@callstack/react-native-brownfield",
|
|
4374
|
+
// seam
|
|
4373
4375
|
"@callstack/react-native-local-notifications",
|
|
4374
4376
|
// seam
|
|
4375
4377
|
"@candlefinance/faster-image",
|
|
@@ -6460,7 +6462,7 @@ var init_registry = __esm({
|
|
|
6460
6462
|
range: ">=5.0.0",
|
|
6461
6463
|
coverage: 0.95,
|
|
6462
6464
|
note: "real upstream package \u2014 not intercepted. the app's expo-application JS runs over the ExpoApplication native module, whose identity constants follow the live Expo config.",
|
|
6463
|
-
working: "upstream constants and platform availability checks, applicationName, applicationId, nativeApplicationVersion, nativeBuildVersion, getIosIdForVendorAsync (localStorage-backed), getIosApplicationReleaseTypeAsync SIMULATOR, ApplicationReleaseType enum, getInstallationTimeAsync, getIosPushNotificationServiceEnvironmentAsync",
|
|
6465
|
+
working: "upstream constants and platform availability checks, applicationName, applicationId, nativeApplicationVersion, nativeBuildVersion, getIosIdForVendorAsync (localStorage-backed), getIosApplicationReleaseTypeAsync SIMULATOR, ApplicationReleaseType enum, getInstallationTimeAsync (persisted iOS Documents creation date), getIosPushNotificationServiceEnvironmentAsync",
|
|
6464
6466
|
missing: "bare/frozen apps without resolved Expo config use simulator metadata; Android id/install referrer on non-Android platforms; push entitlement inspection"
|
|
6465
6467
|
}
|
|
6466
6468
|
]
|
|
@@ -6837,7 +6839,7 @@ var init_registry = __esm({
|
|
|
6837
6839
|
range: ">=10.0.0",
|
|
6838
6840
|
coverage: 1,
|
|
6839
6841
|
note: "comprehensive live-device mock \u2014 hardware fields follow the active device spec and app identity fields follow the live Expo config",
|
|
6840
|
-
working: "all sync and async getters: uniqueId, model, brand, systemName/Version, live bundleId/buildNumber/version/appName, deviceName, deviceType, manufacturer, carrier, totalMemory, diskCapacity, freeDiskStorage, fontScale, isEmulator, isTablet, hasNotch, hasDynamicIsland, isLandscape, brightness, getBatteryLevel and ~60 more"
|
|
6842
|
+
working: "all sync and async getters: uniqueId, model, brand, systemName/Version, live bundleId/buildNumber/version/appName, deviceName, deviceType, manufacturer, carrier, totalMemory, diskCapacity, freeDiskStorage, fontScale, isEmulator, isTablet, hasNotch, hasDynamicIsland, isLandscape, brightness, getBatteryLevel, getFirstInstallTime (persisted iOS Documents creation date) and ~60 more"
|
|
6841
6843
|
}
|
|
6842
6844
|
]
|
|
6843
6845
|
},
|
|
@@ -12373,8 +12375,10 @@ var init_registry = __esm({
|
|
|
12373
12375
|
versions: [
|
|
12374
12376
|
{
|
|
12375
12377
|
range: ">=1.0.0",
|
|
12376
|
-
coverage: 0,
|
|
12377
|
-
note: "
|
|
12378
|
+
coverage: 0.5,
|
|
12379
|
+
note: "published ReactNativeBrownfield.js runs unchanged against a ReactNativeBrownfield seam that mirrors the hostless regime: silent methods, subscribed but never-emitted messages",
|
|
12380
|
+
working: "module presence; ios popToNative, setNativeBackGestureAndButtonEnabled, postMessage all silent; onMessage subscribe and remove with zero events on both platforms; android back-button flag write",
|
|
12381
|
+
missing: "host integration paths: android postMessage dispatch, android popToNative back press, native-to-js message emission"
|
|
12378
12382
|
}
|
|
12379
12383
|
]
|
|
12380
12384
|
},
|
|
@@ -37638,7 +37642,7 @@ async function collectExpoSwiftSources(appRoot) {
|
|
|
37638
37642
|
const namespacesSeen = /* @__PURE__ */ new Set();
|
|
37639
37643
|
let bytes = 0;
|
|
37640
37644
|
let fileCount = 0;
|
|
37641
|
-
for (const entry of Object.
|
|
37645
|
+
for (const [, entry] of Object.entries(search).sort(([a], [b]) => a.localeCompare(b))) {
|
|
37642
37646
|
if (!entry || typeof entry !== "object")
|
|
37643
37647
|
throw new Error("invalid Expo autolinking entry");
|
|
37644
37648
|
const sourceRoot = Reflect.get(entry, "path");
|
|
@@ -37663,8 +37667,8 @@ async function collectExpoSwiftSources(appRoot) {
|
|
|
37663
37667
|
const files2 = {};
|
|
37664
37668
|
const classes = [];
|
|
37665
37669
|
for (const module2 of modules) {
|
|
37666
|
-
const className = module2 && typeof module2 === "object" ? Reflect.get(module2, "class") : null;
|
|
37667
|
-
const name2 = module2 && typeof module2 === "object" ? Reflect.get(module2, "name") : null;
|
|
37670
|
+
const className = typeof module2 === "string" ? module2 : module2 && typeof module2 === "object" ? Reflect.get(module2, "class") : null;
|
|
37671
|
+
const name2 = typeof module2 === "string" ? null : module2 && typeof module2 === "object" ? Reflect.get(module2, "name") : null;
|
|
37668
37672
|
if (typeof className !== "string" || !/^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(className) || name2 !== null && typeof name2 !== "string")
|
|
37669
37673
|
throw new Error(`${sourceRoot}: invalid Expo Apple module descriptor`);
|
|
37670
37674
|
classes.push({
|
|
@@ -37690,7 +37694,10 @@ async function collectExpoSwiftSources(appRoot) {
|
|
|
37690
37694
|
fileCount++;
|
|
37691
37695
|
if (fileCount > MAX_SWIFT_COMPILE_FILES - 2 || bytes > MAX_SWIFT_COMPILE_SOURCE_BYTES)
|
|
37692
37696
|
throw new Error("Expo Swift sources exceed compile service caps");
|
|
37693
|
-
files2[`Sources/${namespace}/${import_node_path21.default.relative(ios, file).split(import_node_path21.default.sep).join("/")}`] =
|
|
37697
|
+
files2[`Sources/${namespace}/${import_node_path21.default.relative(ios, file).split(import_node_path21.default.sep).join("/")}`] = // CocoaPods' iOS umbrella header imports UIKit into every Swift file
|
|
37698
|
+
// through the underlying module; these source units have no clang pod.
|
|
37699
|
+
`import UIKit
|
|
37700
|
+
#sourceLocation(file: ${JSON.stringify(file)}, line: 1)
|
|
37694
37701
|
${import_node_fs20.default.readFileSync(file, "utf8")}`;
|
|
37695
37702
|
}
|
|
37696
37703
|
};
|
|
@@ -49615,6 +49622,9 @@ var init_app_config = __esm({
|
|
|
49615
49622
|
function discoverNativeLinkedAppFonts(opts) {
|
|
49616
49623
|
const metroOrigin = loopbackOriginOf(opts.bundleUrl);
|
|
49617
49624
|
if (!metroOrigin) return [];
|
|
49625
|
+
return (0, import_config_plugin_fonts.metroFontSpecsFromPaths)(discoverNativeLinkedAppFontPaths(opts), metroOrigin);
|
|
49626
|
+
}
|
|
49627
|
+
function discoverNativeLinkedAppFontPaths(opts) {
|
|
49618
49628
|
const project = resolveAppProject(opts.projectDir);
|
|
49619
49629
|
const selectedAppDir = project?.appDir ?? null;
|
|
49620
49630
|
if (!selectedAppDir) return [];
|
|
@@ -49701,7 +49711,7 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
49701
49711
|
if (!relativeRoot.startsWith("..") && !import_node_path39.default.isAbsolute(relativeRoot)) {
|
|
49702
49712
|
collectFontFiles(root, relativeRoot.split(import_node_path39.default.sep).join("/"));
|
|
49703
49713
|
}
|
|
49704
|
-
const bundleDir = import_node_path39.default.posix.dirname(new URL(opts.bundleUrl).pathname).replace(/^\/+/, "");
|
|
49714
|
+
const bundleDir = import_node_path39.default.posix.dirname(opts.bundleUrl ? new URL(opts.bundleUrl).pathname : "/").replace(/^\/+/, "");
|
|
49705
49715
|
const appRelativeDir = bundleDir.split("/").join(import_node_path39.default.sep);
|
|
49706
49716
|
const metroRootCandidates = [selectedAppDir];
|
|
49707
49717
|
if (bundleDir && selectedAppDir.endsWith(import_node_path39.default.sep + appRelativeDir)) {
|
|
@@ -49792,7 +49802,7 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
49792
49802
|
} catch {
|
|
49793
49803
|
}
|
|
49794
49804
|
}
|
|
49795
|
-
return
|
|
49805
|
+
return [...new Set(fontPaths)];
|
|
49796
49806
|
}
|
|
49797
49807
|
async function resolveMetroProjectRoot(bundleUrl, opts) {
|
|
49798
49808
|
const origin = loopbackOriginOf(bundleUrl);
|
|
@@ -53110,9 +53120,98 @@ function targetFromHome(envName, fallbackDir) {
|
|
|
53110
53120
|
const home = process.env[envName] || path35.join(os9.homedir(), fallbackDir);
|
|
53111
53121
|
return path35.join(home, "skills");
|
|
53112
53122
|
}
|
|
53123
|
+
function codexTargets() {
|
|
53124
|
+
const homes = /* @__PURE__ */ new Map();
|
|
53125
|
+
const userHome = process.env.HOME || os9.homedir();
|
|
53126
|
+
const primaryCodexHome = process.env.CODEX_HOME || path35.join(userHome, ".codex");
|
|
53127
|
+
homes.set(path35.resolve(primaryCodexHome), "codex");
|
|
53128
|
+
const tmCodexHomes = process.env.TM_CODEX_HOMES;
|
|
53129
|
+
if (tmCodexHomes) {
|
|
53130
|
+
for (const h of tmCodexHomes.split(path35.delimiter)) {
|
|
53131
|
+
if (h.trim()) {
|
|
53132
|
+
const resolved = path35.resolve(h.trim());
|
|
53133
|
+
if (!homes.has(resolved)) {
|
|
53134
|
+
homes.set(resolved, path35.basename(resolved).replace(/^\./, ""));
|
|
53135
|
+
}
|
|
53136
|
+
}
|
|
53137
|
+
}
|
|
53138
|
+
}
|
|
53139
|
+
const tmHome = process.env.TM_HOME || path35.join(userHome, ".team-machine");
|
|
53140
|
+
const enginePath = path35.join(tmHome, "engine.yaml");
|
|
53141
|
+
if (fs30.existsSync(enginePath)) {
|
|
53142
|
+
try {
|
|
53143
|
+
const content = fs30.readFileSync(enginePath, "utf8");
|
|
53144
|
+
let inCodex = false;
|
|
53145
|
+
let inAccounts = false;
|
|
53146
|
+
let currentAccount = "";
|
|
53147
|
+
for (const line of content.split("\n")) {
|
|
53148
|
+
const indent = line.search(/\S/);
|
|
53149
|
+
const trimmed = line.trim();
|
|
53150
|
+
if (indent === -1) continue;
|
|
53151
|
+
if (indent === 4) {
|
|
53152
|
+
inCodex = trimmed === "codex:";
|
|
53153
|
+
inAccounts = false;
|
|
53154
|
+
currentAccount = "";
|
|
53155
|
+
continue;
|
|
53156
|
+
}
|
|
53157
|
+
if (!inCodex) continue;
|
|
53158
|
+
if (indent === 6 && trimmed === "accounts:") {
|
|
53159
|
+
inAccounts = true;
|
|
53160
|
+
currentAccount = "";
|
|
53161
|
+
continue;
|
|
53162
|
+
}
|
|
53163
|
+
if (!inAccounts) continue;
|
|
53164
|
+
if (indent === 8 && trimmed.endsWith(":")) {
|
|
53165
|
+
currentAccount = trimmed.slice(0, -1).trim();
|
|
53166
|
+
continue;
|
|
53167
|
+
}
|
|
53168
|
+
if (indent >= 10 && currentAccount) {
|
|
53169
|
+
const match = /^home:\s*(.+)$/.exec(trimmed);
|
|
53170
|
+
if (match) {
|
|
53171
|
+
let homeDir = match[1].trim();
|
|
53172
|
+
if (homeDir.startsWith("~")) {
|
|
53173
|
+
homeDir = path35.join(userHome, homeDir.slice(1));
|
|
53174
|
+
}
|
|
53175
|
+
const resolved = path35.resolve(homeDir);
|
|
53176
|
+
if (!homes.has(resolved)) {
|
|
53177
|
+
homes.set(resolved, `codex-${currentAccount}`);
|
|
53178
|
+
}
|
|
53179
|
+
}
|
|
53180
|
+
}
|
|
53181
|
+
}
|
|
53182
|
+
} catch {
|
|
53183
|
+
}
|
|
53184
|
+
}
|
|
53185
|
+
try {
|
|
53186
|
+
for (const entry of fs30.readdirSync(userHome)) {
|
|
53187
|
+
if (entry.startsWith(".codex-")) {
|
|
53188
|
+
const fullPath = path35.join(userHome, entry);
|
|
53189
|
+
try {
|
|
53190
|
+
const stat2 = fs30.statSync(fullPath);
|
|
53191
|
+
if (stat2.isDirectory()) {
|
|
53192
|
+
const resolved = path35.resolve(fullPath);
|
|
53193
|
+
if (!homes.has(resolved)) {
|
|
53194
|
+
homes.set(resolved, entry.replace(/^\./, ""));
|
|
53195
|
+
}
|
|
53196
|
+
}
|
|
53197
|
+
} catch {
|
|
53198
|
+
}
|
|
53199
|
+
}
|
|
53200
|
+
}
|
|
53201
|
+
} catch {
|
|
53202
|
+
}
|
|
53203
|
+
const targets = [];
|
|
53204
|
+
for (const [homePath, label] of homes) {
|
|
53205
|
+
targets.push({
|
|
53206
|
+
label,
|
|
53207
|
+
dir: path35.join(homePath, "skills")
|
|
53208
|
+
});
|
|
53209
|
+
}
|
|
53210
|
+
return targets;
|
|
53211
|
+
}
|
|
53113
53212
|
function defaultAgentTargets() {
|
|
53114
53213
|
return [
|
|
53115
|
-
|
|
53214
|
+
...codexTargets(),
|
|
53116
53215
|
{ label: "claude", dir: targetFromHome("CLAUDE_CONFIG_DIR", ".claude") }
|
|
53117
53216
|
];
|
|
53118
53217
|
}
|
|
@@ -53618,16 +53717,26 @@ async function ensureBridgeForOpen(preferredPort, explicitPort = false, resource
|
|
|
53618
53717
|
);
|
|
53619
53718
|
}
|
|
53620
53719
|
const { executable, prefixArgs } = rnxSelfInvocation();
|
|
53621
|
-
const
|
|
53622
|
-
|
|
53623
|
-
|
|
53624
|
-
{
|
|
53625
|
-
detached: true,
|
|
53626
|
-
stdio: "ignore",
|
|
53627
|
-
// this bridge does not supply the shell, so it needs no runtime updates.
|
|
53628
|
-
env: runtimeSource === "external" ? { ...process.env, PEACH_UPDATE_CHECK: "off" } : process.env
|
|
53629
|
-
}
|
|
53720
|
+
const bridgeLogPath = import_node_path43.default.join(
|
|
53721
|
+
import_node_os11.default.tmpdir(),
|
|
53722
|
+
`peach-bridge-${Date.now()}-${process.pid}.log`
|
|
53630
53723
|
);
|
|
53724
|
+
const bridgeLogFd = import_node_fs41.default.openSync(bridgeLogPath, "a");
|
|
53725
|
+
let child;
|
|
53726
|
+
try {
|
|
53727
|
+
child = (0, import_node_child_process16.spawn)(
|
|
53728
|
+
executable,
|
|
53729
|
+
[...prefixArgs, "serve", "--quiet", "--port", String(preferredPort)],
|
|
53730
|
+
{
|
|
53731
|
+
detached: true,
|
|
53732
|
+
stdio: ["ignore", "ignore", bridgeLogFd],
|
|
53733
|
+
// this bridge does not supply the shell, so it needs no runtime updates.
|
|
53734
|
+
env: runtimeSource === "external" ? { ...process.env, PEACH_UPDATE_CHECK: "off" } : process.env
|
|
53735
|
+
}
|
|
53736
|
+
);
|
|
53737
|
+
} finally {
|
|
53738
|
+
import_node_fs41.default.closeSync(bridgeLogFd);
|
|
53739
|
+
}
|
|
53631
53740
|
if (resources) {
|
|
53632
53741
|
resources.bridge = child;
|
|
53633
53742
|
resources.port = preferredPort;
|
|
@@ -53658,13 +53767,15 @@ async function ensureBridgeForOpen(preferredPort, explicitPort = false, resource
|
|
|
53658
53767
|
}
|
|
53659
53768
|
return selectedPort;
|
|
53660
53769
|
}
|
|
53661
|
-
if (childExit)
|
|
53662
|
-
throw new Error(`peach bridge exited before becoming ready (exit ${childExit})`);
|
|
53663
|
-
}
|
|
53770
|
+
if (childExit) break;
|
|
53664
53771
|
await sleep(150);
|
|
53665
53772
|
}
|
|
53773
|
+
const reason = childExit ? `peach bridge exited before becoming ready (exit ${childExit})` : `peach bridge did not start within ${Math.round(OPEN_BRIDGE_SPAWN_TIMEOUT_MS / 1e3)}s`;
|
|
53774
|
+
const bridgeLog = import_node_fs41.default.readFileSync(bridgeLogPath, "utf8").trim().slice(-2e3);
|
|
53666
53775
|
throw new Error(
|
|
53667
|
-
|
|
53776
|
+
`${reason}${bridgeLog ? `
|
|
53777
|
+
${bridgeLog}` : ""}
|
|
53778
|
+
bridge log: ${bridgeLogPath}`
|
|
53668
53779
|
);
|
|
53669
53780
|
}
|
|
53670
53781
|
function assertExplicitBridgeLock(preferredPort, explicitPort, lock) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/swift.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/vite-swift.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.908 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/kotlin/fork/NOTICE
CHANGED
|
@@ -46,3 +46,6 @@ The FreeType patch preserves explicit forced autohinting and disables implicit
|
|
|
46
46
|
autohinting, matching Android. The Wasm compiler uses Android text gamma 1.4
|
|
47
47
|
and contrast 0; the pinned surface and FreeType units replace their archive
|
|
48
48
|
counterparts. FreeType headers come from the same dependency revision as Skia.
|
|
49
|
+
|
|
50
|
+
Android centered text uses the platform intrinsic padding, integer origin and
|
|
51
|
+
line bounds. Compose selects the added Skiko alignment ordinal only on Android.
|
package/kotlin/fork/README.md
CHANGED
|
@@ -17,7 +17,9 @@ Android behavior for the approved web differences and static text shaping below.
|
|
|
17
17
|
| Compose `ui-skiko` | `SkikoText.nonAndroid.kt`, `SkikoParagraphBuilder.nonAndroid.kt` | Android static advances and letter-spacing scale; Animated text retains fractional shaping |
|
|
18
18
|
| Skia shaper | `SkShaper_harfbuzz.cpp` | measurement-font copy truncates static shaping size; the painted run font retains the requested size |
|
|
19
19
|
| Skia raster | `SkFontHost_FreeType.cpp`, `SkFontHost_FreeType_common.cpp`, `SkSurface.cpp` | Android implicit autohinting policy and text gamma 1.4, contrast 0 |
|
|
20
|
-
| Skia paragraph | `Run.cpp`, `TextLine.cpp`, `TextWrapper.cpp` | Android inter-glyph spacing, caret boundaries
|
|
20
|
+
| Skia paragraph | `Run.cpp`, `TextLine.cpp`, `TextWrapper.cpp`, `DartTypes.h` | Android inter-glyph spacing, caret boundaries, edge trimming before line fits and integer center origins |
|
|
21
|
+
| Compose `ui-skiko` | `SkikoParagraphIntrinsics.nonAndroid.kt`, `SkikoParagraph.nonAndroid.kt`, `SkikoParagraphBuilder.nonAndroid.kt` | Android letter-spacing intrinsic padding, centered line bounds and explicit center alignment |
|
|
22
|
+
| Skiko paragraph | `Alignment.kt` | transports the Android center ordinal without changing existing alignments |
|
|
21
23
|
| Compose `material3` | `PlatformDateFormat.web.kt` | timestamp formatting uses UTC, as Android does |
|
|
22
24
|
| Navigation `navigation-compose` | `DefaultNavTransitions.web.kt` | Android forward fades and predictive pop defaults |
|
|
23
25
|
| Skiko | `OsArch.web.kt` | explicit `setHostOsProvider`; its default lazily retains upstream OS detection |
|
|
@@ -41,7 +43,13 @@ the FreeType binary remains the archive version. Raster changes add no allocatio
|
|
|
41
43
|
and retain the existing A8 preblend path. This adds no allocation beyond the existing
|
|
42
44
|
measurement-font copy, and truncates once per shaped font, outside the glyph loop.
|
|
43
45
|
Paragraph spacing adds constant arithmetic per glyph or cluster; line fits trim
|
|
44
|
-
the same edge half-spaces as completed lines, without allocation.
|
|
46
|
+
the same edge half-spaces as completed lines, without allocation. Android centered
|
|
47
|
+
lines use the platform integer origin; other platforms retain fractional centering.
|
|
48
|
+
Intrinsic measurement checks span letter spacing once and adds Android’s 0.5 px
|
|
49
|
+
padding; line bounds use the platform floor and ceil. These corrections add no
|
|
50
|
+
allocation. Skiko builds before Compose, whose `skiko-wasm-js` dependency resolves
|
|
51
|
+
from this invocation’s Maven directory through `skiko-local.init.gradle`. The init
|
|
52
|
+
script travels in the immutable build record with the patches.
|
|
45
53
|
|
|
46
54
|
```sh
|
|
47
55
|
delivery="scripts/tmp/kotlin-fork-$(date +%s)-$$"
|
package/kotlin/fork/build.sh
CHANGED
|
@@ -102,19 +102,6 @@ gradle() {
|
|
|
102
102
|
rm -rf "${DELIVER}" "${M2}"
|
|
103
103
|
mkdir -p "${DELIVER}"
|
|
104
104
|
|
|
105
|
-
checkout 0
|
|
106
|
-
(
|
|
107
|
-
cd "${SOURCE}"
|
|
108
|
-
gradle -Pcompose.platforms=web -Pjetbrains.publication.version.COMPOSE=1.13.0-alpha01 \
|
|
109
|
-
-Pjetbrains.publication.version.COMPOSE_MATERIAL3=1.13.0-alpha01 \
|
|
110
|
-
-Pjetbrains.publication.version.NAVIGATION=2.10.0-beta01 \
|
|
111
|
-
:compose:ui:ui:publishWasmJsPublicationToMavenLocal \
|
|
112
|
-
:compose:ui:ui-text:publishWasmJsPublicationToMavenLocal \
|
|
113
|
-
:compose:ui:ui-skiko:publishWasmJsPublicationToMavenLocal \
|
|
114
|
-
:compose:material3:material3:publishWasmJsPublicationToMavenLocal \
|
|
115
|
-
:navigation:navigation-compose:publishWasmJsPublicationToMavenLocal
|
|
116
|
-
)
|
|
117
|
-
|
|
118
105
|
checkout 1
|
|
119
106
|
SKIKO_SOURCE=${SOURCE}
|
|
120
107
|
checkout 2
|
|
@@ -161,6 +148,19 @@ cp "${SOURCE}/src/image/SkSurface.cpp" "${SKIKO_SOURCE}/skiko/src/nativeJsMain/c
|
|
|
161
148
|
cp build/libs/skiko-wasm-0.152.0-alpha02.jar "${DELIVER}/"
|
|
162
149
|
)
|
|
163
150
|
|
|
151
|
+
checkout 0
|
|
152
|
+
(
|
|
153
|
+
cd "${SOURCE}"
|
|
154
|
+
gradle -I "${FORK}/skiko-local.init.gradle" -Pcompose.platforms=web -Pjetbrains.publication.version.COMPOSE=1.13.0-alpha01 \
|
|
155
|
+
-Pjetbrains.publication.version.COMPOSE_MATERIAL3=1.13.0-alpha01 \
|
|
156
|
+
-Pjetbrains.publication.version.NAVIGATION=2.10.0-beta01 \
|
|
157
|
+
:compose:ui:ui:publishWasmJsPublicationToMavenLocal \
|
|
158
|
+
:compose:ui:ui-text:publishWasmJsPublicationToMavenLocal \
|
|
159
|
+
:compose:ui:ui-skiko:publishWasmJsPublicationToMavenLocal \
|
|
160
|
+
:compose:material3:material3:publishWasmJsPublicationToMavenLocal \
|
|
161
|
+
:navigation:navigation-compose:publishWasmJsPublicationToMavenLocal
|
|
162
|
+
)
|
|
163
|
+
|
|
164
164
|
cp "${M2}/org/jetbrains/compose/ui/ui-wasm-js/1.13.0-alpha01/ui-wasm-js-1.13.0-alpha01.klib" \
|
|
165
165
|
"${M2}/org/jetbrains/compose/ui/ui-text-wasm-js/1.13.0-alpha01/ui-text-wasm-js-1.13.0-alpha01.klib" \
|
|
166
166
|
"${M2}/org/jetbrains/compose/ui/ui-skiko-wasm-js/1.13.0-alpha01/ui-skiko-wasm-js-1.13.0-alpha01.klib" \
|
|
@@ -170,5 +170,5 @@ cp "${M2}/org/jetbrains/compose/ui/ui-wasm-js/1.13.0-alpha01/ui-wasm-js-1.13.0-a
|
|
|
170
170
|
"${DELIVER}/"
|
|
171
171
|
# the record travels with the klibs it describes, so publishing attaches what
|
|
172
172
|
# this build used, not whatever the checkout holds later
|
|
173
|
-
cp "${FORK}/fork.json" "${FORK}/LICENSE" "${FORK}/NOTICE" "${FORK}/SKIA_LICENSE" "${FORK}"/*.patch "${DELIVER}/"
|
|
173
|
+
cp "${FORK}/fork.json" "${FORK}/LICENSE" "${FORK}/NOTICE" "${FORK}/SKIA_LICENSE" "${FORK}"/*.patch "${FORK}/skiko-local.init.gradle" "${DELIVER}/"
|
|
174
174
|
(cd "${DELIVER}" && sha256sum -- *.klib *.jar > artifacts.sha256 && cat artifacts.sha256)
|
|
@@ -329,3 +329,108 @@ diff --git a/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/t
|
|
|
329
329
|
)
|
|
330
330
|
for (i in 1 until activeStyles.size) {
|
|
331
331
|
style.merge(density, activeStyles[i])
|
|
332
|
+
diff --git a/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/SkikoParagraph.nonAndroid.kt b/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/SkikoParagraph.nonAndroid.kt
|
|
333
|
+
--- a/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/SkikoParagraph.nonAndroid.kt
|
|
334
|
+
+++ b/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/SkikoParagraph.nonAndroid.kt
|
|
335
|
+
@@ -1,3 +1,4 @@
|
|
336
|
+
+// modified for peach: Android text bounds and intrinsic padding match the platform.
|
|
337
|
+
/*
|
|
338
|
+
* Copyright 2023 The Android Open Source Project
|
|
339
|
+
*
|
|
340
|
+
@@ -35,6 +36,8 @@
|
|
341
|
+
import androidx.compose.ui.graphics.toComposeRect
|
|
342
|
+
import androidx.compose.ui.text.PlatformParagraph
|
|
343
|
+
import androidx.compose.ui.text.platform.SkikoParagraphIntrinsics
|
|
344
|
+
+import androidx.compose.ui.text.platform.Platform
|
|
345
|
+
+import androidx.compose.ui.text.platform.currentPlatform
|
|
346
|
+
import androidx.compose.ui.text.platform.cursorHorizontalPosition
|
|
347
|
+
import androidx.compose.ui.text.style.LineHeightStyle
|
|
348
|
+
import androidx.compose.ui.text.style.ResolvedTextDirection
|
|
349
|
+
@@ -43,6 +46,7 @@
|
|
350
|
+
import androidx.compose.ui.text.style.TextOverflow
|
|
351
|
+
import androidx.compose.ui.unit.Constraints
|
|
352
|
+
import androidx.compose.ui.unit.isUnspecified
|
|
353
|
+
+import kotlin.math.ceil
|
|
354
|
+
import kotlin.math.floor
|
|
355
|
+
import org.jetbrains.skia.FontMetrics
|
|
356
|
+
import org.jetbrains.skia.IRange
|
|
357
|
+
@@ -217,10 +221,18 @@
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
override fun getLineLeft(lineIndex: Int): Float =
|
|
361
|
+
- lineMetrics.getOrNull(lineIndex)?.left?.toFloat() ?: 0f
|
|
362
|
+
+ lineMetrics.getOrNull(lineIndex)?.let { line ->
|
|
363
|
+
+ if (currentPlatform() == Platform.Android && paragraphIntrinsics.style.textAlign == TextAlign.Center) {
|
|
364
|
+
+ floor((width - line.width.toFloat()) / 2)
|
|
365
|
+
+ } else line.left.toFloat()
|
|
366
|
+
+ } ?: 0f
|
|
367
|
+
|
|
368
|
+
override fun getLineRight(lineIndex: Int): Float =
|
|
369
|
+
- lineMetrics.getOrNull(lineIndex)?.right?.toFloat() ?: 0f
|
|
370
|
+
+ lineMetrics.getOrNull(lineIndex)?.let { line ->
|
|
371
|
+
+ if (currentPlatform() == Platform.Android && paragraphIntrinsics.style.textAlign == TextAlign.Center) {
|
|
372
|
+
+ ceil((width + line.width.toFloat()) / 2)
|
|
373
|
+
+ } else line.right.toFloat()
|
|
374
|
+
+ } ?: 0f
|
|
375
|
+
|
|
376
|
+
override fun getLineTop(lineIndex: Int) =
|
|
377
|
+
lineMetrics.getOrNull(lineIndex)?.let { line ->
|
|
378
|
+
diff --git a/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/platform/SkikoParagraphIntrinsics.nonAndroid.kt b/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/platform/SkikoParagraphIntrinsics.nonAndroid.kt
|
|
379
|
+
--- a/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/platform/SkikoParagraphIntrinsics.nonAndroid.kt
|
|
380
|
+
+++ b/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/platform/SkikoParagraphIntrinsics.nonAndroid.kt
|
|
381
|
+
@@ -1,3 +1,4 @@
|
|
382
|
+
+// modified for peach: Android text bounds and intrinsic padding match the platform.
|
|
383
|
+
@file:OptIn(InternalComposeUiApi::class)
|
|
384
|
+
|
|
385
|
+
/*
|
|
386
|
+
@@ -26,6 +27,7 @@
|
|
387
|
+
import androidx.compose.ui.text.ParagraphIntrinsics
|
|
388
|
+
import androidx.compose.ui.text.Placeholder
|
|
389
|
+
import androidx.compose.ui.text.StrongDirectionType
|
|
390
|
+
+import androidx.compose.ui.text.SpanStyle
|
|
391
|
+
import androidx.compose.ui.text.TextStyle
|
|
392
|
+
import androidx.compose.ui.text.firstStrongDirectionType
|
|
393
|
+
import androidx.compose.ui.text.font.FontFamily
|
|
394
|
+
@@ -35,11 +37,12 @@
|
|
395
|
+
import androidx.compose.ui.text.style.ResolvedTextDirection
|
|
396
|
+
import androidx.compose.ui.text.style.TextDirection
|
|
397
|
+
import androidx.compose.ui.unit.Density
|
|
398
|
+
+import androidx.compose.ui.unit.TextUnit
|
|
399
|
+
import kotlin.math.ceil
|
|
400
|
+
|
|
401
|
+
internal class SkikoParagraphIntrinsics(
|
|
402
|
+
val text: String,
|
|
403
|
+
- private val style: TextStyle,
|
|
404
|
+
+ val style: TextStyle,
|
|
405
|
+
private val annotations: List<AnnotatedString.Range<out AnnotatedString.Annotation>>,
|
|
406
|
+
private val placeholders: List<Range<Placeholder>>,
|
|
407
|
+
private val density: Density,
|
|
408
|
+
@@ -79,6 +82,16 @@
|
|
409
|
+
val para = layouter!!.layoutParagraph(Float.POSITIVE_INFINITY)
|
|
410
|
+
minIntrinsicWidth = ceil(para.minIntrinsicWidth)
|
|
411
|
+
maxIntrinsicWidth = ceil(para.maxIntrinsicWidth)
|
|
412
|
+
+ val hasLetterSpacing =
|
|
413
|
+
+ (style.letterSpacing != TextUnit.Unspecified && style.letterSpacing.value != 0f) ||
|
|
414
|
+
+ annotations.any {
|
|
415
|
+
+ val span = it.item
|
|
416
|
+
+ span is SpanStyle && span.letterSpacing != TextUnit.Unspecified &&
|
|
417
|
+
+ span.letterSpacing.value != 0f
|
|
418
|
+
+ }
|
|
419
|
+
+ if (currentPlatform() == Platform.Android && maxIntrinsicWidth != 0f && hasLetterSpacing) {
|
|
420
|
+
+ maxIntrinsicWidth += 0.5f
|
|
421
|
+
+ }
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
diff --git a/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/platform/SkikoParagraphBuilder.nonAndroid.kt b/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/platform/SkikoParagraphBuilder.nonAndroid.kt
|
|
426
|
+
--- a/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/platform/SkikoParagraphBuilder.nonAndroid.kt
|
|
427
|
+
+++ b/compose/ui/ui-skiko/src/nonAndroidMain/kotlin/androidx/compose/ui/text/platform/SkikoParagraphBuilder.nonAndroid.kt
|
|
428
|
+
@@ -832,7 +832,7 @@
|
|
429
|
+
return when (this) {
|
|
430
|
+
TextAlign.Left -> SkAlignment.LEFT
|
|
431
|
+
TextAlign.Right -> SkAlignment.RIGHT
|
|
432
|
+
- TextAlign.Center -> SkAlignment.CENTER
|
|
433
|
+
+ TextAlign.Center -> if (currentPlatform() == Platform.Android) SkAlignment.CENTER_ANDROID else SkAlignment.CENTER
|
|
434
|
+
TextAlign.Justify -> SkAlignment.JUSTIFY
|
|
435
|
+
TextAlign.Start -> SkAlignment.START
|
|
436
|
+
TextAlign.End -> SkAlignment.END
|