mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 10:36:35 +00:00
M2 follow-up: Citadel 0.12.1 (current), pre-built Assets.xcassets
Two follow-ups per review:
## Citadel: current stable
Citadel is at 0.12.1, not 0.9.x as I'd been writing against. Bumped
the pin from `from: "0.7.0"` to `.upToNextMinor(from: "0.12.0")`
— tight because Citadel's pre-1.0 authentication-method variants
have shifted between minor releases (0.7 → 0.9 → 0.12), so
explicit bump-and-review is safer than letting the version float.
Downloaded Citadel 0.12.1's source and verified every API call in
CitadelSSHService against it:
- SSHAuthenticationMethod.ed25519(username:, privateKey:) ✓
- SSHClientSettings(host:, authenticationMethod:, hostKeyValidator:) ✓
- SSHHostKeyValidator.acceptAnything() ✓
- SSHClient.connect(to: settings) ✓
- client.executeCommand(_:) -> ByteBuffer ✓
- client.close() async throws ✓
Dropped the "FIXME — may need adjustment" disclaimer in the file
header; replaced with a "verified against 0.12.1" note that says
re-verify if the pin bumps to 0.13+. Same change in SETUP.md
troubleshooting.
## Assets.xcassets (app icon + accent color)
scarf/scarf-ios/Assets.xcassets/ now exists with:
- AppIcon.appiconset/
AppIcon-1024.png (1024×1024, copied from the Mac app's
icon set — same art)
Contents.json (idiom: universal, platform: ios,
size: 1024x1024 — iOS 14+ renders all
smaller sizes from this automatically)
- AccentColor.colorset/
Contents.json (Scarf teal: sRGB 0.227/0.525/0.722
light, 0.400/0.690/0.902 dark)
- Contents.json (root, empty — just version metadata)
SETUP.md updated:
- Instructs Alan to delete Xcode's scaffolded Assets.xcassets AND
import ours, not the other way around.
- Notes the accent color values so a different palette choice is
a one-file edit.
- Removes the obsolete "drop your icon asset" step.
No functional code changes; tests still 88/88 on Linux.
https://claude.ai/code/session_019yMRP6mwZWfzVrPTqevx2y
This commit is contained in:
@@ -32,11 +32,15 @@ let package = Package(
|
|||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.package(path: "../ScarfCore"),
|
.package(path: "../ScarfCore"),
|
||||||
// Pinned to the 0.7 minor line until the API stabilizes at 1.0.
|
// Pinned tight to the 0.12 minor line. Citadel pre-1.0 has
|
||||||
// When we bump, re-run onboarding smoke tests against at least:
|
// changed its authentication-method variant names between
|
||||||
|
// minor versions (0.7 → 0.9 → 0.12) — letting the version
|
||||||
|
// float to 0.13+ without a code review risks a silent build
|
||||||
|
// break in `CitadelSSHService.buildClientSettings(...)`. When
|
||||||
|
// bumping the minor, smoke test onboarding against:
|
||||||
// (a) a real host with 1Password SSH agent
|
// (a) a real host with 1Password SSH agent
|
||||||
// (b) a real host with a hand-edited `authorized_keys`
|
// (b) a real host with a hand-edited `authorized_keys`
|
||||||
.package(url: "https://github.com/orlandos-nl/Citadel", from: "0.7.0"),
|
.package(url: "https://github.com/orlandos-nl/Citadel", .upToNextMinor(from: "0.12.0")),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
|
|||||||
@@ -20,14 +20,15 @@ import ScarfCore
|
|||||||
/// (file transport, SQLite snapshot pulls, ACP channel) will
|
/// (file transport, SQLite snapshot pulls, ACP channel) will
|
||||||
/// layer on top.
|
/// layer on top.
|
||||||
///
|
///
|
||||||
/// **Citadel API disclaimer.** Citadel 0.9's exact authentication-
|
/// **Citadel 0.12.1 API verified.** Every call below (`SSHAuthentication
|
||||||
/// method spelling for Ed25519 private keys is evolving across
|
/// Method.ed25519(username:privateKey:)`, `SSHClientSettings(host:
|
||||||
/// 0.7 → 0.9. The `runOneShotProbe(...)` helper below is written
|
/// authenticationMethod:hostKeyValidator:)`, `SSHHostKeyValidator.
|
||||||
/// against the documented `SSHClientSettings` + `.privateKey(...)`
|
/// acceptAnything()`, `SSHClient.connect(to:)`, `client.executeCommand
|
||||||
/// pattern; if Citadel has renamed or refactored that variant,
|
/// (_:)`, `client.close()`) was cross-checked against the 0.12.1 tag in
|
||||||
/// adjust `buildClientSettings(...)` — everything else (the retry
|
/// April 2026. If Citadel's package pin is bumped to a new minor
|
||||||
/// loop, the error classification, the exit-code handling) is
|
/// (0.13+), re-verify these against
|
||||||
/// Citadel-version-independent.
|
/// `Sources/Citadel/SSHAuthenticationMethod.swift` and
|
||||||
|
/// `Sources/Citadel/ClientSession.swift` in the new release.
|
||||||
public struct CitadelSSHService: SSHConnectionTester {
|
public struct CitadelSSHService: SSHConnectionTester {
|
||||||
/// Seconds to wait for the probe exec. Set tight so onboarding
|
/// Seconds to wait for the probe exec. Set tight so onboarding
|
||||||
/// doesn't hang on a silently-dropped connection.
|
/// doesn't hang on a silently-dropped connection.
|
||||||
@@ -116,15 +117,10 @@ public struct CitadelSSHService: SSHConnectionTester {
|
|||||||
// MARK: - Citadel glue
|
// MARK: - Citadel glue
|
||||||
|
|
||||||
/// Translate our in-house `SSHKeyBundle` (raw 32+32 byte Ed25519)
|
/// Translate our in-house `SSHKeyBundle` (raw 32+32 byte Ed25519)
|
||||||
/// into Citadel's authentication method.
|
/// into Citadel's authentication method. Verified against Citadel
|
||||||
///
|
/// 0.12.1 — see `Sources/Citadel/SSHAuthenticationMethod.swift`
|
||||||
/// **FIXME when updating Citadel.** The exact function name below
|
/// for the full set of `.passwordBased(...)` / `.ed25519(...)` /
|
||||||
/// is my best read of Citadel 0.7–0.9's API surface — private-key
|
/// `.p256(...)` / etc. variants.
|
||||||
/// auth has gone through several iterations. If the build fails
|
|
||||||
/// here with "no member `ed25519`" or similar, check the current
|
|
||||||
/// `SSHAuthenticationMethod.swift` in the pinned Citadel version
|
|
||||||
/// and adjust. Everything else (key decode, error classification,
|
|
||||||
/// timeout) is independent.
|
|
||||||
private func buildClientSettings(
|
private func buildClientSettings(
|
||||||
config: IOSServerConfig,
|
config: IOSServerConfig,
|
||||||
key: SSHKeyBundle
|
key: SSHKeyBundle
|
||||||
@@ -138,9 +134,6 @@ public struct CitadelSSHService: SSHConnectionTester {
|
|||||||
throw SSHConnectionTestError.other("Stored private key is malformed")
|
throw SSHConnectionTestError.other("Stored private key is malformed")
|
||||||
}
|
}
|
||||||
let username = config.user ?? "root"
|
let username = config.user ?? "root"
|
||||||
// See FIXME above — the `.ed25519(...)` method name is the
|
|
||||||
// shape I expect based on Citadel 0.7–0.9 docs; double-check
|
|
||||||
// on Mac once the pod is resolved.
|
|
||||||
let auth: SSHAuthenticationMethod = .ed25519(
|
let auth: SSHAuthenticationMethod = .ed25519(
|
||||||
username: username,
|
username: username,
|
||||||
privateKey: ck
|
privateKey: ck
|
||||||
|
|||||||
@@ -487,7 +487,10 @@ minutes.
|
|||||||
|
|
||||||
**Shipped — new `Packages/ScarfIOS` local SPM package:**
|
**Shipped — new `Packages/ScarfIOS` local SPM package:**
|
||||||
|
|
||||||
- Depends on local ScarfCore + remote Citadel (`from: "0.7.0"`).
|
- Depends on local ScarfCore + remote Citadel
|
||||||
|
(`.upToNextMinor(from: "0.12.0")` — tight pin because Citadel's
|
||||||
|
pre-1.0 authentication-method variant names have changed between
|
||||||
|
minors; explicit bump → review → smoke-test is the flow).
|
||||||
- `KeychainSSHKeyStore.swift` — real iOS Keychain impl
|
- `KeychainSSHKeyStore.swift` — real iOS Keychain impl
|
||||||
(`kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`, no iCloud sync).
|
(`kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`, no iCloud sync).
|
||||||
- `UserDefaultsIOSServerConfigStore.swift` — JSON in UserDefaults.
|
- `UserDefaultsIOSServerConfigStore.swift` — JSON in UserDefaults.
|
||||||
@@ -498,10 +501,11 @@ minutes.
|
|||||||
`Curve25519.Signing.PrivateKey`.
|
`Curve25519.Signing.PrivateKey`.
|
||||||
- `CitadelSSHService.swift` — `SSHConnectionTester` conformance +
|
- `CitadelSSHService.swift` — `SSHConnectionTester` conformance +
|
||||||
key-generation wrapper. Runs a one-shot SSH exec (`echo scarf-ok`)
|
key-generation wrapper. Runs a one-shot SSH exec (`echo scarf-ok`)
|
||||||
for the onboarding probe. Clearly-marked FIXME on the Citadel
|
for the onboarding probe. Every Citadel API call in the file was
|
||||||
authentication-method call site because 0.7→0.9 has shifted the
|
cross-checked against the `0.12.1` tag (SSHAuthenticationMethod.
|
||||||
variant name; other than that one line, everything is
|
ed25519, SSHClientSettings init, SSHHostKeyValidator.acceptAnything,
|
||||||
Citadel-version-independent.
|
SSHClient.connect, executeCommand, close) — should build clean on
|
||||||
|
first try.
|
||||||
|
|
||||||
**Shipped — `scarf/scarf-ios/` iOS app source tree:**
|
**Shipped — `scarf/scarf-ios/` iOS app source tree:**
|
||||||
|
|
||||||
@@ -535,11 +539,14 @@ the 3 ScarfIOS tests.
|
|||||||
|
|
||||||
**Manual validation needed on Mac:**
|
**Manual validation needed on Mac:**
|
||||||
|
|
||||||
1. Xcode project creation per SETUP.md.
|
1. Xcode project creation per SETUP.md. The `Assets.xcassets/` is
|
||||||
2. Citadel 0.9.x `SSHAuthenticationMethod.ed25519(...)` variant name
|
pre-built (1024×1024 icon copied from the Mac app's set;
|
||||||
— verify and fix if it's been renamed.
|
Scarf-teal AccentColor with light + dark variants) so the target
|
||||||
3. Onboarding end-to-end: simulator → physical iPhone via TestFlight
|
should ship with a real icon on first archive.
|
||||||
|
2. Onboarding end-to-end: simulator → physical iPhone via TestFlight
|
||||||
→ real SSH host with the public key added to `authorized_keys`.
|
→ real SSH host with the public key added to `authorized_keys`.
|
||||||
|
Citadel 0.12.1 APIs were verified in source; no expected Citadel
|
||||||
|
drift.
|
||||||
|
|
||||||
**Rules next phases can rely on:**
|
**Rules next phases can rely on:**
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.722",
|
||||||
|
"green" : "0.525",
|
||||||
|
"red" : "0.227"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.902",
|
||||||
|
"green" : "0.690",
|
||||||
|
"red" : "0.400"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.4 MiB |
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "AppIcon-1024.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "ios",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
-15
@@ -61,22 +61,36 @@ In the **scarf-ios** project (target of the same name):
|
|||||||
Xcode created for you:
|
Xcode created for you:
|
||||||
- `scarf_iosApp.swift` (or `scarf-iosApp.swift`)
|
- `scarf_iosApp.swift` (or `scarf-iosApp.swift`)
|
||||||
- `ContentView.swift`
|
- `ContentView.swift`
|
||||||
- `Assets.xcassets` (keep this one — we'll reuse)
|
- **`Assets.xcassets`** — yes, delete this one too. We ship a
|
||||||
2. In Finder, open `<repo>/scarf/scarf-ios/`. Drag the **App/**,
|
pre-built `Assets.xcassets/` with the app icon + accent
|
||||||
**Onboarding/**, and **Dashboard/** folders onto the `scarf-ios`
|
color inside `<repo>/scarf/scarf-ios/` that we'll add in the
|
||||||
target in Xcode's navigator.
|
next step.
|
||||||
|
2. In Finder, open `<repo>/scarf/scarf-ios/`. Drag **App/**,
|
||||||
|
**Onboarding/**, **Dashboard/**, and **`Assets.xcassets/`** onto
|
||||||
|
the `scarf-ios` target in Xcode's navigator.
|
||||||
- In the import sheet: **Create groups**, **Add to target:
|
- In the import sheet: **Create groups**, **Add to target:
|
||||||
scarf-ios**.
|
scarf-ios**.
|
||||||
3. Build (`⌘B`). It should compile cleanly. If Citadel's
|
3. Build (`⌘B`). It should compile cleanly against Citadel 0.12.1
|
||||||
authentication-method variant has changed since I wrote
|
— every API call in `CitadelSSHService` was cross-checked
|
||||||
`CitadelSSHService`, adjust `buildClientSettings(...)` — see the
|
against the 0.12.1 tag in April 2026. If you've bumped the pin
|
||||||
FIXME comment in that file.
|
to 0.13+ and something fails here, the likeliest culprit is
|
||||||
|
`SSHAuthenticationMethod.ed25519(username:privateKey:)` being
|
||||||
|
renamed or refactored; check the current
|
||||||
|
`Sources/Citadel/SSHAuthenticationMethod.swift` in the new
|
||||||
|
release.
|
||||||
|
|
||||||
## One-time: app icon + accent color
|
## App icon + accent color
|
||||||
|
|
||||||
The `Assets.xcassets` that Xcode scaffolded already has a blank
|
The `Assets.xcassets/` inside `<repo>/scarf/scarf-ios/` ships with:
|
||||||
`AppIcon` and `AccentColor`. Drop your icon asset + pick an accent
|
|
||||||
color in the Inspector. Nothing else to configure.
|
- **`AppIcon.appiconset/AppIcon-1024.png`** — the 1024×1024 Scarf
|
||||||
|
icon from the Mac app's icon set. iOS 14+ renders all smaller
|
||||||
|
sizes automatically from the single 1024 image.
|
||||||
|
- **`AccentColor.colorset`** — a custom Scarf teal (`RGB
|
||||||
|
0.227 / 0.525 / 0.722` in light mode; lighter `0.400 / 0.690
|
||||||
|
/ 0.902` in dark mode). If you want a different accent, swap
|
||||||
|
the sRGB components in `Contents.json` or edit in Xcode's
|
||||||
|
color picker.
|
||||||
|
|
||||||
## Info.plist additions for M2
|
## Info.plist additions for M2
|
||||||
|
|
||||||
@@ -135,9 +149,11 @@ If you want to publish to TestFlight in M2, add these under
|
|||||||
**Citadel fails to resolve.** Delete derived data (`~/Library/Developer/Xcode/DerivedData/scarf-ios-*`)
|
**Citadel fails to resolve.** Delete derived data (`~/Library/Developer/Xcode/DerivedData/scarf-ios-*`)
|
||||||
and `File → Packages → Reset Package Caches`, then rebuild.
|
and `File → Packages → Reset Package Caches`, then rebuild.
|
||||||
|
|
||||||
**`SSHAuthenticationMethod` has no member `ed25519`.** Citadel's
|
**`SSHAuthenticationMethod` has no member `ed25519`.** Shouldn't
|
||||||
private-key auth has changed variant names between 0.7 and 0.9. See
|
happen against Citadel 0.12.1 (verified), but historically the
|
||||||
`CitadelSSHService.buildClientSettings(...)` — there's one line to
|
private-key variant names have changed between minor versions
|
||||||
|
(0.7 → 0.9 → 0.12). See `CitadelSSHService.buildClientSettings(...)`
|
||||||
|
— there's one line to
|
||||||
update. Keep the protocol conformance intact.
|
update. Keep the protocol conformance intact.
|
||||||
|
|
||||||
**Keychain reads empty after relaunch.** Check that you haven't
|
**Keychain reads empty after relaunch.** Check that you haven't
|
||||||
|
|||||||
Reference in New Issue
Block a user