diff --git a/AGENTS.md b/AGENTS.md index d410344..7f5f0d7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -92,23 +92,6 @@ as project instructions, not as optional documentation. proof. - Do not hand-edit generated frontend output. -## Phone Configurator parity (mandatory) - -- Every new, changed, renamed, moved, or removed configurable value in - `sky_phone/config/config.lua` or `sky_phone/config/media.lua` **must** be - reflected in the in-game Phone Configurator in the same change. Config-only - changes without matching Configurator support are incomplete and must not be - committed or merged. -- Keep the Configurator's runtime schema, defaults, value types, fixed versus - extensible collection rules, labels, descriptions, English and German - locales, SQL persistence, validation, and save/load roundtrip aligned with - the Lua configuration. -- The Configurator must remain complete when file-based configuration is - disabled. Do not introduce a setting that can only be managed by editing Lua - after `Config.PhoneConfigurator.Enabled` is enabled. -- Add or update contract/fixture coverage so configuration parity regressions - fail automated checks. - ## Working method and verification 1. Trace the relevant client, server, NUI, configuration, persistence, and event diff --git a/README.md b/README.md index 7cbb9f7..6778eaa 100644 --- a/README.md +++ b/README.md @@ -218,34 +218,6 @@ The files contain clearly separated sections for: Restart `sky_phone` after changing Lua configuration. -### In-game phone configurator - -Set the switch at the beginning of `config/config.lua` to use SQL-backed configuration: - -```lua -Config.PhoneConfigurator = { - Enabled = true, -} -``` - -When enabled, `config.lua` and the server-only `media.lua` are first-run defaults. Sky Phone creates -the `sky_phone_configurator` table automatically, loads its saved values before framework and phone -modules initialize, and exposes the editor through `/phonepanel`. Nothing autosaves: stage changes -in the Phone Configurator tool and press the green check. Saving verifies both SQL payloads and then -applies the new server, client, media, app, item, command, provider, animation, and UI values through -Sky Phone's internal runtime refresh. It does not execute a resource restart command. - -Every `Config.*` value from `config.lua`, including server-only sections, and every value from -`Config.Media` is discovered automatically. The bootstrap switch above intentionally remains -file-owned because it decides whether SQL configuration is loaded. Lists, nested objects, vectors, -and numeric-keyed Lua tables use structured editors instead of raw JSON. Shipped schema rows stay -editable but cannot be renamed, converted, or removed. Every list and table still accepts any number -of additional rows; administrator-added rows remain removable. Company job keys are intentionally -fully removable because `Config.Companies.Definitions` is a freely managed job collection. - -Media API keys and server peppers are never returned in plaintext to the NUI. Existing secrets are -shown only as configured and are replaced only when an administrator enters a new value. - ### Language Available locales: @@ -569,11 +541,7 @@ Select `rtx`, `quasar`, `vms`, `rx`, `nolag`, `sn`, `esx_property`, or `qbx_prop ### Companies -Company jobs, public profiles, service numbers, services, permissions, locations, and default -availability are configured under `Config.Companies.Definitions`. Definitions are not limited to the -shipped jobs: add any number of company IDs in the in-game configurator and fill the freely -configurable `Job` value in the automatically generated full company template. Existing job keys can -also be removed; the remaining Companies settings stay available as normal individual fields. +Company jobs, public profiles, service numbers, services, permissions, locations, and default availability are configured under `Config.Companies.Definitions`. ### Weazel News diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 095f0cf..21f575a 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -11,7 +11,6 @@ import { import { useRoute, useRouter } from 'vue-router' import { SkyProvider } from '@/ui' -import AdminPanel from '@/components/AdminPanel.vue' import PhoneHomeIndicator from '@/components/PhoneHomeIndicator.vue' import PhoneControlCenter from '@/components/PhoneControlCenter.vue' import PhoneDynamicIsland from '@/components/PhoneDynamicIsland.vue' @@ -116,13 +115,8 @@ type AppMessage = { | CustomAppCatalogEventData | CustomAppEventData | NavigationEventData - | AdminPanelOpenPayload } -type AdminPanelOpenPayload = Required< - Pick -> - type CustomAppCatalogEventData = { apps?: unknown } @@ -363,9 +357,6 @@ const appTransitionName = computed(() => route.query.transition === 'app-switch' ? 'app-switch' : 'app-window', ) const isLocked = ref(false) -const adminPanelOpen = ref( - isDevelopment && developmentParameters.has('adminPanel'), -) const springboardEditing = ref(false) const isUnlocking = ref(false) const passcodeBusy = ref(false) @@ -639,8 +630,6 @@ function loadUnlockedPhoneData(): void { } function completePhoneSetup(): void { - const requestedRoute = pendingUnlockRoute.value - pendingUnlockRoute.value = null setupPreviewDismissed.value = true setupAppearanceSelected.value = false isLocked.value = false @@ -648,7 +637,7 @@ function completePhoneSetup(): void { passcodeVisible.value = false passcodeRequired.value = false controlCenterOpened.value = false - void router.replace(requestedRoute ?? '/') + void router.replace('/') loadUnlockedPhoneData() } @@ -732,15 +721,7 @@ function openDevelopmentPayphonePreview(): void { function onMessage(event: MessageEvent): void { if (!isTrustedRootMessageSource(event.source, window)) return - if (event.data?.type === 'admin:open') { - const data = event.data.data as AdminPanelOpenPayload | undefined - if (data?.lang && data.locales && data.fallbackLocales) { - phone.setLocale(data.lang, data.locales, data.fallbackLocales) - } - adminPanelOpen.value = true - } else if (event.data?.type === 'admin:close') { - adminPanelOpen.value = false - } else if (event.data?.type === 'custom-apps:catalog') { + if (event.data?.type === 'custom-apps:catalog') { appCatalog.replaceCatalog(event.data.data) const catalogPayload = event.data.data as | { apps?: unknown; debug?: unknown } @@ -785,12 +766,7 @@ function onMessage(event: MessageEvent): void { isPhoneAppId(data.appId) && appStore.isInstalled(data.appId) ) { - const requestedRoute = `/apps/${data.appId}` - if (setupRequired.value || isLocked.value) { - pendingUnlockRoute.value = requestedRoute - } else { - void router.push(requestedRoute) - } + void router.push(`/apps/${data.appId}`) } else { console.error('[Navigation] Ignored an unavailable app target.') } @@ -1755,15 +1731,6 @@ onBeforeUnmount(() => {