Admin-Ka macOS 1.0.0 — app native SwiftUI (WKWebView) notarisée, identité Ka
- shell SwiftUI natif macOS enveloppant administration-ka.com (cookie persistant, liens externes → navigateur, panneaux JS natifs pour confirm/bypass) - icône + splash pastille Ka, fenêtre redimensionnable, hardened runtime - signé Developer ID Application + notarisé (notarytool via clé API ASC) + stapled + DMG Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
19 changed files +659 −0
added
.gitignore
+7 −0
@@ -0,0 +1,7 @@ | ||
| 1 | +.DS_Store | |
| 2 | +build/ | |
| 3 | +DerivedData/ | |
| 4 | +dist/ | |
| 5 | +*.xcuserstate | |
| 6 | +xcuserdata/ | |
| 7 | +screenshots/ | |
added
AdminKaMac.xcodeproj/project.pbxproj
+339 −0
@@ -0,0 +1,339 @@ | ||
| 1 | +// !$*UTF8*$! | |
| 2 | +{ | |
| 3 | + archiveVersion = 1; | |
| 4 | + classes = { | |
| 5 | + }; | |
| 6 | + objectVersion = 77; | |
| 7 | + objects = { | |
| 8 | + | |
| 9 | +/* Begin PBXBuildFile section */ | |
| 10 | + 82BA6DA43D75AB5CDF765360 /* AdminKaMacApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1BE00C7998B3AE9281938C8 /* AdminKaMacApp.swift */; }; | |
| 11 | + A2299018D551DE323C453439 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 02C21000306216EFA864AC79 /* Assets.xcassets */; }; | |
| 12 | + AA4AB8779667D82483FAF045 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6A456697E2205919C39C44B /* RootView.swift */; }; | |
| 13 | + AE613712E51ECADC4D983C00 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7EA81E05D09A3B32940539 /* Theme.swift */; }; | |
| 14 | + E574FBC46EA6ED96B8196E1C /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C8E8B6E60526309BC2B9243 /* WebView.swift */; }; | |
| 15 | +/* End PBXBuildFile section */ | |
| 16 | + | |
| 17 | +/* Begin PBXFileReference section */ | |
| 18 | + 02C21000306216EFA864AC79 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; | |
| 19 | + 5D4FBD2391C5AA22EC0D3742 /* AdminKaMac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AdminKaMac.app; sourceTree = BUILT_PRODUCTS_DIR; }; | |
| 20 | + 5E7EA81E05D09A3B32940539 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; }; | |
| 21 | + 8C8E8B6E60526309BC2B9243 /* WebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = "<group>"; }; | |
| 22 | + B00B669430E6EA7BF4185289 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; | |
| 23 | + B1BE00C7998B3AE9281938C8 /* AdminKaMacApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminKaMacApp.swift; sourceTree = "<group>"; }; | |
| 24 | + CA0F4A21CCC1477D4A5A60A6 /* AdminKaMac.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AdminKaMac.entitlements; sourceTree = "<group>"; }; | |
| 25 | + E6A456697E2205919C39C44B /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = "<group>"; }; | |
| 26 | +/* End PBXFileReference section */ | |
| 27 | + | |
| 28 | +/* Begin PBXGroup section */ | |
| 29 | + 250ED03615C8C0848BF90A43 /* Products */ = { | |
| 30 | + isa = PBXGroup; | |
| 31 | + children = ( | |
| 32 | + 5D4FBD2391C5AA22EC0D3742 /* AdminKaMac.app */, | |
| 33 | + ); | |
| 34 | + name = Products; | |
| 35 | + sourceTree = "<group>"; | |
| 36 | + }; | |
| 37 | + 7A72F9E8B22A3A6F48B7CA35 /* Sources */ = { | |
| 38 | + isa = PBXGroup; | |
| 39 | + children = ( | |
| 40 | + CA0F4A21CCC1477D4A5A60A6 /* AdminKaMac.entitlements */, | |
| 41 | + B1BE00C7998B3AE9281938C8 /* AdminKaMacApp.swift */, | |
| 42 | + B00B669430E6EA7BF4185289 /* Info.plist */, | |
| 43 | + E6A456697E2205919C39C44B /* RootView.swift */, | |
| 44 | + 5E7EA81E05D09A3B32940539 /* Theme.swift */, | |
| 45 | + 8C8E8B6E60526309BC2B9243 /* WebView.swift */, | |
| 46 | + ); | |
| 47 | + path = Sources; | |
| 48 | + sourceTree = "<group>"; | |
| 49 | + }; | |
| 50 | + B39C7C2CA1E0D8B5F2EAB354 = { | |
| 51 | + isa = PBXGroup; | |
| 52 | + children = ( | |
| 53 | + E5ABD6EDCFF9EC4DE2BF91C6 /* Resources */, | |
| 54 | + 7A72F9E8B22A3A6F48B7CA35 /* Sources */, | |
| 55 | + 250ED03615C8C0848BF90A43 /* Products */, | |
| 56 | + ); | |
| 57 | + sourceTree = "<group>"; | |
| 58 | + }; | |
| 59 | + E5ABD6EDCFF9EC4DE2BF91C6 /* Resources */ = { | |
| 60 | + isa = PBXGroup; | |
| 61 | + children = ( | |
| 62 | + 02C21000306216EFA864AC79 /* Assets.xcassets */, | |
| 63 | + ); | |
| 64 | + path = Resources; | |
| 65 | + sourceTree = "<group>"; | |
| 66 | + }; | |
| 67 | +/* End PBXGroup section */ | |
| 68 | + | |
| 69 | +/* Begin PBXNativeTarget section */ | |
| 70 | + F9853118CD34A10A9B8E4F90 /* AdminKaMac */ = { | |
| 71 | + isa = PBXNativeTarget; | |
| 72 | + buildConfigurationList = 37792F69F119471FA311BAB8 /* Build configuration list for PBXNativeTarget "AdminKaMac" */; | |
| 73 | + buildPhases = ( | |
| 74 | + 7008F5E82F8952C5A7C036B7 /* Sources */, | |
| 75 | + C2FB09DFDC9F286E4B1ECB79 /* Resources */, | |
| 76 | + ); | |
| 77 | + buildRules = ( | |
| 78 | + ); | |
| 79 | + dependencies = ( | |
| 80 | + ); | |
| 81 | + name = AdminKaMac; | |
| 82 | + packageProductDependencies = ( | |
| 83 | + ); | |
| 84 | + productName = AdminKaMac; | |
| 85 | + productReference = 5D4FBD2391C5AA22EC0D3742 /* AdminKaMac.app */; | |
| 86 | + productType = "com.apple.product-type.application"; | |
| 87 | + }; | |
| 88 | +/* End PBXNativeTarget section */ | |
| 89 | + | |
| 90 | +/* Begin PBXProject section */ | |
| 91 | + FB566ECDA392935EE6C8E20F /* Project object */ = { | |
| 92 | + isa = PBXProject; | |
| 93 | + attributes = { | |
| 94 | + BuildIndependentTargetsInParallel = YES; | |
| 95 | + LastUpgradeCheck = 1430; | |
| 96 | + TargetAttributes = { | |
| 97 | + F9853118CD34A10A9B8E4F90 = { | |
| 98 | + DevelopmentTeam = 3YM54G49SN; | |
| 99 | + ProvisioningStyle = Manual; | |
| 100 | + }; | |
| 101 | + }; | |
| 102 | + }; | |
| 103 | + buildConfigurationList = A6EFFDB2CC27831A956303CB /* Build configuration list for PBXProject "AdminKaMac" */; | |
| 104 | + developmentRegion = en; | |
| 105 | + hasScannedForEncodings = 0; | |
| 106 | + knownRegions = ( | |
| 107 | + Base, | |
| 108 | + en, | |
| 109 | + ); | |
| 110 | + mainGroup = B39C7C2CA1E0D8B5F2EAB354; | |
| 111 | + minimizedProjectReferenceProxies = 1; | |
| 112 | + preferredProjectObjectVersion = 77; | |
| 113 | + productRefGroup = 250ED03615C8C0848BF90A43 /* Products */; | |
| 114 | + projectDirPath = ""; | |
| 115 | + projectRoot = ""; | |
| 116 | + targets = ( | |
| 117 | + F9853118CD34A10A9B8E4F90 /* AdminKaMac */, | |
| 118 | + ); | |
| 119 | + }; | |
| 120 | +/* End PBXProject section */ | |
| 121 | + | |
| 122 | +/* Begin PBXResourcesBuildPhase section */ | |
| 123 | + C2FB09DFDC9F286E4B1ECB79 /* Resources */ = { | |
| 124 | + isa = PBXResourcesBuildPhase; | |
| 125 | + buildActionMask = 2147483647; | |
| 126 | + files = ( | |
| 127 | + A2299018D551DE323C453439 /* Assets.xcassets in Resources */, | |
| 128 | + ); | |
| 129 | + runOnlyForDeploymentPostprocessing = 0; | |
| 130 | + }; | |
| 131 | +/* End PBXResourcesBuildPhase section */ | |
| 132 | + | |
| 133 | +/* Begin PBXSourcesBuildPhase section */ | |
| 134 | + 7008F5E82F8952C5A7C036B7 /* Sources */ = { | |
| 135 | + isa = PBXSourcesBuildPhase; | |
| 136 | + buildActionMask = 2147483647; | |
| 137 | + files = ( | |
| 138 | + 82BA6DA43D75AB5CDF765360 /* AdminKaMacApp.swift in Sources */, | |
| 139 | + AA4AB8779667D82483FAF045 /* RootView.swift in Sources */, | |
| 140 | + AE613712E51ECADC4D983C00 /* Theme.swift in Sources */, | |
| 141 | + E574FBC46EA6ED96B8196E1C /* WebView.swift in Sources */, | |
| 142 | + ); | |
| 143 | + runOnlyForDeploymentPostprocessing = 0; | |
| 144 | + }; | |
| 145 | +/* End PBXSourcesBuildPhase section */ | |
| 146 | + | |
| 147 | +/* Begin XCBuildConfiguration section */ | |
| 148 | + 47C2705EB0F5CFC9CED0406F /* Release */ = { | |
| 149 | + isa = XCBuildConfiguration; | |
| 150 | + buildSettings = { | |
| 151 | + ALWAYS_SEARCH_USER_PATHS = NO; | |
| 152 | + CLANG_ANALYZER_NONNULL = YES; | |
| 153 | + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; | |
| 154 | + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; | |
| 155 | + CLANG_CXX_LIBRARY = "libc++"; | |
| 156 | + CLANG_ENABLE_MODULES = YES; | |
| 157 | + CLANG_ENABLE_OBJC_ARC = YES; | |
| 158 | + CLANG_ENABLE_OBJC_WEAK = YES; | |
| 159 | + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | |
| 160 | + CLANG_WARN_BOOL_CONVERSION = YES; | |
| 161 | + CLANG_WARN_COMMA = YES; | |
| 162 | + CLANG_WARN_CONSTANT_CONVERSION = YES; | |
| 163 | + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | |
| 164 | + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | |
| 165 | + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; | |
| 166 | + CLANG_WARN_EMPTY_BODY = YES; | |
| 167 | + CLANG_WARN_ENUM_CONVERSION = YES; | |
| 168 | + CLANG_WARN_INFINITE_RECURSION = YES; | |
| 169 | + CLANG_WARN_INT_CONVERSION = YES; | |
| 170 | + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | |
| 171 | + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | |
| 172 | + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | |
| 173 | + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | |
| 174 | + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; | |
| 175 | + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | |
| 176 | + CLANG_WARN_STRICT_PROTOTYPES = YES; | |
| 177 | + CLANG_WARN_SUSPICIOUS_MOVE = YES; | |
| 178 | + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; | |
| 179 | + CLANG_WARN_UNREACHABLE_CODE = YES; | |
| 180 | + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | |
| 181 | + COPY_PHASE_STRIP = NO; | |
| 182 | + CURRENT_PROJECT_VERSION = 1; | |
| 183 | + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; | |
| 184 | + DEVELOPMENT_TEAM = 3YM54G49SN; | |
| 185 | + ENABLE_NS_ASSERTIONS = NO; | |
| 186 | + ENABLE_STRICT_OBJC_MSGSEND = YES; | |
| 187 | + GCC_C_LANGUAGE_STANDARD = gnu11; | |
| 188 | + GCC_NO_COMMON_BLOCKS = YES; | |
| 189 | + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | |
| 190 | + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | |
| 191 | + GCC_WARN_UNDECLARED_SELECTOR = YES; | |
| 192 | + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | |
| 193 | + GCC_WARN_UNUSED_FUNCTION = YES; | |
| 194 | + GCC_WARN_UNUSED_VARIABLE = YES; | |
| 195 | + MACOSX_DEPLOYMENT_TARGET = 13.0; | |
| 196 | + MARKETING_VERSION = 1.0.0; | |
| 197 | + MTL_ENABLE_DEBUG_INFO = NO; | |
| 198 | + MTL_FAST_MATH = YES; | |
| 199 | + PRODUCT_NAME = "$(TARGET_NAME)"; | |
| 200 | + SDKROOT = macosx; | |
| 201 | + SWIFT_COMPILATION_MODE = wholemodule; | |
| 202 | + SWIFT_OPTIMIZATION_LEVEL = "-O"; | |
| 203 | + SWIFT_VERSION = 5.0; | |
| 204 | + }; | |
| 205 | + name = Release; | |
| 206 | + }; | |
| 207 | + 9F641E359B9E74716ED4B9E5 /* Release */ = { | |
| 208 | + isa = XCBuildConfiguration; | |
| 209 | + buildSettings = { | |
| 210 | + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | |
| 211 | + CODE_SIGN_ENTITLEMENTS = Sources/AdminKaMac.entitlements; | |
| 212 | + CODE_SIGN_IDENTITY = "Developer ID Application"; | |
| 213 | + CODE_SIGN_STYLE = Manual; | |
| 214 | + COMBINE_HIDPI_IMAGES = YES; | |
| 215 | + ENABLE_HARDENED_RUNTIME = YES; | |
| 216 | + INFOPLIST_FILE = Sources/Info.plist; | |
| 217 | + LD_RUNPATH_SEARCH_PATHS = ( | |
| 218 | + "$(inherited)", | |
| 219 | + "@executable_path/../Frameworks", | |
| 220 | + ); | |
| 221 | + MACOSX_DEPLOYMENT_TARGET = 13.0; | |
| 222 | + PRODUCT_BUNDLE_IDENTIFIER = com.groupeka.adminkamac; | |
| 223 | + PRODUCT_NAME = "Admin-Ka"; | |
| 224 | + SDKROOT = macosx; | |
| 225 | + }; | |
| 226 | + name = Release; | |
| 227 | + }; | |
| 228 | + CA399800D52E645C7E657403 /* Debug */ = { | |
| 229 | + isa = XCBuildConfiguration; | |
| 230 | + buildSettings = { | |
| 231 | + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | |
| 232 | + CODE_SIGN_ENTITLEMENTS = Sources/AdminKaMac.entitlements; | |
| 233 | + CODE_SIGN_IDENTITY = "Developer ID Application"; | |
| 234 | + CODE_SIGN_STYLE = Manual; | |
| 235 | + COMBINE_HIDPI_IMAGES = YES; | |
| 236 | + ENABLE_HARDENED_RUNTIME = YES; | |
| 237 | + INFOPLIST_FILE = Sources/Info.plist; | |
| 238 | + LD_RUNPATH_SEARCH_PATHS = ( | |
| 239 | + "$(inherited)", | |
| 240 | + "@executable_path/../Frameworks", | |
| 241 | + ); | |
| 242 | + MACOSX_DEPLOYMENT_TARGET = 13.0; | |
| 243 | + PRODUCT_BUNDLE_IDENTIFIER = com.groupeka.adminkamac; | |
| 244 | + PRODUCT_NAME = "Admin-Ka"; | |
| 245 | + SDKROOT = macosx; | |
| 246 | + }; | |
| 247 | + name = Debug; | |
| 248 | + }; | |
| 249 | + E5F59090737C7E513CCF4FB1 /* Debug */ = { | |
| 250 | + isa = XCBuildConfiguration; | |
| 251 | + buildSettings = { | |
| 252 | + ALWAYS_SEARCH_USER_PATHS = NO; | |
| 253 | + CLANG_ANALYZER_NONNULL = YES; | |
| 254 | + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; | |
| 255 | + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; | |
| 256 | + CLANG_CXX_LIBRARY = "libc++"; | |
| 257 | + CLANG_ENABLE_MODULES = YES; | |
| 258 | + CLANG_ENABLE_OBJC_ARC = YES; | |
| 259 | + CLANG_ENABLE_OBJC_WEAK = YES; | |
| 260 | + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | |
| 261 | + CLANG_WARN_BOOL_CONVERSION = YES; | |
| 262 | + CLANG_WARN_COMMA = YES; | |
| 263 | + CLANG_WARN_CONSTANT_CONVERSION = YES; | |
| 264 | + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | |
| 265 | + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | |
| 266 | + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; | |
| 267 | + CLANG_WARN_EMPTY_BODY = YES; | |
| 268 | + CLANG_WARN_ENUM_CONVERSION = YES; | |
| 269 | + CLANG_WARN_INFINITE_RECURSION = YES; | |
| 270 | + CLANG_WARN_INT_CONVERSION = YES; | |
| 271 | + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | |
| 272 | + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | |
| 273 | + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | |
| 274 | + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | |
| 275 | + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; | |
| 276 | + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | |
| 277 | + CLANG_WARN_STRICT_PROTOTYPES = YES; | |
| 278 | + CLANG_WARN_SUSPICIOUS_MOVE = YES; | |
| 279 | + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; | |
| 280 | + CLANG_WARN_UNREACHABLE_CODE = YES; | |
| 281 | + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | |
| 282 | + COPY_PHASE_STRIP = NO; | |
| 283 | + CURRENT_PROJECT_VERSION = 1; | |
| 284 | + DEBUG_INFORMATION_FORMAT = dwarf; | |
| 285 | + DEVELOPMENT_TEAM = 3YM54G49SN; | |
| 286 | + ENABLE_STRICT_OBJC_MSGSEND = YES; | |
| 287 | + ENABLE_TESTABILITY = YES; | |
| 288 | + GCC_C_LANGUAGE_STANDARD = gnu11; | |
| 289 | + GCC_DYNAMIC_NO_PIC = NO; | |
| 290 | + GCC_NO_COMMON_BLOCKS = YES; | |
| 291 | + GCC_OPTIMIZATION_LEVEL = 0; | |
| 292 | + GCC_PREPROCESSOR_DEFINITIONS = ( | |
| 293 | + "$(inherited)", | |
| 294 | + "DEBUG=1", | |
| 295 | + ); | |
| 296 | + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | |
| 297 | + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | |
| 298 | + GCC_WARN_UNDECLARED_SELECTOR = YES; | |
| 299 | + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | |
| 300 | + GCC_WARN_UNUSED_FUNCTION = YES; | |
| 301 | + GCC_WARN_UNUSED_VARIABLE = YES; | |
| 302 | + MACOSX_DEPLOYMENT_TARGET = 13.0; | |
| 303 | + MARKETING_VERSION = 1.0.0; | |
| 304 | + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; | |
| 305 | + MTL_FAST_MATH = YES; | |
| 306 | + ONLY_ACTIVE_ARCH = YES; | |
| 307 | + PRODUCT_NAME = "$(TARGET_NAME)"; | |
| 308 | + SDKROOT = macosx; | |
| 309 | + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; | |
| 310 | + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; | |
| 311 | + SWIFT_VERSION = 5.0; | |
| 312 | + }; | |
| 313 | + name = Debug; | |
| 314 | + }; | |
| 315 | +/* End XCBuildConfiguration section */ | |
| 316 | + | |
| 317 | +/* Begin XCConfigurationList section */ | |
| 318 | + 37792F69F119471FA311BAB8 /* Build configuration list for PBXNativeTarget "AdminKaMac" */ = { | |
| 319 | + isa = XCConfigurationList; | |
| 320 | + buildConfigurations = ( | |
| 321 | + CA399800D52E645C7E657403 /* Debug */, | |
| 322 | + 9F641E359B9E74716ED4B9E5 /* Release */, | |
| 323 | + ); | |
| 324 | + defaultConfigurationIsVisible = 0; | |
| 325 | + defaultConfigurationName = Debug; | |
| 326 | + }; | |
| 327 | + A6EFFDB2CC27831A956303CB /* Build configuration list for PBXProject "AdminKaMac" */ = { | |
| 328 | + isa = XCConfigurationList; | |
| 329 | + buildConfigurations = ( | |
| 330 | + E5F59090737C7E513CCF4FB1 /* Debug */, | |
| 331 | + 47C2705EB0F5CFC9CED0406F /* Release */, | |
| 332 | + ); | |
| 333 | + defaultConfigurationIsVisible = 0; | |
| 334 | + defaultConfigurationName = Debug; | |
| 335 | + }; | |
| 336 | +/* End XCConfigurationList section */ | |
| 337 | + }; | |
| 338 | + rootObject = FB566ECDA392935EE6C8E20F /* Project object */; | |
| 339 | +} | |
added
AdminKaMac.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+7 −0
@@ -0,0 +1,7 @@ | ||
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<Workspace | |
| 3 | + version = "1.0"> | |
| 4 | + <FileRef | |
| 5 | + location = "self:"> | |
| 6 | + </FileRef> | |
| 7 | +</Workspace> | |
added
Resources/Assets.xcassets/AppIcon.appiconset/Contents.json
+15 −0
@@ -0,0 +1,15 @@ | ||
| 1 | +{ | |
| 2 | + "images" : [ | |
| 3 | + {"idiom":"mac","scale":"1x","size":"16x16","filename":"icon_16.png"}, | |
| 4 | + {"idiom":"mac","scale":"2x","size":"16x16","filename":"icon_32.png"}, | |
| 5 | + {"idiom":"mac","scale":"1x","size":"32x32","filename":"icon_32.png"}, | |
| 6 | + {"idiom":"mac","scale":"2x","size":"32x32","filename":"icon_64.png"}, | |
| 7 | + {"idiom":"mac","scale":"1x","size":"128x128","filename":"icon_128.png"}, | |
| 8 | + {"idiom":"mac","scale":"2x","size":"128x128","filename":"icon_256.png"}, | |
| 9 | + {"idiom":"mac","scale":"1x","size":"256x256","filename":"icon_256.png"}, | |
| 10 | + {"idiom":"mac","scale":"2x","size":"256x256","filename":"icon_512.png"}, | |
| 11 | + {"idiom":"mac","scale":"1x","size":"512x512","filename":"icon_512.png"}, | |
| 12 | + {"idiom":"mac","scale":"2x","size":"512x512","filename":"icon_1024.png"} | |
| 13 | + ], | |
| 14 | + "info" : { "author" : "xcode", "version" : 1 } | |
| 15 | +} | |
added
Resources/Assets.xcassets/AppIcon.appiconset/icon_1024.png
+0 −0
Binary file not shown.
added
Resources/Assets.xcassets/AppIcon.appiconset/icon_128.png
+0 −0
Binary file not shown.
added
Resources/Assets.xcassets/AppIcon.appiconset/icon_16.png
+0 −0
Binary file not shown.
added
Resources/Assets.xcassets/AppIcon.appiconset/icon_256.png
+0 −0
Binary file not shown.
added
Resources/Assets.xcassets/AppIcon.appiconset/icon_32.png
+0 −0
Binary file not shown.
added
Resources/Assets.xcassets/AppIcon.appiconset/icon_512.png
+0 −0
Binary file not shown.
added
Resources/Assets.xcassets/AppIcon.appiconset/icon_64.png
+0 −0
Binary file not shown.
added
Resources/Assets.xcassets/Contents.json
+1 −0
@@ -0,0 +1 @@ | ||
| 1 | +{ "info" : { "author" : "xcode", "version" : 1 } } | |
added
Sources/AdminKaMac.entitlements
+6 −0
@@ -0,0 +1,6 @@ | ||
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
| 3 | +<plist version="1.0"><dict> | |
| 4 | + <key>com.apple.security.app-sandbox</key><false/> | |
| 5 | + <key>com.apple.security.network.client</key><true/> | |
| 6 | +</dict></plist> | |
added
Sources/AdminKaMacApp.swift
+14 −0
@@ -0,0 +1,14 @@ | ||
| 1 | +import SwiftUI | |
| 2 | + | |
| 3 | +@main | |
| 4 | +struct AdminKaMacApp: App { | |
| 5 | + var body: some Scene { | |
| 6 | + WindowGroup { | |
| 7 | + RootView() | |
| 8 | + .frame(minWidth: 420, idealWidth: 520, maxWidth: .infinity, | |
| 9 | + minHeight: 640, idealHeight: 860, maxHeight: .infinity) | |
| 10 | + } | |
| 11 | + .windowResizability(.contentSize) | |
| 12 | + .commands { CommandGroup(replacing: .newItem) {} } | |
| 13 | + } | |
| 14 | +} | |
added
Sources/Info.plist
+33 −0
@@ -0,0 +1,33 @@ | ||
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
| 3 | +<plist version="1.0"> | |
| 4 | +<dict> | |
| 5 | + <key>CFBundleDevelopmentRegion</key> | |
| 6 | + <string>$(DEVELOPMENT_LANGUAGE)</string> | |
| 7 | + <key>CFBundleDisplayName</key> | |
| 8 | + <string>Admin-Ka</string> | |
| 9 | + <key>CFBundleExecutable</key> | |
| 10 | + <string>$(EXECUTABLE_NAME)</string> | |
| 11 | + <key>CFBundleIdentifier</key> | |
| 12 | + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | |
| 13 | + <key>CFBundleInfoDictionaryVersion</key> | |
| 14 | + <string>6.0</string> | |
| 15 | + <key>CFBundleName</key> | |
| 16 | + <string>$(PRODUCT_NAME)</string> | |
| 17 | + <key>CFBundlePackageType</key> | |
| 18 | + <string>APPL</string> | |
| 19 | + <key>CFBundleShortVersionString</key> | |
| 20 | + <string>1.0.0</string> | |
| 21 | + <key>CFBundleVersion</key> | |
| 22 | + <string>1</string> | |
| 23 | + <key>LSMinimumSystemVersion</key> | |
| 24 | + <string>13.0</string> | |
| 25 | + <key>NSAppTransportSecurity</key> | |
| 26 | + <dict> | |
| 27 | + <key>NSAllowsArbitraryLoads</key> | |
| 28 | + <false/> | |
| 29 | + </dict> | |
| 30 | + <key>NSHumanReadableCopyright</key> | |
| 31 | + <string>© 2026 Simon-Pierre Boucher — Groupe KA</string> | |
| 32 | +</dict> | |
| 33 | +</plist> | |
added
Sources/RootView.swift
+65 −0
@@ -0,0 +1,65 @@ | ||
| 1 | +import SwiftUI | |
| 2 | + | |
| 3 | +struct RootView: View { | |
| 4 | + @StateObject private var model = WebModel() | |
| 5 | + @State private var showSplash = true | |
| 6 | + | |
| 7 | + var body: some View { | |
| 8 | + ZStack { | |
| 9 | + Ka.bg.ignoresSafeArea() | |
| 10 | + WebView(model: model).opacity(model.loaded ? 1 : 0) | |
| 11 | + | |
| 12 | + if !model.loaded && !model.failed { | |
| 13 | + VStack(spacing: 0) { | |
| 14 | + GeometryReader { geo in | |
| 15 | + Rectangle().fill(Ka.orange) | |
| 16 | + .frame(width: geo.size.width * max(0.04, model.progress), height: 3) | |
| 17 | + .animation(.easeOut(duration: 0.25), value: model.progress) | |
| 18 | + }.frame(height: 3) | |
| 19 | + Spacer() | |
| 20 | + } | |
| 21 | + } | |
| 22 | + if showSplash { splash.transition(.opacity) } | |
| 23 | + if model.failed { offline } | |
| 24 | + } | |
| 25 | + .onChange(of: model.loaded) { loaded in | |
| 26 | + if loaded { | |
| 27 | + DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { | |
| 28 | + withAnimation(.easeInOut(duration: 0.4)) { showSplash = false } | |
| 29 | + } | |
| 30 | + } | |
| 31 | + } | |
| 32 | + } | |
| 33 | + | |
| 34 | + private var splash: some View { | |
| 35 | + ZStack { | |
| 36 | + Ka.bg.ignoresSafeArea() | |
| 37 | + VStack(spacing: 16) { | |
| 38 | + KaMark(size: 88) | |
| 39 | + Text("Admin-Ka").font(.system(size: 24, weight: .heavy, design: .rounded)).foregroundColor(Ka.ink) | |
| 40 | + Text("Console Claude Code · Groupe KA") | |
| 41 | + .font(.system(size: 13, weight: .semibold, design: .rounded)).foregroundColor(Ka.muted) | |
| 42 | + if !model.failed { ProgressView().controlSize(.small).padding(.top, 4) } | |
| 43 | + } | |
| 44 | + } | |
| 45 | + } | |
| 46 | + | |
| 47 | + private var offline: some View { | |
| 48 | + ZStack { | |
| 49 | + Ka.bg.ignoresSafeArea() | |
| 50 | + VStack(spacing: 14) { | |
| 51 | + KaMark(size: 68) | |
| 52 | + Text("Hors ligne").font(.system(size: 20, weight: .heavy, design: .rounded)).foregroundColor(Ka.ink) | |
| 53 | + Text("Impossible de joindre administration-ka.com") | |
| 54 | + .font(.system(size: 13, weight: .medium, design: .rounded)).foregroundColor(Ka.muted) | |
| 55 | + Button { | |
| 56 | + showSplash = true; model.reload() | |
| 57 | + } label: { | |
| 58 | + Text("Réessayer").font(.system(size: 14, weight: .heavy, design: .rounded)) | |
| 59 | + .foregroundColor(Ka.ink).padding(.horizontal, 22).padding(.vertical, 10) | |
| 60 | + .background(Capsule().fill(Ka.orange).overlay(Capsule().strokeBorder(Ka.ink, lineWidth: 2))) | |
| 61 | + }.buttonStyle(.plain).padding(.top, 4) | |
| 62 | + } | |
| 63 | + } | |
| 64 | + } | |
| 65 | +} | |
added
Sources/Theme.swift
+34 −0
@@ -0,0 +1,34 @@ | ||
| 1 | +import SwiftUI | |
| 2 | + | |
| 3 | +enum Ka { | |
| 4 | + static let bg = Color(hex: 0xF2F1EC) | |
| 5 | + static let card = Color(hex: 0xFCFBF8) | |
| 6 | + static let ink = Color(hex: 0x1A1611) | |
| 7 | + static let orange = Color(hex: 0xF97316) | |
| 8 | + static let muted = Color(hex: 0x6D675C) | |
| 9 | + static let url = URL(string: "https://www.administration-ka.com")! | |
| 10 | +} | |
| 11 | + | |
| 12 | +extension Color { | |
| 13 | + init(hex: UInt, alpha: Double = 1) { | |
| 14 | + self.init(.sRGB, | |
| 15 | + red: Double((hex >> 16) & 0xff) / 255, | |
| 16 | + green: Double((hex >> 8) & 0xff) / 255, | |
| 17 | + blue: Double(hex & 0xff) / 255, | |
| 18 | + opacity: alpha) | |
| 19 | + } | |
| 20 | +} | |
| 21 | + | |
| 22 | +struct KaMark: View { | |
| 23 | + var size: CGFloat = 84 | |
| 24 | + var body: some View { | |
| 25 | + RoundedRectangle(cornerRadius: size * 0.28, style: .continuous) | |
| 26 | + .fill(Ka.orange) | |
| 27 | + .overlay(RoundedRectangle(cornerRadius: size * 0.28, style: .continuous) | |
| 28 | + .strokeBorder(Ka.ink, lineWidth: max(2, size * 0.035))) | |
| 29 | + .overlay(Text("Ka") | |
| 30 | + .font(.system(size: size * 0.42, weight: .heavy, design: .rounded)) | |
| 31 | + .foregroundColor(Ka.ink)) | |
| 32 | + .frame(width: size, height: size) | |
| 33 | + } | |
| 34 | +} | |
added
Sources/WebView.swift
+98 −0
@@ -0,0 +1,98 @@ | ||
| 1 | +import SwiftUI | |
| 2 | +import WebKit | |
| 3 | +import AppKit | |
| 4 | + | |
| 5 | +final class WebModel: ObservableObject { | |
| 6 | + @Published var progress: Double = 0 | |
| 7 | + @Published var loaded = false | |
| 8 | + @Published var failed = false | |
| 9 | + var webView: WKWebView? | |
| 10 | + func reload() { | |
| 11 | + failed = false; loaded = false; progress = 0 | |
| 12 | + if let wv = webView { if wv.url == nil { wv.load(URLRequest(url: Ka.url)) } else { wv.reload() } } | |
| 13 | + } | |
| 14 | +} | |
| 15 | + | |
| 16 | +struct WebView: NSViewRepresentable { | |
| 17 | + @ObservedObject var model: WebModel | |
| 18 | + | |
| 19 | + func makeCoordinator() -> Coordinator { Coordinator(model: model) } | |
| 20 | + | |
| 21 | + func makeNSView(context: Context) -> WKWebView { | |
| 22 | + let cfg = WKWebViewConfiguration() | |
| 23 | + cfg.websiteDataStore = .default() // cookie de session persistant | |
| 24 | + cfg.defaultWebpagePreferences.allowsContentJavaScript = true | |
| 25 | + let wv = WKWebView(frame: .zero, configuration: cfg) | |
| 26 | + wv.navigationDelegate = context.coordinator | |
| 27 | + wv.uiDelegate = context.coordinator | |
| 28 | + wv.setValue(false, forKey: "drawsBackground") // fond transparent → crème | |
| 29 | + wv.customUserAgent = "AdminKa-macOS/1.0 (Groupe KA console)" | |
| 30 | + context.coordinator.observe(wv) | |
| 31 | + model.webView = wv | |
| 32 | + wv.load(URLRequest(url: Ka.url)) | |
| 33 | + return wv | |
| 34 | + } | |
| 35 | + | |
| 36 | + func updateNSView(_ nsView: WKWebView, context: Context) {} | |
| 37 | + | |
| 38 | + final class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate { | |
| 39 | + let model: WebModel | |
| 40 | + private var obs: NSKeyValueObservation? | |
| 41 | + init(model: WebModel) { self.model = model } | |
| 42 | + | |
| 43 | + func observe(_ wv: WKWebView) { | |
| 44 | + obs = wv.observe(\.estimatedProgress, options: [.new]) { [weak self] wv, _ in | |
| 45 | + DispatchQueue.main.async { self?.model.progress = wv.estimatedProgress } | |
| 46 | + } | |
| 47 | + } | |
| 48 | + func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { | |
| 49 | + DispatchQueue.main.async { | |
| 50 | + withAnimation(.easeOut(duration: 0.35)) { self.model.loaded = true } | |
| 51 | + self.model.failed = false | |
| 52 | + } | |
| 53 | + } | |
| 54 | + func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { fail(error) } | |
| 55 | + func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { fail(error) } | |
| 56 | + private func fail(_ error: Error) { | |
| 57 | + if (error as NSError).code == NSURLErrorCancelled { return } | |
| 58 | + DispatchQueue.main.async { self.model.failed = true } | |
| 59 | + } | |
| 60 | + | |
| 61 | + // liens externes → navigateur par défaut | |
| 62 | + func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, | |
| 63 | + decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { | |
| 64 | + if let url = navigationAction.request.url, let host = url.host, | |
| 65 | + navigationAction.navigationType == .linkActivated, host != Ka.url.host { | |
| 66 | + NSWorkspace.shared.open(url); decisionHandler(.cancel); return | |
| 67 | + } | |
| 68 | + decisionHandler(.allow) | |
| 69 | + } | |
| 70 | + func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, | |
| 71 | + for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { | |
| 72 | + if let url = navigationAction.request.url { NSWorkspace.shared.open(url) } | |
| 73 | + return nil | |
| 74 | + } | |
| 75 | + | |
| 76 | + // --- Panneaux JS natifs (confirm() indispensable pour le mode BYPASS) --- | |
| 77 | + func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, | |
| 78 | + initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) { | |
| 79 | + let a = NSAlert(); a.messageText = "Admin-Ka"; a.informativeText = message; a.addButton(withTitle: "OK") | |
| 80 | + a.runModal(); completionHandler() | |
| 81 | + } | |
| 82 | + func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, | |
| 83 | + initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) { | |
| 84 | + let a = NSAlert(); a.messageText = "Admin-Ka"; a.informativeText = message | |
| 85 | + a.addButton(withTitle: "OK"); a.addButton(withTitle: "Annuler") | |
| 86 | + completionHandler(a.runModal() == .alertFirstButtonReturn) | |
| 87 | + } | |
| 88 | + func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, | |
| 89 | + defaultText: String?, initiatedByFrame frame: WKFrameInfo, | |
| 90 | + completionHandler: @escaping (String?) -> Void) { | |
| 91 | + let a = NSAlert(); a.messageText = "Admin-Ka"; a.informativeText = prompt | |
| 92 | + a.addButton(withTitle: "OK"); a.addButton(withTitle: "Annuler") | |
| 93 | + let tf = NSTextField(frame: NSRect(x: 0, y: 0, width: 260, height: 24)); tf.stringValue = defaultText ?? "" | |
| 94 | + a.accessoryView = tf | |
| 95 | + completionHandler(a.runModal() == .alertFirstButtonReturn ? tf.stringValue : nil) | |
| 96 | + } | |
| 97 | + } | |
| 98 | +} | |
added
project.yml
+40 −0
@@ -0,0 +1,40 @@ | ||
| 1 | +name: AdminKaMac | |
| 2 | +options: | |
| 3 | + bundleIdPrefix: com.groupeka | |
| 4 | + deploymentTarget: | |
| 5 | + macOS: "13.0" | |
| 6 | + createIntermediateGroups: true | |
| 7 | +settings: | |
| 8 | + base: | |
| 9 | + MARKETING_VERSION: "1.0.0" | |
| 10 | + CURRENT_PROJECT_VERSION: "1" | |
| 11 | + DEVELOPMENT_TEAM: "3YM54G49SN" | |
| 12 | + SWIFT_VERSION: "5.0" | |
| 13 | +targets: | |
| 14 | + AdminKaMac: | |
| 15 | + type: application | |
| 16 | + platform: macOS | |
| 17 | + sources: | |
| 18 | + - Sources | |
| 19 | + - Resources | |
| 20 | + info: | |
| 21 | + path: Sources/Info.plist | |
| 22 | + properties: | |
| 23 | + CFBundleDisplayName: Admin-Ka | |
| 24 | + CFBundleShortVersionString: "1.0.0" | |
| 25 | + CFBundleVersion: "1" | |
| 26 | + LSMinimumSystemVersion: "13.0" | |
| 27 | + NSHumanReadableCopyright: "© 2026 Simon-Pierre Boucher — Groupe KA" | |
| 28 | + NSAppTransportSecurity: | |
| 29 | + NSAllowsArbitraryLoads: false | |
| 30 | + settings: | |
| 31 | + base: | |
| 32 | + PRODUCT_BUNDLE_IDENTIFIER: com.groupeka.adminkamac | |
| 33 | + PRODUCT_NAME: Admin-Ka | |
| 34 | + ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon | |
| 35 | + ENABLE_HARDENED_RUNTIME: "YES" | |
| 36 | + CODE_SIGN_STYLE: Manual | |
| 37 | + CODE_SIGN_IDENTITY: "Developer ID Application" | |
| 38 | + COMBINE_HIDPI_IMAGES: "YES" | |
| 39 | + MACOSX_DEPLOYMENT_TARGET: "13.0" | |
| 40 | + CODE_SIGN_ENTITLEMENTS: Sources/AdminKaMac.entitlements | |
| 41 | ||