feat(skills): blank-slate skills — install --no-skills + opt-out/opt-in (#36228)
* feat(install): --no-skills flag for blank-slate default profile Add an install-time --no-skills flag so the default ~/.hermes profile can be created with zero bundled skills, matching what `hermes profile create --no-skills` already does for named profiles. The flag writes $HERMES_HOME/.no-bundled-skills and skips the install-time seed. sync_skills() now honors that marker with an early return (skipped_opt_out=True), so neither the installer, a later `hermes update`, nor a direct sync re-injects bundled skills into a profile that opted out. Previously the marker was only checked by seed_profile_skills() (named profiles); the default profile had no opt-out and `hermes update` would re-seed it every time. Tests: TestNoBundledSkillsOptOut covers marker-present (no-op) and marker-absent (normal seed) paths. * feat(skills): hermes skills opt-out / opt-in for existing profiles Adds an interactive counterpart to the install-time --no-skills flag so an already-installed profile (default or named) can toggle the .no-bundled-skills marker without reinstalling. - `hermes skills opt-out` writes the marker (stop future seeding). Safe by default: nothing on disk is touched. - `hermes skills opt-out --remove` ALSO deletes already-present bundled skills, but ONLY ones that are manifest-tracked AND byte-identical to their origin hash. User-edited bundled skills, hub-installed skills, and hand-written skills are never removed. Previews + confirms before deleting (--yes to skip). - `hermes skills opt-in [--sync]` removes the marker and optionally re-seeds immediately. Core logic lives in tools/skills_sync.py (set_bundled_skills_opt_out, is_bundled_skills_opt_out, remove_pristine_bundled_skills) reusing the existing manifest origin-hash machinery for the safety check. Tests: TestOptOutToggleAndRemove covers marker toggle idempotency and proves user-modified + non-bundled skills survive --remove. * docs: blank-slate skills — install --no-skills + opt-out/opt-in - features/skills.md: new 'Starting with a blank slate' section covering the install flag, profile-create flag, and runtime opt-out/opt-in, with a safe-by-default note. - reference/cli-commands.md: document the new skills opt-out / opt-in subcommands + examples. - reference/profile-commands.md: fix the marker filename (was .no-skills, actually .no-bundled-skills) and cross-link the runtime commands. Validated with a full docusaurus build (exit 0); the three edited pages compile clean with no new warnings.
This commit is contained in:
@ -70,6 +70,7 @@ DETECTED_BROWSER_EXECUTABLE=""
|
||||
USE_VENV=true
|
||||
RUN_SETUP=true
|
||||
SKIP_BROWSER=false
|
||||
NO_SKILLS=false
|
||||
BRANCH="main"
|
||||
INSTALL_COMMIT=""
|
||||
ENSURE_DEPS=""
|
||||
@ -104,6 +105,10 @@ while [[ $# -gt 0 ]]; do
|
||||
SKIP_BROWSER=true
|
||||
shift
|
||||
;;
|
||||
--no-skills)
|
||||
NO_SKILLS=true
|
||||
shift
|
||||
;;
|
||||
--branch|-Branch)
|
||||
BRANCH="$2"
|
||||
shift 2
|
||||
@ -158,6 +163,9 @@ while [[ $# -gt 0 ]]; do
|
||||
echo " --no-venv Don't create virtual environment"
|
||||
echo " --skip-setup Skip interactive setup wizard"
|
||||
echo " --skip-browser Skip Playwright/Chromium install (browser tools won't work)"
|
||||
echo " --no-skills Start with a blank slate — seed no bundled skills, and"
|
||||
echo " write \$HERMES_HOME/.no-bundled-skills so future"
|
||||
echo " 'hermes update' runs never inject bundled skills either"
|
||||
echo " --branch NAME Git branch to install (default: main)"
|
||||
echo " --commit SHA Pin checkout to a specific commit after clone/update"
|
||||
echo " --manifest Print desktop bootstrap stage manifest as JSON"
|
||||
@ -1767,14 +1775,26 @@ SOUL_EOF
|
||||
log_success "Configuration directory ready: ~/.hermes/"
|
||||
|
||||
# Seed bundled skills into ~/.hermes/skills/ (manifest-based, one-time per skill)
|
||||
log_info "Syncing bundled skills to ~/.hermes/skills/ ..."
|
||||
if "$INSTALL_DIR/venv/bin/python" "$INSTALL_DIR/tools/skills_sync.py" 2>/dev/null; then
|
||||
log_success "Skills synced to ~/.hermes/skills/"
|
||||
if [ "$NO_SKILLS" = true ]; then
|
||||
# Blank-slate install: write the opt-out marker and skip seeding.
|
||||
# skills_sync.py and `hermes update` both honor this marker, so the
|
||||
# default profile stays empty across future updates too.
|
||||
printf '%s\n' \
|
||||
"This profile opted out of bundled-skill seeding (installed with --no-skills)." \
|
||||
"Delete this file to re-enable sync on the next 'hermes update'." \
|
||||
> "$HERMES_HOME/.no-bundled-skills" 2>/dev/null || true
|
||||
log_info "Skipping bundled skills (--no-skills). Wrote $HERMES_HOME/.no-bundled-skills"
|
||||
log_info " Future 'hermes update' runs will not inject bundled skills. Delete the marker to opt back in."
|
||||
else
|
||||
# Fallback: simple directory copy if Python sync fails
|
||||
if [ -d "$INSTALL_DIR/skills" ] && [ ! "$(ls -A "$HERMES_HOME/skills/" 2>/dev/null | grep -v '.bundled_manifest')" ]; then
|
||||
cp -r "$INSTALL_DIR/skills/"* "$HERMES_HOME/skills/" 2>/dev/null || true
|
||||
log_success "Skills copied to ~/.hermes/skills/"
|
||||
log_info "Syncing bundled skills to ~/.hermes/skills/ ..."
|
||||
if "$INSTALL_DIR/venv/bin/python" "$INSTALL_DIR/tools/skills_sync.py" 2>/dev/null; then
|
||||
log_success "Skills synced to ~/.hermes/skills/"
|
||||
else
|
||||
# Fallback: simple directory copy if Python sync fails
|
||||
if [ -d "$INSTALL_DIR/skills" ] && [ ! "$(ls -A "$HERMES_HOME/skills/" 2>/dev/null | grep -v '.bundled_manifest')" ]; then
|
||||
cp -r "$INSTALL_DIR/skills/"* "$HERMES_HOME/skills/" 2>/dev/null || true
|
||||
log_success "Skills copied to ~/.hermes/skills/"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user