Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ let package = Package(
name: "KeyPathPluginKit",
targets: ["KeyPathPluginKit"]
),
.library(
name: "KeyPathCLISupport",
targets: ["KeyPathCLISupport"]
),
.executable(
name: "keypath-cli",
targets: ["KeyPathCLIMain"]
Expand Down Expand Up @@ -123,6 +127,13 @@ let package = Package(
.swiftLanguageMode(.v6)
]
),
.target(
name: "KeyPathCLISupport",
path: "Sources/KeyPathCLISupport",
swiftSettings: [
.swiftLanguageMode(.v6)
]
),
// Installation wizard (extracted from KeyPathAppKit for incremental compilation)
.target(
name: "KeyPathInstallationWizard",
Expand Down Expand Up @@ -246,6 +257,7 @@ let package = Package(
.target(
name: "KeyPathCLI",
dependencies: [
"KeyPathCLISupport",
"KeyPathAppKit",
.product(name: "ArgumentParser", package: "swift-argument-parser")
],
Expand Down
1 change: 1 addition & 0 deletions Sources/KeyPathCLI/Commands/CompletionsCommand.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ArgumentParser
import Foundation
import KeyPathAppKit
import KeyPathCLISupport

struct Completions: ParsableCommand {
static let configuration = CommandConfiguration(
Expand All @@ -12,7 +13,7 @@
Fish.self,
Install.self,
InstallMan.self,
CompletionValues.self,

Check warning on line 16 in Sources/KeyPathCLI/Commands/CompletionsCommand.swift

View workflow job for this annotation

GitHub Actions / code-quality

Collection literals should not have trailing commas (trailing_comma)
]
)

Expand Down Expand Up @@ -128,7 +129,7 @@

# Dynamic completions for keypath argument values
complete -c keypath -n '__fish_seen_subcommand_from pack; and __fish_seen_subcommand_from show install uninstall configure' -xa '(keypath completions values pack 2>/dev/null)'
complete -c keypath -n '__fish_seen_subcommand_from collection; and __fish_seen_subcommand_from enable disable show delete rename duplicate' -xa '(keypath completions values collection 2>/dev/null)'

Check warning on line 132 in Sources/KeyPathCLI/Commands/CompletionsCommand.swift

View workflow job for this annotation

GitHub Actions / code-quality

Line should be 200 characters or less; currently it has 206 characters (line_length)
complete -c keypath -n '__fish_seen_subcommand_from rule; and __fish_seen_subcommand_from enable disable show remove' -xa '(keypath completions values rule 2>/dev/null)'
complete -c keypath -n '__fish_seen_subcommand_from layer; and __fish_seen_subcommand_from switch delete rename' -xa '(keypath completions values layer 2>/dev/null)'
"""
Expand All @@ -148,7 +149,7 @@
"/Applications/KeyPath.app/Contents/Resources/man",
NSString("~/Applications/KeyPath.app/Contents/Resources/man").expandingTildeInPath,
// Development: relative to binary
Bundle.main.bundlePath + "/../share/man/man1",

Check warning on line 152 in Sources/KeyPathCLI/Commands/CompletionsCommand.swift

View workflow job for this annotation

GitHub Actions / code-quality

Collection literals should not have trailing commas (trailing_comma)
]

var sourceDir: String?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ArgumentParser
import Foundation
import KeyPathAppKit
import KeyPathCLISupport

struct ServiceStatus: AsyncParsableCommand {
static let configuration = CommandConfiguration(
Expand Down
2 changes: 1 addition & 1 deletion Sources/KeyPathCLI/KeyPathTool.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ArgumentParser
import Foundation
import KeyPathAppKit
import KeyPathCLISupport

public struct KeyPathCLI: AsyncParsableCommand {
public init() {}
Expand Down Expand Up @@ -30,7 +30,7 @@
StopShortcut.self,
RestartShortcut.self,
LogsShortcut.self,
UnmapShortcut.self,

Check warning on line 33 in Sources/KeyPathCLI/KeyPathTool.swift

View workflow job for this annotation

GitHub Actions / code-quality

Collection literals should not have trailing commas (trailing_comma)
]
)
}
2 changes: 1 addition & 1 deletion Sources/KeyPathCLI/Utilities/Output.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Foundation
import KeyPathAppKit
import KeyPathCLISupport

public struct OutputContext: Sendable {
public let isInteractive: Bool
Expand Down
6 changes: 2 additions & 4 deletions Sources/KeyPathCLI/Utilities/UpdateChecker.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import Foundation
import KeyPathAppKit
import KeyPathCLISupport
import KeyPathCore

enum UpdateChecker {
private static let cacheFile: String = {
"\(KeyPathConstants.Config.directory)/.update-check"
}()
private static let cacheFile: String = "\(KeyPathConstants.Config.directory)/.update-check"

private static let checkInterval: TimeInterval = 86400 // 24 hours

Expand Down
File renamed without changes.
30 changes: 25 additions & 5 deletions docs/TEST_HYGIENE_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,16 @@ Status:
types and command-parse/output-contract tests; then move storage/config/packs
facades only when their dependencies can move with them. Keep installer and
simulator facades AppKit-backed until a measured lane shows they dominate.
- Started the extraction by creating a pure `KeyPathCLISupport` target and
moving `CLIVersion` plus `printErr` out of `KeyPathAppKit`. This is a
foothold only: it validates the new module boundary, but `KeyPathCLI` still
depends on `KeyPathAppKit`.
- Post-extraction validation:
- `swift build --target KeyPathCLISupport` passed in 1.33s;
- warm `swift build --product keypath-cli` passed in 85.79s and still
compiled the AppKit graph;
- `./Scripts/test-lane.sh cli` passed 341 tests with build=131s, test=3s,
total=135s, zero Swift warnings, zero app warnings, and zero app errors.
- Do not split installer/wizard targets further unless a lane timing run shows
they dominate a workflow we care about.

Expand Down Expand Up @@ -638,6 +648,14 @@ Milestone 7 now has enough evidence to keep the bounded isolated Core lane:
models, schema/version helpers, and low-level facade logic; command parsing
tests can move there first. AppKit-backed installer/simulator/system facades
should move later, only with dependency evidence.
- First extraction checkpoint: `KeyPathCLISupport` now owns pure CLI support
helpers (`CLIVersion`, `printErr`) and builds independently in 1.33s. This
does not yet make the CLI lane build-isolated; the warm CLI lane still spent
131s in prebuild and passed 341 tests. Stop the CLI/AppKit extraction here
for this hygiene phase: moving result models, output contracts, command-parse
tests, and facade logic would be architectural refactoring with a narrower
payoff. Revisit only when CLI-heavy work becomes frequent enough to justify a
dedicated architecture milestone.
Because the root-package build dominates this lane, keep the current filter
and treat `unit` as fast model/parser/renderer coverage, not true Core
isolation. The `core-isolated` lane remains the true Core-only fast path.
Expand Down Expand Up @@ -687,8 +705,10 @@ The Mac mini workflow is deferred. Revisit it only after the MacBook Air loop is
fast and boring enough that remote execution would solve a measured capacity
problem instead of compensating for harness noise.

Next planned milestone: treat the current lane set as the stable local loop and
watch for regressions. CLI/AppKit extraction is worth revisiting only if a
measured workflow needs true build isolation; the current `cli` lane already
gives a fast, stable selection path. Installer/wizard splits should follow only
after the remaining lane timings justify the extra dependency work.
Next planned milestone: stop active test-hygiene performance work and treat the
current lane set as the stable local loop. Watch for regressions in warning
counts, log size, and lane timing while doing real product work. CLI/AppKit
extraction is worth revisiting only if a measured workflow needs true build
isolation; the current `cli` lane already gives a stable selection path.
Installer/wizard splits should follow only after lane timings justify the extra
dependency work.
Loading