peachsim 0.1.527
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/LICENSE +22 -0
- package/README.md +640 -0
- package/cli/app-config.ts +82 -0
- package/cli/app-fonts.ts +388 -0
- package/cli/app-project.ts +59 -0
- package/cli/app-splash.ts +171 -0
- package/cli/app-state-reset.ts +26 -0
- package/cli/auth.ts +184 -0
- package/cli/bin.ts +59 -0
- package/cli/bridge-diagnostics.ts +226 -0
- package/cli/bridge-flow-runner.ts +2806 -0
- package/cli/browser-backend.ts +44 -0
- package/cli/browser-evals.ts +96 -0
- package/cli/cli-update.ts +261 -0
- package/cli/cloud-client.ts +1530 -0
- package/cli/cloud-dispatch.ts +206 -0
- package/cli/cloud-session.ts +227 -0
- package/cli/command-contract.ts +221 -0
- package/cli/command-registry.ts +304 -0
- package/cli/commands/agent-wrapper.ts +1048 -0
- package/cli/commands/agent.ts +439 -0
- package/cli/commands/app-fonts.ts +99 -0
- package/cli/commands/assert.ts +542 -0
- package/cli/commands/auth.ts +71 -0
- package/cli/commands/box/bundle-plane.ts +71 -0
- package/cli/commands/box/checkout-plane.ts +256 -0
- package/cli/commands/box/plane-share.ts +208 -0
- package/cli/commands/box/rnx-command.ts +60 -0
- package/cli/commands/box/search-command.ts +157 -0
- package/cli/commands/box.ts +925 -0
- package/cli/commands/camera.ts +266 -0
- package/cli/commands/cleanup.ts +169 -0
- package/cli/commands/compat.ts +176 -0
- package/cli/commands/config.ts +34 -0
- package/cli/commands/control.ts +2154 -0
- package/cli/commands/cpu-profile.ts +941 -0
- package/cli/commands/daemon-mac-app.ts +165 -0
- package/cli/commands/daemon.ts +800 -0
- package/cli/commands/debug.ts +751 -0
- package/cli/commands/desktop.ts +39 -0
- package/cli/commands/detect.ts +201 -0
- package/cli/commands/detox.ts +481 -0
- package/cli/commands/device.ts +134 -0
- package/cli/commands/diagnose.ts +589 -0
- package/cli/commands/do-chain.ts +408 -0
- package/cli/commands/electron.ts +94 -0
- package/cli/commands/film.ts +379 -0
- package/cli/commands/flow.ts +1240 -0
- package/cli/commands/inspect/actions.ts +516 -0
- package/cli/commands/inspect/core.ts +2086 -0
- package/cli/commands/inspect/count.ts +17 -0
- package/cli/commands/inspect/describe.ts +119 -0
- package/cli/commands/inspect/env.ts +25 -0
- package/cli/commands/inspect/find.ts +169 -0
- package/cli/commands/inspect/get-layout.ts +53 -0
- package/cli/commands/inspect/keyboard.ts +54 -0
- package/cli/commands/inspect/list.ts +175 -0
- package/cli/commands/inspect/memory.ts +215 -0
- package/cli/commands/inspect/redaction.ts +39 -0
- package/cli/commands/inspect/resolve-target.ts +77 -0
- package/cli/commands/inspect/screens.ts +78 -0
- package/cli/commands/inspect/settle.ts +32 -0
- package/cli/commands/inspect/settling.ts +197 -0
- package/cli/commands/inspect/shared.ts +259 -0
- package/cli/commands/inspect/sleep.ts +15 -0
- package/cli/commands/inspect/tree.ts +23 -0
- package/cli/commands/inspect/url.ts +17 -0
- package/cli/commands/inspect/wait-event.ts +211 -0
- package/cli/commands/inspect/wait-idle.ts +25 -0
- package/cli/commands/inspect/wait-ready.ts +87 -0
- package/cli/commands/inspect/wait-selector.ts +59 -0
- package/cli/commands/inspect/wait.ts +32 -0
- package/cli/commands/inspect.ts +4738 -0
- package/cli/commands/install-cli.ts +275 -0
- package/cli/commands/install-desktop.ts +385 -0
- package/cli/commands/login.ts +357 -0
- package/cli/commands/logout.ts +24 -0
- package/cli/commands/maestro-generate.ts +375 -0
- package/cli/commands/maestro.ts +536 -0
- package/cli/commands/mode.ts +58 -0
- package/cli/commands/no-bridge-hint.ts +80 -0
- package/cli/commands/perf.ts +67 -0
- package/cli/commands/permissions.ts +203 -0
- package/cli/commands/platform.ts +410 -0
- package/cli/commands/preview.ts +103 -0
- package/cli/commands/profile.ts +106 -0
- package/cli/commands/react.ts +353 -0
- package/cli/commands/record.ts +1435 -0
- package/cli/commands/report-issue.ts +305 -0
- package/cli/commands/reset.ts +89 -0
- package/cli/commands/runtime.ts +348 -0
- package/cli/commands/screenshot-command.ts +106 -0
- package/cli/commands/screenshot-layers.ts +144 -0
- package/cli/commands/screenshot-mode.ts +38 -0
- package/cli/commands/screenshot.ts +492 -0
- package/cli/commands/screenshots-capture.ts +608 -0
- package/cli/commands/screenshots.ts +127 -0
- package/cli/commands/serve.ts +139 -0
- package/cli/commands/setup.ts +416 -0
- package/cli/commands/shell-boolean-mode.ts +82 -0
- package/cli/commands/skills.ts +468 -0
- package/cli/commands/slides.ts +357 -0
- package/cli/commands/state.ts +94 -0
- package/cli/commands/storage.ts +58 -0
- package/cli/commands/telemetry.ts +55 -0
- package/cli/commands/test.ts +535 -0
- package/cli/commands/three-mode.ts +771 -0
- package/cli/commands/timeline.ts +121 -0
- package/cli/commands/upgrade.ts +167 -0
- package/cli/commands/upload.ts +1203 -0
- package/cli/commands/version.ts +63 -0
- package/cli/commands/welcome.ts +17 -0
- package/cli/commands/what-happened.ts +328 -0
- package/cli/current-sim.ts +217 -0
- package/cli/desktop-companion.ts +315 -0
- package/cli/drivers/electron.ts +70 -0
- package/cli/drivers/index.ts +20 -0
- package/cli/drivers/playwright-provisioning.ts +184 -0
- package/cli/drivers/playwright-sim-host.ts +537 -0
- package/cli/drivers/playwright.ts +209 -0
- package/cli/drivers/registry.ts +65 -0
- package/cli/drivers/types.ts +102 -0
- package/cli/flow-export.ts +55 -0
- package/cli/flow-file.ts +142 -0
- package/cli/flow-live-status.ts +126 -0
- package/cli/flow-session.ts +140 -0
- package/cli/help-core.ts +143 -0
- package/cli/help.ts +44 -0
- package/cli/hidden-runtime-alias.ts +19 -0
- package/cli/hints.ts +214 -0
- package/cli/inspect-notice-state.ts +114 -0
- package/cli/internal-child.ts +176 -0
- package/cli/maestro-js.ts +323 -0
- package/cli/main.ts +704 -0
- package/cli/open-url.ts +8 -0
- package/cli/outbound-endpoints.ts +830 -0
- package/cli/parent-pid.ts +204 -0
- package/cli/parse-args.ts +189 -0
- package/cli/privacy.ts +53 -0
- package/cli/prompt.ts +56 -0
- package/cli/recording-access.ts +108 -0
- package/cli/registry.ts +2 -0
- package/cli/resolve-assets.ts +63 -0
- package/cli/rnx-in-process.ts +98 -0
- package/cli/run-registry.ts +226 -0
- package/cli/run-rnx-core.ts +148 -0
- package/cli/run-rnx.ts +137 -0
- package/cli/runtime-notes.ts +66 -0
- package/cli/runtime-summary.ts +25 -0
- package/cli/secure-file.ts +31 -0
- package/cli/self-invocation.ts +58 -0
- package/cli/send-to-box.ts +109 -0
- package/cli/setup-repository.ts +191 -0
- package/cli/shell-init.ts +98 -0
- package/cli/standalone.ts +4 -0
- package/cli/telemetry.ts +84 -0
- package/cli/ui.ts +68 -0
- package/cli/ws-bridge.ts +1020 -0
- package/detox/attempt-events.cjs +23 -0
- package/detox/colors.ts +54 -0
- package/detox/config-loader.ts +135 -0
- package/detox/element-types.ts +48 -0
- package/detox/expectations.ts +534 -0
- package/detox/gestures.ts +501 -0
- package/detox/index.ts +2694 -0
- package/detox/jest-preset.cjs +29 -0
- package/detox/jest-setup-after-env.cjs +22 -0
- package/detox/matchers.ts +30 -0
- package/detox/motion-change.cjs +109 -0
- package/detox/motion-change.d.cts +35 -0
- package/detox/navigation-lifecycle.ts +290 -0
- package/detox/navigation.ts +43 -0
- package/detox/proof-frame.cjs +114 -0
- package/detox/record-block-execution.cjs +78 -0
- package/detox/screenshots/animated-color-test-rest-norngh.png +0 -0
- package/detox/screenshots/color-test-after-drag-norngh.png +0 -0
- package/detox/screenshots/color-test-rest-norngh.png +0 -0
- package/detox/screenshots/theme-blue-toggle.png +0 -0
- package/detox/screenshots/theme-blue.png +0 -0
- package/detox/screenshots/theme-red-toggle.png +0 -0
- package/detox/screenshots/theme-red.png +0 -0
- package/dist-lib/agent-daemon-client.cjs +502 -0
- package/dist-lib/agent-events.cjs +48 -0
- package/dist-lib/agent-identity.cjs +53 -0
- package/dist-lib/agent-sessions.cjs +759 -0
- package/dist-lib/attached-projects.cjs +526 -0
- package/dist-lib/auth/shared-session.cjs +208 -0
- package/dist-lib/backend-origin.cjs +88 -0
- package/dist-lib/beta.cjs +41 -0
- package/dist-lib/beta.mjs +13 -0
- package/dist-lib/bridge-constants.cjs +161 -0
- package/dist-lib/bridge-contract-input.cjs +451 -0
- package/dist-lib/bridge-contract-input.mjs +414 -0
- package/dist-lib/bridge-contract.cjs +130 -0
- package/dist-lib/bridge-contract.mjs +94 -0
- package/dist-lib/capture-contract.cjs +220 -0
- package/dist-lib/capture-contract.mjs +190 -0
- package/dist-lib/cli-constants.cjs +32 -0
- package/dist-lib/cloud-contract.cjs +194 -0
- package/dist-lib/cloud-contract.mjs +145 -0
- package/dist-lib/cloud.cjs +670 -0
- package/dist-lib/cloud.mjs +639 -0
- package/dist-lib/config.cjs +96 -0
- package/dist-lib/detox/index.cjs +3789 -0
- package/dist-lib/detox/jest-preset.cjs +29 -0
- package/dist-lib/dev-bundle-resolution.cjs +290 -0
- package/dist-lib/home-paths.cjs +638 -0
- package/dist-lib/host/bridge-host.cjs +10903 -0
- package/dist-lib/host/fetch-proxy-handler.cjs +421 -0
- package/dist-lib/host/fetch-proxy-overrides.cjs +63 -0
- package/dist-lib/host/fetch-proxy-overrides.mjs +37 -0
- package/dist-lib/host/replacement-module-handler.cjs +469 -0
- package/dist-lib/host/websocket-proxy.cjs +298 -0
- package/dist-lib/index.cjs +4268 -0
- package/dist-lib/jump-to-source-babel.cjs +93 -0
- package/dist-lib/jump-to-source-native.cjs +112 -0
- package/dist-lib/menu.cjs +646 -0
- package/dist-lib/menu.mjs +604 -0
- package/dist-lib/metro-fingerprint-registry.cjs +186 -0
- package/dist-lib/metro-fingerprint-registry.mjs +156 -0
- package/dist-lib/metro-production-bundle.cjs +329 -0
- package/dist-lib/metro-production-bundle.mjs +295 -0
- package/dist-lib/metro.cjs +904 -0
- package/dist-lib/profiles.cjs +246 -0
- package/dist-lib/public-brand.cjs +39 -0
- package/dist-lib/react-native-host-modules.cjs +51 -0
- package/dist-lib/react-native-host-modules.mjs +25 -0
- package/dist-lib/render-mode.cjs +54 -0
- package/dist-lib/scripts/dev-server-scanner.cjs +1232 -0
- package/dist-lib/sdk.cjs +2433 -0
- package/dist-lib/sdk.mjs +2336 -0
- package/dist-lib/skills.cjs +39132 -0
- package/dist-lib/swift-submit.cjs +92 -0
- package/dist-lib/swift-submit.mjs +65 -0
- package/dist-lib/swift.cjs +1646 -0
- package/dist-lib/vite.cjs +1591 -0
- package/package.json +290 -0
- package/scripts/dev-server-scanner.ts +1291 -0
- package/scripts/optional-demo-registry.ts +113 -0
- package/skills/contrast/SKILL.md +165 -0
- package/skills/rnx-debug/SKILL.md +433 -0
- package/skills/rnx-perf/SKILL.md +399 -0
- package/skills/rnx-setup/SKILL.md +172 -0
- package/skills/rnx-test/SKILL.md +321 -0
- package/skills/rnx-visual/SKILL.md +126 -0
- package/src/agent-daemon-client.ts +410 -0
- package/src/agent-events.ts +71 -0
- package/src/agent-identity.ts +23 -0
- package/src/agent-prompt.ts +71 -0
- package/src/agent-sessions.ts +580 -0
- package/src/app-url.ts +39 -0
- package/src/attached-projects.ts +539 -0
- package/src/auth/shared-session.ts +235 -0
- package/src/backend-origin.ts +70 -0
- package/src/beta.ts +19 -0
- package/src/bridge-constants.ts +175 -0
- package/src/bridge-contract-input.ts +502 -0
- package/src/bridge-contract.ts +558 -0
- package/src/browser-cache.ts +16 -0
- package/src/capture-contract.ts +587 -0
- package/src/cli-constants.ts +1 -0
- package/src/cli-version.ts +40 -0
- package/src/cloud-contract.ts +274 -0
- package/src/cloud.ts +762 -0
- package/src/codex-client.ts +234 -0
- package/src/config.ts +132 -0
- package/src/connect.ts +101 -0
- package/src/dev-bundle-resolution.ts +346 -0
- package/src/dev-server-open.ts +198 -0
- package/src/disk-cleanup.ts +540 -0
- package/src/flow-timeout-scale.ts +15 -0
- package/src/home-paths.ts +806 -0
- package/src/host/agent-host.ts +666 -0
- package/src/host/bridge-host.ts +2788 -0
- package/src/host/fetch-proxy-handler.ts +449 -0
- package/src/host/fetch-proxy-overrides.ts +51 -0
- package/src/host/open-url.ts +89 -0
- package/src/host/plane-host.ts +203 -0
- package/src/host/replacement-module-handler.ts +158 -0
- package/src/host/websocket-proxy.ts +315 -0
- package/src/index.ts +71 -0
- package/src/jump-to-source-babel.ts +135 -0
- package/src/jump-to-source-native.ts +102 -0
- package/src/menu.ts +777 -0
- package/src/metro-fingerprint-registry.ts +302 -0
- package/src/metro-plugin.ts +341 -0
- package/src/metro-production-bundle.ts +471 -0
- package/src/native-dev-bundle-url.ts +118 -0
- package/src/native-seam-manifest.ts +341 -0
- package/src/playwright-host-log.ts +16 -0
- package/src/plist.ts +27 -0
- package/src/poll-until.ts +123 -0
- package/src/profiles.ts +179 -0
- package/src/public-brand.ts +9 -0
- package/src/react-native-host-modules.ts +26 -0
- package/src/render-mode.ts +27 -0
- package/src/rolldown-plugin-swift.ts +240 -0
- package/src/runtime-assets.ts +233 -0
- package/src/runtime-delivery.ts +54 -0
- package/src/screenshots/compose.ts +422 -0
- package/src/screenshots/frame-compose.ts +514 -0
- package/src/screenshots/orchestrate.ts +256 -0
- package/src/screenshots/org-deck.ts +91 -0
- package/src/screenshots/registry.ts +58 -0
- package/src/screenshots/schema.ts +364 -0
- package/src/sdk.ts +15 -0
- package/src/settings-bundle.ts +418 -0
- package/src/shell-bridge-identity.ts +15 -0
- package/src/sim-client.ts +697 -0
- package/src/skills/builtin/a11y-review.ts +132 -0
- package/src/skills/builtin/compat-check.ts +71 -0
- package/src/skills/builtin/maestro-test.ts +121 -0
- package/src/skills/builtin/perf-profile.ts +90 -0
- package/src/skills/builtin/screenshot-all.ts +52 -0
- package/src/skills/builtin/visual-diff.ts +100 -0
- package/src/skills/registry.ts +107 -0
- package/src/skills/types.ts +41 -0
- package/src/swift-submit.ts +185 -0
- package/src/swift.ts +7 -0
- package/src/team-machine-prompt.ts +73 -0
- package/src/vite-plugin-one.ts +264 -0
- package/src/vite-plugin-swift.ts +620 -0
- package/src/vite-plugin.ts +1946 -0
- package/src/worklets-babel.ts +250 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// skill type definitions — self-contained agent capabilities
|
|
2
|
+
|
|
3
|
+
export type SkillType = 'testing' | 'screenshot' | 'review' | 'performance' | 'custom'
|
|
4
|
+
|
|
5
|
+
export interface SkillTool {
|
|
6
|
+
name: string
|
|
7
|
+
description: string
|
|
8
|
+
parameters: Record<string, { type: string; description: string; required?: boolean }>
|
|
9
|
+
execute: (params: Record<string, any>, context: SkillContext) => Promise<SkillResult>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface SkillContext {
|
|
13
|
+
url: string // sootsim URL
|
|
14
|
+
projectDir: string // project root
|
|
15
|
+
outputDir: string // where to write artifacts
|
|
16
|
+
verbose: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface SkillResult {
|
|
20
|
+
success: boolean
|
|
21
|
+
message: string
|
|
22
|
+
artifacts?: SkillArtifact[]
|
|
23
|
+
data?: Record<string, any>
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface SkillArtifact {
|
|
27
|
+
type: 'screenshot' | 'video' | 'report' | 'flow' | 'json'
|
|
28
|
+
name: string
|
|
29
|
+
path: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface RNXSkill {
|
|
33
|
+
name: string
|
|
34
|
+
description: string
|
|
35
|
+
type: SkillType
|
|
36
|
+
version: string
|
|
37
|
+
triggers: string[] // natural language patterns that activate this skill
|
|
38
|
+
tools: SkillTool[]
|
|
39
|
+
setup?: (context: SkillContext) => Promise<void>
|
|
40
|
+
teardown?: (context: SkillContext) => Promise<void>
|
|
41
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* swift-compile's caller half: ask the compile host for this project's wasm
|
|
3
|
+
* artifact, and poll until it is published.
|
|
4
|
+
*
|
|
5
|
+
* This is the `.swift` transform's one request path, shared by every host
|
|
6
|
+
* that renders a project's swift sources: the in-IDE bundler worker (posts
|
|
7
|
+
* its own origin's `/api/swift-compile`), the node bundle builder used by
|
|
8
|
+
* the test-drive CLI and the deploy publisher (posts an absolute endpoint),
|
|
9
|
+
* and the One/rolldown `.swift` transform (same, with a `ccdn_` credential).
|
|
10
|
+
* A caller never compiles in-process: the container is the one compiler, and
|
|
11
|
+
* no bundler is that instance.
|
|
12
|
+
*
|
|
13
|
+
* It lives here (rather than in the app's `src/bundler/`) because the One
|
|
14
|
+
* transform ships in this package and cannot import app code; the app's own
|
|
15
|
+
* callers import this subpath back. The route path and the outcome shape are
|
|
16
|
+
* the wire coupling to `src/compile/swiftCompileContract.ts`, which owns the
|
|
17
|
+
* server-side caps, parsers, and refusals and imports these back.
|
|
18
|
+
*
|
|
19
|
+
* Browser-safe: node-only submitters live beside their call sites.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export const SWIFT_COMPILE_PATH = '/api/swift-compile'
|
|
23
|
+
|
|
24
|
+
export interface SwiftImageUpload {
|
|
25
|
+
/** the raster file picked for the asset (has the extension). */
|
|
26
|
+
file: string
|
|
27
|
+
/** the raster bytes, base64: carried once so the service can publish them. */
|
|
28
|
+
data: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type SwiftCompileOutcome =
|
|
32
|
+
/**
|
|
33
|
+
* the artifact is published; the bundler mounts it by url and hash.
|
|
34
|
+
*
|
|
35
|
+
* `artifactUrl` is root-relative (`/compile/asset/<sha256>`), because the
|
|
36
|
+
* host that compiles has no browser origin in front of it: the local node
|
|
37
|
+
* dev server and the cf-build container would each have to guess one. The
|
|
38
|
+
* caller that renders the module resolves it against its own origin, which
|
|
39
|
+
* is the origin the artifact route is served from in dev and in prod alike.
|
|
40
|
+
*/
|
|
41
|
+
| {
|
|
42
|
+
status: 'published'
|
|
43
|
+
artifactUrl: string
|
|
44
|
+
hash: string
|
|
45
|
+
/**
|
|
46
|
+
* the published photo rasters, bundle asset name to absolute url.
|
|
47
|
+
* root-relative like the artifact url; the caller resolves it against
|
|
48
|
+
* its own origin, and the entry embeds it as the image table. absent
|
|
49
|
+
* when the request packs no images.
|
|
50
|
+
*/
|
|
51
|
+
imageUrls?: Record<string, string>
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* the build is running; poll the same source set again. One build is tens of
|
|
55
|
+
* seconds and a service-binding request is cancelled at about four, so the
|
|
56
|
+
* container answers this before the connection dies and the caller polls.
|
|
57
|
+
*/
|
|
58
|
+
| { status: 'compiling'; hash: string }
|
|
59
|
+
/** refused before any work: no entry, too many files, over a cap, over a rate limit. */
|
|
60
|
+
| { status: 'refused'; detail: string }
|
|
61
|
+
/** the compiler ran and failed; detail carries its diagnostic verbatim. */
|
|
62
|
+
| { status: 'failed'; detail: string }
|
|
63
|
+
|
|
64
|
+
const POLL_INTERVAL_MS = 1500
|
|
65
|
+
|
|
66
|
+
export interface SwiftCompileContext {
|
|
67
|
+
/**
|
|
68
|
+
* the compile credential: the signed preview token `BundlerSessionRuntime`
|
|
69
|
+
* mints for a live project session, or a `ccdn_` API key. `compileCredential.server.ts`
|
|
70
|
+
* is the one verifier. absent means this build has no credential and a
|
|
71
|
+
* project with `.swift` sources cannot be compiled.
|
|
72
|
+
*/
|
|
73
|
+
assetReadToken?: string
|
|
74
|
+
/**
|
|
75
|
+
* absolute origin of the app serving `/api/swift-compile`. The browser
|
|
76
|
+
* worker omits it and posts its own origin; a node caller that is not that
|
|
77
|
+
* app must pass one.
|
|
78
|
+
*/
|
|
79
|
+
endpoint?: string
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export type SwiftCompileSubmit = (work: {
|
|
83
|
+
files: Record<string, string>
|
|
84
|
+
/** the bundle pack; absent means the project packs none. */
|
|
85
|
+
resources?: Record<string, string>
|
|
86
|
+
/** the photo rasters to publish; absent means the project packs none. */
|
|
87
|
+
images?: Record<string, SwiftImageUpload>
|
|
88
|
+
entry: string
|
|
89
|
+
}) => Promise<SwiftCompileOutcome>
|
|
90
|
+
|
|
91
|
+
/** the HTTP submitter, shared by the browser worker and the node build. */
|
|
92
|
+
export function httpSwiftCompileSubmit(
|
|
93
|
+
context: SwiftCompileContext,
|
|
94
|
+
): SwiftCompileSubmit | undefined {
|
|
95
|
+
const { assetReadToken, endpoint } = context
|
|
96
|
+
if (!assetReadToken) return undefined
|
|
97
|
+
const url = endpoint
|
|
98
|
+
? `${endpoint.replace(/\/+$/, '')}${SWIFT_COMPILE_PATH}`
|
|
99
|
+
: SWIFT_COMPILE_PATH
|
|
100
|
+
|
|
101
|
+
return async (work) => {
|
|
102
|
+
let response: Response
|
|
103
|
+
try {
|
|
104
|
+
response = await fetch(url, {
|
|
105
|
+
method: 'POST',
|
|
106
|
+
headers: { 'content-type': 'application/json' },
|
|
107
|
+
body: JSON.stringify({ ...work, token: assetReadToken }),
|
|
108
|
+
})
|
|
109
|
+
} catch (error) {
|
|
110
|
+
throw new Error(
|
|
111
|
+
`contrast-bundler: fetch failed for ${url} while compiling ${work.entry}: ${error instanceof Error ? error.message : String(error)}`,
|
|
112
|
+
{ cause: error },
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
if (!response.ok) {
|
|
116
|
+
const detail = (await response.text()).trim()
|
|
117
|
+
throw new Error(
|
|
118
|
+
`contrast-bundler: the swift compile for ${work.entry} answered ${response.status}${detail ? `: ${detail}` : ''}`,
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
return (await response.json()) as SwiftCompileOutcome
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface SwiftModuleAddress {
|
|
126
|
+
/** absolute url the tenant fetches the wasm from. */
|
|
127
|
+
url: string
|
|
128
|
+
hash: string
|
|
129
|
+
/** bundle asset name to absolute photo url, when the pack publishes any. */
|
|
130
|
+
imageUrls?: Record<string, string>
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** the service answers root-relative; the caller that knows the origin resolves. */
|
|
134
|
+
function resolveImageUrls(
|
|
135
|
+
urls: Record<string, string>,
|
|
136
|
+
origin: string,
|
|
137
|
+
): Record<string, string> {
|
|
138
|
+
const resolved: Record<string, string> = {}
|
|
139
|
+
for (const [name, url] of Object.entries(urls)) {
|
|
140
|
+
resolved[name] = new URL(url, origin).href
|
|
141
|
+
}
|
|
142
|
+
return resolved
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* one project's swift sources as a published artifact address.
|
|
147
|
+
*
|
|
148
|
+
* `origin` is the origin the artifact route answers on — the app's own origin
|
|
149
|
+
* for the browser worker, the caller's compile origin for a node build. The
|
|
150
|
+
* contract's url is root-relative because the compile host has no browser
|
|
151
|
+
* origin in front of it, so the resolution happens here, at the one caller
|
|
152
|
+
* that knows both.
|
|
153
|
+
*/
|
|
154
|
+
export async function compileSwiftProject(
|
|
155
|
+
submit: SwiftCompileSubmit,
|
|
156
|
+
work: {
|
|
157
|
+
files: Record<string, string>
|
|
158
|
+
resources?: Record<string, string>
|
|
159
|
+
images?: Record<string, SwiftImageUpload>
|
|
160
|
+
entry: string
|
|
161
|
+
},
|
|
162
|
+
origin: string,
|
|
163
|
+
): Promise<SwiftModuleAddress> {
|
|
164
|
+
while (true) {
|
|
165
|
+
const outcome = await submit(work)
|
|
166
|
+
switch (outcome.status) {
|
|
167
|
+
case 'published':
|
|
168
|
+
return {
|
|
169
|
+
url: new URL(outcome.artifactUrl, origin).href,
|
|
170
|
+
hash: outcome.hash,
|
|
171
|
+
...(outcome.imageUrls === undefined
|
|
172
|
+
? {}
|
|
173
|
+
: { imageUrls: resolveImageUrls(outcome.imageUrls, origin) }),
|
|
174
|
+
}
|
|
175
|
+
case 'compiling':
|
|
176
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS))
|
|
177
|
+
continue
|
|
178
|
+
case 'refused':
|
|
179
|
+
case 'failed':
|
|
180
|
+
throw new Error(
|
|
181
|
+
`contrast-bundler: the swift sources for ${work.entry} cannot be compiled: ${outcome.detail}`,
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
package/src/swift.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// the runtime the `.swift` vite transform emits its module against. the
|
|
2
|
+
// implementation lives beside the toolchain it drives, in sootsim-swift.
|
|
3
|
+
export {
|
|
4
|
+
createSwiftEntry,
|
|
5
|
+
type SwiftEntryOptions,
|
|
6
|
+
type SwiftModuleOptions,
|
|
7
|
+
} from '../../sootsim-swift/src/mount.tsx'
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process'
|
|
2
|
+
import {
|
|
3
|
+
isValidTeamMachineSessionId,
|
|
4
|
+
teamMachineSessionIdFromCliIdentity,
|
|
5
|
+
} from './agent-identity.ts'
|
|
6
|
+
import type { AgentPromptEnvelope } from './agent-prompt.ts'
|
|
7
|
+
|
|
8
|
+
export { teamMachineSessionIdFromCliIdentity } from './agent-identity.ts'
|
|
9
|
+
|
|
10
|
+
export function formatTeamMachinePromptText(prompt: AgentPromptEnvelope): string {
|
|
11
|
+
return typeof prompt.text === 'string' ? prompt.text.trim() : ''
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function resolveTeamMachineCommand(explicit?: string): string {
|
|
15
|
+
const fromArg = explicit?.trim()
|
|
16
|
+
if (fromArg) return fromArg
|
|
17
|
+
return 'tm'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function sendPromptToTeamMachineSession(input: {
|
|
21
|
+
sessionId: string
|
|
22
|
+
prompt: AgentPromptEnvelope
|
|
23
|
+
command?: string
|
|
24
|
+
timeoutMs?: number
|
|
25
|
+
}): Promise<void> {
|
|
26
|
+
const sessionId = input.sessionId.trim()
|
|
27
|
+
if (!isValidTeamMachineSessionId(sessionId)) {
|
|
28
|
+
throw new Error(`invalid Team Machine session id: ${sessionId || '<empty>'}`)
|
|
29
|
+
}
|
|
30
|
+
const text = formatTeamMachinePromptText(input.prompt)
|
|
31
|
+
if (!text) {
|
|
32
|
+
throw new Error('prompt text is empty')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const command = resolveTeamMachineCommand(input.command)
|
|
36
|
+
const timeoutMs = input.timeoutMs ?? 15_000
|
|
37
|
+
await new Promise<void>((resolve, reject) => {
|
|
38
|
+
const child = spawn(command, ['send', sessionId, text], {
|
|
39
|
+
stdio: ['ignore', 'ignore', 'pipe'],
|
|
40
|
+
env: process.env,
|
|
41
|
+
})
|
|
42
|
+
let stderr = ''
|
|
43
|
+
const timer = setTimeout(() => {
|
|
44
|
+
try {
|
|
45
|
+
child.kill('SIGTERM')
|
|
46
|
+
} catch {}
|
|
47
|
+
reject(new Error(`tm send timed out after ${Math.round(timeoutMs / 1000)}s`))
|
|
48
|
+
}, timeoutMs)
|
|
49
|
+
|
|
50
|
+
child.stderr?.setEncoding('utf8')
|
|
51
|
+
child.stderr?.on('data', (chunk) => {
|
|
52
|
+
if (stderr.length < 4000) stderr += String(chunk)
|
|
53
|
+
})
|
|
54
|
+
child.on('error', (err) => {
|
|
55
|
+
clearTimeout(timer)
|
|
56
|
+
reject(err)
|
|
57
|
+
})
|
|
58
|
+
child.on('close', (code, signal) => {
|
|
59
|
+
clearTimeout(timer)
|
|
60
|
+
if (code === 0) {
|
|
61
|
+
resolve()
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
const detail = stderr.trim()
|
|
65
|
+
reject(
|
|
66
|
+
new Error(
|
|
67
|
+
detail ||
|
|
68
|
+
`tm send exited with ${signal ? `signal ${signal}` : `code ${code ?? 'unknown'}`}`,
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
// sootsim plugin for One/Vite — serves the installed sootsim runtime at /__soot/
|
|
2
|
+
// from ~/.rnx/runtimes/<version>. version-owned localhost origins remain
|
|
3
|
+
// bound to that directory across an active-runtime update.
|
|
4
|
+
//
|
|
5
|
+
// usage in vite.config.ts:
|
|
6
|
+
// import { rnxPlugin } from 'rnxsim/vite'
|
|
7
|
+
// export default { plugins: [one(), rnxPlugin()] }
|
|
8
|
+
|
|
9
|
+
import fs from 'fs'
|
|
10
|
+
import { randomUUID } from 'node:crypto'
|
|
11
|
+
import path from 'path'
|
|
12
|
+
import { DEFAULT_SOOTSIM_BRIDGE_PORT } from './bridge-constants'
|
|
13
|
+
import {
|
|
14
|
+
launchRnxDesktop,
|
|
15
|
+
resolveRnxDesktopAppName,
|
|
16
|
+
resolveRnxDesktopLaunchTarget,
|
|
17
|
+
tagRnxBundleForPlugin,
|
|
18
|
+
type RnxDesktopOpenOption,
|
|
19
|
+
} from './dev-server-open'
|
|
20
|
+
import { isDaemonLockfileFresh, readDaemonLockfile } from './home-paths'
|
|
21
|
+
import { handleReplacementModuleRequest } from './host/replacement-module-handler'
|
|
22
|
+
import {
|
|
23
|
+
isRootRuntimeAssetPath,
|
|
24
|
+
resolveRuntimeFilePath,
|
|
25
|
+
resolveRuntimeRootForRequestHost,
|
|
26
|
+
serveRuntimeFile,
|
|
27
|
+
SOOTSIM_RUNTIME_MISSING_MESSAGE,
|
|
28
|
+
} from './runtime-assets'
|
|
29
|
+
import type { Plugin } from 'vite'
|
|
30
|
+
|
|
31
|
+
export interface RnxPluginOptions {
|
|
32
|
+
// custom bundle URL (default: auto-detect from One's metro)
|
|
33
|
+
bundleUrl?: string
|
|
34
|
+
// path prefix (default: '/__soot')
|
|
35
|
+
prefix?: string
|
|
36
|
+
// disable sootsim
|
|
37
|
+
enabled?: boolean
|
|
38
|
+
// launch the sootsim simulator loading this server's bundle once the dev
|
|
39
|
+
// server is listening. skipped when CI or RNX_NO_OPEN is set.
|
|
40
|
+
open?: RnxDesktopOpenOption
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function rnxPlugin(options: RnxPluginOptions = {}): Plugin {
|
|
44
|
+
const prefix = options.prefix || '/__soot'
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
name: 'sootsim-one',
|
|
48
|
+
|
|
49
|
+
// use-latest-callback ships a CJS main (module.exports, no default) with
|
|
50
|
+
// an esm.mjs shim that re-imports it. react-native-bottom-tabs
|
|
51
|
+
// default-imports it from source served live, so vite hands the browser
|
|
52
|
+
// the raw CJS file and the import fails with 'does not provide an export
|
|
53
|
+
// named default' before anything mounts. forcing it through dep
|
|
54
|
+
// optimization lets esbuild's CJS interop answer the default import, and
|
|
55
|
+
// every bare import of it (including the nested copy's) resolves to the
|
|
56
|
+
// one pre-bundled instance.
|
|
57
|
+
config() {
|
|
58
|
+
return { optimizeDeps: { include: ['use-latest-callback'] } }
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
configureServer(server) {
|
|
62
|
+
if (options.enabled === false) return
|
|
63
|
+
const bundleUrl =
|
|
64
|
+
options.bundleUrl ||
|
|
65
|
+
'/node_modules/one/metro-entry.bundle?platform=ios&dev=true&minify=false'
|
|
66
|
+
const appName = resolveRnxDesktopAppName(options.open, server.config.root)
|
|
67
|
+
const replacementToken = randomUUID()
|
|
68
|
+
const configuredPort = server.config.server.port || 8081
|
|
69
|
+
const listeningPort = (): number => {
|
|
70
|
+
const address = server.httpServer?.address()
|
|
71
|
+
return address && typeof address === 'object' ? address.port : configuredPort
|
|
72
|
+
}
|
|
73
|
+
const bundleForPort = (port: number): string =>
|
|
74
|
+
tagRnxBundleForPlugin(
|
|
75
|
+
bundleUrl,
|
|
76
|
+
`http://localhost:${port}`,
|
|
77
|
+
replacementToken,
|
|
78
|
+
server.config.root,
|
|
79
|
+
appName,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
// build the shell HTML, injecting the bundle URL (so main.tsx loads this
|
|
83
|
+
// app's bundle) AND window.__sootsimBridgePort. the bridge-port injection
|
|
84
|
+
// mirrors the dev-stack bridge-host: without it the engine's
|
|
85
|
+
// resolveBridgePort() falls back to a location-derived guess that mis-maps
|
|
86
|
+
// a non-Contrast app port (the mobile template's :4400 -> 9068) and the sim
|
|
87
|
+
// can't reach the bridge. resolved per-request from the daemon lockfile
|
|
88
|
+
// (the CLI's `open` writes/uses it before the shell loads) so the engine
|
|
89
|
+
// targets the SAME bridge the CLI does; default port otherwise.
|
|
90
|
+
const buildShellHtml = (runtimeRoot: string): string => {
|
|
91
|
+
const html = fs.readFileSync(path.join(runtimeRoot, 'index.html'), 'utf8')
|
|
92
|
+
const lock = readDaemonLockfile()
|
|
93
|
+
const bridgePort =
|
|
94
|
+
lock && isDaemonLockfileFresh(lock) && lock.bridgePort > 0
|
|
95
|
+
? lock.bridgePort
|
|
96
|
+
: DEFAULT_SOOTSIM_BRIDGE_PORT
|
|
97
|
+
// inject the bridge port + a default bundle (only when the URL has none,
|
|
98
|
+
// so the CLI's resolved bundle wins), and PRESERVE the existing query.
|
|
99
|
+
// preserving the query is essential: `rnx open` stamps the open URL
|
|
100
|
+
// with `inspectOpen=<token>` and matches the registered sim by that
|
|
101
|
+
// token (waitForSimMatch). the old code forced `?bundle=` only and
|
|
102
|
+
// stripped inspectOpen, so the sim registered but never matched and
|
|
103
|
+
// `open` timed out after 60s.
|
|
104
|
+
const inject =
|
|
105
|
+
`<script>(function(){var u=new URL(location.href);` +
|
|
106
|
+
`if(!u.searchParams.has('bundle'))u.searchParams.set('bundle',${JSON.stringify(bundleForPort(listeningPort()))});` +
|
|
107
|
+
`window.__sootsimBridgePort=${bridgePort};` +
|
|
108
|
+
`history.replaceState(null,'','${prefix}/'+u.search)})()</script>`
|
|
109
|
+
return html.replace('</head>', inject + '</head>')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// mirror Set-Cookie into a readable header for sootsim's fetch wrapper
|
|
113
|
+
server.middlewares.use((req, res, next) => {
|
|
114
|
+
const origWriteHead = res.writeHead.bind(res)
|
|
115
|
+
res.writeHead = function (statusCode: number, ...args: unknown[]) {
|
|
116
|
+
const setCookie = res.getHeader('set-cookie')
|
|
117
|
+
if (setCookie) {
|
|
118
|
+
const value = Array.isArray(setCookie)
|
|
119
|
+
? setCookie.join(', ')
|
|
120
|
+
: String(setCookie)
|
|
121
|
+
res.setHeader('x-sootsim-set-cookie', value)
|
|
122
|
+
res.setHeader('access-control-expose-headers', 'x-sootsim-set-cookie')
|
|
123
|
+
}
|
|
124
|
+
return (origWriteHead as (...args: unknown[]) => typeof res)(
|
|
125
|
+
statusCode,
|
|
126
|
+
...args,
|
|
127
|
+
)
|
|
128
|
+
} as typeof res.writeHead
|
|
129
|
+
next()
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
// serve a minimal /__server-scan describing THIS vite dev server, so a
|
|
133
|
+
// sootsim shell loaded from <port>/__soot can resolve this app's native
|
|
134
|
+
// bundle. dev-bundle-resolution's resolvePortViaServerScan fetches
|
|
135
|
+
// `/__server-scan` RELATIVE to the shell origin; when the shell is loaded
|
|
136
|
+
// from this target origin, that hits here. without it the request SPA-
|
|
137
|
+
// falls-back to 404 and the bundle never resolves (rnx open hangs).
|
|
138
|
+
// we describe only this server (the shell drives THIS app) — no localhost-
|
|
139
|
+
// wide scan, so the published plugin pulls in no shell-only scanner
|
|
140
|
+
// internals. shape matches DiscoveredServer enough for the resolver.
|
|
141
|
+
server.middlewares.use((req, res, next) => {
|
|
142
|
+
if ((req.url || '').split('?')[0] !== '/__server-scan') return next()
|
|
143
|
+
const scanPort = listeningPort()
|
|
144
|
+
const pluginBundleUrl = bundleForPort(scanPort)
|
|
145
|
+
const absoluteBundleUrl = pluginBundleUrl.startsWith('http')
|
|
146
|
+
? pluginBundleUrl
|
|
147
|
+
: `http://localhost:${scanPort}${pluginBundleUrl}`
|
|
148
|
+
res.setHeader('content-type', 'application/json')
|
|
149
|
+
res.end(
|
|
150
|
+
JSON.stringify([
|
|
151
|
+
{
|
|
152
|
+
port: scanPort,
|
|
153
|
+
framework: 'one',
|
|
154
|
+
bundleUrl: absoluteBundleUrl,
|
|
155
|
+
...(appName ? { projectName: appName } : {}),
|
|
156
|
+
lastSeen: Date.now(),
|
|
157
|
+
},
|
|
158
|
+
]),
|
|
159
|
+
)
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
server.middlewares.use((req, res, next) => {
|
|
163
|
+
void handleReplacementModuleRequest(req, res, {
|
|
164
|
+
projectRoot: server.config.root,
|
|
165
|
+
requestToken: replacementToken,
|
|
166
|
+
requireLoopbackOrigin: true,
|
|
167
|
+
}).then((handled) => {
|
|
168
|
+
if (!handled) next()
|
|
169
|
+
})
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
server.middlewares.use((req, res, next) => {
|
|
173
|
+
const url = req.url || ''
|
|
174
|
+
const pathname = url.split('?')[0]
|
|
175
|
+
const runtimeRoot = resolveRuntimeRootForRequestHost(req.headers.host)
|
|
176
|
+
|
|
177
|
+
if (!runtimeRoot) {
|
|
178
|
+
if (
|
|
179
|
+
pathname === prefix ||
|
|
180
|
+
pathname === prefix + '/' ||
|
|
181
|
+
pathname.startsWith(prefix + '/')
|
|
182
|
+
) {
|
|
183
|
+
res.statusCode = 500
|
|
184
|
+
res.end(SOOTSIM_RUNTIME_MISSING_MESSAGE)
|
|
185
|
+
return
|
|
186
|
+
}
|
|
187
|
+
next()
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// root-relative runtime assets emitted by the shell and engine vite
|
|
192
|
+
// builds. only intercept when the asset exists in the active runtime.
|
|
193
|
+
if (isRootRuntimeAssetPath(pathname)) {
|
|
194
|
+
const fullPath = resolveRuntimeFilePath(runtimeRoot, pathname)
|
|
195
|
+
if (fullPath) {
|
|
196
|
+
serveRuntimeFile(req, res, fullPath)
|
|
197
|
+
return
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// serve the sootsim HTML shell — inject bundle URL + bridge port
|
|
202
|
+
if (pathname === prefix || pathname === prefix + '/') {
|
|
203
|
+
res.setHeader('content-type', 'text/html')
|
|
204
|
+
res.end(buildShellHtml(runtimeRoot))
|
|
205
|
+
return
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// serve runtime files under /__soot/*.
|
|
209
|
+
if (pathname.startsWith(prefix + '/')) {
|
|
210
|
+
const fullPath = resolveRuntimeFilePath(
|
|
211
|
+
runtimeRoot,
|
|
212
|
+
pathname.slice(prefix.length),
|
|
213
|
+
)
|
|
214
|
+
if (fullPath) {
|
|
215
|
+
serveRuntimeFile(req, res, fullPath)
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// extensionless in-shell routes should still load the shell.
|
|
220
|
+
const ext = path.extname(pathname)
|
|
221
|
+
if (!ext) {
|
|
222
|
+
res.setHeader('content-type', 'text/html')
|
|
223
|
+
res.end(buildShellHtml(runtimeRoot))
|
|
224
|
+
return
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
next()
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
const port = configuredPort
|
|
232
|
+
const sootsimUrl = `http://localhost:${port}${prefix}/`
|
|
233
|
+
console.log(`[rnx] serving at ${sootsimUrl}`)
|
|
234
|
+
|
|
235
|
+
if (appName && !process.env.CI && !process.env.RNX_NO_OPEN) {
|
|
236
|
+
server.httpServer?.once('listening', () => {
|
|
237
|
+
const openPort = listeningPort()
|
|
238
|
+
launchRnxDesktop(
|
|
239
|
+
resolveRnxDesktopLaunchTarget(openPort, bundleForPort(openPort)),
|
|
240
|
+
appName,
|
|
241
|
+
)
|
|
242
|
+
})
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export const sootsimPlugin = rnxPlugin
|
|
249
|
+
export default rnxPlugin
|
|
250
|
+
|
|
251
|
+
// the `.swift` transform is opt-in per project: an app that never imports a
|
|
252
|
+
// `.swift` file has no reason to watch for one, and an app that ships a native
|
|
253
|
+
// ios/ tree (every swift file in it is a pod or an xcode target, not app
|
|
254
|
+
// source) would otherwise rebuild the wrong package on every edit. a local
|
|
255
|
+
// vite app registers `swiftPlugin` in both the bundler that builds its native
|
|
256
|
+
// bundle and the main dev server that serves the artifact; a One app on the
|
|
257
|
+
// rolldown native engine registers `swiftRemotePlugin` through
|
|
258
|
+
// `native.bundlerOptions.plugins` instead, which submits to
|
|
259
|
+
// `/api/swift-compile` and needs no local toolchain and no serving.
|
|
260
|
+
export { swiftPlugin, type SwiftPluginOptions } from './vite-plugin-swift.ts'
|
|
261
|
+
export {
|
|
262
|
+
swiftRemotePlugin,
|
|
263
|
+
type SwiftRemotePluginOptions,
|
|
264
|
+
} from './rolldown-plugin-swift.ts'
|