-
Notifications
You must be signed in to change notification settings - Fork 0
Beta #109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Beta #109
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import type { ReactNode } from "react"; | ||
| import { SiteHeader } from "@/components/layout/site-header"; | ||
| import { SiteFooter } from "@/components/layout/site-footer"; | ||
|
|
||
| export function AppShell({ children }: { children: ReactNode }) { | ||
| return ( | ||
| <div className="flex min-h-screen flex-col bg-background text-foreground"> | ||
| <SiteHeader /> | ||
| <main className="flex-1">{children}</main> | ||
| <SiteFooter /> | ||
| </div> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,125 @@ | ||||||||
| import { useEffect, useMemo, useState } from "react"; | ||||||||
| import { useLocation } from "wouter"; | ||||||||
| import { Search, TerminalSquare } from "lucide-react"; | ||||||||
| import { | ||||||||
| CommandDialog, | ||||||||
| CommandEmpty, | ||||||||
| CommandGroup, | ||||||||
| CommandInput, | ||||||||
| CommandItem, | ||||||||
| CommandList, | ||||||||
| CommandSeparator, | ||||||||
| } from "@/components/ui/command"; | ||||||||
| import { Kbd } from "@/components/ui/kbd"; | ||||||||
| import { searchTools, getRecentTools } from "@/lib/tool-registry"; | ||||||||
| import type { ToolDefinition } from "@/lib/tool-registry"; | ||||||||
|
|
||||||||
| export function CommandPalette() { | ||||||||
| const [open, setOpen] = useState(false); | ||||||||
| const [value, setValue] = useState(""); | ||||||||
| const [, navigate] = useLocation(); | ||||||||
|
|
||||||||
| useEffect(() => { | ||||||||
| const onKey = (e: KeyboardEvent) => { | ||||||||
| if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { | ||||||||
| e.preventDefault(); | ||||||||
| setOpen((o) => !o); | ||||||||
| } | ||||||||
| }; | ||||||||
| window.addEventListener("keydown", onKey); | ||||||||
| return () => window.removeEventListener("keydown", onKey); | ||||||||
| }, []); | ||||||||
|
|
||||||||
| const results = useMemo( | ||||||||
| () => (value.trim() ? searchTools(value, 10) : []), | ||||||||
| [value], | ||||||||
| ); | ||||||||
| const recents = useMemo( | ||||||||
| () => (value.trim() ? [] : getRecentTools().slice(0, 5)), | ||||||||
| [value, open], | ||||||||
| ); | ||||||||
|
|
||||||||
| const run = (url: string) => { | ||||||||
| setOpen(false); | ||||||||
| setValue(""); | ||||||||
| const base = import.meta.env.BASE_URL.replace(/\/$/, ""); | ||||||||
| navigate(base + url); | ||||||||
|
Comment on lines
+39
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: Assessment: 🟠 Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** artifacts/personal-tool-console/src/components/layout/command-palette.tsx
**Line:** 39:40
**Comment:**
*Api Mismatch: `WouterRouter` already applies `BASE_URL`, so prefixing it again sends navigation to a doubled base path on subpath deployments.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Comment on lines
+45
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| }; | ||||||||
|
|
||||||||
| const ToolRow = ({ tool }: { tool: ToolDefinition }) => { | ||||||||
|
Check warning on line 49 in artifacts/personal-tool-console/src/components/layout/command-palette.tsx
|
||||||||
| const Icon = tool.icon; | ||||||||
| return ( | ||||||||
| <CommandItem | ||||||||
| value={`${tool.name} ${tool.slug} ${tool.keywords.join(" ")}`} | ||||||||
| onSelect={() => run(`/tools/${tool.slug}`)} | ||||||||
| > | ||||||||
| <Icon className="mr-2 h-4 w-4" /> | ||||||||
| <span className="flex-1 truncate">{tool.name}</span> | ||||||||
| {tool.status === "coming-soon" && ( | ||||||||
| <span className="text-[10px] uppercase tracking-wide text-muted-foreground/70"> | ||||||||
| Soon | ||||||||
| </span> | ||||||||
| )} | ||||||||
| </CommandItem> | ||||||||
| ); | ||||||||
| }; | ||||||||
|
|
||||||||
| return ( | ||||||||
| <> | ||||||||
| <div className="hidden items-center gap-2 md:flex"> | ||||||||
| <button | ||||||||
| type="button" | ||||||||
| onClick={() => setOpen(true)} | ||||||||
| className="inline-flex items-center gap-2 rounded-lg border border-border bg-card/60 px-3 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground" | ||||||||
| > | ||||||||
| <Search className="h-3.5 w-3.5" /> | ||||||||
| <span className="hidden lg:inline">Search tools…</span> | ||||||||
| <Kbd>⌘K</Kbd> | ||||||||
| </button> | ||||||||
| <button | ||||||||
| type="button" | ||||||||
| onClick={() => run("/console")} | ||||||||
| className="inline-flex items-center gap-2 rounded-lg border border-border bg-card/60 px-3 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground" | ||||||||
| aria-label="Open command console" | ||||||||
| > | ||||||||
| <TerminalSquare className="h-3.5 w-3.5" /> | ||||||||
| </button> | ||||||||
| </div> | ||||||||
|
|
||||||||
| <CommandDialog open={open} onOpenChange={setOpen}> | ||||||||
| <CommandInput | ||||||||
| placeholder="Search tools, categories…" | ||||||||
| value={value} | ||||||||
| onValueChange={setValue} | ||||||||
| /> | ||||||||
| <CommandList> | ||||||||
| <CommandEmpty>No tools found for “{value}”.</CommandEmpty> | ||||||||
| {value.trim() ? ( | ||||||||
| <CommandGroup heading="Tools"> | ||||||||
| {results.map((tool) => ( | ||||||||
| <ToolRow key={tool.slug} tool={tool} /> | ||||||||
| ))} | ||||||||
| </CommandGroup> | ||||||||
| ) : ( | ||||||||
| <> | ||||||||
| <CommandItem onSelect={() => run("/console")}> | ||||||||
| <TerminalSquare className="mr-2 h-4 w-4" /> | ||||||||
| <span className="flex-1">Open command console</span> | ||||||||
| </CommandItem> | ||||||||
| {recents.length > 0 && ( | ||||||||
| <> | ||||||||
| <CommandSeparator /> | ||||||||
| <CommandGroup heading="Recent"> | ||||||||
| {recents.map((tool) => ( | ||||||||
| <ToolRow key={tool.slug} tool={tool} /> | ||||||||
| ))} | ||||||||
| </CommandGroup> | ||||||||
| </> | ||||||||
| )} | ||||||||
| </> | ||||||||
| )} | ||||||||
| </CommandList> | ||||||||
| </CommandDialog> | ||||||||
| </> | ||||||||
| ); | ||||||||
| } | ||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import { Link } from "wouter"; | ||
| import { Wrench } from "lucide-react"; | ||
| import { SITE_NAME } from "@/hooks/use-page-title"; | ||
|
|
||
| export function SiteFooter() { | ||
| return ( | ||
| <footer className="border-t border-border"> | ||
| <div className="mx-auto max-w-7xl px-4 py-8 lg:px-8"> | ||
| <div className="flex flex-col items-start justify-between gap-6 sm:flex-row sm:items-center"> | ||
| <div className="flex items-center gap-2 text-sm font-semibold tracking-tight"> | ||
| <span className="grid h-7 w-7 place-items-center rounded-lg bg-primary text-primary-foreground"> | ||
| <Wrench className="h-4 w-4" /> | ||
| </span> | ||
| <span>{SITE_NAME}</span> | ||
| </div> | ||
| <div className="flex flex-wrap items-center gap-x-4 gap-y-2 text-sm text-muted-foreground"> | ||
| <Link href="/" className="transition-colors hover:text-foreground"> | ||
| Catalog | ||
| </Link> | ||
| <Link | ||
| href="/console" | ||
| className="transition-colors hover:text-foreground" | ||
| > | ||
| Command console | ||
| </Link> | ||
| <span className="text-muted-foreground/60"> | ||
| Tools run locally in your browser — nothing is uploaded. | ||
| </span> | ||
|
Comment on lines
+23
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: The privacy statement is false: the speed test posts payloads to Assessment: 🟠 Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** artifacts/personal-tool-console/src/components/layout/site-footer.tsx
**Line:** 23:25
**Comment:**
*Docstring Mismatch: The privacy statement is false: the speed test posts payloads to `/api/upload-test`, and other tools send entered domains and URLs to external services.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix |
||
| </div> | ||
| </div> | ||
| <p className="mt-6 text-xs text-muted-foreground/50"> | ||
| © {new Date().getFullYear()} {SITE_NAME}. | ||
| </p> | ||
| </div> | ||
| </footer> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| import { Link, useLocation } from "wouter"; | ||
| import { Wrench } from "lucide-react"; | ||
| import { CommandPalette } from "@/components/layout/command-palette"; | ||
| import { SITE_NAME } from "@/hooks/use-page-title"; | ||
| import { cn } from "@/lib/utils"; | ||
|
|
||
| const NAV = [ | ||
| { href: "/", label: "Catalog" }, | ||
| { href: "/console", label: "Console" }, | ||
| ]; | ||
|
|
||
| export function SiteHeader() { | ||
| const [path] = useLocation(); | ||
| return ( | ||
| <header className="sticky top-0 z-40 border-b border-border bg-background/80 backdrop-blur-xl"> | ||
| <div className="mx-auto flex h-14 max-w-7xl items-center justify-between gap-4 px-4 lg:px-8"> | ||
| <Link | ||
| href="/" | ||
| className="flex items-center gap-2 text-sm font-semibold tracking-tight" | ||
| > | ||
| <span className="grid h-7 w-7 place-items-center rounded-lg bg-primary text-primary-foreground"> | ||
| <Wrench className="h-4 w-4" /> | ||
| </span> | ||
| <span>{SITE_NAME}</span> | ||
| </Link> | ||
| <nav className="flex items-center gap-1 text-sm"> | ||
| {NAV.map((item) => { | ||
| const active = path === item.href; | ||
| return ( | ||
| <Link | ||
| key={item.href} | ||
| href={item.href} | ||
| className={cn( | ||
| "rounded-lg px-3 py-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground", | ||
| active && "bg-accent text-accent-foreground", | ||
| )} | ||
| > | ||
| {item.label} | ||
| </Link> | ||
| ); | ||
| })} | ||
| </nav> | ||
| <CommandPalette /> | ||
| </div> | ||
| </header> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❌ New issue: Complex Conditional
CommandPalette.onKey has 1 complex conditionals with 2 branches, threshold = 2
Suppress