Initial public release of Warp.

Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
David Stern
2026-04-28 08:43:33 -05:00
commit 0dbd3d567a
4982 changed files with 1431549 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
---
BasedOnStyle: Google
IndentWidth: 4
+3
View File
@@ -0,0 +1,3 @@
#import <AppKit/AppKit.h>
NSString *get_default_app_bundle_for_file(id);
+15
View File
@@ -0,0 +1,15 @@
#import <AppKit/AppKit.h>
NSString *get_default_app_bundle_for_file(NSString *file_path) {
NSURL *fileUrl = [NSURL fileURLWithPath:file_path];
NSURL *appUrl = [[NSWorkspace sharedWorkspace] URLForApplicationToOpenURL:fileUrl];
if (!appUrl) {
return nil;
}
NSBundle *appBundle = [NSBundle bundleWithURL:appUrl];
if (!appBundle) {
return nil;
}
return [appBundle bundleIdentifier];
}
@@ -0,0 +1,15 @@
#import <Sentry/Sentry.h>
void start(id, id, id, bool);
void setUser(id);
void recordBreadcrumb(id, id, id, double);
@interface SentryLevelMapper : NSObject
/**
* Maps a string to a SentryLevel. If the passed string doesn't match any level this defaults to
* the 'error' level. See https://develop.sentry.dev/sdk/event-payloads/#optional-attributes
*/
+ (SentryLevel)levelWithString:(NSString *)string;
@end
@@ -0,0 +1,95 @@
#import "crash_reporting.h"
#import <MetricKit/MetricKit.h>
#import <Sentry/Sentry-Swift.h>
#import <Sentry/Sentry.h>
void startSentry(id sentryUrl, id environment, id version, bool isDogfood) {
[SentrySDK startWithConfigureOptions:^(SentryOptions *options) {
options.dsn = sentryUrl;
options.debug = NO;
options.environment = environment;
options.releaseName = version;
options.enableAppHangTracking = isDogfood;
}];
}
void stopSentry() { [SentrySDK close]; }
void crashSentry() { [SentrySDK crash]; }
void setUser(id userId) {
SentryUser *user = [[SentryUser alloc] init];
user.userId = userId;
[SentrySDK setUser:user];
// `SentrySDK setUser:` retains its own copy (per the ObjC `copy` property
// contract on `SentryUser.userId` / `SentryScope.user`), so balance the
// `alloc]/init]` here. Mirrors `recordBreadcrumb` below, which releases its
// allocated `SentryBreadcrumb` after `[SentrySDK addBreadcrumb:]`.
[user release];
}
// Define constants for the integer representations of the SentryLevel Swift
// enum.
//
// We intentionally use a different prefix (kLevel instead of kSentryLevel) to
// ensure there are no symbol name conflicts with Sentry's own code.
//
// SentryLevel is defined here:
// https://github.com/getsentry/sentry-cocoa/blob/b8ac05036d8cf7b5aa6bda6a108d7827f286ca04/Sources/Swift/Helper/Log/SentryLevel.swift#L4-L26
NSUInteger kLevelNone = 0;
NSUInteger kLevelDebug = 1;
NSUInteger kLevelInfo = 2;
NSUInteger kLevelWarning = 3;
NSUInteger kLevelError = 4;
NSUInteger kLevelFatal = 5;
// Maps the string representation of a breadcrumb level to the corresponding
// SentryLevel enum value.
//
// See Sentry-internal mapping function here:
// https://github.com/getsentry/sentry-cocoa/blob/854478ce6e1b9349d9a30c2adb59a49e80867991/Sources/Sentry/SentryLevelMapper.m
SentryLevel levelFromString(NSString *string) {
if ([string isEqualToString:@"none"]) {
return kLevelNone;
}
if ([string isEqualToString:@"debug"]) {
return kLevelDebug;
}
if ([string isEqualToString:@"info"]) {
return kLevelInfo;
}
if ([string isEqualToString:@"warning"]) {
return kLevelWarning;
}
if ([string isEqualToString:@"error"]) {
return kLevelError;
}
if ([string isEqualToString:@"fatal"]) {
return kLevelFatal;
}
// Default is error, see https://develop.sentry.dev/sdk/event-payloads/#optional-attributes
return kLevelError;
}
void recordBreadcrumb(id message, id category, id level, double seconds_since_epoch) {
// The Rust logger may be initialized before the Sentry Cocoa SDK is enabled.
if (![SentrySDK isEnabled]) {
return;
}
SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init];
crumb.level = levelFromString(level);
crumb.category = category;
crumb.message = message;
crumb.timestamp = [NSDate dateWithTimeIntervalSince1970:seconds_since_epoch];
[SentrySDK addBreadcrumb:crumb];
[crumb release];
}
void setTag(id key, id value) {
// Set a tag on the current scope using the sentry-cocoa SDK.
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
[scope setTagValue:value forKey:key];
}];
}
+7
View File
@@ -0,0 +1,7 @@
// Our class for handling NSServices messages.
@interface WarpServicesProvider : NSObject
@end
// Functions implemented in Rust.
id warp_services_provider_custom_url_scheme();
void warp_app_open_urls(id app, id urls);
+65
View File
@@ -0,0 +1,65 @@
#import <AppKit/AppKit.h>
#import "services.h"
@implementation WarpServicesProvider
// Opens a new tab for each file URL in the pasteboard, with the initial
// directory set to the provided path (or parent directory, if the path
// is to a file).
//
// This is registered as a service endpoint in the embedded Info.plist.
- (void)openTab:(NSPasteboard *)pboard userData:(NSString *)userData error:(NSString **)error {
[self forFilesFromPasteboard:pboard performAction:@"/new_tab"];
}
// Opens a new window for each file URL in the pasteboard, with the initial
// directory set to the provided path (or parent directory, if the path
// is to a file).
//
// This is registered as a service endpoint in the embedded Info.plist.
- (void)openWindow:(NSPasteboard *)pboard userData:(NSString *)userData error:(NSString **)error {
[self forFilesFromPasteboard:pboard performAction:@"/new_window"];
}
// Parses file URLs from the provided pasteboard and makes an intent into
// the application to perform the provided action for each path.
- (void)forFilesFromPasteboard:(NSPasteboard *)pboard performAction:(NSString *)action {
@autoreleasepool {
NSArray<NSURL *> *urls = [pboard readObjectsForClasses:@[ [NSURL class] ] options:0];
NSMutableArray<NSString *> *filePaths = [NSMutableArray array];
for (NSURL *url in urls) {
[filePaths addObject:url.path];
}
NSMutableArray<NSURL *> *warpUrls = [NSMutableArray array];
for (NSString *path in filePaths) {
NSURLComponents *components = [[[NSURLComponents alloc] init] autorelease];
NSString *scheme = warp_services_provider_custom_url_scheme();
[components setScheme:scheme];
[components setHost:@"action"];
[components setPath:action];
NSMutableArray *queryItems = [NSMutableArray array];
[queryItems addObject:[NSURLQueryItem queryItemWithName:@"path" value:path]];
[components setQueryItems:queryItems];
[warpUrls addObject:components.URL];
};
NSApplication *app = [NSApplication sharedApplication];
warp_app_open_urls(app, warpUrls);
}
}
@end
// Creates a new WarpServicesProvider and registers it as the global services
// provider for the application
void warp_register_services_provider() {
WarpServicesProvider *provider = [[WarpServicesProvider alloc] init];
// Set the global NSServices provider for the application. This holds a
// strong reference to the provider, so we don't have to worry about it
// being prematurely cleaned up while the application exist.
[NSApp setServicesProvider:provider];
[provider release];
}
+7
View File
@@ -0,0 +1,7 @@
#[cfg(target_family = "wasm")]
pub mod wasm;
pub fn init() {
#[cfg(target_family = "wasm")]
wasm::init();
}
+50
View File
@@ -0,0 +1,50 @@
use js_sys::ReferenceError;
use thiserror::Error;
use wasm_bindgen::{JsCast, JsValue};
pub use warp_web_event_bus::{emit_event, WarpEvent};
/// This function should be called early in application initialization to ensure that
/// static variables are initialized.
pub(super) fn init() {
unsafe {
extern "C" {
/// __wasm_call_ctors is a function defined by the `wasm-ld` linker, and is used to
/// initialize static variables.
///
/// It should be called once at runtime before other code is executed.
fn __wasm_call_ctors();
}
__wasm_call_ctors();
}
}
mod ffi {
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_name = "warpUserHandoff", catch)]
pub fn user_handoff() -> Result<Option<String>, JsValue>;
}
}
#[derive(Debug, Clone, Error)]
pub enum AuthHandoffError {
#[error("The host page doesn't support user handoff")]
Unsupported,
#[error("Unexpected handoff error: {0:?}")]
Unexpected(JsValue),
}
/// Fetch the user's Firebase refresh token from the host React app.
pub fn user_handoff() -> Result<Option<String>, AuthHandoffError> {
ffi::user_handoff().map_err(|err| {
if ReferenceError::instanceof(&err) {
AuthHandoffError::Unsupported
} else {
AuthHandoffError::Unexpected(err)
}
})
}