diff --git a/ClaudeCodeUsage.xcodeproj/project.pbxproj b/ClaudeCodeUsage.xcodeproj/project.pbxproj new file mode 100644 index 0000000..66c2a4b --- /dev/null +++ b/ClaudeCodeUsage.xcodeproj/project.pbxproj @@ -0,0 +1,659 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + ECF410572F03E6FD00DFC0C8 /* ClaudeUsageCore in Frameworks */ = {isa = PBXBuildFile; productRef = ECF410562F03E6FD00DFC0C8 /* ClaudeUsageCore */; }; + ECF410592F03E6FD00DFC0C8 /* ClaudeUsageData in Frameworks */ = {isa = PBXBuildFile; productRef = ECF410582F03E6FD00DFC0C8 /* ClaudeUsageData */; }; + ECF4105C2F03EA3E00DFC0C8 /* ClaudeUsageCore in Frameworks */ = {isa = PBXBuildFile; productRef = ECF4105B2F03EA3E00DFC0C8 /* ClaudeUsageCore */; }; + ECF4105F2F03EA5900DFC0C8 /* ClaudeUsageData in Frameworks */ = {isa = PBXBuildFile; productRef = ECF4105E2F03EA5900DFC0C8 /* ClaudeUsageData */; }; + ECF4108D2F03EC6700DFC0C8 /* ClaudeUsageCore in Frameworks */ = {isa = PBXBuildFile; productRef = ECF4108C2F03EC6700DFC0C8 /* ClaudeUsageCore */; }; + ECF410902F03EC7800DFC0C8 /* ClaudeUsageData in Frameworks */ = {isa = PBXBuildFile; productRef = ECF4108F2F03EC7800DFC0C8 /* ClaudeUsageData */; }; + ECF412B72F03F5BB00DFC0C8 /* ClaudeUsageUI in Frameworks */ = {isa = PBXBuildFile; productRef = ECF412B62F03F5BB00DFC0C8 /* ClaudeUsageUI */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + ECF410392F03E6AE00DFC0C8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = ECF410232F03E6AD00DFC0C8 /* Project object */; + proxyType = 1; + remoteGlobalIDString = ECF4102A2F03E6AD00DFC0C8; + remoteInfo = ClaudeCodeUsage; + }; + ECF410432F03E6AE00DFC0C8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = ECF410232F03E6AD00DFC0C8 /* Project object */; + proxyType = 1; + remoteGlobalIDString = ECF4102A2F03E6AD00DFC0C8; + remoteInfo = ClaudeCodeUsage; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + ECF4102B2F03E6AD00DFC0C8 /* ClaudeCodeUsage.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ClaudeCodeUsage.app; sourceTree = BUILT_PRODUCTS_DIR; }; + ECF410382F03E6AE00DFC0C8 /* ClaudeCodeUsageTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ClaudeCodeUsageTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + ECF410422F03E6AE00DFC0C8 /* ClaudeCodeUsageUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ClaudeCodeUsageUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + ECF412B82F03F9B900DFC0C8 /* ClaudeCodeUsage.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = file; path = ClaudeCodeUsage.xctestplan; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + ECF4102D2F03E6AD00DFC0C8 /* ClaudeCodeUsage */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = ClaudeCodeUsage; + sourceTree = ""; + }; + ECF4103B2F03E6AE00DFC0C8 /* ClaudeCodeUsageTests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = ClaudeCodeUsageTests; + sourceTree = ""; + }; + ECF410452F03E6AE00DFC0C8 /* ClaudeCodeUsageUITests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = ClaudeCodeUsageUITests; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + ECF410282F03E6AD00DFC0C8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ECF4105F2F03EA5900DFC0C8 /* ClaudeUsageData in Frameworks */, + ECF410592F03E6FD00DFC0C8 /* ClaudeUsageData in Frameworks */, + ECF412B72F03F5BB00DFC0C8 /* ClaudeUsageUI in Frameworks */, + ECF410572F03E6FD00DFC0C8 /* ClaudeUsageCore in Frameworks */, + ECF410902F03EC7800DFC0C8 /* ClaudeUsageData in Frameworks */, + ECF4105C2F03EA3E00DFC0C8 /* ClaudeUsageCore in Frameworks */, + ECF4108D2F03EC6700DFC0C8 /* ClaudeUsageCore in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ECF410352F03E6AE00DFC0C8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ECF4103F2F03E6AE00DFC0C8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + ECF410222F03E6AD00DFC0C8 = { + isa = PBXGroup; + children = ( + ECF412B82F03F9B900DFC0C8 /* ClaudeCodeUsage.xctestplan */, + ECF4102D2F03E6AD00DFC0C8 /* ClaudeCodeUsage */, + ECF4103B2F03E6AE00DFC0C8 /* ClaudeCodeUsageTests */, + ECF410452F03E6AE00DFC0C8 /* ClaudeCodeUsageUITests */, + ECF4102C2F03E6AD00DFC0C8 /* Products */, + ); + sourceTree = ""; + }; + ECF4102C2F03E6AD00DFC0C8 /* Products */ = { + isa = PBXGroup; + children = ( + ECF4102B2F03E6AD00DFC0C8 /* ClaudeCodeUsage.app */, + ECF410382F03E6AE00DFC0C8 /* ClaudeCodeUsageTests.xctest */, + ECF410422F03E6AE00DFC0C8 /* ClaudeCodeUsageUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + ECF4102A2F03E6AD00DFC0C8 /* ClaudeCodeUsage */ = { + isa = PBXNativeTarget; + buildConfigurationList = ECF4104C2F03E6AE00DFC0C8 /* Build configuration list for PBXNativeTarget "ClaudeCodeUsage" */; + buildPhases = ( + ECF410272F03E6AD00DFC0C8 /* Sources */, + ECF410282F03E6AD00DFC0C8 /* Frameworks */, + ECF410292F03E6AD00DFC0C8 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + ECF4102D2F03E6AD00DFC0C8 /* ClaudeCodeUsage */, + ); + name = ClaudeCodeUsage; + packageProductDependencies = ( + ECF410562F03E6FD00DFC0C8 /* ClaudeUsageCore */, + ECF410582F03E6FD00DFC0C8 /* ClaudeUsageData */, + ECF4105B2F03EA3E00DFC0C8 /* ClaudeUsageCore */, + ECF4105E2F03EA5900DFC0C8 /* ClaudeUsageData */, + ECF4108C2F03EC6700DFC0C8 /* ClaudeUsageCore */, + ECF4108F2F03EC7800DFC0C8 /* ClaudeUsageData */, + ECF412B62F03F5BB00DFC0C8 /* ClaudeUsageUI */, + ); + productName = ClaudeCodeUsage; + productReference = ECF4102B2F03E6AD00DFC0C8 /* ClaudeCodeUsage.app */; + productType = "com.apple.product-type.application"; + }; + ECF410372F03E6AE00DFC0C8 /* ClaudeCodeUsageTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = ECF4104F2F03E6AE00DFC0C8 /* Build configuration list for PBXNativeTarget "ClaudeCodeUsageTests" */; + buildPhases = ( + ECF410342F03E6AE00DFC0C8 /* Sources */, + ECF410352F03E6AE00DFC0C8 /* Frameworks */, + ECF410362F03E6AE00DFC0C8 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ECF4103A2F03E6AE00DFC0C8 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + ECF4103B2F03E6AE00DFC0C8 /* ClaudeCodeUsageTests */, + ); + name = ClaudeCodeUsageTests; + packageProductDependencies = ( + ); + productName = ClaudeCodeUsageTests; + productReference = ECF410382F03E6AE00DFC0C8 /* ClaudeCodeUsageTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + ECF410412F03E6AE00DFC0C8 /* ClaudeCodeUsageUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = ECF410522F03E6AE00DFC0C8 /* Build configuration list for PBXNativeTarget "ClaudeCodeUsageUITests" */; + buildPhases = ( + ECF4103E2F03E6AE00DFC0C8 /* Sources */, + ECF4103F2F03E6AE00DFC0C8 /* Frameworks */, + ECF410402F03E6AE00DFC0C8 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ECF410442F03E6AE00DFC0C8 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + ECF410452F03E6AE00DFC0C8 /* ClaudeCodeUsageUITests */, + ); + name = ClaudeCodeUsageUITests; + packageProductDependencies = ( + ); + productName = ClaudeCodeUsageUITests; + productReference = ECF410422F03E6AE00DFC0C8 /* ClaudeCodeUsageUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + ECF410232F03E6AD00DFC0C8 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 2610; + LastUpgradeCheck = 2610; + TargetAttributes = { + ECF4102A2F03E6AD00DFC0C8 = { + CreatedOnToolsVersion = 26.1.1; + }; + ECF410372F03E6AE00DFC0C8 = { + CreatedOnToolsVersion = 26.1.1; + TestTargetID = ECF4102A2F03E6AD00DFC0C8; + }; + ECF410412F03E6AE00DFC0C8 = { + CreatedOnToolsVersion = 26.1.1; + TestTargetID = ECF4102A2F03E6AD00DFC0C8; + }; + }; + }; + buildConfigurationList = ECF410262F03E6AD00DFC0C8 /* Build configuration list for PBXProject "ClaudeCodeUsage" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = ECF410222F03E6AD00DFC0C8; + minimizedProjectReferenceProxies = 1; + packageReferences = ( + ECF4108B2F03EC6700DFC0C8 /* XCLocalSwiftPackageReference "Packages/ClaudeUsageCore" */, + ECF4108E2F03EC7800DFC0C8 /* XCLocalSwiftPackageReference "Packages/ClaudeUsageData" */, + ECF412B52F03F5BB00DFC0C8 /* XCLocalSwiftPackageReference "Packages/ClaudeUsageUI" */, + ); + preferredProjectObjectVersion = 77; + productRefGroup = ECF4102C2F03E6AD00DFC0C8 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + ECF4102A2F03E6AD00DFC0C8 /* ClaudeCodeUsage */, + ECF410372F03E6AE00DFC0C8 /* ClaudeCodeUsageTests */, + ECF410412F03E6AE00DFC0C8 /* ClaudeCodeUsageUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + ECF410292F03E6AD00DFC0C8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ECF410362F03E6AE00DFC0C8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ECF410402F03E6AE00DFC0C8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + ECF410272F03E6AD00DFC0C8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ECF410342F03E6AE00DFC0C8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ECF4103E2F03E6AE00DFC0C8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + ECF4103A2F03E6AE00DFC0C8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = ECF4102A2F03E6AD00DFC0C8 /* ClaudeCodeUsage */; + targetProxy = ECF410392F03E6AE00DFC0C8 /* PBXContainerItemProxy */; + }; + ECF410442F03E6AE00DFC0C8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = ECF4102A2F03E6AD00DFC0C8 /* ClaudeCodeUsage */; + targetProxy = ECF410432F03E6AE00DFC0C8 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + ECF4104A2F03E6AE00DFC0C8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = NA5BE2D52P; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 26.1; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + ECF4104B2F03E6AE00DFC0C8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = NA5BE2D52P; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 26.1; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + }; + name = Release; + }; + ECF4104D2F03E6AE00DFC0C8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = ClaudeCodeUsage/ClaudeCodeUsage.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = NA5BE2D52P; + ENABLE_APP_SANDBOX = NO; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_LSUIElement = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 15.6; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.unchartedworks.ClaudeCodeUsage; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + ECF4104E2F03E6AE00DFC0C8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = ClaudeCodeUsage/ClaudeCodeUsage.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = NA5BE2D52P; + ENABLE_APP_SANDBOX = NO; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_LSUIElement = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 15.6; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.unchartedworks.ClaudeCodeUsage; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + ECF410502F03E6AE00DFC0C8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = NA5BE2D52P; + GENERATE_INFOPLIST_FILE = YES; + MACOSX_DEPLOYMENT_TARGET = 26.1; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.unchartedworks.ClaudeCodeUsageTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ClaudeCodeUsage.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/ClaudeCodeUsage"; + }; + name = Debug; + }; + ECF410512F03E6AE00DFC0C8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = NA5BE2D52P; + GENERATE_INFOPLIST_FILE = YES; + MACOSX_DEPLOYMENT_TARGET = 26.1; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.unchartedworks.ClaudeCodeUsageTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ClaudeCodeUsage.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/ClaudeCodeUsage"; + }; + name = Release; + }; + ECF410532F03E6AE00DFC0C8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = NA5BE2D52P; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.unchartedworks.ClaudeCodeUsageUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = ClaudeCodeUsage; + }; + name = Debug; + }; + ECF410542F03E6AE00DFC0C8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = NA5BE2D52P; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.unchartedworks.ClaudeCodeUsageUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = ClaudeCodeUsage; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + ECF410262F03E6AD00DFC0C8 /* Build configuration list for PBXProject "ClaudeCodeUsage" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + ECF4104A2F03E6AE00DFC0C8 /* Debug */, + ECF4104B2F03E6AE00DFC0C8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + ECF4104C2F03E6AE00DFC0C8 /* Build configuration list for PBXNativeTarget "ClaudeCodeUsage" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + ECF4104D2F03E6AE00DFC0C8 /* Debug */, + ECF4104E2F03E6AE00DFC0C8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + ECF4104F2F03E6AE00DFC0C8 /* Build configuration list for PBXNativeTarget "ClaudeCodeUsageTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + ECF410502F03E6AE00DFC0C8 /* Debug */, + ECF410512F03E6AE00DFC0C8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + ECF410522F03E6AE00DFC0C8 /* Build configuration list for PBXNativeTarget "ClaudeCodeUsageUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + ECF410532F03E6AE00DFC0C8 /* Debug */, + ECF410542F03E6AE00DFC0C8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + ECF4108B2F03EC6700DFC0C8 /* XCLocalSwiftPackageReference "Packages/ClaudeUsageCore" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Packages/ClaudeUsageCore; + }; + ECF4108E2F03EC7800DFC0C8 /* XCLocalSwiftPackageReference "Packages/ClaudeUsageData" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Packages/ClaudeUsageData; + }; + ECF412B52F03F5BB00DFC0C8 /* XCLocalSwiftPackageReference "Packages/ClaudeUsageUI" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Packages/ClaudeUsageUI; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + ECF410562F03E6FD00DFC0C8 /* ClaudeUsageCore */ = { + isa = XCSwiftPackageProductDependency; + productName = ClaudeUsageCore; + }; + ECF410582F03E6FD00DFC0C8 /* ClaudeUsageData */ = { + isa = XCSwiftPackageProductDependency; + productName = ClaudeUsageData; + }; + ECF4105B2F03EA3E00DFC0C8 /* ClaudeUsageCore */ = { + isa = XCSwiftPackageProductDependency; + productName = ClaudeUsageCore; + }; + ECF4105E2F03EA5900DFC0C8 /* ClaudeUsageData */ = { + isa = XCSwiftPackageProductDependency; + productName = ClaudeUsageData; + }; + ECF4108C2F03EC6700DFC0C8 /* ClaudeUsageCore */ = { + isa = XCSwiftPackageProductDependency; + productName = ClaudeUsageCore; + }; + ECF4108F2F03EC7800DFC0C8 /* ClaudeUsageData */ = { + isa = XCSwiftPackageProductDependency; + productName = ClaudeUsageData; + }; + ECF412B62F03F5BB00DFC0C8 /* ClaudeUsageUI */ = { + isa = XCSwiftPackageProductDependency; + productName = ClaudeUsageUI; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = ECF410232F03E6AD00DFC0C8 /* Project object */; +} diff --git a/ClaudeCodeUsage.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ClaudeCodeUsage.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ClaudeCodeUsage.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ClaudeCodeUsage.xcodeproj/xcshareddata/xcschemes/ClaudeCodeUsage.xcscheme b/ClaudeCodeUsage.xcodeproj/xcshareddata/xcschemes/ClaudeCodeUsage.xcscheme new file mode 100644 index 0000000..73f6c05 --- /dev/null +++ b/ClaudeCodeUsage.xcodeproj/xcshareddata/xcschemes/ClaudeCodeUsage.xcscheme @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ClaudeCodeUsage.xctestplan b/ClaudeCodeUsage.xctestplan new file mode 100644 index 0000000..ddb54d2 --- /dev/null +++ b/ClaudeCodeUsage.xctestplan @@ -0,0 +1,40 @@ +{ + "configurations" : [ + { + "id" : "863E2FD1-1C91-46C5-B5FA-75CAF5654882", + "name" : "Test Scheme Action", + "options" : { + + } + } + ], + "defaultOptions" : { + "performanceAntipatternCheckerEnabled" : true, + "targetForVariableExpansion" : { + "containerPath" : "container:ClaudeCodeUsage.xcodeproj", + "identifier" : "ECF4102A2F03E6AD00DFC0C8", + "name" : "ClaudeCodeUsage" + } + }, + "testTargets" : [ + { + "enabled" : false, + "parallelizable" : true, + "target" : { + "containerPath" : "container:ClaudeCodeUsage.xcodeproj", + "identifier" : "ECF410372F03E6AE00DFC0C8", + "name" : "ClaudeCodeUsageTests" + } + }, + { + "enabled" : false, + "parallelizable" : true, + "target" : { + "containerPath" : "container:ClaudeCodeUsage.xcodeproj", + "identifier" : "ECF410412F03E6AE00DFC0C8", + "name" : "ClaudeCodeUsageUITests" + } + } + ], + "version" : 1 +} diff --git a/ClaudeCodeUsage/Assets.xcassets/AccentColor.colorset/Contents.json b/ClaudeCodeUsage/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/ClaudeCodeUsage/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ClaudeCodeUsage/Assets.xcassets/AppIcon.appiconset/Contents.json b/ClaudeCodeUsage/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..3f00db4 --- /dev/null +++ b/ClaudeCodeUsage/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ClaudeCodeUsage/Assets.xcassets/Contents.json b/ClaudeCodeUsage/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/ClaudeCodeUsage/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ClaudeCodeUsage/ClaudeCodeUsage.entitlements b/ClaudeCodeUsage/ClaudeCodeUsage.entitlements new file mode 100644 index 0000000..4c3fbcf --- /dev/null +++ b/ClaudeCodeUsage/ClaudeCodeUsage.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/Sources/ClaudeUsage/App/ClaudeCodeUsageApp.swift b/ClaudeCodeUsage/ClaudeCodeUsageApp.swift similarity index 100% rename from Sources/ClaudeUsage/App/ClaudeCodeUsageApp.swift rename to ClaudeCodeUsage/ClaudeCodeUsageApp.swift diff --git a/ClaudeCodeUsageTests/ClaudeCodeUsageTests.swift b/ClaudeCodeUsageTests/ClaudeCodeUsageTests.swift new file mode 100644 index 0000000..43293c9 --- /dev/null +++ b/ClaudeCodeUsageTests/ClaudeCodeUsageTests.swift @@ -0,0 +1,17 @@ +// +// ClaudeCodeUsageTests.swift +// ClaudeCodeUsageTests +// +// Created by Liang on 30-12-2025. +// + +import Testing +@testable import ClaudeCodeUsage + +struct ClaudeCodeUsageTests { + + @Test func example() async throws { + // Write your test here and use APIs like `#expect(...)` to check expected conditions. + } + +} diff --git a/ClaudeCodeUsageUITests/ClaudeCodeUsageUITests.swift b/ClaudeCodeUsageUITests/ClaudeCodeUsageUITests.swift new file mode 100644 index 0000000..6211a65 --- /dev/null +++ b/ClaudeCodeUsageUITests/ClaudeCodeUsageUITests.swift @@ -0,0 +1,41 @@ +// +// ClaudeCodeUsageUITests.swift +// ClaudeCodeUsageUITests +// +// Created by Liang on 30-12-2025. +// + +import XCTest + +final class ClaudeCodeUsageUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + @MainActor + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + @MainActor + func testLaunchPerformance() throws { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } +} diff --git a/ClaudeCodeUsageUITests/ClaudeCodeUsageUITestsLaunchTests.swift b/ClaudeCodeUsageUITests/ClaudeCodeUsageUITestsLaunchTests.swift new file mode 100644 index 0000000..66232f9 --- /dev/null +++ b/ClaudeCodeUsageUITests/ClaudeCodeUsageUITestsLaunchTests.swift @@ -0,0 +1,33 @@ +// +// ClaudeCodeUsageUITestsLaunchTests.swift +// ClaudeCodeUsageUITests +// +// Created by Liang on 30-12-2025. +// + +import XCTest + +final class ClaudeCodeUsageUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + @MainActor + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} diff --git a/Makefile b/Makefile index 2ea56f6..5b518e4 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Makefile for ClaudeCodeUsage # Provides convenient commands for development -.PHONY: help build test coverage clean format lint docs +.PHONY: help build test test-core test-data test-ui coverage clean format lint docs # Default target help: @@ -23,8 +23,16 @@ build: swift build # Run all tests -test: - swift test --parallel +test: test-core test-data test-ui + +test-core: + swift test --package-path Packages/ClaudeUsageCore + +test-data: + swift test --package-path Packages/ClaudeUsageData + +test-ui: + swift test --package-path Packages/ClaudeUsageUI # Generate code coverage report coverage: diff --git a/Package.swift b/Package.swift deleted file mode 100644 index 5a683df..0000000 --- a/Package.swift +++ /dev/null @@ -1,87 +0,0 @@ -// swift-tools-version: 6.0 - -import PackageDescription - -let package = Package( - name: "ClaudeUsage", - platforms: [ - .macOS(.v15), - ], - products: [ - // Domain layer - pure types, protocols, analytics - .library( - name: "ClaudeUsageCore", - targets: ["ClaudeUsageCore"]), - // Data layer - repository, parsing, monitoring - .library( - name: "ClaudeUsageData", - targets: ["ClaudeUsageData"]), - // UI layer - SwiftUI views and stores - .library( - name: "ClaudeUsageUI", - targets: ["ClaudeUsageUI"]), - // macOS menu bar app - .executable( - name: "ClaudeCodeUsage", - targets: ["ClaudeUsage"]) - ], - dependencies: [], - targets: [ - // MARK: - Domain Layer (no dependencies) - - .target( - name: "ClaudeUsageCore", - dependencies: [], - path: "Sources/ClaudeUsageCore"), - - // MARK: - Data Layer (depends on Core) - - .target( - name: "ClaudeUsageData", - dependencies: ["ClaudeUsageCore"], - path: "Sources/ClaudeUsageData"), - - // MARK: - UI Layer (SwiftUI views, stores) - - .target( - name: "ClaudeUsageUI", - dependencies: [ - "ClaudeUsageCore", - "ClaudeUsageData" - ], - path: "Sources/ClaudeUsageUI"), - - // MARK: - App Entry Point - - .executableTarget( - name: "ClaudeUsage", - dependencies: [ - "ClaudeUsageUI" - ], - path: "Sources/ClaudeUsage"), - - // MARK: - Tests - - .testTarget( - name: "ClaudeUsageCoreTests", - dependencies: ["ClaudeUsageCore"], - path: "Tests/ClaudeUsageCoreTests"), - - .testTarget( - name: "ClaudeUsageDataTests", - dependencies: ["ClaudeUsageData"], - path: "Tests/ClaudeUsageDataTests"), - - .testTarget( - name: "ClaudeUsageTests", - dependencies: [ - "ClaudeUsageUI", - "ClaudeUsageData" - ], - path: "Tests/ClaudeUsageTests", - swiftSettings: [ - .unsafeFlags(["-enable-testing"]), - .define("ENABLE_CODE_COVERAGE", .when(configuration: .debug)) - ]), - ] -) diff --git a/Packages/ClaudeUsageCore/Package.swift b/Packages/ClaudeUsageCore/Package.swift new file mode 100644 index 0000000..2cfea26 --- /dev/null +++ b/Packages/ClaudeUsageCore/Package.swift @@ -0,0 +1,26 @@ +// swift-tools-version: 6.0 + +import PackageDescription + +let package = Package( + name: "ClaudeUsageCore", + platforms: [ + .macOS(.v15), + ], + products: [ + .library( + name: "ClaudeUsageCore", + targets: ["ClaudeUsageCore"]), + ], + targets: [ + .target( + name: "ClaudeUsageCore", + dependencies: [], + path: "Sources"), + + .testTarget( + name: "ClaudeUsageCoreTests", + dependencies: ["ClaudeUsageCore"], + path: "Tests"), + ] +) diff --git a/Sources/ClaudeUsageCore/Analytics/PricingCalculator.swift b/Packages/ClaudeUsageCore/Sources/Analytics/PricingCalculator.swift similarity index 100% rename from Sources/ClaudeUsageCore/Analytics/PricingCalculator.swift rename to Packages/ClaudeUsageCore/Sources/Analytics/PricingCalculator.swift diff --git a/Sources/ClaudeUsageCore/Analytics/UsageAggregator.swift b/Packages/ClaudeUsageCore/Sources/Analytics/UsageAggregator.swift similarity index 100% rename from Sources/ClaudeUsageCore/Analytics/UsageAggregator.swift rename to Packages/ClaudeUsageCore/Sources/Analytics/UsageAggregator.swift diff --git a/Sources/ClaudeUsageCore/Analytics/UsageAnalytics.swift b/Packages/ClaudeUsageCore/Sources/Analytics/UsageAnalytics.swift similarity index 100% rename from Sources/ClaudeUsageCore/Analytics/UsageAnalytics.swift rename to Packages/ClaudeUsageCore/Sources/Analytics/UsageAnalytics.swift diff --git a/Sources/ClaudeUsageCore/ClaudeUsageCore.swift b/Packages/ClaudeUsageCore/Sources/ClaudeUsageCore.swift similarity index 100% rename from Sources/ClaudeUsageCore/ClaudeUsageCore.swift rename to Packages/ClaudeUsageCore/Sources/ClaudeUsageCore.swift diff --git a/Sources/ClaudeUsageCore/Models/BurnRate.swift b/Packages/ClaudeUsageCore/Sources/Models/BurnRate.swift similarity index 100% rename from Sources/ClaudeUsageCore/Models/BurnRate.swift rename to Packages/ClaudeUsageCore/Sources/Models/BurnRate.swift diff --git a/Sources/ClaudeUsageCore/Models/SessionBlock.swift b/Packages/ClaudeUsageCore/Sources/Models/SessionBlock.swift similarity index 100% rename from Sources/ClaudeUsageCore/Models/SessionBlock.swift rename to Packages/ClaudeUsageCore/Sources/Models/SessionBlock.swift diff --git a/Sources/ClaudeUsageCore/Models/TokenCounts.swift b/Packages/ClaudeUsageCore/Sources/Models/TokenCounts.swift similarity index 100% rename from Sources/ClaudeUsageCore/Models/TokenCounts.swift rename to Packages/ClaudeUsageCore/Sources/Models/TokenCounts.swift diff --git a/Sources/ClaudeUsageCore/Models/UsageEntry.swift b/Packages/ClaudeUsageCore/Sources/Models/UsageEntry.swift similarity index 100% rename from Sources/ClaudeUsageCore/Models/UsageEntry.swift rename to Packages/ClaudeUsageCore/Sources/Models/UsageEntry.swift diff --git a/Sources/ClaudeUsageCore/Models/UsageStats.swift b/Packages/ClaudeUsageCore/Sources/Models/UsageStats.swift similarity index 100% rename from Sources/ClaudeUsageCore/Models/UsageStats.swift rename to Packages/ClaudeUsageCore/Sources/Models/UsageStats.swift diff --git a/Sources/ClaudeUsageCore/Protocols/UsageDataSource.swift b/Packages/ClaudeUsageCore/Sources/Protocols/UsageDataSource.swift similarity index 100% rename from Sources/ClaudeUsageCore/Protocols/UsageDataSource.swift rename to Packages/ClaudeUsageCore/Sources/Protocols/UsageDataSource.swift diff --git a/Tests/ClaudeUsageCoreTests/PricingCalculatorTests.swift b/Packages/ClaudeUsageCore/Tests/PricingCalculatorTests.swift similarity index 100% rename from Tests/ClaudeUsageCoreTests/PricingCalculatorTests.swift rename to Packages/ClaudeUsageCore/Tests/PricingCalculatorTests.swift diff --git a/Tests/ClaudeUsageCoreTests/TokenCountsTests.swift b/Packages/ClaudeUsageCore/Tests/TokenCountsTests.swift similarity index 100% rename from Tests/ClaudeUsageCoreTests/TokenCountsTests.swift rename to Packages/ClaudeUsageCore/Tests/TokenCountsTests.swift diff --git a/Tests/ClaudeUsageCoreTests/UsageAggregatorTests.swift b/Packages/ClaudeUsageCore/Tests/UsageAggregatorTests.swift similarity index 100% rename from Tests/ClaudeUsageCoreTests/UsageAggregatorTests.swift rename to Packages/ClaudeUsageCore/Tests/UsageAggregatorTests.swift diff --git a/Packages/ClaudeUsageData/Package.swift b/Packages/ClaudeUsageData/Package.swift new file mode 100644 index 0000000..9130da7 --- /dev/null +++ b/Packages/ClaudeUsageData/Package.swift @@ -0,0 +1,29 @@ +// swift-tools-version: 6.0 + +import PackageDescription + +let package = Package( + name: "ClaudeUsageData", + platforms: [ + .macOS(.v15), + ], + products: [ + .library( + name: "ClaudeUsageData", + targets: ["ClaudeUsageData"]), + ], + dependencies: [ + .package(path: "../ClaudeUsageCore"), + ], + targets: [ + .target( + name: "ClaudeUsageData", + dependencies: ["ClaudeUsageCore"], + path: "Sources"), + + .testTarget( + name: "ClaudeUsageDataTests", + dependencies: ["ClaudeUsageData"], + path: "Tests"), + ] +) diff --git a/Sources/ClaudeUsageData/ClaudeUsageData.swift b/Packages/ClaudeUsageData/Sources/ClaudeUsageData.swift similarity index 100% rename from Sources/ClaudeUsageData/ClaudeUsageData.swift rename to Packages/ClaudeUsageData/Sources/ClaudeUsageData.swift diff --git a/Sources/ClaudeUsageData/Monitoring/DirectoryMonitor.swift b/Packages/ClaudeUsageData/Sources/Monitoring/DirectoryMonitor.swift similarity index 100% rename from Sources/ClaudeUsageData/Monitoring/DirectoryMonitor.swift rename to Packages/ClaudeUsageData/Sources/Monitoring/DirectoryMonitor.swift diff --git a/Sources/ClaudeUsageData/Monitoring/SessionMonitor.swift b/Packages/ClaudeUsageData/Sources/Monitoring/SessionMonitor.swift similarity index 100% rename from Sources/ClaudeUsageData/Monitoring/SessionMonitor.swift rename to Packages/ClaudeUsageData/Sources/Monitoring/SessionMonitor.swift diff --git a/Sources/ClaudeUsageData/Parsing/JSONLParser.swift b/Packages/ClaudeUsageData/Sources/Parsing/JSONLParser.swift similarity index 100% rename from Sources/ClaudeUsageData/Parsing/JSONLParser.swift rename to Packages/ClaudeUsageData/Sources/Parsing/JSONLParser.swift diff --git a/Sources/ClaudeUsageData/Repository/FileDiscovery.swift b/Packages/ClaudeUsageData/Sources/Repository/FileDiscovery.swift similarity index 100% rename from Sources/ClaudeUsageData/Repository/FileDiscovery.swift rename to Packages/ClaudeUsageData/Sources/Repository/FileDiscovery.swift diff --git a/Sources/ClaudeUsageData/Repository/UsageRepository.swift b/Packages/ClaudeUsageData/Sources/Repository/UsageRepository.swift similarity index 100% rename from Sources/ClaudeUsageData/Repository/UsageRepository.swift rename to Packages/ClaudeUsageData/Sources/Repository/UsageRepository.swift diff --git a/Tests/ClaudeUsageDataTests/FileDiscoveryTests.swift b/Packages/ClaudeUsageData/Tests/FileDiscoveryTests.swift similarity index 100% rename from Tests/ClaudeUsageDataTests/FileDiscoveryTests.swift rename to Packages/ClaudeUsageData/Tests/FileDiscoveryTests.swift diff --git a/Tests/ClaudeUsageDataTests/JSONLParserTests.swift b/Packages/ClaudeUsageData/Tests/JSONLParserTests.swift similarity index 100% rename from Tests/ClaudeUsageDataTests/JSONLParserTests.swift rename to Packages/ClaudeUsageData/Tests/JSONLParserTests.swift diff --git a/Tests/ClaudeUsageDataTests/SessionMonitorTests.swift b/Packages/ClaudeUsageData/Tests/SessionMonitorTests.swift similarity index 100% rename from Tests/ClaudeUsageDataTests/SessionMonitorTests.swift rename to Packages/ClaudeUsageData/Tests/SessionMonitorTests.swift diff --git a/Tests/ClaudeUsageDataTests/UsageRepositoryTests.swift b/Packages/ClaudeUsageData/Tests/UsageRepositoryTests.swift similarity index 100% rename from Tests/ClaudeUsageDataTests/UsageRepositoryTests.swift rename to Packages/ClaudeUsageData/Tests/UsageRepositoryTests.swift diff --git a/Packages/ClaudeUsageUI/.swiftpm/xcode/xcshareddata/xcschemes/ClaudeUsageUI.xcscheme b/Packages/ClaudeUsageUI/.swiftpm/xcode/xcshareddata/xcschemes/ClaudeUsageUI.xcscheme new file mode 100644 index 0000000..f9610b3 --- /dev/null +++ b/Packages/ClaudeUsageUI/.swiftpm/xcode/xcshareddata/xcschemes/ClaudeUsageUI.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Packages/ClaudeUsageUI/Package.swift b/Packages/ClaudeUsageUI/Package.swift new file mode 100644 index 0000000..ac00a6f --- /dev/null +++ b/Packages/ClaudeUsageUI/Package.swift @@ -0,0 +1,40 @@ +// swift-tools-version: 6.0 + +import PackageDescription + +let package = Package( + name: "ClaudeUsageUI", + platforms: [ + .macOS(.v15), + ], + products: [ + .library( + name: "ClaudeUsageUI", + targets: ["ClaudeUsageUI"]), + ], + dependencies: [ + .package(path: "../ClaudeUsageCore"), + .package(path: "../ClaudeUsageData"), + ], + targets: [ + .target( + name: "ClaudeUsageUI", + dependencies: [ + "ClaudeUsageCore", + "ClaudeUsageData", + ], + path: "Sources"), + + .testTarget( + name: "ClaudeUsageUITests", + dependencies: [ + "ClaudeUsageUI", + "ClaudeUsageData", + ], + path: "Tests", + swiftSettings: [ + .unsafeFlags(["-enable-testing"]), + .define("ENABLE_CODE_COVERAGE", .when(configuration: .debug)), + ]), + ] +) diff --git a/Sources/ClaudeUsageUI/AppLifecycleManager.swift b/Packages/ClaudeUsageUI/Sources/AppLifecycleManager.swift similarity index 100% rename from Sources/ClaudeUsageUI/AppLifecycleManager.swift rename to Packages/ClaudeUsageUI/Sources/AppLifecycleManager.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/AnalyticsRows.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/AnalyticsRows.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/AnalyticsRows.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/AnalyticsRows.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/AnalyticsView.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/AnalyticsView.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/AnalyticsView.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/AnalyticsView.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Cards/AnalyticsCard.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Cards/AnalyticsCard.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Cards/AnalyticsCard.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Cards/AnalyticsCard.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Cards/PredictionsCard.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Cards/PredictionsCard.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Cards/PredictionsCard.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Cards/PredictionsCard.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Cards/TokenDistributionCard.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Cards/TokenDistributionCard.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Cards/TokenDistributionCard.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Cards/TokenDistributionCard.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Cards/UsageTrendsCard.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Cards/UsageTrendsCard.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Cards/UsageTrendsCard.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Cards/UsageTrendsCard.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Cards/YearlyCostHeatmapCard.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Cards/YearlyCostHeatmapCard.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Cards/YearlyCostHeatmapCard.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Cards/YearlyCostHeatmapCard.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration+Accessibility.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration+Accessibility.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration+Accessibility.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration+Accessibility.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration+ColorThemes.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration+ColorThemes.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration+ColorThemes.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration+ColorThemes.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Configuration/HeatmapConfiguration.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Grid/DaySquare.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Grid/DaySquare.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Grid/DaySquare.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Grid/DaySquare.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Grid/HeatmapGrid.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Grid/HeatmapGrid.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Grid/HeatmapGrid.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Grid/HeatmapGrid.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Grid/HeatmapGridLayout.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Grid/HeatmapGridLayout.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Grid/HeatmapGridLayout.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Grid/HeatmapGridLayout.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Grid/HeatmapGridPerformance.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Grid/HeatmapGridPerformance.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Grid/HeatmapGridPerformance.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Grid/HeatmapGridPerformance.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Grid/WeekColumn.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Grid/WeekColumn.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Grid/WeekColumn.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Grid/WeekColumn.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Legend/HeatmapLegend+Factory.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Legend/HeatmapLegend+Factory.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Legend/HeatmapLegend+Factory.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Legend/HeatmapLegend+Factory.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Legend/HeatmapLegend.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Legend/HeatmapLegend.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Legend/HeatmapLegend.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Legend/HeatmapLegend.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Legend/HeatmapLegendBuilder.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Legend/HeatmapLegendBuilder.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Legend/HeatmapLegendBuilder.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Legend/HeatmapLegendBuilder.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Legend/LegendSquare.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Legend/LegendSquare.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Legend/LegendSquare.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Legend/LegendSquare.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/ActivityLevel.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/ActivityLevel.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/ActivityLevel.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/ActivityLevel.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/ActivityLevelLabels.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/ActivityLevelLabels.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/ActivityLevelLabels.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/ActivityLevelLabels.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/BorderStyle.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/BorderStyle.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/BorderStyle.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/BorderStyle.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/ColorScheme.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/ColorScheme.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/ColorScheme.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/ColorScheme.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/DateConstants.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/DateConstants.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/DateConstants.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/DateConstants.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/DateRangeValidation.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/DateRangeValidation.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/DateRangeValidation.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/DateRangeValidation.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/HeatmapData.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/HeatmapData.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/HeatmapData.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/HeatmapData.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/HeatmapDateCalculator.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/HeatmapDateCalculator.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/HeatmapDateCalculator.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/HeatmapDateCalculator.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/MonthOperations.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/MonthOperations.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/MonthOperations.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/MonthOperations.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/WeekOperations.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/WeekOperations.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Models/WeekOperations.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Models/WeekOperations.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Stores/HeatmapStore+DataGeneration.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Stores/HeatmapStore+DataGeneration.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Stores/HeatmapStore+DataGeneration.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Stores/HeatmapStore+DataGeneration.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Stores/HeatmapStore+SupportingTypes.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Stores/HeatmapStore+SupportingTypes.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Stores/HeatmapStore+SupportingTypes.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Stores/HeatmapStore+SupportingTypes.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Stores/HeatmapStore.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Stores/HeatmapStore.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Stores/HeatmapStore.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Stores/HeatmapStore.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltip+Factory.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltip+Factory.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltip+Factory.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltip+Factory.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltip.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltip.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltip.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltip.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltipBuilder.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltipBuilder.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltipBuilder.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Tooltip/HeatmapTooltipBuilder.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Tooltip/TooltipConfiguration.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Tooltip/TooltipConfiguration.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Tooltip/TooltipConfiguration.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Tooltip/TooltipConfiguration.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Tooltip/TooltipPositioning.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Tooltip/TooltipPositioning.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/Tooltip/TooltipPositioning.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/Tooltip/TooltipPositioning.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/YearlyCostHeatmap+Factories.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/YearlyCostHeatmap+Factories.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/YearlyCostHeatmap+Factories.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/YearlyCostHeatmap+Factories.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/YearlyCostHeatmap+Preview.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/YearlyCostHeatmap+Preview.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/YearlyCostHeatmap+Preview.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/YearlyCostHeatmap+Preview.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/YearlyCostHeatmap.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/YearlyCostHeatmap.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Analytics/Heatmap/YearlyCostHeatmap.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Analytics/Heatmap/YearlyCostHeatmap.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Components/EmptyStateView.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Components/EmptyStateView.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Components/EmptyStateView.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Components/EmptyStateView.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Daily/DailyUsageView.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Daily/DailyUsageView.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Daily/DailyUsageView.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Daily/DailyUsageView.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/MainView.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/MainView.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/MainView.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/MainView.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Models/ModelsView.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Models/ModelsView.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Models/ModelsView.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Models/ModelsView.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Overview/MetricCard.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Overview/MetricCard.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Overview/MetricCard.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Overview/MetricCard.swift diff --git a/Sources/ClaudeUsageUI/MainWindow/Overview/OverviewView.swift b/Packages/ClaudeUsageUI/Sources/MainWindow/Overview/OverviewView.swift similarity index 100% rename from Sources/ClaudeUsageUI/MainWindow/Overview/OverviewView.swift rename to Packages/ClaudeUsageUI/Sources/MainWindow/Overview/OverviewView.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Components/ActionButtons.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Components/ActionButtons.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Components/ActionButtons.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Components/ActionButtons.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Components/GraphView.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Components/GraphView.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Components/GraphView.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Components/GraphView.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Components/MetricRow.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Components/MetricRow.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Components/MetricRow.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Components/MetricRow.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Components/ProgressBar.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Components/ProgressBar.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Components/ProgressBar.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Components/ProgressBar.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Components/SectionHeader.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Components/SectionHeader.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Components/SectionHeader.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Components/SectionHeader.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Components/SettingsMenu.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Components/SettingsMenu.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Components/SettingsMenu.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Components/SettingsMenu.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Helpers/ColorService.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Helpers/ColorService.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Helpers/ColorService.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Helpers/ColorService.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Helpers/FormatterService.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Helpers/FormatterService.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Helpers/FormatterService.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Helpers/FormatterService.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/MenuBarContentView.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/MenuBarContentView.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/MenuBarContentView.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/MenuBarContentView.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/MenuBarScene.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/MenuBarScene.swift similarity index 89% rename from Sources/ClaudeUsageUI/MenuBar/MenuBarScene.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/MenuBarScene.swift index 0ea065a..0922338 100644 --- a/Sources/ClaudeUsageUI/MenuBar/MenuBarScene.swift +++ b/Packages/ClaudeUsageUI/Sources/MenuBar/MenuBarScene.swift @@ -6,6 +6,10 @@ import SwiftUI import ClaudeUsageCore +// MARK: - Preview Detection + +private let isRunningForPreviews = ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PLAYGROUNDS"] == "1" + // MARK: - Menu Bar Scene public struct MenuBarScene: Scene { @@ -29,16 +33,29 @@ public struct MenuBarScene: Scene { .menuBarExtraStyle(.window) } + @ViewBuilder private var menuContent: some View { - MenuBarContentView(settingsService: settingsService) - .environment(store) + if isRunningForPreviews { + // Minimal content for preview mode to avoid blocking app launch + Text("Preview Mode") + .frame(width: 200, height: 100) + } else { + MenuBarContentView(settingsService: settingsService) + .environment(store) + } } + @ViewBuilder private var menuLabel: some View { - MenuBarLabel(store: store) - .environment(store) - .task { await initializeOnce() } - .contextMenu { contextMenu } + if isRunningForPreviews { + // Minimal label for preview mode + Image(systemName: "dollarsign.circle") + } else { + MenuBarLabel(store: store) + .environment(store) + .task { await initializeOnce() } + .contextMenu { contextMenu } + } } private var contextMenu: some View { diff --git a/Sources/ClaudeUsageUI/MenuBar/Sections/CostMetricsSection.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Sections/CostMetricsSection.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Sections/CostMetricsSection.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Sections/CostMetricsSection.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Sections/SessionMetricsSection.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Sections/SessionMetricsSection.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Sections/SessionMetricsSection.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Sections/SessionMetricsSection.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Sections/UsageMetricsSection.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Sections/UsageMetricsSection.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Sections/UsageMetricsSection.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Sections/UsageMetricsSection.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Theme/MenuBarStyles.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Theme/MenuBarStyles.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Theme/MenuBarStyles.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Theme/MenuBarStyles.swift diff --git a/Sources/ClaudeUsageUI/MenuBar/Theme/MenuBarTheme.swift b/Packages/ClaudeUsageUI/Sources/MenuBar/Theme/MenuBarTheme.swift similarity index 100% rename from Sources/ClaudeUsageUI/MenuBar/Theme/MenuBarTheme.swift rename to Packages/ClaudeUsageUI/Sources/MenuBar/Theme/MenuBarTheme.swift diff --git a/Packages/ClaudeUsageUI/Sources/Previews.swift b/Packages/ClaudeUsageUI/Sources/Previews.swift new file mode 100644 index 0000000..0903535 --- /dev/null +++ b/Packages/ClaudeUsageUI/Sources/Previews.swift @@ -0,0 +1,63 @@ +// +// Previews.swift +// All app previews in one place +// + +#if DEBUG +import SwiftUI +import ClaudeUsageCore + +// MARK: - Menu Bar Preview + +struct MenuBarPreviewWrapper: View { + @State private var store = UsageStore() + + var body: some View { + content + .frame(height: 500) + .task { await store.loadData() } + } + + @ViewBuilder + private var content: some View { + if store.state.hasLoaded { + MenuBarContentView(settingsService: AppSettingsService()) + .environment(store) + } else { + ProgressView("Loading...") + .frame(width: MenuBarTheme.Layout.menuBarWidth, height: 200) + } + } +} + +// MARK: - Main Window Preview + +struct MainWindowPreviewWrapper: View { + @State private var store = UsageStore() + + var body: some View { + MainView(settingsService: AppSettingsService()) + .environment(store) + .frame(width: 1000, height: 700) + .task { await store.loadData() } + } +} + +// MARK: - Previews + +#Preview("Menu Bar") { + MenuBarPreviewWrapper() +} + +#Preview("Main Window") { + MainWindowPreviewWrapper() +} + +#Preview("All") { + HStack { + MenuBarPreviewWrapper() + Divider() + MainWindowPreviewWrapper() + } +} +#endif diff --git a/Sources/ClaudeUsageUI/Settings/AppSettingsService.swift b/Packages/ClaudeUsageUI/Sources/Settings/AppSettingsService.swift similarity index 100% rename from Sources/ClaudeUsageUI/Settings/AppSettingsService.swift rename to Packages/ClaudeUsageUI/Sources/Settings/AppSettingsService.swift diff --git a/Sources/ClaudeUsageUI/Settings/OpenAtLoginToggle.swift b/Packages/ClaudeUsageUI/Sources/Settings/OpenAtLoginToggle.swift similarity index 100% rename from Sources/ClaudeUsageUI/Settings/OpenAtLoginToggle.swift rename to Packages/ClaudeUsageUI/Sources/Settings/OpenAtLoginToggle.swift diff --git a/Sources/ClaudeUsageUI/Shared/Charts/HourlyChart/HourlyChartModels.swift b/Packages/ClaudeUsageUI/Sources/Shared/Charts/HourlyChart/HourlyChartModels.swift similarity index 100% rename from Sources/ClaudeUsageUI/Shared/Charts/HourlyChart/HourlyChartModels.swift rename to Packages/ClaudeUsageUI/Sources/Shared/Charts/HourlyChart/HourlyChartModels.swift diff --git a/Sources/ClaudeUsageUI/Shared/Charts/HourlyChart/HourlyCostChartSimple.swift b/Packages/ClaudeUsageUI/Sources/Shared/Charts/HourlyChart/HourlyCostChartSimple.swift similarity index 100% rename from Sources/ClaudeUsageUI/Shared/Charts/HourlyChart/HourlyCostChartSimple.swift rename to Packages/ClaudeUsageUI/Sources/Shared/Charts/HourlyChart/HourlyCostChartSimple.swift diff --git a/Sources/ClaudeUsageUI/Shared/Charts/HourlyChart/HourlyTooltipViews.swift b/Packages/ClaudeUsageUI/Sources/Shared/Charts/HourlyChart/HourlyTooltipViews.swift similarity index 100% rename from Sources/ClaudeUsageUI/Shared/Charts/HourlyChart/HourlyTooltipViews.swift rename to Packages/ClaudeUsageUI/Sources/Shared/Charts/HourlyChart/HourlyTooltipViews.swift diff --git a/Sources/ClaudeUsageUI/Stores/Services/Clock/ClockProtocol.swift b/Packages/ClaudeUsageUI/Sources/Stores/Services/Clock/ClockProtocol.swift similarity index 100% rename from Sources/ClaudeUsageUI/Stores/Services/Clock/ClockProtocol.swift rename to Packages/ClaudeUsageUI/Sources/Stores/Services/Clock/ClockProtocol.swift diff --git a/Sources/ClaudeUsageUI/Stores/Services/Clock/SystemClock.swift b/Packages/ClaudeUsageUI/Sources/Stores/Services/Clock/SystemClock.swift similarity index 100% rename from Sources/ClaudeUsageUI/Stores/Services/Clock/SystemClock.swift rename to Packages/ClaudeUsageUI/Sources/Stores/Services/Clock/SystemClock.swift diff --git a/Sources/ClaudeUsageUI/Stores/Services/Clock/TestClock.swift b/Packages/ClaudeUsageUI/Sources/Stores/Services/Clock/TestClock.swift similarity index 100% rename from Sources/ClaudeUsageUI/Stores/Services/Clock/TestClock.swift rename to Packages/ClaudeUsageUI/Sources/Stores/Services/Clock/TestClock.swift diff --git a/Sources/ClaudeUsageUI/Stores/Services/Loading/AppConfiguration.swift b/Packages/ClaudeUsageUI/Sources/Stores/Services/Loading/AppConfiguration.swift similarity index 66% rename from Sources/ClaudeUsageUI/Stores/Services/Loading/AppConfiguration.swift rename to Packages/ClaudeUsageUI/Sources/Stores/Services/Loading/AppConfiguration.swift index 7ea1753..17c3d50 100644 --- a/Sources/ClaudeUsageUI/Stores/Services/Loading/AppConfiguration.swift +++ b/Packages/ClaudeUsageUI/Sources/Stores/Services/Loading/AppConfiguration.swift @@ -5,6 +5,16 @@ import Foundation +// MARK: - Home Directory Helper + +/// Returns the real user home directory, even in sandboxed apps. +/// In sandboxed apps, NSHomeDirectory() returns the container path, +/// but we need the actual user home to access ~/.claude +private func realHomeDirectory() -> String { + guard let pw = getpwuid(getuid()) else { return NSHomeDirectory() } + return String(cString: pw.pointee.pw_dir) +} + // MARK: - Configuration public struct AppConfiguration: Sendable { @@ -14,7 +24,7 @@ public struct AppConfiguration: Sendable { let dailyCostThreshold: Double static let `default` = AppConfiguration( - basePath: NSHomeDirectory() + "/.claude", + basePath: realHomeDirectory() + "/.claude", refreshInterval: 30.0, sessionDurationHours: 5.0, dailyCostThreshold: 10.0 diff --git a/Sources/ClaudeUsageUI/Stores/Services/Loading/LoadTrace.swift b/Packages/ClaudeUsageUI/Sources/Stores/Services/Loading/LoadTrace.swift similarity index 100% rename from Sources/ClaudeUsageUI/Stores/Services/Loading/LoadTrace.swift rename to Packages/ClaudeUsageUI/Sources/Stores/Services/Loading/LoadTrace.swift diff --git a/Sources/ClaudeUsageUI/Stores/Services/Loading/SessionMonitorService.swift b/Packages/ClaudeUsageUI/Sources/Stores/Services/Loading/SessionMonitorService.swift similarity index 100% rename from Sources/ClaudeUsageUI/Stores/Services/Loading/SessionMonitorService.swift rename to Packages/ClaudeUsageUI/Sources/Stores/Services/Loading/SessionMonitorService.swift diff --git a/Sources/ClaudeUsageUI/Stores/Services/Loading/UsageDataLoader.swift b/Packages/ClaudeUsageUI/Sources/Stores/Services/Loading/UsageDataLoader.swift similarity index 100% rename from Sources/ClaudeUsageUI/Stores/Services/Loading/UsageDataLoader.swift rename to Packages/ClaudeUsageUI/Sources/Stores/Services/Loading/UsageDataLoader.swift diff --git a/Sources/ClaudeUsageUI/Stores/Services/RefreshCoordinator.swift b/Packages/ClaudeUsageUI/Sources/Stores/Services/RefreshCoordinator.swift similarity index 94% rename from Sources/ClaudeUsageUI/Stores/Services/RefreshCoordinator.swift rename to Packages/ClaudeUsageUI/Sources/Stores/Services/RefreshCoordinator.swift index 134019d..075130c 100644 --- a/Sources/ClaudeUsageUI/Stores/Services/RefreshCoordinator.swift +++ b/Packages/ClaudeUsageUI/Sources/Stores/Services/RefreshCoordinator.swift @@ -7,6 +7,13 @@ import Foundation import AppKit import ClaudeUsageData +// MARK: - Home Directory Helper + +private func realHomeDirectory() -> String { + guard let pw = getpwuid(getuid()) else { return NSHomeDirectory() } + return String(cString: pw.pointee.pw_dir) +} + // MARK: - Timing Constants private enum Timing { @@ -40,7 +47,7 @@ final class RefreshCoordinator { init( clock: any ClockProtocol = SystemClock(), refreshInterval: TimeInterval, - basePath: String = NSHomeDirectory() + "/.claude" + basePath: String = realHomeDirectory() + "/.claude" ) { self.clock = clock self.lastRefreshTime = clock.now diff --git a/Sources/ClaudeUsageUI/Stores/UsageStore.swift b/Packages/ClaudeUsageUI/Sources/Stores/UsageStore.swift similarity index 100% rename from Sources/ClaudeUsageUI/Stores/UsageStore.swift rename to Packages/ClaudeUsageUI/Sources/Stores/UsageStore.swift diff --git a/Tests/ClaudeUsageTests/HeatmapStoreTests.swift b/Packages/ClaudeUsageUI/Tests/HeatmapStoreTests.swift similarity index 100% rename from Tests/ClaudeUsageTests/HeatmapStoreTests.swift rename to Packages/ClaudeUsageUI/Tests/HeatmapStoreTests.swift diff --git a/Tests/ClaudeUsageTests/UsageDataLoaderTests.swift b/Packages/ClaudeUsageUI/Tests/UsageDataLoaderTests.swift similarity index 100% rename from Tests/ClaudeUsageTests/UsageDataLoaderTests.swift rename to Packages/ClaudeUsageUI/Tests/UsageDataLoaderTests.swift