chore: rename to Titan 14401768
Steve · 2025-12-21 00:06 15 file(s) · +99 −99
Gemini.xcodeproj/project.pbxproj → Titan.xcodeproj/project.pbxproj +55 −55
12 12
			containerPortal = 0C5424842EF79292001BB2ED /* Project object */;
13 13
			proxyType = 1;
14 14
			remoteGlobalIDString = 0C54248B2EF79292001BB2ED;
15 -
			remoteInfo = Gemini;
15 +
			remoteInfo = Titan;
16 16
		};
17 17
		0C5424A42EF79293001BB2ED /* PBXContainerItemProxy */ = {
18 18
			isa = PBXContainerItemProxy;
19 19
			containerPortal = 0C5424842EF79292001BB2ED /* Project object */;
20 20
			proxyType = 1;
21 21
			remoteGlobalIDString = 0C54248B2EF79292001BB2ED;
22 -
			remoteInfo = Gemini;
22 +
			remoteInfo = Titan;
23 23
		};
24 24
/* End PBXContainerItemProxy section */
25 25
26 26
/* Begin PBXFileReference section */
27 -
		0C54248C2EF79292001BB2ED /* Gemini.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Gemini.app; sourceTree = BUILT_PRODUCTS_DIR; };
28 -
		0C5424992EF79293001BB2ED /* GeminiTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GeminiTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
29 -
		0C5424A32EF79293001BB2ED /* GeminiUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GeminiUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
27 +
		0C54248C2EF79292001BB2ED /* Titan.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Titan.app; sourceTree = BUILT_PRODUCTS_DIR; };
28 +
		0C5424992EF79293001BB2ED /* TitanTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TitanTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
29 +
		0C5424A32EF79293001BB2ED /* TitanUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TitanUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
30 30
/* End PBXFileReference section */
31 31
32 32
/* Begin PBXFileSystemSynchronizedRootGroup section */
33 -
		0C54248E2EF79292001BB2ED /* Gemini */ = {
33 +
		0C54248E2EF79292001BB2ED /* Titan */ = {
34 34
			isa = PBXFileSystemSynchronizedRootGroup;
35 -
			path = Gemini;
35 +
			path = Titan;
36 36
			sourceTree = "<group>";
37 37
		};
38 -
		0C54249C2EF79293001BB2ED /* GeminiTests */ = {
38 +
		0C54249C2EF79293001BB2ED /* TitanTests */ = {
39 39
			isa = PBXFileSystemSynchronizedRootGroup;
40 -
			path = GeminiTests;
40 +
			path = TitanTests;
41 41
			sourceTree = "<group>";
42 42
		};
43 -
		0C5424A62EF79293001BB2ED /* GeminiUITests */ = {
43 +
		0C5424A62EF79293001BB2ED /* TitanUITests */ = {
44 44
			isa = PBXFileSystemSynchronizedRootGroup;
45 -
			path = GeminiUITests;
45 +
			path = TitanUITests;
46 46
			sourceTree = "<group>";
47 47
		};
48 48
/* End PBXFileSystemSynchronizedRootGroup section */
75 75
		0C5424832EF79292001BB2ED = {
76 76
			isa = PBXGroup;
77 77
			children = (
78 -
				0C54248E2EF79292001BB2ED /* Gemini */,
79 -
				0C54249C2EF79293001BB2ED /* GeminiTests */,
80 -
				0C5424A62EF79293001BB2ED /* GeminiUITests */,
78 +
				0C54248E2EF79292001BB2ED /* Titan */,
79 +
				0C54249C2EF79293001BB2ED /* TitanTests */,
80 +
				0C5424A62EF79293001BB2ED /* TitanUITests */,
81 81
				0C54248D2EF79292001BB2ED /* Products */,
82 82
			);
83 83
			sourceTree = "<group>";
85 85
		0C54248D2EF79292001BB2ED /* Products */ = {
86 86
			isa = PBXGroup;
87 87
			children = (
88 -
				0C54248C2EF79292001BB2ED /* Gemini.app */,
89 -
				0C5424992EF79293001BB2ED /* GeminiTests.xctest */,
90 -
				0C5424A32EF79293001BB2ED /* GeminiUITests.xctest */,
88 +
				0C54248C2EF79292001BB2ED /* Titan.app */,
89 +
				0C5424992EF79293001BB2ED /* TitanTests.xctest */,
90 +
				0C5424A32EF79293001BB2ED /* TitanUITests.xctest */,
91 91
			);
92 92
			name = Products;
93 93
			sourceTree = "<group>";
95 95
/* End PBXGroup section */
96 96
97 97
/* Begin PBXNativeTarget section */
98 -
		0C54248B2EF79292001BB2ED /* Gemini */ = {
98 +
		0C54248B2EF79292001BB2ED /* Titan */ = {
99 99
			isa = PBXNativeTarget;
100 -
			buildConfigurationList = 0C5424AD2EF79293001BB2ED /* Build configuration list for PBXNativeTarget "Gemini" */;
100 +
			buildConfigurationList = 0C5424AD2EF79293001BB2ED /* Build configuration list for PBXNativeTarget "Titan" */;
101 101
			buildPhases = (
102 102
				0C5424882EF79292001BB2ED /* Sources */,
103 103
				0C5424892EF79292001BB2ED /* Frameworks */,
108 108
			dependencies = (
109 109
			);
110 110
			fileSystemSynchronizedGroups = (
111 -
				0C54248E2EF79292001BB2ED /* Gemini */,
111 +
				0C54248E2EF79292001BB2ED /* Titan */,
112 112
			);
113 -
			name = Gemini;
113 +
			name = Titan;
114 114
			packageProductDependencies = (
115 115
			);
116 -
			productName = Gemini;
117 -
			productReference = 0C54248C2EF79292001BB2ED /* Gemini.app */;
116 +
			productName = Titan;
117 +
			productReference = 0C54248C2EF79292001BB2ED /* Titan.app */;
118 118
			productType = "com.apple.product-type.application";
119 119
		};
120 -
		0C5424982EF79293001BB2ED /* GeminiTests */ = {
120 +
		0C5424982EF79293001BB2ED /* TitanTests */ = {
121 121
			isa = PBXNativeTarget;
122 -
			buildConfigurationList = 0C5424B02EF79293001BB2ED /* Build configuration list for PBXNativeTarget "GeminiTests" */;
122 +
			buildConfigurationList = 0C5424B02EF79293001BB2ED /* Build configuration list for PBXNativeTarget "TitanTests" */;
123 123
			buildPhases = (
124 124
				0C5424952EF79293001BB2ED /* Sources */,
125 125
				0C5424962EF79293001BB2ED /* Frameworks */,
131 131
				0C54249B2EF79293001BB2ED /* PBXTargetDependency */,
132 132
			);
133 133
			fileSystemSynchronizedGroups = (
134 -
				0C54249C2EF79293001BB2ED /* GeminiTests */,
134 +
				0C54249C2EF79293001BB2ED /* TitanTests */,
135 135
			);
136 -
			name = GeminiTests;
136 +
			name = TitanTests;
137 137
			packageProductDependencies = (
138 138
			);
139 -
			productName = GeminiTests;
140 -
			productReference = 0C5424992EF79293001BB2ED /* GeminiTests.xctest */;
139 +
			productName = TitanTests;
140 +
			productReference = 0C5424992EF79293001BB2ED /* TitanTests.xctest */;
141 141
			productType = "com.apple.product-type.bundle.unit-test";
142 142
		};
143 -
		0C5424A22EF79293001BB2ED /* GeminiUITests */ = {
143 +
		0C5424A22EF79293001BB2ED /* TitanUITests */ = {
144 144
			isa = PBXNativeTarget;
145 -
			buildConfigurationList = 0C5424B32EF79293001BB2ED /* Build configuration list for PBXNativeTarget "GeminiUITests" */;
145 +
			buildConfigurationList = 0C5424B32EF79293001BB2ED /* Build configuration list for PBXNativeTarget "TitanUITests" */;
146 146
			buildPhases = (
147 147
				0C54249F2EF79293001BB2ED /* Sources */,
148 148
				0C5424A02EF79293001BB2ED /* Frameworks */,
154 154
				0C5424A52EF79293001BB2ED /* PBXTargetDependency */,
155 155
			);
156 156
			fileSystemSynchronizedGroups = (
157 -
				0C5424A62EF79293001BB2ED /* GeminiUITests */,
157 +
				0C5424A62EF79293001BB2ED /* TitanUITests */,
158 158
			);
159 -
			name = GeminiUITests;
159 +
			name = TitanUITests;
160 160
			packageProductDependencies = (
161 161
			);
162 -
			productName = GeminiUITests;
163 -
			productReference = 0C5424A32EF79293001BB2ED /* GeminiUITests.xctest */;
162 +
			productName = TitanUITests;
163 +
			productReference = 0C5424A32EF79293001BB2ED /* TitanUITests.xctest */;
164 164
			productType = "com.apple.product-type.bundle.ui-testing";
165 165
		};
166 166
/* End PBXNativeTarget section */
186 186
					};
187 187
				};
188 188
			};
189 -
			buildConfigurationList = 0C5424872EF79292001BB2ED /* Build configuration list for PBXProject "Gemini" */;
189 +
			buildConfigurationList = 0C5424872EF79292001BB2ED /* Build configuration list for PBXProject "Titan" */;
190 190
			developmentRegion = en;
191 191
			hasScannedForEncodings = 0;
192 192
			knownRegions = (
200 200
			projectDirPath = "";
201 201
			projectRoot = "";
202 202
			targets = (
203 -
				0C54248B2EF79292001BB2ED /* Gemini */,
204 -
				0C5424982EF79293001BB2ED /* GeminiTests */,
205 -
				0C5424A22EF79293001BB2ED /* GeminiUITests */,
203 +
				0C54248B2EF79292001BB2ED /* Titan */,
204 +
				0C5424982EF79293001BB2ED /* TitanTests */,
205 +
				0C5424A22EF79293001BB2ED /* TitanUITests */,
206 206
			);
207 207
		};
208 208
/* End PBXProject section */
258 258
/* Begin PBXTargetDependency section */
259 259
		0C54249B2EF79293001BB2ED /* PBXTargetDependency */ = {
260 260
			isa = PBXTargetDependency;
261 -
			target = 0C54248B2EF79292001BB2ED /* Gemini */;
261 +
			target = 0C54248B2EF79292001BB2ED /* Titan */;
262 262
			targetProxy = 0C54249A2EF79293001BB2ED /* PBXContainerItemProxy */;
263 263
		};
264 264
		0C5424A52EF79293001BB2ED /* PBXTargetDependency */ = {
265 265
			isa = PBXTargetDependency;
266 -
			target = 0C54248B2EF79292001BB2ED /* Gemini */;
266 +
			target = 0C54248B2EF79292001BB2ED /* Titan */;
267 267
			targetProxy = 0C5424A42EF79293001BB2ED /* PBXContainerItemProxy */;
268 268
		};
269 269
/* End PBXTargetDependency section */
410 410
					"@executable_path/Frameworks",
411 411
				);
412 412
				MARKETING_VERSION = 1.0;
413 -
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.Gemini;
413 +
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.Titan;
414 414
				PRODUCT_NAME = "$(TARGET_NAME)";
415 415
				STRING_CATALOG_GENERATE_SYMBOLS = YES;
416 416
				SWIFT_APPROACHABLE_CONCURRENCY = YES;
442 442
					"@executable_path/Frameworks",
443 443
				);
444 444
				MARKETING_VERSION = 1.0;
445 -
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.Gemini;
445 +
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.Titan;
446 446
				PRODUCT_NAME = "$(TARGET_NAME)";
447 447
				STRING_CATALOG_GENERATE_SYMBOLS = YES;
448 448
				SWIFT_APPROACHABLE_CONCURRENCY = YES;
464 464
				GENERATE_INFOPLIST_FILE = YES;
465 465
				IPHONEOS_DEPLOYMENT_TARGET = 26.1;
466 466
				MARKETING_VERSION = 1.0;
467 -
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.GeminiTests;
467 +
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.TitanTests;
468 468
				PRODUCT_NAME = "$(TARGET_NAME)";
469 469
				STRING_CATALOG_GENERATE_SYMBOLS = NO;
470 470
				SWIFT_APPROACHABLE_CONCURRENCY = YES;
472 472
				SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
473 473
				SWIFT_VERSION = 5.0;
474 474
				TARGETED_DEVICE_FAMILY = "1,2";
475 -
				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Gemini.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Gemini";
475 +
				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Titan.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Titan";
476 476
			};
477 477
			name = Debug;
478 478
		};
486 486
				GENERATE_INFOPLIST_FILE = YES;
487 487
				IPHONEOS_DEPLOYMENT_TARGET = 26.1;
488 488
				MARKETING_VERSION = 1.0;
489 -
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.GeminiTests;
489 +
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.TitanTests;
490 490
				PRODUCT_NAME = "$(TARGET_NAME)";
491 491
				STRING_CATALOG_GENERATE_SYMBOLS = NO;
492 492
				SWIFT_APPROACHABLE_CONCURRENCY = YES;
494 494
				SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
495 495
				SWIFT_VERSION = 5.0;
496 496
				TARGETED_DEVICE_FAMILY = "1,2";
497 -
				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Gemini.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Gemini";
497 +
				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Titan.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Titan";
498 498
			};
499 499
			name = Release;
500 500
		};
506 506
				DEVELOPMENT_TEAM = W8QNM2N67P;
507 507
				GENERATE_INFOPLIST_FILE = YES;
508 508
				MARKETING_VERSION = 1.0;
509 -
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.GeminiUITests;
509 +
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.TitanUITests;
510 510
				PRODUCT_NAME = "$(TARGET_NAME)";
511 511
				STRING_CATALOG_GENERATE_SYMBOLS = NO;
512 512
				SWIFT_APPROACHABLE_CONCURRENCY = YES;
514 514
				SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
515 515
				SWIFT_VERSION = 5.0;
516 516
				TARGETED_DEVICE_FAMILY = "1,2";
517 -
				TEST_TARGET_NAME = Gemini;
517 +
				TEST_TARGET_NAME = Titan;
518 518
			};
519 519
			name = Debug;
520 520
		};
526 526
				DEVELOPMENT_TEAM = W8QNM2N67P;
527 527
				GENERATE_INFOPLIST_FILE = YES;
528 528
				MARKETING_VERSION = 1.0;
529 -
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.GeminiUITests;
529 +
				PRODUCT_BUNDLE_IDENTIFIER = com.stevedylandev.TitanUITests;
530 530
				PRODUCT_NAME = "$(TARGET_NAME)";
531 531
				STRING_CATALOG_GENERATE_SYMBOLS = NO;
532 532
				SWIFT_APPROACHABLE_CONCURRENCY = YES;
534 534
				SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
535 535
				SWIFT_VERSION = 5.0;
536 536
				TARGETED_DEVICE_FAMILY = "1,2";
537 -
				TEST_TARGET_NAME = Gemini;
537 +
				TEST_TARGET_NAME = Titan;
538 538
			};
539 539
			name = Release;
540 540
		};
541 541
/* End XCBuildConfiguration section */
542 542
543 543
/* Begin XCConfigurationList section */
544 -
		0C5424872EF79292001BB2ED /* Build configuration list for PBXProject "Gemini" */ = {
544 +
		0C5424872EF79292001BB2ED /* Build configuration list for PBXProject "Titan" */ = {
545 545
			isa = XCConfigurationList;
546 546
			buildConfigurations = (
547 547
				0C5424AB2EF79293001BB2ED /* Debug */,
550 550
			defaultConfigurationIsVisible = 0;
551 551
			defaultConfigurationName = Release;
552 552
		};
553 -
		0C5424AD2EF79293001BB2ED /* Build configuration list for PBXNativeTarget "Gemini" */ = {
553 +
		0C5424AD2EF79293001BB2ED /* Build configuration list for PBXNativeTarget "Titan" */ = {
554 554
			isa = XCConfigurationList;
555 555
			buildConfigurations = (
556 556
				0C5424AE2EF79293001BB2ED /* Debug */,
559 559
			defaultConfigurationIsVisible = 0;
560 560
			defaultConfigurationName = Release;
561 561
		};
562 -
		0C5424B02EF79293001BB2ED /* Build configuration list for PBXNativeTarget "GeminiTests" */ = {
562 +
		0C5424B02EF79293001BB2ED /* Build configuration list for PBXNativeTarget "TitanTests" */ = {
563 563
			isa = XCConfigurationList;
564 564
			buildConfigurations = (
565 565
				0C5424B12EF79293001BB2ED /* Debug */,
568 568
			defaultConfigurationIsVisible = 0;
569 569
			defaultConfigurationName = Release;
570 570
		};
571 -
		0C5424B32EF79293001BB2ED /* Build configuration list for PBXNativeTarget "GeminiUITests" */ = {
571 +
		0C5424B32EF79293001BB2ED /* Build configuration list for PBXNativeTarget "TitanUITests" */ = {
572 572
			isa = XCConfigurationList;
573 573
			buildConfigurations = (
574 574
				0C5424B42EF79293001BB2ED /* Debug */,
Gemini.xcodeproj/project.xcworkspace/contents.xcworkspacedata → Titan.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 −0
Gemini.xcodeproj/xcuserdata/stevedylandev.xcuserdatad/xcschemes/xcschememanagement.plist → Titan.xcodeproj/xcuserdata/stevedylandev.xcuserdatad/xcschemes/xcschememanagement.plist +1 −1
4 4
<dict>
5 5
	<key>SchemeUserState</key>
6 6
	<dict>
7 -
		<key>Gemini.xcscheme_^#shared#^_</key>
7 +
		<key>Titan.xcscheme_^#shared#^_</key>
8 8
		<dict>
9 9
			<key>orderHint</key>
10 10
			<integer>0</integer>
Gemini/Assets.xcassets/AccentColor.colorset/Contents.json → Titan/Assets.xcassets/AccentColor.colorset/Contents.json +0 −0
Gemini/Assets.xcassets/AppIcon.appiconset/Contents.json → Titan/Assets.xcassets/AppIcon.appiconset/Contents.json +0 −0
Gemini/Assets.xcassets/Contents.json → Titan/Assets.xcassets/Contents.json +0 −0
Gemini/GeminiApp.swift → Titan/TitanApp.swift +3 −3
1 1
//
2 -
//  GeminiApp.swift
3 -
//  Gemini
2 +
//  TitanApp.swift
3 +
//  Titan
4 4
//
5 5
//  Created by Steve Simkins on 12/20/25.
6 6
//
8 8
import SwiftUI
9 9
10 10
@main
11 -
struct GeminiApp: App {
11 +
struct TitanApp: App {
12 12
    var body: some Scene {
13 13
        WindowGroup {
14 14
            ContentView()
Gemini/Models/GeminiLine.swift → Titan/Models/TitanLine.swift +3 −3
1 1
//
2 -
//  GeminiLine.swift
3 -
//  Gemini
2 +
//  TitanLine.swift
3 +
//  Titan
4 4
//
5 5
6 6
import Foundation
7 7
8 -
enum GeminiLine {
8 +
enum TitanLine {
9 9
    case text(String)
10 10
    case link(url: String, label: String)
11 11
    case heading1(String)
Gemini/Services/GeminiClient.swift → Titan/Services/TitanClient.swift +12 −12
1 1
//
2 -
//  GeminiClient.swift
3 -
//  Gemini
2 +
//  TitanClient.swift
3 +
//  Titan
4 4
//
5 5
//  Created by Steve Simkins on 12/20/25.
6 6
//
10 10
11 11
// MARK: - Response Types
12 12
13 -
struct GeminiResponse {
13 +
struct TitanResponse {
14 14
    let statusCode: Int
15 15
    let meta: String
16 16
    let body: Data?
34 34
    }
35 35
}
36 36
37 -
enum GeminiError: LocalizedError {
37 +
enum TitanError: LocalizedError {
38 38
    case invalidResponse
39 39
    case invalidURL
40 40
48 48
49 49
// MARK: - Client
50 50
51 -
class GeminiClient {
51 +
class TitanClient {
52 52
    let rejectUnauthorized: Bool
53 53
    
54 54
    init(rejectUnauthorized: Bool = true) {
59 59
        hostname: String,
60 60
        port: Int = 1965,
61 61
        urlString: String
62 -
    ) async throws -> GeminiResponse {
62 +
    ) async throws -> TitanResponse {
63 63
        let host = NWEndpoint.Host(hostname)
64 64
        let port = NWEndpoint.Port(integerLiteral: UInt16(port))
65 65
        
84 84
        let connection = NWConnection(host: host, port: port, using: parameters)
85 85
        let state = ConnectionState()
86 86
        
87 -
        return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<GeminiResponse, Error>) in
87 +
        return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<TitanResponse, Error>) in
88 88
            connection.stateUpdateHandler = { connectionState in
89 89
                switch connectionState {
90 90
                case .ready:
144 144
        }
145 145
    }
146 146
147 -
    private func parseResponse(_ data: Data) throws -> GeminiResponse {
147 +
    private func parseResponse(_ data: Data) throws -> TitanResponse {
148 148
        // Find the first CRLF which separates header from body
149 149
        let crlf = Data([0x0D, 0x0A]) // \r\n
150 150
        guard let crlfRange = data.range(of: crlf) else {
151 -
            throw GeminiError.invalidResponse
151 +
            throw TitanError.invalidResponse
152 152
        }
153 153
154 154
        let headerData = data[..<crlfRange.lowerBound]
155 155
        guard let headerString = String(data: headerData, encoding: .utf8) else {
156 -
            throw GeminiError.invalidResponse
156 +
            throw TitanError.invalidResponse
157 157
        }
158 158
159 159
        // Parse status code (first 2 characters)
160 160
        guard headerString.count >= 2,
161 161
              let statusCode = Int(headerString.prefix(2)) else {
162 -
            throw GeminiError.invalidResponse
162 +
            throw TitanError.invalidResponse
163 163
        }
164 164
165 165
        // Meta is everything after status code and space
176 176
177 177
        print("📥 Status: \(statusCode), Meta: \(meta)")
178 178
179 -
        return GeminiResponse(statusCode: statusCode, meta: meta, body: body)
179 +
        return TitanResponse(statusCode: statusCode, meta: meta, body: body)
180 180
    }
181 181
    
182 182
    // Helper class to manage connection state
Gemini/Services/GeminiParser.swift → Titan/Services/TitanParser.swift +5 −5
1 1
//
2 -
//  GeminiParser.swift
3 -
//  Gemini
2 +
//  TitanParser.swift
3 +
//  Titan
4 4
//
5 5
6 6
import Foundation
7 7
8 -
struct GeminiParser {
9 -
    static func parse(_ content: String, baseURL: String) -> [GeminiLine] {
10 -
        var lines: [GeminiLine] = []
8 +
struct TitanParser {
9 +
    static func parse(_ content: String, baseURL: String) -> [TitanLine] {
10 +
        var lines: [TitanLine] = []
11 11
        var inPreformatted = false
12 12
13 13
        for line in content.components(separatedBy: .newlines) {
Gemini/Views/ContentView.swift → Titan/Views/ContentView.swift +5 −5
1 1
//
2 2
//  ContentView.swift
3 -
//  Gemini
3 +
//  Titan
4 4
//
5 5
6 6
import SwiftUI
26 26
    var body: some View {
27 27
        VStack(spacing: 12) {
28 28
            ScrollView {
29 -
                GeminiContentView(content: responseText, baseURL: urlText, onLinkTap: { url in
29 +
                TitanContentView(content: responseText, baseURL: urlText, onLinkTap: { url in
30 30
                    navigateTo(url)
31 31
                })
32 32
                .frame(maxWidth: .infinity, alignment: .leading)
170 170
        }
171 171
    }
172 172
173 -
    private func fetchWithRedirects(urlString: String, redirectCount: Int) async throws -> (GeminiResponse, String) {
173 +
    private func fetchWithRedirects(urlString: String, redirectCount: Int) async throws -> (TitanResponse, String) {
174 174
        guard let url = URL(string: urlString),
175 175
              let host = url.host else {
176 -
            throw GeminiError.invalidURL
176 +
            throw TitanError.invalidURL
177 177
        }
178 178
179 -
        let client = GeminiClient(rejectUnauthorized: false)
179 +
        let client = TitanClient(rejectUnauthorized: false)
180 180
        let port = url.port ?? 1965
181 181
        let response = try await client.connect(
182 182
            hostname: host,
Gemini/Views/GeminiContentView.swift → Titan/Views/TitanContentView.swift +5 −5
1 1
//
2 -
//  GeminiContentView.swift
3 -
//  Gemini
2 +
//  TitanContentView.swift
3 +
//  Titan
4 4
//
5 5
6 6
import SwiftUI
7 7
8 -
struct GeminiContentView: View {
8 +
struct TitanContentView: View {
9 9
    let content: String
10 10
    let baseURL: String
11 11
    let onLinkTap: (String) -> Void
17 17
    }
18 18
19 19
    var body: some View {
20 -
        let lines = GeminiParser.parse(content, baseURL: baseURL)
20 +
        let lines = TitanParser.parse(content, baseURL: baseURL)
21 21
22 22
        LazyVStack(alignment: .leading, spacing: 4) {
23 23
            ForEach(Array(lines.enumerated()), id: \.offset) { _, line in
28 28
    }
29 29
30 30
    @ViewBuilder
31 -
    private func lineView(for line: GeminiLine) -> some View {
31 +
    private func lineView(for line: TitanLine) -> some View {
32 32
        switch line {
33 33
        case .text(let text):
34 34
            Text(text)
GeminiTests/GeminiTests.swift → TitanTests/TitanTests.swift +4 −4
1 1
//
2 -
//  GeminiTests.swift
3 -
//  GeminiTests
2 +
//  TitanTests.swift
3 +
//  TitanTests
4 4
//
5 5
//  Created by Steve Simkins on 12/20/25.
6 6
//
7 7
8 8
import Testing
9 -
@testable import Gemini
9 +
@testable import Titan
10 10
11 -
struct GeminiTests {
11 +
struct TitanTests {
12 12
13 13
    @Test func example() async throws {
14 14
        // Write your test here and use APIs like `#expect(...)` to check expected conditions.
GeminiUITests/GeminiUITests.swift → TitanUITests/TitanUITests.swift +3 −3
1 1
//
2 -
//  GeminiUITests.swift
3 -
//  GeminiUITests
2 +
//  TitanUITests.swift
3 +
//  TitanUITests
4 4
//
5 5
//  Created by Steve Simkins on 12/20/25.
6 6
//
7 7
8 8
import XCTest
9 9
10 -
final class GeminiUITests: XCTestCase {
10 +
final class TitanUITests: XCTestCase {
11 11
12 12
    override func setUpWithError() throws {
13 13
        // Put setup code here. This method is called before the invocation of each test method in the class.
GeminiUITests/GeminiUITestsLaunchTests.swift → TitanUITests/TitanUITestsLaunchTests.swift +3 −3
1 1
//
2 -
//  GeminiUITestsLaunchTests.swift
3 -
//  GeminiUITests
2 +
//  TitanUITestsLaunchTests.swift
3 +
//  TitanUITests
4 4
//
5 5
//  Created by Steve Simkins on 12/20/25.
6 6
//
7 7
8 8
import XCTest
9 9
10 -
final class GeminiUITestsLaunchTests: XCTestCase {
10 +
final class TitanUITestsLaunchTests: XCTestCase {
11 11
12 12
    override class var runsForEachTargetApplicationUIConfiguration: Bool {
13 13
        true