.prettierrc.json was missing "semi": false, so prettier wanted to add semicolons to a codebase written without them (763 semicolon-free statements vs. 150 with, in hand-written .ts; zero hand-written .svelte files use them at all). That's why prettier --check failed on 249 files — not because the code was unformatted, but because the config didn't match the actual house style. Added "semi": false; left printWidth/etc as configured (printWidth barely moves the failure count: 218/213/212 files at 100/120/140). Ran `prettier --write .` with the corrected config. Verified semantics-preserving before and after: - eslint: 142 problems both before and after, byte-identical - build passes, 38/38 tests pass - token-stream diff (whitespace/semicolons/quotes normalized) on all 218 changed files: only 52 had any remaining token change, all either trailing-comma removal (matching trailingComma: "none") or import/ ternary reflow — no semantic changes - live smoke test: Knowledge, Tasks, Fleet map, and a chat window (AgentTrace, markdown, Scope graph, activity rail) all render correctly, no console errors Most of the diff is shadcn/ui vendor files (lib/components/ui/) moving from the CLI's own style (double quotes, tabs, semicolons) to house style; re-running `shadcn-svelte add` on a component will need a follow-up format pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
58 lines
2.0 KiB
Svelte
58 lines
2.0 KiB
Svelte
<script lang="ts">
|
|
// Notes — a trivial installable app demoing the App Store lifecycle.
|
|
// Installed from the App Store, gets a desktop icon, opens in a window,
|
|
// has its own localStorage-backed state, and uninstalls cleanly. No
|
|
// shell-internal imports — this is a self-contained app that could be
|
|
// shipped as a standalone bundle (Phase 4 will load such bundles from
|
|
// a URL; here it's bundled and discovered via the catalog).
|
|
let { storageKey = 'oikos-app-notes' }: { storageKey?: string } = $props()
|
|
|
|
let text = $state('')
|
|
let saved = $state(false)
|
|
|
|
function load(): string {
|
|
if (typeof localStorage === 'undefined') return ''
|
|
return localStorage.getItem(storageKey) ?? ''
|
|
}
|
|
function save(): void {
|
|
if (typeof localStorage === 'undefined') return
|
|
localStorage.setItem(storageKey, text)
|
|
saved = true
|
|
setTimeout(() => (saved = false), 1500)
|
|
}
|
|
|
|
function onKeydown(e: KeyboardEvent) {
|
|
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 's') {
|
|
e.preventDefault()
|
|
save()
|
|
}
|
|
}
|
|
|
|
text = load()
|
|
$effect(() => {
|
|
if (!text) return
|
|
const t = setTimeout(() => save(), 2000)
|
|
return () => clearTimeout(t)
|
|
})
|
|
</script>
|
|
|
|
<div class="flex h-full min-h-0 flex-col gap-2 p-4">
|
|
<div class="flex shrink-0 items-center justify-between">
|
|
<h2 class="text-sm font-medium">Notes</h2>
|
|
<span class="text-xs text-muted-foreground">
|
|
{#if saved}saved{:else}unsaved{/if}
|
|
</span>
|
|
</div>
|
|
<textarea
|
|
bind:value={text}
|
|
onkeydown={onKeydown}
|
|
placeholder="Type here. Auto-saves 2s after you stop, or Cmd/Ctrl+S."
|
|
class="min-h-0 flex-1 resize-none rounded-md border bg-background p-3 font-mono text-sm leading-relaxed focus-visible:outline-2 focus-visible:outline-ring"
|
|
></textarea>
|
|
<p class="shrink-0 text-xs text-muted-foreground">
|
|
A demo installable app — uninstall it from the App Store to remove its icon and window. Its
|
|
notes persist in localStorage under
|
|
<code class="font-mono">{storageKey}</code>.
|
|
</p>
|
|
</div>
|