import { GxState } from "./state.js" import { GxNotice } from "./notice.js" import { TroubleshootPage, TmuxPage } from "./diagnostic-tools.js" import { navigate } from "./router.js" import { SystemMonitor } from "./system-monitor.js" import { CrashReportsFeed } from "./crash-reports.js" import { storedSize } from "./record-deletion.js" import { StarPortLogsFeed, BUNDLE_URL, fileUrl, outcomeLabel } from "./starport-logs.js" import { MenuTile } from "./menu-tile.js" import { BluetoothNotice, bluetoothConnection } from "./bluetooth-notice.js" export const Logs = { name: "Logs", components: { GxState, GxNotice, BluetoothNotice, SystemMonitor, TroubleshootPage, TmuxPage, MenuTile }, props: { path: { type: String, required: true }, mode: { type: String, required: true }, unauthorized: { type: Function, required: true }, tools: { type: Array, required: true } }, data: () => ({ crashes: { reports: [], scanIncomplete: false, listLimited: false, status: "idle", error: "", selected: null, preview: null, previewStatus: "idle", deleting: false, storageBytes: 0, reportCount: 0 }, search: "", starportLogs: { sessions: [], others: [], status: "idle", error: "" }, bluetooth: bluetoothConnection() }), computed: { visibleReports() { return this.crashes.reports.filter((item) => item.name.toLowerCase().includes(this.search.toLowerCase())) }, }, created() { this.crashFeed = new CrashReportsFeed({ publish: (update) => Object.assign(this.crashes, update), unauthorized: this.unauthorized }) this.starportFeed = new StarPortLogsFeed({ publish: (update) => Object.assign(this.starportLogs, update), unauthorized: this.unauthorized }) }, mounted() { if (this.path === "/logs/crashes" && this.mode === "local") this.crashFeed.start() if (this.path === "/logs/starport" && this.mode === "local") this.starportFeed.start() }, beforeUnmount() { this.crashFeed.stop(); this.starportFeed.stop() }, watch: { path(next, previous) { if (next === "/logs/crashes" && this.mode === "local") this.crashFeed.start() else if (previous === "/logs/crashes") { this.crashFeed.stop(); this.search = "" } if (next === "/logs/starport" && this.mode === "local") this.starportFeed.start() else if (previous === "/logs/starport") this.starportFeed.stop() }, }, methods: { storedSize, go: navigate, bundleUrl: () => BUNDLE_URL, fileUrl, outcomeLabel, reportDate(seconds) { return new Date(seconds * 1000).toLocaleString() }, reportSize(bytes) { return `${(bytes / 1024).toFixed(1)} KiB` }, async copyPreview() { if (!this.crashes.preview) return try { await navigator.clipboard.writeText(this.crashes.preview.text) } catch { this.crashes.error = "Copy is unavailable in this browser." } }, }, template: `
Logs, diagnostics, drive state, and help.
Guides and help from the community.
Find setup guides, feature explanations, and troubleshooting steps for StarPilot and Android Auto.
Open the WikiAsk the community for help, share what you have tried, and follow StarPilot announcements.
Join DiscordLocal reports saved when a process stops unexpectedly.
Directory scan is incomplete; newer reports may be omitted.
Showing the 200 newest reports; older reports are omitted.
Preview truncated to the first 256 KiB.
{{ crashes.preview.text }}The last 20 connection sessions, newest first. The archive includes every session, a readable report for each, StarPort settings, the car view's renderer logs, and a snapshot of the device (Wi-Fi, Bluetooth and kernel logs, build, CPU load). Hardware addresses are masked.