peachsim 0.1.899 → 0.1.900
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/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/platform.ts +15 -2
- package/cli/commands/skills.ts +125 -10
- 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 +3 -3
- 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 +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +3 -3
- 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 +3 -3
- 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 +98 -6
- 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/package.json +1 -1
- package/src/expo-swift-host.ts +10 -2
package/cli/app-fonts.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { createRequire } from 'node:module'
|
|
|
4
4
|
import path from 'node:path'
|
|
5
5
|
import {
|
|
6
6
|
expoFontPathsFromPlugins,
|
|
7
|
+
nativeLinkedFontSpecsFromPaths,
|
|
7
8
|
metroFontSpecsFromPaths,
|
|
8
9
|
type ConfigPluginFontSpec,
|
|
9
10
|
} from 'peach-engine/engine/config-plugin-fonts'
|
|
@@ -27,7 +28,14 @@ export function discoverNativeLinkedAppFonts(opts: {
|
|
|
27
28
|
}): DiscoveredAppFontSpec[] {
|
|
28
29
|
const metroOrigin = loopbackOriginOf(opts.bundleUrl)
|
|
29
30
|
if (!metroOrigin) return []
|
|
31
|
+
return metroFontSpecsFromPaths(discoverNativeLinkedAppFontPaths(opts), metroOrigin)
|
|
32
|
+
}
|
|
30
33
|
|
|
34
|
+
function discoverNativeLinkedAppFontPaths(opts: {
|
|
35
|
+
projectDir: string
|
|
36
|
+
platform?: string
|
|
37
|
+
bundleUrl?: string
|
|
38
|
+
}): string[] {
|
|
31
39
|
const project = resolveAppProject(opts.projectDir)
|
|
32
40
|
const selectedAppDir = project?.appDir ?? null
|
|
33
41
|
if (!selectedAppDir) return []
|
|
@@ -142,7 +150,7 @@ export function discoverNativeLinkedAppFonts(opts: {
|
|
|
142
150
|
// the bundle path is the entry relative to metro's root, so a bundle at
|
|
143
151
|
// /apps/app/index.bundle served for /repo/apps/app puts that root at /repo.
|
|
144
152
|
const bundleDir = path.posix
|
|
145
|
-
.dirname(new URL(opts.bundleUrl).pathname)
|
|
153
|
+
.dirname(opts.bundleUrl ? new URL(opts.bundleUrl).pathname : '/')
|
|
146
154
|
.replace(/^\/+/, '')
|
|
147
155
|
const appRelativeDir = bundleDir.split('/').join(path.sep)
|
|
148
156
|
const metroRootCandidates = [selectedAppDir]
|
|
@@ -258,7 +266,24 @@ export function discoverNativeLinkedAppFonts(opts: {
|
|
|
258
266
|
} catch {}
|
|
259
267
|
}
|
|
260
268
|
|
|
261
|
-
return
|
|
269
|
+
return [...new Set(fontPaths)]
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// prebuilt guests cannot discover files linked into their native binary.
|
|
273
|
+
// carry the same declarations as self-contained asset urls beside their JS.
|
|
274
|
+
export function readNativeLinkedAppFontsWire(opts: {
|
|
275
|
+
projectDir: string
|
|
276
|
+
platform?: string
|
|
277
|
+
}): string {
|
|
278
|
+
if (!resolveAppProject(opts.projectDir)) {
|
|
279
|
+
throw new Error(`native font project is unavailable: ${opts.projectDir}`)
|
|
280
|
+
}
|
|
281
|
+
return encodeAppFontsWire(
|
|
282
|
+
nativeLinkedFontSpecsFromPaths(discoverNativeLinkedAppFontPaths(opts), (fontPath) => {
|
|
283
|
+
const bytes = fs.readFileSync(path.resolve(opts.projectDir, fontPath))
|
|
284
|
+
return `data:${fontContentType(fontPath)};base64,${bytes.toString('base64')}`
|
|
285
|
+
}),
|
|
286
|
+
)
|
|
262
287
|
}
|
|
263
288
|
|
|
264
289
|
// resolve a metro dev server's project root. Expo's middleware advertises it
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
12
|
PREBUILT_BUNDLE_DEVICE_PATH,
|
|
13
|
+
prebuiltAppFontsPartPath,
|
|
13
14
|
PREBUILT_BUNDLE_PART_BYTES,
|
|
14
15
|
prebuiltBundlePartPath,
|
|
15
16
|
} from '@peach/box/template'
|
|
@@ -19,16 +20,24 @@ export class BundleFilePlane implements ProjectFilePlane {
|
|
|
19
20
|
private readonly parts = new Map<string, Uint8Array>()
|
|
20
21
|
private readonly entries = new Map<string, ProjectFileMeta>()
|
|
21
22
|
|
|
22
|
-
constructor(bundle: Uint8Array, device: string | null) {
|
|
23
|
+
constructor(bundle: Uint8Array, device: string | null, appFonts = '') {
|
|
23
24
|
if (bundle.byteLength === 0) throw new Error('a Box bundle cannot be empty')
|
|
25
|
+
if (appFonts)
|
|
26
|
+
this.recordParts(new TextEncoder().encode(appFonts), prebuiltAppFontsPartPath)
|
|
24
27
|
if (device) this.record(PREBUILT_BUNDLE_DEVICE_PATH, new TextEncoder().encode(device))
|
|
28
|
+
this.recordParts(bundle, prebuiltBundlePartPath)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private recordParts(content: Uint8Array, partPath: (index: number) => string): void {
|
|
25
32
|
for (
|
|
26
33
|
let offset = 0, index = 0;
|
|
27
|
-
offset <
|
|
34
|
+
offset < content.byteLength;
|
|
28
35
|
offset += PREBUILT_BUNDLE_PART_BYTES, index++
|
|
29
36
|
) {
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
this.record(
|
|
38
|
+
partPath(index),
|
|
39
|
+
content.subarray(offset, offset + PREBUILT_BUNDLE_PART_BYTES),
|
|
40
|
+
)
|
|
32
41
|
}
|
|
33
42
|
}
|
|
34
43
|
|
package/cli/commands/box.ts
CHANGED
|
@@ -30,8 +30,10 @@ import {
|
|
|
30
30
|
heartbeatSession,
|
|
31
31
|
resolveCloudBoxReference,
|
|
32
32
|
} from 'peach-cloud-box/client'
|
|
33
|
+
import { getRuntimePlatform, isDeviceModel } from 'peach-engine/settings/devices'
|
|
33
34
|
import { readDefaultBox, writeDefaultBox } from '../../src/home-paths'
|
|
34
35
|
import { rnxPublicBrand } from '../../src/public-brand'
|
|
36
|
+
import { readNativeLinkedAppFontsWire } from '../app-fonts'
|
|
35
37
|
import { authHeaderOrExit, cloudAccountIdOrExit, type CliAuth } from '../auth'
|
|
36
38
|
import { produceCloudBoxArtifact, type CloudBoxArtifactProduction } from '../cloud-client'
|
|
37
39
|
import { openUrl } from '../open-url'
|
|
@@ -523,6 +525,7 @@ function cloudBoxClient(options: {
|
|
|
523
525
|
*/
|
|
524
526
|
export async function createPrebuiltBundleBox(options: {
|
|
525
527
|
bundle: Uint8Array
|
|
528
|
+
nativeProjectDir?: string
|
|
526
529
|
// the simulator's device model, or null for the Box page's default
|
|
527
530
|
device: string | null
|
|
528
531
|
name: string
|
|
@@ -536,7 +539,19 @@ export async function createPrebuiltBundleBox(options: {
|
|
|
536
539
|
name: options.name,
|
|
537
540
|
stack: prebuiltBundleBoxTemplate.stack,
|
|
538
541
|
template: BOX_TEMPLATES.resolve({ name: prebuiltBundleBoxTemplate.name }).provenance,
|
|
539
|
-
source: new BundleFilePlane(
|
|
542
|
+
source: new BundleFilePlane(
|
|
543
|
+
options.bundle,
|
|
544
|
+
options.device,
|
|
545
|
+
options.nativeProjectDir
|
|
546
|
+
? readNativeLinkedAppFontsWire({
|
|
547
|
+
projectDir: options.nativeProjectDir,
|
|
548
|
+
platform:
|
|
549
|
+
options.device && isDeviceModel(options.device)
|
|
550
|
+
? getRuntimePlatform(options.device)
|
|
551
|
+
: 'ios',
|
|
552
|
+
})
|
|
553
|
+
: '',
|
|
554
|
+
),
|
|
540
555
|
...(options.secrets ? { secrets: options.secrets } : {}),
|
|
541
556
|
})
|
|
542
557
|
}
|
|
@@ -576,6 +591,11 @@ async function runCloudBoxCreate(
|
|
|
576
591
|
// --bundle IS the template choice: the box runs an app that is already
|
|
577
592
|
// built, so naming a second template would ask for two different boxes.
|
|
578
593
|
const bundlePath = flag(args, 'bundle')
|
|
594
|
+
const nativeProjectDir = flag(args, 'native-project')
|
|
595
|
+
if (nativeProjectDir && !bundlePath) {
|
|
596
|
+
console.error(` ${peach} box create: --native-project requires --bundle.`)
|
|
597
|
+
return 1
|
|
598
|
+
}
|
|
579
599
|
const namedTemplate = flag(args, 'template')
|
|
580
600
|
if (bundlePath && namedTemplate) {
|
|
581
601
|
console.error(
|
|
@@ -687,6 +707,7 @@ async function runCloudBoxCreate(
|
|
|
687
707
|
? await createPrebuiltBundleBox({
|
|
688
708
|
...connection,
|
|
689
709
|
bundle: source.bundle,
|
|
710
|
+
nativeProjectDir,
|
|
690
711
|
device: null,
|
|
691
712
|
name,
|
|
692
713
|
...(secrets ? { secrets } : {}),
|
package/cli/commands/platform.ts
CHANGED
|
@@ -29,7 +29,12 @@ function isDeviceModel(value: string): value is DeviceModel {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// flags this command reads for itself rather than treating as the bundle.
|
|
32
|
-
const REMOTE_VALUE_FLAGS = new Set([
|
|
32
|
+
const REMOTE_VALUE_FLAGS = new Set([
|
|
33
|
+
'--device',
|
|
34
|
+
'--name',
|
|
35
|
+
'--endpoint',
|
|
36
|
+
'--native-project',
|
|
37
|
+
])
|
|
33
38
|
|
|
34
39
|
function remoteInputFromArgs(
|
|
35
40
|
args: string[],
|
|
@@ -37,11 +42,13 @@ function remoteInputFromArgs(
|
|
|
37
42
|
): {
|
|
38
43
|
bundlePath: string
|
|
39
44
|
name: string | null
|
|
45
|
+
nativeProjectDir: string | undefined
|
|
40
46
|
reuse: boolean
|
|
41
47
|
fresh: boolean
|
|
42
48
|
} {
|
|
43
49
|
const positional: string[] = []
|
|
44
50
|
let name: string | null = null
|
|
51
|
+
let nativeProjectDir: string | undefined
|
|
45
52
|
for (let index = 0; index < args.length; index++) {
|
|
46
53
|
const arg = args[index]
|
|
47
54
|
if (arg === '--remote' || arg === '--nano' || arg === '--reuse' || arg === '--new') {
|
|
@@ -51,6 +58,7 @@ function remoteInputFromArgs(
|
|
|
51
58
|
const value = args[++index] ?? null
|
|
52
59
|
if (!value) throw new Error(`peach remote ${platform} ${arg} requires a value`)
|
|
53
60
|
if (arg === '--name') name = value
|
|
61
|
+
if (arg === '--native-project') nativeProjectDir = value
|
|
54
62
|
continue
|
|
55
63
|
}
|
|
56
64
|
const assigned = arg.match(/^(--[a-z-]+)=(.*)$/)
|
|
@@ -59,6 +67,7 @@ function remoteInputFromArgs(
|
|
|
59
67
|
if (!value)
|
|
60
68
|
throw new Error(`peach remote ${platform} ${assigned[1]} requires a value`)
|
|
61
69
|
if (assigned[1] === '--name') name = value
|
|
70
|
+
if (assigned[1] === '--native-project') nativeProjectDir = value
|
|
62
71
|
continue
|
|
63
72
|
}
|
|
64
73
|
if (
|
|
@@ -88,7 +97,7 @@ function remoteInputFromArgs(
|
|
|
88
97
|
if (reuse && fresh) {
|
|
89
98
|
throw new Error(`peach remote ${platform} cannot combine --reuse and --new`)
|
|
90
99
|
}
|
|
91
|
-
return { bundlePath: positional[0], name, reuse, fresh }
|
|
100
|
+
return { bundlePath: positional[0], name, nativeProjectDir, reuse, fresh }
|
|
92
101
|
}
|
|
93
102
|
|
|
94
103
|
/**
|
|
@@ -242,6 +251,8 @@ async function runRemoteCreate(
|
|
|
242
251
|
selectedDevice: string,
|
|
243
252
|
): Promise<number> {
|
|
244
253
|
const input = remoteInputFromArgs(args, platform)
|
|
254
|
+
if (input.nativeProjectDir)
|
|
255
|
+
throw new Error('--native-project requires a prebuilt micro Box')
|
|
245
256
|
const [
|
|
246
257
|
{ authHeaderOrExit, cloudAccountIdOrExit },
|
|
247
258
|
{
|
|
@@ -404,6 +415,7 @@ async function runRemoteBox(
|
|
|
404
415
|
|
|
405
416
|
const existingSession = readCloudSession()
|
|
406
417
|
if (
|
|
418
|
+
!input.nativeProjectDir &&
|
|
407
419
|
existingSession?.service === 'box' &&
|
|
408
420
|
!input.fresh &&
|
|
409
421
|
existingSession.apiOrigin === endpoint &&
|
|
@@ -454,6 +466,7 @@ async function runRemoteBox(
|
|
|
454
466
|
}
|
|
455
467
|
const created = await box.createPrebuiltBundleBox({
|
|
456
468
|
bundle: new Uint8Array(artifact.bytes),
|
|
469
|
+
nativeProjectDir: input.nativeProjectDir,
|
|
457
470
|
device: selectedDevice,
|
|
458
471
|
name: input.name ?? boxNameForBundle(input.bundlePath),
|
|
459
472
|
endpoint,
|
package/cli/commands/skills.ts
CHANGED
|
@@ -137,9 +137,117 @@ function targetFromHome(envName: string, fallbackDir: string): string {
|
|
|
137
137
|
return path.join(home, 'skills')
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
function codexTargets(): InstallTarget[] {
|
|
141
|
+
const homes = new Map<string, string>()
|
|
142
|
+
const userHome = process.env.HOME || os.homedir()
|
|
143
|
+
|
|
144
|
+
// 1. Default CODEX_HOME or ~/.codex
|
|
145
|
+
const primaryCodexHome = process.env.CODEX_HOME || path.join(userHome, '.codex')
|
|
146
|
+
homes.set(path.resolve(primaryCodexHome), 'codex')
|
|
147
|
+
|
|
148
|
+
// 2. TM_CODEX_HOMES env var
|
|
149
|
+
const tmCodexHomes = process.env.TM_CODEX_HOMES
|
|
150
|
+
if (tmCodexHomes) {
|
|
151
|
+
for (const h of tmCodexHomes.split(path.delimiter)) {
|
|
152
|
+
if (h.trim()) {
|
|
153
|
+
const resolved = path.resolve(h.trim())
|
|
154
|
+
if (!homes.has(resolved)) {
|
|
155
|
+
homes.set(resolved, path.basename(resolved).replace(/^\./, ''))
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 3. Engine configuration from ~/.team-machine/engine.yaml or $TM_HOME/engine.yaml
|
|
162
|
+
const tmHome = process.env.TM_HOME || path.join(userHome, '.team-machine')
|
|
163
|
+
const enginePath = path.join(tmHome, 'engine.yaml')
|
|
164
|
+
if (fs.existsSync(enginePath)) {
|
|
165
|
+
try {
|
|
166
|
+
const content = fs.readFileSync(enginePath, 'utf8')
|
|
167
|
+
let inCodex = false
|
|
168
|
+
let inAccounts = false
|
|
169
|
+
let currentAccount = ''
|
|
170
|
+
for (const line of content.split('\n')) {
|
|
171
|
+
const indent = line.search(/\S/)
|
|
172
|
+
const trimmed = line.trim()
|
|
173
|
+
if (indent === -1) continue
|
|
174
|
+
|
|
175
|
+
if (indent === 4) {
|
|
176
|
+
inCodex = trimmed === 'codex:'
|
|
177
|
+
inAccounts = false
|
|
178
|
+
currentAccount = ''
|
|
179
|
+
continue
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (!inCodex) continue
|
|
183
|
+
|
|
184
|
+
if (indent === 6 && trimmed === 'accounts:') {
|
|
185
|
+
inAccounts = true
|
|
186
|
+
currentAccount = ''
|
|
187
|
+
continue
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (!inAccounts) continue
|
|
191
|
+
|
|
192
|
+
if (indent === 8 && trimmed.endsWith(':')) {
|
|
193
|
+
currentAccount = trimmed.slice(0, -1).trim()
|
|
194
|
+
continue
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (indent >= 10 && currentAccount) {
|
|
198
|
+
const match = /^home:\s*(.+)$/.exec(trimmed)
|
|
199
|
+
if (match) {
|
|
200
|
+
let homeDir = match[1].trim()
|
|
201
|
+
if (homeDir.startsWith('~')) {
|
|
202
|
+
homeDir = path.join(userHome, homeDir.slice(1))
|
|
203
|
+
}
|
|
204
|
+
const resolved = path.resolve(homeDir)
|
|
205
|
+
if (!homes.has(resolved)) {
|
|
206
|
+
homes.set(resolved, `codex-${currentAccount}`)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
} catch {
|
|
212
|
+
// ignore read error
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// 4. Native Codex profile directories in home matching .codex-*
|
|
217
|
+
try {
|
|
218
|
+
for (const entry of fs.readdirSync(userHome)) {
|
|
219
|
+
if (entry.startsWith('.codex-')) {
|
|
220
|
+
const fullPath = path.join(userHome, entry)
|
|
221
|
+
try {
|
|
222
|
+
const stat = fs.statSync(fullPath)
|
|
223
|
+
if (stat.isDirectory()) {
|
|
224
|
+
const resolved = path.resolve(fullPath)
|
|
225
|
+
if (!homes.has(resolved)) {
|
|
226
|
+
homes.set(resolved, entry.replace(/^\./, ''))
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
} catch {
|
|
230
|
+
// ignore
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
} catch {
|
|
235
|
+
// ignore
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const targets: InstallTarget[] = []
|
|
239
|
+
for (const [homePath, label] of homes) {
|
|
240
|
+
targets.push({
|
|
241
|
+
label,
|
|
242
|
+
dir: path.join(homePath, 'skills'),
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
return targets
|
|
246
|
+
}
|
|
247
|
+
|
|
140
248
|
function defaultAgentTargets(): InstallTarget[] {
|
|
141
249
|
return [
|
|
142
|
-
|
|
250
|
+
...codexTargets(),
|
|
143
251
|
{ label: 'claude', dir: targetFromHome('CLAUDE_CONFIG_DIR', '.claude') },
|
|
144
252
|
]
|
|
145
253
|
}
|
|
@@ -162,7 +270,7 @@ export function hasInstalledPeachSkills(): boolean {
|
|
|
162
270
|
function agentTarget(target: string): InstallTarget[] {
|
|
163
271
|
if (target === 'all') return defaultAgentTargets()
|
|
164
272
|
if (target === 'codex') {
|
|
165
|
-
return
|
|
273
|
+
return codexTargets()
|
|
166
274
|
}
|
|
167
275
|
if (target === 'claude') {
|
|
168
276
|
return [{ label: 'claude', dir: targetFromHome('CLAUDE_CONFIG_DIR', '.claude') }]
|
|
@@ -289,14 +397,21 @@ function symlinkPointsTo(dest: string, src: string): boolean {
|
|
|
289
397
|
// holding a byte-identical copy of the skill. only our installer creates
|
|
290
398
|
// those shapes, so replacing them can't lose user work.
|
|
291
399
|
function isOwnLegacyInstall(stat: fs.Stats, dest: string, srcDir: string): boolean {
|
|
292
|
-
// a dangling link into a removed checkout's skills dir is our own install too
|
|
400
|
+
// a dangling link into a removed checkout's skills dir or a link into an obsolete worktree is our own install too
|
|
293
401
|
if (stat.isSymbolicLink()) {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
.
|
|
298
|
-
|
|
299
|
-
|
|
402
|
+
try {
|
|
403
|
+
const link = fs.readlinkSync(dest)
|
|
404
|
+
const isPeachSkill = link.endsWith(
|
|
405
|
+
`${path.sep}skills${path.sep}${path.basename(srcDir)}`,
|
|
406
|
+
)
|
|
407
|
+
if (isPeachSkill) {
|
|
408
|
+
if (!fs.existsSync(dest)) return true
|
|
409
|
+
if (link.includes(`${path.sep}.worktrees${path.sep}`)) return true
|
|
410
|
+
}
|
|
411
|
+
} catch {
|
|
412
|
+
return false
|
|
413
|
+
}
|
|
414
|
+
return false
|
|
300
415
|
}
|
|
301
416
|
if (!stat.isDirectory()) return false
|
|
302
417
|
let entries: string[]
|
|
@@ -350,7 +465,7 @@ const LEGACY_BUNDLED_SKILL_DIRS = [
|
|
|
350
465
|
'sootsim-debug',
|
|
351
466
|
'sootsim-perf',
|
|
352
467
|
'sootsim-test',
|
|
353
|
-
'
|
|
468
|
+
'sootsim-visual',
|
|
354
469
|
'rnx-setup',
|
|
355
470
|
'rnx-debug',
|
|
356
471
|
'rnx-perf',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.900 | (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.900 | (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.900 | (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.900 | (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.900 | (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.900 | (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.900 | (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/beta.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.900 | (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/beta.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.900 | (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.900 | (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.900 | (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.900 | (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;
|
|
@@ -8633,8 +8633,8 @@ async function collectExpoSwiftSources(appRoot) {
|
|
|
8633
8633
|
const files2 = {};
|
|
8634
8634
|
const classes = [];
|
|
8635
8635
|
for (const module2 of modules) {
|
|
8636
|
-
const className = module2 && typeof module2 === "object" ? Reflect.get(module2, "class") : null;
|
|
8637
|
-
const name2 = module2 && typeof module2 === "object" ? Reflect.get(module2, "name") : null;
|
|
8636
|
+
const className = typeof module2 === "string" ? module2 : module2 && typeof module2 === "object" ? Reflect.get(module2, "class") : null;
|
|
8637
|
+
const name2 = typeof module2 === "string" ? null : module2 && typeof module2 === "object" ? Reflect.get(module2, "name") : null;
|
|
8638
8638
|
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")
|
|
8639
8639
|
throw new Error(`${sourceRoot}: invalid Expo Apple module descriptor`);
|
|
8640
8640
|
classes.push({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.900 | (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.900 | (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.900 | (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.900 | (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/cloud.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.900 | (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/cloud.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.900 | (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/config.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.900 | (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/detox/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.900 | (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.900 | (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.900 | (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;
|
|
@@ -8440,8 +8440,8 @@ async function collectExpoSwiftSources(appRoot) {
|
|
|
8440
8440
|
const files2 = {};
|
|
8441
8441
|
const classes = [];
|
|
8442
8442
|
for (const module2 of modules) {
|
|
8443
|
-
const className = module2 && typeof module2 === "object" ? Reflect.get(module2, "class") : null;
|
|
8444
|
-
const name2 = module2 && typeof module2 === "object" ? Reflect.get(module2, "name") : null;
|
|
8443
|
+
const className = typeof module2 === "string" ? module2 : module2 && typeof module2 === "object" ? Reflect.get(module2, "class") : null;
|
|
8444
|
+
const name2 = typeof module2 === "string" ? null : module2 && typeof module2 === "object" ? Reflect.get(module2, "name") : null;
|
|
8445
8445
|
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")
|
|
8446
8446
|
throw new Error(`${sourceRoot}: invalid Expo Apple module descriptor`);
|
|
8447
8447
|
classes.push({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.900 | (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/home-paths.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.900 | (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;
|