ruby_everywhere 0.3.0 → 0.5.0

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.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +339 -0
  3. data/bridge/README.md +70 -1
  4. data/bridge/everywhere/bridge.js +211 -3
  5. data/bridge/everywhere/native.css +61 -0
  6. data/lib/everywhere/android_resources.rb +217 -0
  7. data/lib/everywhere/android_sdk.rb +330 -0
  8. data/lib/everywhere/asset_catalog.rb +185 -0
  9. data/lib/everywhere/auth_handoff.rb +404 -0
  10. data/lib/everywhere/auth_token.rb +118 -0
  11. data/lib/everywhere/builders/android.rb +844 -0
  12. data/lib/everywhere/builders/desktop.rb +326 -0
  13. data/lib/everywhere/builders/ios.rb +40 -3
  14. data/lib/everywhere/child_processes.rb +74 -0
  15. data/lib/everywhere/commands/build.rb +95 -14
  16. data/lib/everywhere/commands/clean.rb +10 -5
  17. data/lib/everywhere/commands/dev.rb +462 -57
  18. data/lib/everywhere/commands/doctor.rb +89 -3
  19. data/lib/everywhere/commands/install.rb +21 -1
  20. data/lib/everywhere/commands/logs.rb +117 -8
  21. data/lib/everywhere/commands/release.rb +2 -2
  22. data/lib/everywhere/config.rb +703 -13
  23. data/lib/everywhere/console.rb +117 -0
  24. data/lib/everywhere/desktop_assets.rb +150 -0
  25. data/lib/everywhere/dock/footer.rb +150 -0
  26. data/lib/everywhere/dock/screen.rb +114 -0
  27. data/lib/everywhere/dock/state.rb +59 -0
  28. data/lib/everywhere/dock.rb +238 -0
  29. data/lib/everywhere/emulator.rb +405 -0
  30. data/lib/everywhere/engine.rb +12 -0
  31. data/lib/everywhere/fatal.rb +20 -0
  32. data/lib/everywhere/icon.rb +196 -0
  33. data/lib/everywhere/line_pump.rb +89 -0
  34. data/lib/everywhere/log_filter.rb +111 -0
  35. data/lib/everywhere/native_helper.rb +39 -9
  36. data/lib/everywhere/omniauth.rb +88 -0
  37. data/lib/everywhere/paths.rb +109 -11
  38. data/lib/everywhere/relay.rb +77 -0
  39. data/lib/everywhere/shellout.rb +90 -15
  40. data/lib/everywhere/task_pool.rb +123 -0
  41. data/lib/everywhere/ui.rb +54 -11
  42. data/lib/everywhere/version.rb +1 -1
  43. data/support/desktop/README.md +121 -0
  44. data/support/{shell → desktop}/src-tauri/Cargo.lock +23 -0
  45. data/support/{shell → desktop}/src-tauri/Cargo.toml +19 -1
  46. data/support/{shell → desktop}/src-tauri/capabilities/default.json +7 -0
  47. data/support/desktop/src-tauri/gen/schemas/capabilities.json +1 -0
  48. data/support/desktop/src-tauri/src/extension_host.rs +53 -0
  49. data/support/desktop/src-tauri/src/extensions/mod.rs +39 -0
  50. data/support/{shell → desktop}/src-tauri/src/main.rs +355 -10
  51. data/support/{shell → desktop}/src-tauri/tauri.conf.json +2 -2
  52. data/support/mobile/android/README.md +217 -0
  53. data/support/mobile/android/app/build.gradle.kts +156 -0
  54. data/support/mobile/android/app/everywhere.properties +8 -0
  55. data/support/mobile/android/app/native-packages.gradle.kts +16 -0
  56. data/support/mobile/android/app/proguard-rules.pro +21 -0
  57. data/support/mobile/android/app/src/debug/res/xml/network_security_config.xml +30 -0
  58. data/support/mobile/android/app/src/main/AndroidManifest.xml +42 -0
  59. data/support/mobile/android/app/src/main/assets/everywhere.json +9 -0
  60. data/support/mobile/android/app/src/main/assets/fonts/MaterialIcons-Regular.codepoints +2235 -0
  61. data/support/mobile/android/app/src/main/assets/fonts/MaterialIcons-Regular.ttf +0 -0
  62. data/support/mobile/android/app/src/main/assets/json/path-configuration.json +19 -0
  63. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/AuthFlow.kt +268 -0
  64. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereApplication.kt +178 -0
  65. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereConfig.kt +409 -0
  66. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereEvents.kt +68 -0
  67. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereHost.kt +101 -0
  68. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/IconFont.kt +211 -0
  69. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/MainActivity.kt +975 -0
  70. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/MainTabs.kt +201 -0
  71. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/WebBottomSheetFragment.kt +13 -0
  72. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/WebFragment.kt +36 -0
  73. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/BiometricsComponent.kt +535 -0
  74. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/HapticsComponent.kt +141 -0
  75. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/MenuComponent.kt +361 -0
  76. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/NotificationComponent.kt +151 -0
  77. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/PermissionsComponent.kt +271 -0
  78. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/StorageComponent.kt +101 -0
  79. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/WebControlChannel.kt +204 -0
  80. data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/extensions/EverywhereExtensions.kt +51 -0
  81. data/support/mobile/android/app/src/main/res/color/bottom_navigation_active_indicator.xml +4 -0
  82. data/support/mobile/android/app/src/main/res/color/bottom_navigation_item.xml +11 -0
  83. data/support/mobile/android/app/src/main/res/drawable/ic_launcher_foreground.xml +26 -0
  84. data/support/mobile/android/app/src/main/res/drawable/ic_tab_placeholder.xml +28 -0
  85. data/support/mobile/android/app/src/main/res/layout/activity_main.xml +116 -0
  86. data/support/mobile/android/app/src/main/res/layout/bridge_menu_sheet.xml +83 -0
  87. data/support/mobile/android/app/src/main/res/layout/bridge_menu_sheet_item.xml +35 -0
  88. data/support/mobile/android/app/src/main/res/layout/tab_more_sheet.xml +48 -0
  89. data/support/mobile/android/app/src/main/res/layout/tab_more_sheet_item.xml +35 -0
  90. data/support/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +12 -0
  91. data/support/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +6 -0
  92. data/support/mobile/android/app/src/main/res/values/colors.xml +21 -0
  93. data/support/mobile/android/app/src/main/res/values/ic_launcher_background.xml +5 -0
  94. data/support/mobile/android/app/src/main/res/values/strings.xml +18 -0
  95. data/support/mobile/android/app/src/main/res/values/styles.xml +32 -0
  96. data/support/mobile/android/app/src/main/res/values/themes.xml +53 -0
  97. data/support/mobile/android/app/src/main/res/values-night/colors.xml +11 -0
  98. data/support/mobile/android/app/src/main/res/values-night/themes.xml +33 -0
  99. data/support/mobile/android/app/src/main/res/xml/network_security_config.xml +12 -0
  100. data/support/mobile/android/app/src/stamped/AndroidManifest.xml +34 -0
  101. data/support/mobile/android/build.gradle.kts +8 -0
  102. data/support/mobile/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  103. data/support/mobile/android/gradle/wrapper/gradle-wrapper.properties +10 -0
  104. data/support/mobile/android/gradle.properties +14 -0
  105. data/support/mobile/android/gradlew +251 -0
  106. data/support/mobile/android/gradlew.bat +94 -0
  107. data/support/mobile/android/settings.gradle.kts +28 -0
  108. data/support/mobile/ios/App/AppDelegate.swift +5 -0
  109. data/support/mobile/ios/App/AuthFlow.swift +101 -0
  110. data/support/mobile/ios/App/EverywhereConfig.swift +84 -0
  111. data/support/mobile/ios/App/SceneDelegate.swift +103 -0
  112. data/support/mobile/ios/App.xcodeproj/project.pbxproj +4 -0
  113. data/support/mobile/ios/README.md +4 -1
  114. data/support/{macos → release/macos}/notarize.sh +2 -2
  115. metadata +97 -17
  116. data/support/github/build.yml +0 -85
  117. data/support/shell/src-tauri/gen/schemas/capabilities.json +0 -1
  118. /data/support/{shell → desktop}/splash/index.html +0 -0
  119. /data/support/{shell → desktop}/src-tauri/build.rs +0 -0
  120. /data/support/{shell → desktop}/src-tauri/gen/schemas/acl-manifests.json +0 -0
  121. /data/support/{shell → desktop}/src-tauri/gen/schemas/desktop-schema.json +0 -0
  122. /data/support/{shell → desktop}/src-tauri/gen/schemas/macOS-schema.json +0 -0
  123. /data/support/{shell → desktop}/src-tauri/icons/icon.png +0 -0
  124. /data/support/{shell → desktop}/src-tauri/src/updater.rs +0 -0
  125. /data/support/{macos → release/macos}/entitlements.plist +0 -0
@@ -1,3 +1,4 @@
1
+ import AuthenticationServices
1
2
  import HotwireNative
2
3
  import UIKit
3
4
  import WebKit
@@ -43,6 +44,18 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
43
44
  /// until the first navigator/tab bar is built, then routed.
44
45
  private var pendingUniversalLinkURL: URL?
45
46
 
47
+ /// Third-party sign-in, run in the system browser (everywhere.yml `auth:`).
48
+ /// Held for the scene's lifetime — the session inside it must outlive the
49
+ /// call that started it.
50
+ private lazy var authFlow = AuthFlow { [weak self] in
51
+ self?.window ?? ASPresentationAnchor()
52
+ }
53
+
54
+ /// Set while the web view is spending a handoff token. The visit that
55
+ /// follows carries the Set-Cookie headers that sign the app in, so the
56
+ /// auth-gated tab bar can only be fetched once it has finished.
57
+ private var awaitingAuthHandoff = false
58
+
46
59
  func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
47
60
  guard let windowScene = scene as? UIWindowScene else { return }
48
61
 
@@ -75,6 +88,9 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
75
88
  NotificationCenter.default.addObserver(
76
89
  self, selector: #selector(handleNativeVisit(_:)),
77
90
  name: .everywhereNativeVisit, object: nil)
91
+ NotificationCenter.default.addObserver(
92
+ self, selector: #selector(handleAuthFlow(_:)),
93
+ name: .everywhereAuthFlow, object: nil)
78
94
 
79
95
  // Cookie hydration BEFORE the first visit: after a force-kill relaunch
80
96
  // (iOS kills the app when a Settings permission changes) the first
@@ -182,6 +198,10 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
182
198
  /// 3. refresh the auth-aware server config, which rebuilds the tab bar
183
199
  /// back in if (and only if) the user is now signed in.
184
200
  private func resetApp(to target: URL) {
201
+ // A sign-in sheet still up is answering a question the app no longer
202
+ // has — the reset is re-rooting or re-authing underneath it.
203
+ authFlow.cancel()
204
+ awaitingAuthHandoff = false
185
205
  clearWebContentCache()
186
206
  rebuildRoot(entries: [], routeTo: target)
187
207
  loadedTabsFingerprint = "" // matches the empty tab set we just built
@@ -203,6 +223,75 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
203
223
  activeNavigator.route(url)
204
224
  }
205
225
 
226
+ // MARK: Third-party sign-in
227
+
228
+ /// `{action: "authFlow", to: "/auth/github"}` from the gem's
229
+ /// /everywhere/auth/native page — the fallback for visits the proposal
230
+ /// handler never sees (a `data-turbo="false"` link, or OmniAuth 2's POST).
231
+ @objc private func handleAuthFlow(_ note: Notification) {
232
+ guard let to = note.userInfo?["to"] as? String, to.hasPrefix("/"), !to.hasPrefix("//") else { return }
233
+ startAuthFlow(to: to)
234
+ }
235
+
236
+ /// Open a provider sign-in in the system browser. Nothing is loaded in the
237
+ /// web view: the whole point is that this URL never touches it.
238
+ private func startAuthFlow(to: String) {
239
+ guard let scheme = config.authScheme,
240
+ let start = config.authStartURL(to: to, returnTo: currentPath)
241
+ else { return }
242
+
243
+ #if DEBUG
244
+ NSLog("authFlow: %@", start.absoluteString)
245
+ #endif
246
+
247
+ authFlow.start(url: start, scheme: scheme) { [weak self] result in
248
+ guard let self else { return }
249
+ switch result {
250
+ case .success(let token):
251
+ self.finishAuthFlow(token: token)
252
+ case .failure(.canceled):
253
+ break // they closed the sheet; they're still on the page they started from
254
+ case .failure(let error):
255
+ self.presentAuthFailure(error)
256
+ }
257
+ }
258
+ }
259
+
260
+ /// Spend the handoff token in the web view and rebuild around whatever it
261
+ /// signs the app in as. Deliberately the reset sequence, in order:
262
+ /// 1. drop cached web content — the pre-auth pages are all stale now,
263
+ /// 2. drop to a single navigator aimed at the handoff, which sets the
264
+ /// session cookie in the WEB VIEW's jar (the browser's jar, where the
265
+ /// flow actually happened, is unreachable from here) and redirects on
266
+ /// to the app's post-sign-in page,
267
+ /// 3. once that request has finished — and only then, or the fetch races
268
+ /// the cookie — re-read the auth-gated config, which brings the tab
269
+ /// bar back for the user who just signed in.
270
+ private func finishAuthFlow(token: String) {
271
+ guard let handoff = config.authHandoffURL(token: token) else { return }
272
+
273
+ clearWebContentCache()
274
+ rebuildRoot(entries: [], routeTo: handoff)
275
+ loadedTabsFingerprint = "" // matches the empty tab set we just built
276
+ awaitingAuthHandoff = true
277
+ }
278
+
279
+ private func presentAuthFailure(_ error: AuthFlow.Failure) {
280
+ NSLog("authFlow failed: %@", String(describing: error))
281
+
282
+ let alert = UIAlertController(title: "Sign-in didn't finish",
283
+ message: "Something went wrong on the way back to the app. Please try again.",
284
+ preferredStyle: .alert)
285
+ alert.addAction(UIAlertAction(title: "OK", style: .default))
286
+ activeNavigator.activeNavigationController.present(alert, animated: true)
287
+ }
288
+
289
+ /// The path the user is currently on, for the flow to come back to when the
290
+ /// app's own sign-in doesn't name a destination.
291
+ private var currentPath: String? {
292
+ activeNavigator.currentVisitableURL.map { config.pathAndQuery(of: $0) }
293
+ }
294
+
206
295
  // MARK: Instance switching (multi-instance apps)
207
296
 
208
297
  /// `Everywhere.instance.set(url)`: persist the picked instance as the
@@ -444,6 +533,13 @@ extension SceneDelegate: NavigatorDelegate {
444
533
  resetApp(to: resetTarget(from: proposal.url))
445
534
  return .reject
446
535
  }
536
+ // A provider sign-in: hand it to the system browser instead of loading
537
+ // it here. Rejecting leaves the user on the page they tapped from, which
538
+ // is where they belong if they close the sheet.
539
+ if let target = config.authTarget(for: proposal.url) {
540
+ startAuthFlow(to: target)
541
+ return .reject
542
+ }
447
543
  // App-provided native screens: a path rule's `view_controller`
448
544
  // identifier resolves through the extension registry (everywhere.yml
449
545
  // native.ios.screens). Unknown identifiers fall through to the web.
@@ -460,6 +556,13 @@ extension SceneDelegate: NavigatorDelegate {
460
556
 
461
557
  func requestDidFinish(at url: URL) {
462
558
  dismissSplash()
559
+
560
+ // The handoff has landed, so its cookies are in the web view's jar:
561
+ // now the tab bar can be fetched as the signed-in user.
562
+ if awaitingAuthHandoff {
563
+ awaitingAuthHandoff = false
564
+ loadPathConfiguration(serverOnly: true)
565
+ }
463
566
  }
464
567
 
465
568
  func visitableDidFailRequest(_ visitable: any Visitable, error: HotwireNativeError, retryHandler: RetryBlock?) {
@@ -18,6 +18,7 @@
18
18
  EBE000000000000000000060 /* StorageComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBE000000000000000000059 /* StorageComponent.swift */; };
19
19
  EBE000000000000000000068 /* MenuComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBE000000000000000000067 /* MenuComponent.swift */; };
20
20
  EBE000000000000000000063 /* EverywhereHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBE000000000000000000062 /* EverywhereHost.swift */; };
21
+ EBE000000000000000000070 /* AuthFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBE000000000000000000069 /* AuthFlow.swift */; };
21
22
  EBE000000000000000000036 /* everywhere.json in Resources */ = {isa = PBXBuildFile; fileRef = EBE000000000000000000018 /* everywhere.json */; };
22
23
  EBE000000000000000000037 /* path-configuration.json in Resources */ = {isa = PBXBuildFile; fileRef = EBE000000000000000000019 /* path-configuration.json */; };
23
24
  EBE000000000000000000038 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EBE000000000000000000020 /* Assets.xcassets */; };
@@ -45,6 +46,7 @@
45
46
  EBE000000000000000000020 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
46
47
  EBE000000000000000000021 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
47
48
  EBE000000000000000000062 /* EverywhereHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EverywhereHost.swift; sourceTree = "<group>"; };
49
+ EBE000000000000000000069 /* AuthFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthFlow.swift; sourceTree = "<group>"; };
48
50
  /* End PBXFileReference section */
49
51
 
50
52
  /* Begin PBXFileSystemSynchronizedRootGroup section */
@@ -89,6 +91,7 @@
89
91
  EBE000000000000000000015 /* EverywhereConfig.swift */,
90
92
  EBE000000000000000000016 /* ErrorViewController.swift */,
91
93
  EBE000000000000000000062 /* EverywhereHost.swift */,
94
+ EBE000000000000000000069 /* AuthFlow.swift */,
92
95
  EBE000000000000000000005 /* Bridge */,
93
96
  EBE000000000000000000061 /* Extensions */,
94
97
  EBE000000000000000000023 /* Resources */,
@@ -215,6 +218,7 @@
215
218
  EBE000000000000000000060 /* StorageComponent.swift in Sources */,
216
219
  EBE000000000000000000068 /* MenuComponent.swift in Sources */,
217
220
  EBE000000000000000000063 /* EverywhereHost.swift in Sources */,
221
+ EBE000000000000000000070 /* AuthFlow.swift in Sources */,
218
222
  );
219
223
  runOnlyForDeploymentPostprocessing = 0;
220
224
  };
@@ -19,7 +19,10 @@ this template, it overwrites **exactly** these files and nothing else:
19
19
  4. `App/Assets.xcassets/AppIcon.appiconset/AppIcon.png` — the app icon (1024×1024 opaque PNG)
20
20
  5. *(optionally)* `App/Assets.xcassets/AccentColor.colorset/Contents.json` and
21
21
  `App/Assets.xcassets/LaunchBackground.colorset/Contents.json` — brand colors
22
- 6. *(optionally)* `App/App.entitlements` — the Associated Domains entitlement,
22
+ 6. *(optionally)* `App/Info.plist`'s `CFBundleURLTypes` — the sign-in callback
23
+ scheme, written **only** when `auth:` is set in `everywhere.yml` (alongside
24
+ the permission usage strings, which are stamped the same way)
25
+ 7. *(optionally)* `App/App.entitlements` — the Associated Domains entitlement,
23
26
  written **only** when `deep_linking:` is set in `everywhere.yml`. The matching
24
27
  `CODE_SIGN_ENTITLEMENTS` is added to the xcconfig in the same case, so the
25
28
  default build stays entitlement-free and the frozen template still compiles
@@ -7,7 +7,7 @@
7
7
  # easiest way is to source your release env first:
8
8
  #
9
9
  # source ~/Projects/atlastools.dev/atlas-workspaces/.env.release
10
- # cli/support/macos/notarize.sh "example/dist/Example Notes.app"
10
+ # cli/support/release/macos/notarize.sh "example/dist/Example Notes.app"
11
11
  #
12
12
  # Required env vars (these match Tauri's names, so your existing .env works):
13
13
  # APPLE_SIGNING_IDENTITY e.g. "Developer ID Application: Your Name (TEAMID)"
@@ -33,7 +33,7 @@ APP="${1:?usage: notarize.sh /path/to/App.app}"
33
33
  # containing spaces/parens (e.g. APPLE_SIGNING_IDENTITY=Developer ID
34
34
  # Application: Name (TEAM)) that plain `source .env.release` cannot.
35
35
  #
36
- # ENV_FILE=.env.release cli/support/macos/notarize.sh "App.app"
36
+ # ENV_FILE=.env.release cli/support/release/macos/notarize.sh "App.app"
37
37
  if [ -n "${ENV_FILE:-}" ]; then
38
38
  [ -f "$ENV_FILE" ] || { echo "ENV_FILE not found: $ENV_FILE" >&2; exit 1; }
39
39
  while IFS= read -r line || [ -n "$line" ]; do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_everywhere
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrea Fomera
@@ -76,6 +76,7 @@ extensions: []
76
76
  extra_rdoc_files: []
77
77
  files:
78
78
  - LICENSE.txt
79
+ - README.md
79
80
  - bridge/LICENSE
80
81
  - bridge/README.md
81
82
  - bridge/everywhere/bridge.js
@@ -85,9 +86,17 @@ files:
85
86
  - exe/every
86
87
  - exe/rbe
87
88
  - lib/everywhere.rb
89
+ - lib/everywhere/android_resources.rb
90
+ - lib/everywhere/android_sdk.rb
91
+ - lib/everywhere/asset_catalog.rb
92
+ - lib/everywhere/auth_handoff.rb
93
+ - lib/everywhere/auth_token.rb
88
94
  - lib/everywhere/blake2b.rb
89
95
  - lib/everywhere/boot.rb
96
+ - lib/everywhere/builders/android.rb
97
+ - lib/everywhere/builders/desktop.rb
90
98
  - lib/everywhere/builders/ios.rb
99
+ - lib/everywhere/child_processes.rb
91
100
  - lib/everywhere/cli.rb
92
101
  - lib/everywhere/commands/build.rb
93
102
  - lib/everywhere/commands/clean.rb
@@ -106,16 +115,26 @@ files:
106
115
  - lib/everywhere/commands/shell_dir.rb
107
116
  - lib/everywhere/commands/updates_keygen.rb
108
117
  - lib/everywhere/config.rb
118
+ - lib/everywhere/console.rb
109
119
  - lib/everywhere/database.rb
120
+ - lib/everywhere/desktop_assets.rb
121
+ - lib/everywhere/dock.rb
122
+ - lib/everywhere/dock/footer.rb
123
+ - lib/everywhere/dock/screen.rb
124
+ - lib/everywhere/dock/state.rb
125
+ - lib/everywhere/emulator.rb
110
126
  - lib/everywhere/engine.rb
127
+ - lib/everywhere/fatal.rb
111
128
  - lib/everywhere/framework.rb
112
129
  - lib/everywhere/icon.rb
113
130
  - lib/everywhere/ignore.rb
131
+ - lib/everywhere/line_pump.rb
114
132
  - lib/everywhere/log_filter.rb
115
133
  - lib/everywhere/minisign.rb
116
134
  - lib/everywhere/mobile_config_endpoint.rb
117
135
  - lib/everywhere/mobile_configs_controller.rb
118
136
  - lib/everywhere/native_helper.rb
137
+ - lib/everywhere/omniauth.rb
119
138
  - lib/everywhere/paths.rb
120
139
  - lib/everywhere/platform/client.rb
121
140
  - lib/everywhere/platform/credentials.rb
@@ -123,16 +142,87 @@ files:
123
142
  - lib/everywhere/png.rb
124
143
  - lib/everywhere/raster.rb
125
144
  - lib/everywhere/receipt.rb
145
+ - lib/everywhere/relay.rb
126
146
  - lib/everywhere/s3.rb
127
147
  - lib/everywhere/shellout.rb
128
148
  - lib/everywhere/simulator.rb
149
+ - lib/everywhere/task_pool.rb
129
150
  - lib/everywhere/ui.rb
130
151
  - lib/everywhere/update_manifest.rb
131
152
  - lib/everywhere/version.rb
132
153
  - lib/ruby_everywhere.rb
133
- - support/github/build.yml
134
- - support/macos/entitlements.plist
135
- - support/macos/notarize.sh
154
+ - support/desktop/README.md
155
+ - support/desktop/splash/index.html
156
+ - support/desktop/src-tauri/Cargo.lock
157
+ - support/desktop/src-tauri/Cargo.toml
158
+ - support/desktop/src-tauri/build.rs
159
+ - support/desktop/src-tauri/capabilities/default.json
160
+ - support/desktop/src-tauri/gen/schemas/acl-manifests.json
161
+ - support/desktop/src-tauri/gen/schemas/capabilities.json
162
+ - support/desktop/src-tauri/gen/schemas/desktop-schema.json
163
+ - support/desktop/src-tauri/gen/schemas/macOS-schema.json
164
+ - support/desktop/src-tauri/icons/icon.png
165
+ - support/desktop/src-tauri/src/extension_host.rs
166
+ - support/desktop/src-tauri/src/extensions/mod.rs
167
+ - support/desktop/src-tauri/src/main.rs
168
+ - support/desktop/src-tauri/src/updater.rs
169
+ - support/desktop/src-tauri/tauri.conf.json
170
+ - support/mobile/android/README.md
171
+ - support/mobile/android/app/build.gradle.kts
172
+ - support/mobile/android/app/everywhere.properties
173
+ - support/mobile/android/app/native-packages.gradle.kts
174
+ - support/mobile/android/app/proguard-rules.pro
175
+ - support/mobile/android/app/src/debug/res/xml/network_security_config.xml
176
+ - support/mobile/android/app/src/main/AndroidManifest.xml
177
+ - support/mobile/android/app/src/main/assets/everywhere.json
178
+ - support/mobile/android/app/src/main/assets/fonts/MaterialIcons-Regular.codepoints
179
+ - support/mobile/android/app/src/main/assets/fonts/MaterialIcons-Regular.ttf
180
+ - support/mobile/android/app/src/main/assets/json/path-configuration.json
181
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/AuthFlow.kt
182
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereApplication.kt
183
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereConfig.kt
184
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereEvents.kt
185
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereHost.kt
186
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/IconFont.kt
187
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/MainActivity.kt
188
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/MainTabs.kt
189
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/WebBottomSheetFragment.kt
190
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/WebFragment.kt
191
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/BiometricsComponent.kt
192
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/HapticsComponent.kt
193
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/MenuComponent.kt
194
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/NotificationComponent.kt
195
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/PermissionsComponent.kt
196
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/StorageComponent.kt
197
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/WebControlChannel.kt
198
+ - support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/extensions/EverywhereExtensions.kt
199
+ - support/mobile/android/app/src/main/res/color/bottom_navigation_active_indicator.xml
200
+ - support/mobile/android/app/src/main/res/color/bottom_navigation_item.xml
201
+ - support/mobile/android/app/src/main/res/drawable/ic_launcher_foreground.xml
202
+ - support/mobile/android/app/src/main/res/drawable/ic_tab_placeholder.xml
203
+ - support/mobile/android/app/src/main/res/layout/activity_main.xml
204
+ - support/mobile/android/app/src/main/res/layout/bridge_menu_sheet.xml
205
+ - support/mobile/android/app/src/main/res/layout/bridge_menu_sheet_item.xml
206
+ - support/mobile/android/app/src/main/res/layout/tab_more_sheet.xml
207
+ - support/mobile/android/app/src/main/res/layout/tab_more_sheet_item.xml
208
+ - support/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
209
+ - support/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
210
+ - support/mobile/android/app/src/main/res/values-night/colors.xml
211
+ - support/mobile/android/app/src/main/res/values-night/themes.xml
212
+ - support/mobile/android/app/src/main/res/values/colors.xml
213
+ - support/mobile/android/app/src/main/res/values/ic_launcher_background.xml
214
+ - support/mobile/android/app/src/main/res/values/strings.xml
215
+ - support/mobile/android/app/src/main/res/values/styles.xml
216
+ - support/mobile/android/app/src/main/res/values/themes.xml
217
+ - support/mobile/android/app/src/main/res/xml/network_security_config.xml
218
+ - support/mobile/android/app/src/stamped/AndroidManifest.xml
219
+ - support/mobile/android/build.gradle.kts
220
+ - support/mobile/android/gradle.properties
221
+ - support/mobile/android/gradle/wrapper/gradle-wrapper.jar
222
+ - support/mobile/android/gradle/wrapper/gradle-wrapper.properties
223
+ - support/mobile/android/gradlew
224
+ - support/mobile/android/gradlew.bat
225
+ - support/mobile/android/settings.gradle.kts
136
226
  - support/mobile/ios/App.xcodeproj/project.pbxproj
137
227
  - support/mobile/ios/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata
138
228
  - support/mobile/ios/App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -144,6 +234,7 @@ files:
144
234
  - support/mobile/ios/App/Assets.xcassets/AppIcon.appiconset/Contents.json
145
235
  - support/mobile/ios/App/Assets.xcassets/Contents.json
146
236
  - support/mobile/ios/App/Assets.xcassets/LaunchBackground.colorset/Contents.json
237
+ - support/mobile/ios/App/AuthFlow.swift
147
238
  - support/mobile/ios/App/Base.lproj/LaunchScreen.storyboard
148
239
  - support/mobile/ios/App/Bridge/BiometricsComponent.swift
149
240
  - support/mobile/ios/App/Bridge/HapticsComponent.swift
@@ -162,19 +253,8 @@ files:
162
253
  - support/mobile/ios/NativeExtensions/Package.swift
163
254
  - support/mobile/ios/NativeExtensions/Sources/NativeExtensions/Exports.swift
164
255
  - support/mobile/ios/README.md
165
- - support/shell/splash/index.html
166
- - support/shell/src-tauri/Cargo.lock
167
- - support/shell/src-tauri/Cargo.toml
168
- - support/shell/src-tauri/build.rs
169
- - support/shell/src-tauri/capabilities/default.json
170
- - support/shell/src-tauri/gen/schemas/acl-manifests.json
171
- - support/shell/src-tauri/gen/schemas/capabilities.json
172
- - support/shell/src-tauri/gen/schemas/desktop-schema.json
173
- - support/shell/src-tauri/gen/schemas/macOS-schema.json
174
- - support/shell/src-tauri/icons/icon.png
175
- - support/shell/src-tauri/src/main.rs
176
- - support/shell/src-tauri/src/updater.rs
177
- - support/shell/src-tauri/tauri.conf.json
256
+ - support/release/macos/entitlements.plist
257
+ - support/release/macos/notarize.sh
178
258
  homepage: https://rubyeverywhere.com
179
259
  licenses:
180
260
  - MIT
@@ -1,85 +0,0 @@
1
- # RubyEverywhere Platform — reusable build workflow.
2
- #
3
- # Lives in the RunnerDispatch build repo (private, RubyEverywhere-owned). The
4
- # Platform triggers it via workflow_dispatch (see app/models/runner_dispatch.rb);
5
- # it runs one artifact on an ephemeral, single-use macOS runner and reports back
6
- # through the Runner API. No customer source lives in this repo — it arrives as
7
- # the snapshot the runner downloads.
8
- #
9
- # The heavy part is provisioning the toolchain (rbe-tebako fork + deps + Xcode
10
- # shims). Cache it aggressively; a warm runner builds in minutes.
11
-
12
- name: RubyEverywhere Platform Build
13
-
14
- on:
15
- workflow_dispatch:
16
- inputs:
17
- artifact_id:
18
- description: Artifact public id (art_…)
19
- required: true
20
- runner_token:
21
- description: Per-artifact runner token
22
- required: true
23
- callback_base_url:
24
- description: Platform base URL the runner reports back to
25
- required: true
26
-
27
- # One in-flight job per artifact.
28
- concurrency:
29
- group: build-${{ inputs.artifact_id }}
30
- cancel-in-progress: false
31
-
32
- jobs:
33
- build:
34
- # macOS/iOS → macos; Android → ubuntu; Windows → windows (routed by the
35
- # dispatcher today only macOS is live).
36
- runs-on: macos-14 # Apple Silicon
37
- timeout-minutes: 45
38
-
39
- steps:
40
- - name: Set up Ruby (to run the every CLI itself)
41
- uses: ruby/setup-ruby@v1
42
- with:
43
- ruby-version: "3.4"
44
-
45
- - name: Provision the RubyEverywhere toolchain
46
- run: |
47
- set -euo pipefail
48
- # The signing engine needs the rbe-tebako fork + build deps. This is the
49
- # slow step — restore it from cache in a real setup (actions/cache on
50
- # ~/.tebako, ~/.tebako-shims, brew).
51
- brew install bison
52
- gem install ruby_everywhere # provides `every`
53
- # gem install rbe-tebako # the fork (or build from source)
54
- # bin/setup-xcode-shims # Xcode 26 CXX shim, rbconfig patch
55
- every doctor || true # surfaces any missing toolchain bits
56
-
57
- - name: Install Apple intermediate certificates
58
- run: |
59
- set -euo pipefail
60
- # The delivered .p12 holds only the leaf; codesign needs the Developer
61
- # ID intermediate to build a complete chain (a clean runner has none).
62
- for cert in DeveloperIDG2CA AppleWWDRCAG3; do
63
- curl -fsSL "https://www.apple.com/certificateauthority/$cert.cer" -o "$RUNNER_TEMP/$cert.cer"
64
- sudo security import "$RUNNER_TEMP/$cert.cer" -k /Library/Keychains/System.keychain || true
65
- done
66
-
67
- - name: Provision the generic Tauri shell
68
- run: |
69
- set -euo pipefail
70
- # The shell (src-tauri) is generic — same for every app. Pull the
71
- # pinned prebuilt shell for this platform.
72
- echo "SHELL_DIR=$RUNNER_TEMP/shell/src-tauri" >> "$GITHUB_ENV"
73
- # gh release download --repo rubyeverywhere/shell --pattern 'src-tauri-*' ...
74
- # OR: git clone --depth 1 https://github.com/rubyeverywhere/shell "$RUNNER_TEMP/shell"
75
-
76
- - name: Run the build
77
- run: |
78
- every platform runner \
79
- --artifact "${{ inputs.artifact_id }}" \
80
- --token "${{ inputs.runner_token }}" \
81
- --url "${{ inputs.callback_base_url }}" \
82
- --shell-dir "$SHELL_DIR"
83
- # Signing credentials are pulled JIT from the Platform into a throwaway
84
- # keychain by the runner itself — they are never GitHub secrets, and the
85
- # ephemeral runner is destroyed after this job.
@@ -1 +0,0 @@
1
- {"default":{"identifier":"default","description":"Main window IPC: local app origins (the packaged Rails app serves on 127.0.0.1)","remote":{"urls":["http://127.0.0.1:*","http://localhost:*"]},"local":true,"windows":["main"],"permissions":["core:default","core:window:allow-set-title","notification:default","dialog:default","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text"]}}
File without changes
File without changes