mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-13 15:46:22 +00:00
fix(skills): UI section separation and fix find-alternatives rendering (#492)
* fix(skills): UI section separation and fix find-alternatives rendering - Split skills page into "My Skills" (user) and "BrowserOS Skills" (built-in) sections - Fix find-alternatives SKILL.md — replace angle bracket placeholders with curly braces to prevent MDXEditor from parsing them as JSX and rendering empty content * fix(skills): bump find-alternatives to v1.1 for CDN sync
This commit is contained in:
@@ -108,17 +108,12 @@ export const SkillsPage: FC = () => {
|
||||
) : null}
|
||||
|
||||
{!isLoading && !error && skills.length > 0 ? (
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-3">
|
||||
{skills.map((skill) => (
|
||||
<SkillCard
|
||||
key={skill.id}
|
||||
skill={skill}
|
||||
onEdit={() => handleEdit(skill)}
|
||||
onDelete={() => setSkillToDelete(skill)}
|
||||
onToggle={(enabled) => handleToggle(skill, enabled)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<SkillSections
|
||||
skills={skills}
|
||||
onEdit={handleEdit}
|
||||
onDelete={(skill) => setSkillToDelete(skill)}
|
||||
onToggle={handleToggle}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<SkillDialog
|
||||
@@ -251,6 +246,50 @@ const EmptyState: FC<{ onCreateClick: () => void }> = ({ onCreateClick }) => (
|
||||
</Card>
|
||||
)
|
||||
|
||||
const SkillGrid: FC<{ children: React.ReactNode }> = ({ children }) => (
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-3">
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
||||
const SkillSections: FC<{
|
||||
skills: SkillMeta[]
|
||||
onEdit: (skill: SkillMeta) => void
|
||||
onDelete: (skill: SkillMeta) => void
|
||||
onToggle: (skill: SkillMeta, enabled: boolean) => void
|
||||
}> = ({ skills, onEdit, onDelete, onToggle }) => {
|
||||
const userSkills = skills.filter((s) => !s.builtIn)
|
||||
const builtInSkills = skills.filter((s) => s.builtIn)
|
||||
|
||||
const renderCard = (skill: SkillMeta) => (
|
||||
<SkillCard
|
||||
key={skill.id}
|
||||
skill={skill}
|
||||
onEdit={() => onEdit(skill)}
|
||||
onDelete={() => onDelete(skill)}
|
||||
onToggle={(enabled) => onToggle(skill, enabled)}
|
||||
/>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{userSkills.length > 0 ? (
|
||||
<div className="space-y-3">
|
||||
<h3 className="font-semibold text-sm">My Skills</h3>
|
||||
<SkillGrid>{userSkills.map(renderCard)}</SkillGrid>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{builtInSkills.length > 0 ? (
|
||||
<div className="space-y-3">
|
||||
<h3 className="font-semibold text-sm">BrowserOS Skills</h3>
|
||||
<SkillGrid>{builtInSkills.map(renderCard)}</SkillGrid>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const SkillCard: FC<{
|
||||
skill: SkillMeta
|
||||
onEdit: () => void
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Find alternative products to something the user is looking at or co
|
||||
metadata:
|
||||
display-name: Find Alternatives
|
||||
enabled: "true"
|
||||
version: "1.0"
|
||||
version: "1.1"
|
||||
---
|
||||
|
||||
# Find Alternatives
|
||||
@@ -48,12 +48,12 @@ Activate when the user:
|
||||
|
||||
| Tab | Target | Query |
|
||||
|-----|--------|-------|
|
||||
| 1 | Google Shopping | `<product category> alternatives under $<budget>` |
|
||||
| 2 | Google Search | `best <product category> alternatives <year> reddit` |
|
||||
| 3 | Google Search | `<product category> vs comparison <year>` |
|
||||
| 4 | Amazon | `<product category>` filtered to price range |
|
||||
| 5 | Walmart | `<product category>` in price range |
|
||||
| 6 | Best Buy / category retailer | `<product category>` |
|
||||
| 1 | Google Shopping | `{product category} alternatives under ${budget}` |
|
||||
| 2 | Google Search | `best {product category} alternatives {year} reddit` |
|
||||
| 3 | Google Search | `{product category} vs comparison {year}` |
|
||||
| 4 | Amazon | `{product category}` filtered to price range |
|
||||
| 5 | Walmart | `{product category}` in price range |
|
||||
| 6 | Best Buy / category retailer | `{product category}` |
|
||||
| 7–10 | Review sites, Reddit threads, or niche retailers relevant to the category |
|
||||
|
||||
For **each tab**:
|
||||
@@ -64,10 +64,10 @@ For **each tab**:
|
||||
| Read results | `get_page_content` | Extract search results as markdown |
|
||||
| Visit promising results | `navigate_page` | Click through to individual product pages and review articles |
|
||||
| Extract data | `get_page_content` | Pull product details — name, price, features, ratings, reviews |
|
||||
| **Save immediately** | `evaluate_script` | Write to `raw/<n>-<source-slug>.json` (see format below) |
|
||||
| **Save immediately** | `evaluate_script` | Write to `raw/{n}-{source-slug}.json` (see format below) |
|
||||
| Close tab | `close_page` | Free the tab after saving |
|
||||
|
||||
#### Raw Data Format (`raw/<n>-<source-slug>.json`)
|
||||
#### Raw Data Format (`raw/{n}-{source-slug}.json`)
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -115,21 +115,21 @@ After all sources are saved:
|
||||
5. **Write `findings.md`** with the full ranking, reasoning, and source references:
|
||||
|
||||
```markdown
|
||||
# Alternatives for: <Reference Product>
|
||||
# Alternatives for: {Reference Product}
|
||||
|
||||
**Reference price:** $X
|
||||
**Budget range:** $X – $Y
|
||||
**Date:** <current date>
|
||||
**Date:** {current date}
|
||||
|
||||
## Top 5 Alternatives
|
||||
|
||||
### 1. <Product Name> — ⭐⭐⭐⭐⭐ (5/5)
|
||||
- **Price:** $X at <Retailer>
|
||||
- **Why:** <1–2 sentence justification>
|
||||
- **Link:** <product URL>
|
||||
- _Source: raw/<n>-<slug>.json_
|
||||
### 1. {Product Name} — ⭐⭐⭐⭐⭐ (5/5)
|
||||
- **Price:** $X at {Retailer}
|
||||
- **Why:** {1–2 sentence justification}
|
||||
- **Link:** {product URL}
|
||||
- _Source: raw/{n}-{slug}.json_
|
||||
|
||||
### 2. <Product Name> — ⭐⭐⭐⭐ (4/5)
|
||||
### 2. {Product Name} — ⭐⭐⭐⭐ (4/5)
|
||||
...
|
||||
|
||||
## Comparison vs Reference
|
||||
@@ -147,14 +147,14 @@ Generate a self-contained `report.html` in the output directory:
|
||||
| Requirement | Detail |
|
||||
|-------------|--------|
|
||||
| **Theme** | Light background (`#ffffff`), clean sans-serif typography, generous whitespace |
|
||||
| **Header** | "Alternatives for: <Product Name>", date, budget range |
|
||||
| **Header** | "Alternatives for: {Product Name}", date, budget range |
|
||||
| **Reference product card** | Show the original product with its price, rating, and link as the baseline |
|
||||
| **Top 5 cards** | Each alternative as a card showing: rank, name, rating (star visualization), price, key features, and a clickable "View Product" link to the actual product page |
|
||||
| **Comparison table** | Side-by-side table with the reference product and all 5 alternatives — price, rating, key features, pros/cons |
|
||||
| **Rating explanation** | Brief note on how the 1–5 rating was determined |
|
||||
| **Product links** | Every product name and "View Product" button must be a clickable `<a href>` to the actual product URL |
|
||||
| **Product links** | Every product name and "View Product" button must be a clickable link to the actual product URL |
|
||||
| **Source references** | Footer section listing all sources consulted with links |
|
||||
| **Self-contained** | All styles in a `<style>` block — no external CSS or JS |
|
||||
| **Self-contained** | All styles in a style block — no external CSS or JS |
|
||||
| **Responsive** | Readable on desktop and mobile |
|
||||
| **Footer** | "Generated by BrowserOS Find Alternatives" with date |
|
||||
|
||||
@@ -165,7 +165,7 @@ Use `evaluate_script` to write the HTML file.
|
||||
| Step | Tool | Detail |
|
||||
|------|------|--------|
|
||||
| Close hidden window | `close_window` | Clean up the research workspace |
|
||||
| Open report | `new_page` | Open `file://<path>/report.html` in the user's active window |
|
||||
| Open report | `new_page` | Open `file://{path}/report.html` in the user's active window |
|
||||
| Notify user | — | Summarize the top pick, mention the report path, and highlight any standout findings |
|
||||
|
||||
## Tool Reference
|
||||
@@ -186,4 +186,4 @@ Use `evaluate_script` to write the HTML file.
|
||||
- **Deduplicate across retailers** — the same product on Amazon and Walmart should appear once with the best price noted.
|
||||
- If the reference product is niche, broaden the search to the general category rather than exact alternatives.
|
||||
- Include at least one budget option and one premium option to give the user a range.
|
||||
- If a product has very few reviews (<50), note the low confidence in the rating.
|
||||
- If a product has very few reviews (under 50), note the low confidence in the rating.
|
||||
|
||||
Reference in New Issue
Block a user