Local-first Swift tools for preparing Feedback Assistant reports on macOS.
RelatoKit (from the Portuguese relato, meaning report or account) provides a local-first Swift CLI and library for preparing Feedback Assistant reports on macOS. It can inspect the local Feedback Assistant store, generate structured report payloads, open Apple's native app, and assist with form entry through Accessibility automation.
RelatoKit keeps authentication, diagnostics, and final submission inside Feedback Assistant. It does not bypass entitlements, disable platform security, forge Apple credentials, or submit feedback without explicit --confirm confirmation.
The CLI is optimized for agent workflows: create a machine-readable JSON payload, review the generated Markdown report, open and fill the native app, inspect Apple-only fields, and click Submit only after explicit confirmation.
relato prepare \
--title "Xcode canvas stops updating after file rename" \
--description "Steps, expected result, actual result." \
--snapshot ./snapshot.png \
--bundle-id com.apple.dt.Xcode \
--kind bug
relato submit --payload feedback-submission.json --dry-run
relato submit --payload feedback-submission.json- macOS 14.0+
- Swift 6.0+
- Xcode command line tools
- Feedback Assistant installed and signed in
- Accessibility permission for Terminal, if you use native form filling
Build from source:
git clone https://github.com/rryam/RelatoKit.git
cd RelatoKit
swift build -c release
.build/release/relato --help
.build/release/relato versionAdd the library to another Swift package:
dependencies: [
.package(url: "https://github.com/rryam/RelatoKit.git", branch: "main")
].product(name: "RelatoKit", package: "RelatoKit")RelatoKit gives you a small command-line workflow around the native Feedback Assistant app:
- read-only inspection of the local Feedback Assistant store
- topic and area inference from title, description, bundle identifier, and curated Feedback Assistant area mappings
- JSON and Markdown report preparation
- native Feedback Assistant route launching
- AX-driven title, description, bundle ID, fail-closed popup handling, and submit handoff
- background local attachment staging into Feedback Assistant draft folders
- fail-closed behavior when native controls require focus, keyboard, or pointer ownership
Inspect the local store:
relato store summary
relato store list --limit 20
relato store uploads
relato categoriesCheck routing and categorization:
relato routes
relato open new --print-only
relato categorize \
--title "Xcode preview fails to refresh" \
--description "The canvas stops updating after renaming a SwiftUI file." \
--bundle-id com.apple.dt.XcodeRelatoKit uses curated mappings for common Feedback Assistant destinations, including macOS app/system areas, Developer Tools areas, Developer Technologies frameworks, and top-level platform forms such as iOS & iPadOS, watchOS, tvOS, visionOS, HomePod, AirPods, Enterprise & Education, MFi, and DMA Interoperability.
Prepare a report:
relato prepare \
--title "Xcode preview fails to refresh" \
--description "Steps to reproduce, expected result, and actual result." \
--snapshot ./snapshot.png \
--bundle-id com.apple.dt.Xcode \
--kind bugrelato prepare writes two files:
feedback-submission.json- the machine-readable payload used byrelato open-native,relato fill, andrelato submitfeedback-submission.md- the human-readable report for agent review, logs, notes, or evidence attachments
--snapshot can point to any local evidence file, including a screenshot, Markdown note, log, sample project archive, or sysdiagnose pointer.
Open and fill the native app:
relato open-native --payload feedback-submission.json
relato fill --payload feedback-submission.jsonSubmit through the native app with explicit confirmation:
relato submit --payload feedback-submission.json --dry-run
relato submit --payload feedback-submission.json --confirmWithout --confirm, relato submit opens Feedback Assistant without activation, fills the fields it can safely set, hides the app again, stages the snapshot, and stops before Submit.
With --confirm, RelatoKit asks the signed-in native app to press Submit through Accessibility, then performs best-effort local store verification. This check can show local store changes and matching recent items, but it is not a server-side receipt from Apple.
Feedback Assistant may add required native-only fields based on the selected topic, such as popups, Xcode version, device details, logs, or sysdiagnose attachments. Review those fields in the app before using --confirm.
relato store summary [--db PATH]
relato store list [--limit N] [--db PATH]
relato store uploads [--limit N] [--db PATH]
relato categories [--db PATH]
relato categorize --title TEXT [--description TEXT] [--bundle-id ID]
relato prepare --title TEXT --description TEXT [--snapshot PATH] [--bundle-id ID] [--kind bug|suggestion] [--output-dir DIR]
relato routes
relato open ROUTE [--id ID] [--print-only]
relato open-native [--payload PATH]
relato fill [--payload PATH] [--select-popups]
relato submit [--payload PATH] [--select-popups] [--wait-seconds N] [--verify-wait-seconds N] [--db PATH] [--confirm] [--verify-store] [--dry-run]
relato versionAgent-oriented help:
relato help payload
relato help submit
relato help fill
relato help storeRelatoKit uses an Objective-C Accessibility engine for native form automation. It opens Feedback Assistant without activation, hides it after launch or fill, and writes supported text fields through passive AX value updates. It does not synthesize mouse movement, pointer clicks, or keyboard input for the normal fill path.
Local snapshots are staged into Feedback Assistant's local draft folder after the native draft exists. This avoids driving the visible Add Attachment menu and keeps the user's active app undisturbed where macOS allows it.
Some Feedback Assistant controls are native-only by design. Topic-specific popups, diagnostics prompts, device selections, and log-gathering flows may require review inside Apple's app. When a control cannot be completed safely in the background, RelatoKit fails closed instead of taking over focus, keyboard, or pointer ownership.
For the automation model, see docs/AX_AUTOMATION.md.
RelatoKit intentionally stays on the native Feedback Assistant side of the workflow:
--confirmpresses the native Submit button through Accessibility. It is not private headless submission.- Local store verification is local evidence only. It can show drafts, recent items, and upload-task changes, but it is not an Apple server receipt.
- Private FeedbackCore and feedbackd APIs are research-only and are not used by the shipping CLI.
- RelatoKit does not bypass entitlements, forge Apple credentials, patch platform security, or redistribute Apple private headers.
RelatoKit is pre-1.0. The stable surface is report preparation, local store inspection, native route launch, hidden text-field fill, local attachment staging, explicit native submit handoff, and best-effort local verification. Research probes live under Research/ and are not part of the SwiftPM build.
- No entitlement bypass.
- No forged Apple credentials.
- No SIP or platform security workarounds.
- No private headless submission to Apple.
- No redistribution of Apple private headers or copied framework code.
swift build
swift test
swift build -c release
make check- docs/COMMANDS.md - generated command reference
- docs/AX_AUTOMATION.md - native Accessibility automation notes
- CONTRIBUTING.md - development workflow
- SUPPORT.md - support checklist
- SECURITY.md - security reporting and project boundary
MIT
RelatoKit is an independent, unofficial tool and is not affiliated with, endorsed by, or sponsored by Apple Inc. Apple, macOS, Xcode, and Feedback Assistant are trademarks of Apple Inc.