Conversation
Adds 3 contract tests under framework/cli/cmd/json_contract_test.go that unmarshal real --json output into typed structs mirroring the contract consumed by the macOS companion app (apps/macos/Ulk/Models/UlkReports.swift). Any future breaking change to the JSON shape (renamed/removed field, type change) will fail these tests, forcing a coordinated update on the Swift side. The Go types are intentionally lenient (pointers + omitempty) to accept both the not-installed status payload and the full one. Tested: go test ./cmd/ -run "TestStatusJSONContract|TestDoctorJSONContract|TestCheckJSONContract" → ok https://claude.ai/code/session_01TyhPjizanX1g8xSQ6chwTu
Replaces ad-hoc text parsing with strongly-typed Codable models that mirror the JSON contract enforced by framework/cli/cmd/json_contract_test.go. - UlkReports.swift : StatusReport / DoctorReport / DoctorIssue / CheckReport / CheckTool — all Codable + Equatable, with derived helpers (enabledModules, unfixed, isHealthy, missingTools) - UlkBridge.swift : new typed methods status() / doctorReport() / check() that decode JSON via decodeJSON<T>(); runCapturing gains an allowNonZeroExit param so doctor (which exits non-zero when issues exist but emits valid JSON) is not flagged as a hard error - UlkBridge.detectInstall() now prefers status() over filesystem heuristics when the binary is available — populates SystemSnapshot.statusReport and configFlags from the real state.json modules map - SystemSnapshot gains statusReport: StatusReport? field - SystemState exposes removeSkill(_:) wrapper that delegates to UlkBridge and reloads the snapshot - UlkBridge.removeSkill(named:) does input sanitisation (no slashes) and uses FileManager.removeItem on ~/.claude/skills/<name> - UlkReportsTests : 5 tests covering not-installed/full payload, doctor healthy/with-issues, check found+missing https://claude.ai/code/session_01TyhPjizanX1g8xSQ6chwTu
XcodeGen generates Ulk.xcodeproj from project.yml (~80 lines of YAML) on demand. The .xcodeproj is gitignored — source of truth lives in project.yml. Avoids 1000+ line UUID-laced project.pbxproj diffs and keeps the file tree in sync automatically. - project.yml : Ulk app target (macOS 14+, hardened runtime, entitlements wired, AppIcon + AccentColor) + UlkTests target (bundle.unit-test, gathers coverage) - .gitignore : Ulk.xcodeproj/ ignored (regenerable artefact) - README : new "Projet Xcode" section explaining XcodeGen workflow, v0.2 status, JSON contract section, updated build commands Local dev : brew install xcodegen cd apps/macos/Ulk && xcodegen generate && open Ulk.xcodeproj https://claude.ai/code/session_01TyhPjizanX1g8xSQ6chwTu
- SkillsTab : trash button on community/opt-in skills triggers a
destructive-style SwiftUI alert, then SystemState.removeSkill →
UlkBridge.removeSkill (FileManager) → snapshot reload. Bundled
skills (figma-, swift-, flutter-, kepano-, …) keep their reveal-
in-Finder action only — they are managed by `ulk install`, not by
direct deletion. Switched the folder action to
NSWorkspace.activateFileViewerSelecting so it actually reveals
rather than opens the directory.
- CI macos-app.yml : split into two parallel jobs
1. spm — swift build/test (UlkCore library) — fast feedback
2. xcodegen — brew install xcodegen → generate → xcodebuild
on the real .xcodeproj with CODE_SIGNING_ALLOWED=NO. Catches
project.yml drift immediately.
- Spec card : Roadmap v0.1 marked done (PR #143), v0.2 detailed,
v0.2.1 added (remaining toggles + search + notifications),
Changelog updated, related field gains json_contract_test.go.
https://claude.ai/code/session_01TyhPjizanX1g8xSQ6chwTu
|
Warning Rate limit exceeded
To continue reviewing without waiting, purchase usage credits in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (11)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Suite logique de PR #143 (v0.1 mergée). Quatre commits atomiques :
test(cli)—framework/cli/cmd/json_contract_test.go: 3 tests Go qui verrouillent le shape deulk status/doctor/check --jsonfeat(macos)— Modèles SwiftStatusReport/DoctorReport/CheckReport(Ulk/Models/UlkReports.swift) miroir du contrat Go ;UlkBridge.status()/doctorReport()/check()typés ;SystemSnapshot.statusReportpeuplé depuis le vraistate.jsonbuild(macos)— XcodeGen remplace le projet Xcode hypothétique :project.yml(~80 lignes YAML, source de vérité) ;.xcodeprojgitignoredfeat(macos)— 1er toggle fonctionnel end-to-end (suppression skill community/opt-in via FileManager + alert SwiftUI) ; CI macOS-app passée à 2 jobs parallèles (SwiftPM + XcodeGen/xcodebuild) ; spec card v0.2Contrat JSON Go ↔ Swift
Pierre angulaire de cette PR. Les deux côtés sont liés par un test :
Test plan
cd framework/cli && go test ./cmd/ -run "TestStatusJSONContract|TestDoctorJSONContract|TestCheckJSONContract"→ okcd apps/macos/Ulk && swift test(CI macos-14 — SPM job)cd apps/macos/Ulk && xcodegen generate && xcodebuild -project Ulk.xcodeproj -scheme Ulk build(CI macos-14 — xcodegen job)Limites assumées (v0.2.1+)
Spec complète :
docs/backlog/2026-05-06-FEATURE-MACOS-COMPANION-APP/CARD.mdNote sur l'autre check rouge attendu
Le job pré-existant
Go CLI > Coverage gate(issue #144) va probablement échouer ici aussi car cette PR touche.github/workflows/**. Ce n'est pas une régression de cette PR — la couverture du packagecmdest à 18% sur main. Voir #144 pour le fix.https://claude.ai/code/session_01TyhPjizanX1g8xSQ6chwTu
Generated by Claude Code