Skip to content

web: skills in Settings — SkillsConfig in config.json, /api/config/skills, Skills pane; drop --skills-dir; v0.9.48 - #194

Merged
cymoo merged 2 commits into
mainfrom
web-skills-settings
Aug 10, 2026
Merged

web: skills in Settings — SkillsConfig in config.json, /api/config/skills, Skills pane; drop --skills-dir; v0.9.48#194
cymoo merged 2 commits into
mainfrom
web-skills-settings

Conversation

@cymoo

@cymoo cymoo commented Aug 10, 2026

Copy link
Copy Markdown
Owner

What

Skills support in the web UI Settings: view and manage skill directories from the browser, with per-directory discovery.

  • SkillsConfig in config.json — one precedence-ordered skills.dirs list; the pydantic default is [".agents/skills", "~/.agents/skills"] (project scope first, on duplicate skill names the earlier root wins). Removing a default from the list is how it gets disabled; the pane offers restoring it. No key in an older config.json → defaults apply unchanged.
  • --skills-dir / LOVIA_SKILLS_DIR removed — config.json is the single source of truth (pre-1.0 breaking change, patch bump per convention). The flag now fails with argparse's "unrecognized arguments".
  • Never bricks the boot — a listed directory that doesn't exist is skipped with an info log (previously resolve_skills_dirs raised UserError, which would have made a stale config.json unbootable once dirs live there). Schema-invalid entries (blank strings) still fail loudly with the standard "fix the file" hint.
  • PUT /api/config/skills — full-list replacement through the usual validate-by-building → persist → hot-swap path; GET /api/config/skills — live per-directory discovery report (found skills with descriptions, parse problems, shadowed duplicates, missing dirs) reusing DirectorySkillSource._read_metadata so validation can't drift from the served plugin.
  • Settings → Skills pane — directory rows with default badges and status lines, expandable skill lists, add/remove with immediate apply, restore-defaults, zh + en strings.

Verification

  • pytest 2309 passed; ruff check, mypy, and tsc --noEmit (CI-pinned) clean.
  • Playwright end-to-end against a live server: 18/18 checks — default rows + discovery, broken-SKILL.md problem row, shadowed duplicate badge, add/remove custom dir, missing-dir status with the server staying healthy, restore defaults, blank entry → 400, zh locale rendering.
  • Manual robustness: stale "dirs": ["/nope"] in config.json → boots with info log; "dirs": [""] → clean UserError naming skills; lovia web --skills-dir x → exit 2.

🤖 Generated with Claude Code

…ills, Skills pane; drop --skills-dir; v0.9.48

Skill directories move into config.json as a single precedence-ordered
skills.dirs list, defaulting to ./.agents/skills and ~/.agents/skills
(remove a default in Settings -> Skills to disable it). The pane shows
per-directory discovery: found skills, parse problems, shadowed
duplicates, missing paths. A listed directory that doesn't exist is
skipped at build time (info log), so a stale config.json can never make
the server unbootable. --skills-dir and LOVIA_SKILLS_DIR are removed;
config.json is the single source of truth (pre-1.0 breaking change).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 10, 2026 13:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class Skills management to the lovia web Settings UI, moving skill directory configuration into config.json and exposing new API endpoints for updating and scanning Skills roots without risking boot failures on missing directories.

Changes:

  • Introduces SkillsConfig in the web config schema (defaulting to [".agents/skills", "~/.agents/skills"]) and removes --skills-dir / LOVIA_SKILLS_DIR support.
  • Adds PUT /api/config/skills for config updates and GET /api/config/skills for live per-directory discovery status, plus a new Settings → Skills pane.
  • Updates docs/tests and bumps version to 0.9.48.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
uv.lock Updates locked package version to 0.9.48.
pyproject.toml Bumps project version to 0.9.48.
lovia/init.py Bumps __version__ to 0.9.48.
lovia/web/config/schema.py Adds SkillsConfig and default skills roots to WebConfig.
lovia/web/config/skills.py New module for skills root resolution and scan reporting.
lovia/web/config/init.py Re-exports skills config/constants and scan/resolve helpers.
lovia/web/builder.py Switches skills directory resolution to config.skills (no CLI/env).
lovia/web/api/config.py Adds PUT/GET /api/config/skills and includes skills in /api/config.
lovia/web/main.py Removes --skills-dir flag and related ignored-flag warnings.
lovia/web/static/js/api.js Adds api.setSkills() / api.getSkills() client methods.
lovia/web/static/js/settings.js Adds “Skills” tab to Settings dialog.
lovia/web/static/js/model-config.js Implements the Settings → Skills pane UI and behaviors.
lovia/web/static/js/i18n.js Adds zh/en strings for the new Skills UI.
lovia/web/static/styles.css Adds CSS styling for Skills pane rows and details.
tests/web/test_web_cli.py Updates CLI tests for new skills resolution + removed flag behavior.
tests/web/test_config_schema.py Adds schema/roundtrip tests for SkillsConfig.
tests/web/test_config_api.py Adds API tests for skills config update and scan reporting.
docs/en/web-ui.md Documents Skills directories management via Settings → Skills.
docs/en/skills.md Links to Web UI Skills behavior.
docs/en/http-api.md Documents new /api/config/skills endpoints.
docs/zh/web-ui.md Chinese docs updates for Skills directories management.
docs/zh/skills.md Chinese docs link to Web UI Skills behavior.
docs/zh/http-api.md Chinese HTTP API docs include /api/config/skills.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +677 to +687
try {
await api.setSkills({ dirs: next });
await loadConfig();
toast(t('cfg.saved'));
} catch (err) {
errBox.textContent = String(err.message || err);
errBox.hidden = false;
}
saving = false;
render();
};
Comment on lines +71 to +80
if not root.exists:
if root.kind == "project_default" and Path("skills").is_dir():
log.warning(
"./skills is no longer auto-loaded; move it to ./%s "
"or add it in Settings -> Skills",
DEFAULT_SKILLS_DIR,
)
else:
log.info("skills directory not found, skipped: %s", root.path)
continue
Comment on lines +40 to +55
def skill_roots(skills: SkillsConfig) -> list[SkillRoot]:
"""Every configured root in precedence order, deduplicated by identity."""
roots: list[SkillRoot] = []
seen: set[Path] = set()
for raw in skills.dirs:
expanded = Path(raw).expanduser()
key = expanded.resolve()
if key in seen:
continue
seen.add(key)
roots.append(
SkillRoot(
kind=_kind(raw), path=raw, resolved=expanded, exists=expanded.is_dir()
)
)
return roots
…rocess legacy hint, identity-duplicate rows stay removable

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cymoo

cymoo commented Aug 10, 2026

Copy link
Copy Markdown
Owner Author

Addressed all three review comments:

  1. Error visibilitysave() now reports failures via an error toast (matching the model-list actions), which survives the pane re-render; the dead errBox is gone.
  2. Legacy ./skills hint — fires once per process (module flag), matching the docstring; no more log spam on every hot-swap.
  3. Identity duplicatesskill_roots() no longer folds entries that resolve to the same directory: each configured string keeps its own removable row (the duplicate's skills show as shadowed), and only resolve_skills_dirs() dedupes the actual plugin roots. Pinned by test_skills_scan_keeps_identity_duplicates_visible.

Full suite, ruff, mypy, tsc, and the 18-check Playwright driver all pass on the fix.

@cymoo
cymoo merged commit df95852 into main Aug 10, 2026
9 checks passed
@cymoo
cymoo deleted the web-skills-settings branch August 10, 2026 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants