{"repo":"NousResearch/hermes-agent","public_id":"23746","display_label":"Clone profile from any source via dropdown","summary":"These issues and PRs relate to adding or requesting a feature that allows cloning a new profile from any existing profile, replacing a checkbox with a dropdown selector. The theme is consistent across a dashboard UI change and a corresponding profile backend feature.","subsystem":"hermes_cli","counts":{"members":3,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":1,"merged_prs":1,"attempt_prs":1},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":45630,"merged_at":"2026-06-13T14:33:59+00:00"},"resolution":{"state":"resolved","by":"pr-45630"},"freshness":{"state":"verified","last_verified_at":"2026-06-13T14:33:59+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.6666666666666666},"fix_edges":[{"issue_number":23746,"pr_number":45630,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-06-13T14:33:59+00:00"}],"members":[{"kind":"issue","number":23746,"title":"[Feature]: Dashboard — clone new profile from any profile (dropdown instead of checkbox)","url":null,"state":"closed"},{"kind":"pr","number":45558,"title":"feat(dashboard): clone new profile from any profile (dropdown instead of checkbox)","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#45630","number":45630}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":45630,"title":"feat(profile): clone profiles from any source","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["apps/desktop/src/app/chat/sidebar/profile-switcher.tsx","apps/desktop/src/app/profiles/create-profile-dialog.tsx","apps/desktop/src/app/profiles/index.tsx","apps/desktop/src/i18n/en.ts","apps/desktop/src/i18n/ja.ts","apps/desktop/src/i18n/types.ts","apps/desktop/src/i18n/zh-hant.ts","apps/desktop/src/i18n/zh.ts","apps/desktop/src/types/hermes.ts","docs/design/profile-builder.md","hermes_cli/main.py","hermes_cli/profiles.py","hermes_cli/subcommands/profile.py","hermes_cli/web_server.py","scripts/release.py","tests/hermes_cli/test_web_server.py","web/src/i18n/af.ts","web/src/i18n/de.ts","web/src/i18n/en.ts","web/src/i18n/es.ts","web/src/i18n/fr.ts","web/src/i18n/ga.ts","web/src/i18n/hu.ts","web/src/i18n/it.ts","web/src/i18n/ja.ts","web/src/i18n/ko.ts","web/src/i18n/pt.ts","web/src/i18n/ru.ts","web/src/i18n/tr.ts","web/src/i18n/types.ts","web/src/i18n/uk.ts","web/src/i18n/zh-hant.ts","web/src/i18n/zh.ts","web/src/lib/api.ts","web/src/pages/ProfileBuilderPage.tsx","web/src/pages/ProfilesPage.tsx","website/docs/reference/cli-commands.md","website/docs/reference/faq.md","website/docs/reference/profile-commands.md","website/docs/user-guide/profiles.md","website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/cli-commands.md","website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/faq.md","website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/profile-commands.md","website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/profiles.md"],"fix_hunks":[{"file":"apps/desktop/src/app/chat/sidebar/profile-switcher.tsx","hunks":["@@ -284,6 +284,7 @@ export function ProfileRail() {\n           selectProfile(name)\n         }}\n         open={createOpen}\n+        profiles={profiles}\n       />\n \n       <RenameProfileDialog"]},{"file":"apps/desktop/src/app/profiles/create-profile-dialog.tsx","hunks":["@@ -2,14 +2,15 @@ import { useEffect, useState } from 'react'\n \n import { ActionStatus } from '@/components/ui/action-status'\n import { Button } from '@/components/ui/button'\n-import { Checkbox } from '@/components/ui/checkbox'\n import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'\n import { Input } from '@/components/ui/input'\n+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\n import { Textarea } from '@/components/ui/textarea'\n import { createProfile, updateProfileSoul } from '@/hermes'\n import { useI18n } from '@/i18n'\n import { AlertTriangle } from '@/lib/icons'\n import { cn } from '@/lib/utils'\n+import type { ProfileInfo } from '@/types/hermes'\n \n const PROFILE_NAME_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/\n ","@@ -23,16 +24,18 @@ export function isValidProfileName(name: string): boolean {\n export function CreateProfileDialog({\n   onClose,\n   onCreated,\n-  open\n+  open,\n+  profiles = []\n }: {\n   onClose: () => void\n   onCreated?: (name: string) => Promise<void> | void\n   open: boolean\n+  profiles?: ProfileInfo[]\n }) {\n   const { t } = useI18n()\n   const p = t.profiles\n   const [name, setName] = useState('')\n-  const [cloneFromDefault, setCloneFromDefault] = useState(true)\n+  const [cloneFrom, setCloneFrom] = useState<null | string>('default')\n   const [soul, setSoul] = useState('')\n   const [status, setStatus] = useState<'done' | 'idle' | 'saving'>('idle')\n   const [error, setError] = useState<null | string>(null)","@@ -43,7 +46,7 @@ export function CreateProfileDialog({\n     }\n \n     setName('')\n-    setCloneFromDefault(true)\n+    setCloneFrom('default')\n     setSoul('')\n     setError(null)\n     setStatus('idle')","@@ -66,7 +69,7 @@ export function CreateProfileDialog({\n     setError(null)\n \n     try {\n-      await createProfile({ name: trimmed, clone_from_default: cloneFromDefault })\n+      await createProfile({ name: trimmed, clone_from: cloneFrom })\n \n       if (soul.trim()) {\n         await updateProfileSoul(trimmed, soul)","@@ -107,17 +110,25 @@ export function CreateProfileDialog({\n             </p>\n           </div>\n \n-          <label className=\"flex cursor-pointer select-none items-start gap-2.5 px-0.5 py-1\">\n-            <Checkbox\n-              checked={cloneFromDefault}\n-              className=\"mt-0.5 shrink-0\"\n-              onCheckedChange={checked => setCloneFromDefault(checked === true)}\n-            />\n-            <span className=\"grid gap-0.5 leading-snug\">\n-              <span className=\"text-sm font-medium\">{p.cloneFromDefault}</span>\n-              <span className=\"text-xs text-muted-foreground\">{p.cloneFromDefaultDesc}</span>\n-            </span>\n-          </label>\n+          <div className=\"grid gap-1.5\">\n+            <label className=\"text-xs font-medium\" htmlFor=\"new-profile-clone-from\">\n+              {p.cloneFrom}\n+            </label>\n+            <Select onValueChange={value => setCloneFrom(value === '__none__' ? null : value)} value={cloneFrom ?? '__none__'}>\n+              <SelectTrigger className=\"h-9 rounded-md\" id=\"new-profile-clone-from\">\n+                <SelectValue />\n+              </SelectTrigger>\n+              <SelectContent>\n+                <SelectItem value=\"__none__\">{p.cloneFromNone}</SelectItem>\n+                {profiles.map(profile => (\n+                  <SelectItem key={profile.name} value={profile.name}>\n+                    {profile.name}\n+                  </SelectItem>\n+                ))}\n+              </SelectContent>\n+            </Select>\n+            <p className=\"text-xs text-muted-foreground\">{p.cloneFromDesc}</p>\n+          </div>\n \n           <div className=\"grid gap-1.5\">\n             <label className=\"text-xs font-medium\" htmlFor=\"new-profile-soul\">","@@ -127,7 +138,7 @@ export function CreateProfileDialog({\n               className=\"min-h-28 font-mono text-xs leading-5\"\n               id=\"new-profile-soul\"\n               onChange={event => setSoul(event.target.value)}\n-              placeholder={p.soulPlaceholder(cloneFromDefault ? p.soulPlaceholderCloned : p.soulPlaceholderEmpty)}\n+              placeholder={p.soulPlaceholder(cloneFrom ? p.soulPlaceholderCloned : p.soulPlaceholderEmpty)}\n               value={soul}\n             />\n           </div>"]},{"file":"apps/desktop/src/app/profiles/index.tsx","hunks":["@@ -12,6 +12,7 @@ import {\n   DialogTitle\n } from '@/components/ui/dialog'\n import { Input } from '@/components/ui/input'\n+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\n import { Textarea } from '@/components/ui/textarea'\n import {\n   createProfile,","@@ -82,14 +83,14 @@ export function ProfilesView({ onClose }: ProfilesViewProps) {\n   }, [profiles, selectedName])\n \n   const handleCreate = useCallback(\n-    async (name: string, cloneFromDefault: boolean) => {\n+    async (name: string, cloneFrom: null | string) => {\n       const trimmed = name.trim()\n \n       if (!isValidProfileName(trimmed)) {\n         throw new Error(p.nameHint)\n       }\n \n-      await createProfile({ name: trimmed, clone_from_default: cloneFromDefault })\n+      await createProfile({ name: trimmed, clone_from: cloneFrom })\n       notify({ kind: 'success', title: p.created, message: trimmed })\n       setSelectedName(trimmed)\n       await refresh()","@@ -180,8 +181,9 @@ export function ProfilesView({ onClose }: ProfilesViewProps) {\n \n       <CreateProfileDialog\n           onClose={() => setCreateOpen(false)}\n-          onCreate={async (name, cloneFromDefault) => handleCreate(name, cloneFromDefault)}\n+          onCreate={async (name, cloneFrom) => handleCreate(name, cloneFrom)}\n           open={createOpen}\n+          profiles={profiles ?? []}\n         />\n \n         <Dialog onOpenChange={open => !open && !deleting && setPendingDelete(null)} open={pendingDelete !== null}>","@@ -453,16 +455,18 @@ function SoulEditor({ profileName }: { profileName: string }) {\n function CreateProfileDialog({\n   onClose,\n   onCreate,\n-  open\n+  open,\n+  profiles\n }: {\n   onClose: () => void\n-  onCreate: (name: string, cloneFromDefault: boolean) => Promise<void>\n+  onCreate: (name: string, cloneFrom: null | string) => Promise<void>\n   open: boolean\n+  profiles: ProfileInfo[]\n }) {\n   const { t } = useI18n()\n   const p = t.profiles\n   const [name, setName] = useState('')\n-  const [cloneFromDefault, setCloneFromDefault] = useState(true)\n+  const [cloneFrom, setCloneFrom] = useState<null | string>('default')\n   const [saving, setSaving] = useState(false)\n   const [error, setError] = useState<null | string>(null)\n ","@@ -472,7 +476,7 @@ function CreateProfileDialog({\n     }\n \n     setName('')\n-    setCloneFromDefault(true)\n+    setCloneFrom('default')\n     setError(null)\n     setSaving(false)\n   }, [open])","@@ -493,7 +497,7 @@ function CreateProfileDialog({\n     setError(null)\n \n     try {\n-      await onCreate(trimmed, cloneFromDefault)\n+      await onCreate(trimmed, cloneFrom)\n       onClose()\n     } catch (err) {\n       setError(err instanceof Error ? err.message : p.failedCreate)","@@ -528,18 +532,25 @@ function CreateProfileDialog({\n             </p>\n           </div>\n \n-          <label className=\"flex cursor-pointer items-center gap-2 rounded-md border border-border/40 bg-background/50 px-3 py-2 text-sm\">\n-            <input\n-              checked={cloneFromDefault}\n-              className=\"size-4 accent-primary\"\n-              onChange={event => setCloneFromDefault(event.target.checked)}\n-              type=\"checkbox\"\n-            />\n-            <span>\n-              <span className=\"font-medium\">{p.cloneFromDefault}</span>\n-              <span className=\"ml-2 text-xs text-muted-foreground\">{p.cloneFromDefaultDesc}</span>\n-            </span>\n-          </label>\n+          <div className=\"grid gap-1.5\">\n+            <label className=\"text-xs font-medium\" htmlFor=\"new-profile-clone-from\">\n+              {p.cloneFrom}\n+            </label>\n+            <Select onValueChange={value => setCloneFrom(value === '__none__' ? null : value)} value={cloneFrom ?? '__none__'}>\n+              <SelectTrigger className=\"h-9 rounded-md\" id=\"new-profile-clone-from\">\n+                <SelectValue />\n+              </SelectTrigger>\n+              <SelectContent>\n+                <SelectItem value=\"__none__\">{p.cloneFromNone}</SelectItem>\n+                {profiles.map(profile => (\n+                  <SelectItem key={profile.name} value={profile.name}>\n+                    {profile.name}\n+                  </SelectItem>\n+                ))}\n+              </SelectContent>\n+            </Select>\n+            <p className=\"text-xs text-muted-foreground\">{p.cloneFromDesc}</p>\n+          </div>\n \n           {error && (\n             <div className=\"flex items-start gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive\">"]},{"file":"apps/desktop/src/i18n/en.ts","hunks":["@@ -903,6 +903,9 @@ export const en: Translations = {\n     deleting: 'Deleting...',\n     createDesc: 'Profiles are independent Hermes environments: separate config, skills, and SOUL.md.',\n     nameLabel: 'Name',\n+    cloneFrom: 'Clone from',\n+    cloneFromNone: 'None (blank)',\n+    cloneFromDesc: 'Copies config, skills, and SOUL.md from the selected source profile.',\n     cloneFromDefault: 'Clone from default',\n     cloneFromDefaultDesc: 'Copy config, skills, and SOUL.md from your default profile.',\n     invalidName: hint => `Invalid name. ${hint}`,"]},{"file":"apps/desktop/src/i18n/ja.ts","hunks":["@@ -1041,6 +1041,9 @@ export const ja = defineLocale({\n     deleting: '削除中...',\n     createDesc: 'プロファイルは独立した Hermes 環境です：設定、スキル、SOUL.md が別々になります。',\n     nameLabel: '名前',\n+    cloneFrom: '複製元',\n+    cloneFromNone: 'なし（空）',\n+    cloneFromDesc: '選択したプロファイルから設定、スキル、SOUL.md をコピーします。',\n     cloneFromDefault: 'デフォルトプロファイルから設定を複製',\n     cloneFromDefaultDesc: 'デフォルトプロファイルから設定、スキル、SOUL.md をコピーします。',\n     invalidName: hint => `無効なプロファイル名。${hint}`,"]},{"file":"apps/desktop/src/i18n/types.ts","hunks":["@@ -695,6 +695,9 @@ export interface Translations {\n     deleting: string\n     createDesc: string\n     nameLabel: string\n+    cloneFrom: string\n+    cloneFromNone: string\n+    cloneFromDesc: string\n     cloneFromDefault: string\n     cloneFromDefaultDesc: string\n     invalidName: (hint: string) => string"]},{"file":"apps/desktop/src/i18n/zh-hant.ts","hunks":["@@ -999,6 +999,9 @@ export const zhHant = defineLocale({\n     deleting: '刪除中…',\n     createDesc: '設定檔是獨立的 Hermes 環境：各自擁有獨立的設定、技能和 SOUL.md。',\n     nameLabel: '名稱',\n+    cloneFrom: '複製來源',\n+    cloneFromNone: '無（空白）',\n+    cloneFromDesc: '從選取的來源設定檔複製設定、技能和 SOUL.md。',\n     cloneFromDefault: '從預設設定檔複製設定',\n     cloneFromDefaultDesc: '從您的預設設定檔複製設定、技能和 SOUL.md。',\n     invalidName: hint => `設定檔名稱無效。${hint}`,"]},{"file":"apps/desktop/src/i18n/zh.ts","hunks":["@@ -1092,6 +1092,9 @@ export const zh: Translations = {\n     deleting: '删除中…',\n     createDesc: '配置档案是相互独立的 Hermes 环境：各自拥有独立的配置、技能和 SOUL.md。',\n     nameLabel: '名称',\n+    cloneFrom: '克隆来源',\n+    cloneFromNone: '无（空白）',\n+    cloneFromDesc: '从选中的来源配置档案复制配置、技能和 SOUL.md。',\n     cloneFromDefault: '从默认档案克隆',\n     cloneFromDefaultDesc: '从你的默认配置档案复制配置、技能和 SOUL.md。',\n     invalidName: hint => `名称无效。${hint}`,"]},{"file":"apps/desktop/src/types/hermes.ts","hunks":["@@ -470,7 +470,7 @@ export interface CronJobUpdates {\n \n export interface ProfileCreatePayload {\n   clone_all?: boolean\n-  clone_from?: string\n+  clone_from?: null | string\n   clone_from_default?: boolean\n   name: string\n   no_skills?: boolean"]},{"file":"docs/design/profile-builder.md","hunks":["@@ -85,6 +85,8 @@ Extend `ProfileCreate` and the create endpoint — no new endpoints, no rewrite:\n ```python\n class ProfileCreate(BaseModel):\n     name: str\n+    clone_from: Optional[str] = None\n+    # Backward compatibility for older dashboard/desktop clients.\n     clone_from_default: bool = False\n     clone_all: bool = False\n     no_skills: bool = False"]},{"file":"hermes_cli/main.py","hunks":["@@ -9860,19 +9860,20 @@ def cmd_profile(args):\n \n         try:\n             clone_from = getattr(args, \"clone_from\", None)\n+            clone_config = clone or clone_from is not None\n \n             profile_dir = create_profile(\n                 name=name,\n                 clone_from=clone_from,\n                 clone_all=clone_all,\n-                clone_config=clone,\n+                clone_config=clone_config,\n                 no_alias=no_alias,\n                 no_skills=no_skills,\n                 description=getattr(args, \"description\", None),\n             )\n             print(f\"\\nProfile '{name}' created at {profile_dir}\")\n \n-            if clone or clone_all:\n+            if clone_config or clone_all:\n                 source_label = (\n                     getattr(args, \"clone_from\", None) or get_active_profile_name()\n                 )","@@ -9886,8 +9887,8 @@ def cmd_profile(args):\n                         f\"Cloned config, .env, SOUL.md, and skills from {source_label}.\"\n                     )\n \n-            # Auto-clone Honcho config for the new profile (only with --clone/--clone-all)\n-            if clone or clone_all:\n+            # Auto-clone Honcho config for the new profile (only with clone operations)\n+            if clone_config or clone_all:\n                 try:\n                     from plugins.memory.honcho.cli import clone_honcho_for_profile\n ","@@ -9896,10 +9897,10 @@ def cmd_profile(args):\n                 except Exception:\n                     pass  # Honcho plugin not installed or not configured\n \n-            # Seed bundled skills (skip if --clone-all already copied them, or\n-            # if --no-skills was passed — in which case seed_profile_skills()\n-            # honors the marker file and returns skipped_opt_out=True).\n-            if not clone_all:\n+            # Seed bundled skills for fresh profiles only. Clone operations\n+            # already copied the source profile's skills, including any\n+            # user-installed or intentionally removed skills.\n+            if not (clone_config or clone_all):\n                 result = seed_profile_skills(profile_dir)\n                 if result and result.get(\"skipped_opt_out\"):\n                     print("]},{"file":"hermes_cli/profiles.py","hunks":["@@ -784,9 +784,9 @@ def create_profile(\n     Path\n         The newly created profile directory.\n     \"\"\"\n-    if no_skills and (clone_config or clone_all):\n+    if no_skills and (clone_from is not None or clone_config or clone_all):\n         raise ValueError(\n-            \"--no-skills is mutually exclusive with --clone / --clone-all \"\n+            \"--no-skills is mutually exclusive with --clone / --clone-from / --clone-all \"\n             \"(cloning explicitly copies skills from the source profile).\"\n         )\n     canon = normalize_profile_name(name)"]},{"file":"hermes_cli/subcommands/profile.py","hunks":["@@ -35,17 +35,17 @@ def build_profile_parser(subparsers, *, cmd_profile: Callable) -> None:\n     profile_create.add_argument(\n         \"--clone\",\n         action=\"store_true\",\n-        help=\"Copy config.yaml, .env, SOUL.md from active profile\",\n+        help=\"Copy config.yaml, .env, SOUL.md, and skills from active profile\",\n     )\n     profile_create.add_argument(\n         \"--clone-all\",\n         action=\"store_true\",\n-        help=\"Full copy of active profile (all state)\",\n+        help=\"Full copy of active profile (all state, excluding per-profile history)\",\n     )\n     profile_create.add_argument(\n         \"--clone-from\",\n         metavar=\"SOURCE\",\n-        help=\"Source profile to clone from (default: active)\",\n+        help=\"Source profile to clone from; implies --clone unless --clone-all is set\",\n     )\n     profile_create.add_argument(\n         \"--no-alias\", action=\"store_true\", help=\"Skip wrapper script creation\""]},{"file":"hermes_cli/web_server.py","hunks":["@@ -8493,15 +8493,13 @@ def _run():\n \n class ProfileCreate(BaseModel):\n     name: str\n+    clone_from: Optional[str] = None\n+    # Backward compatibility for older dashboard/desktop clients. New clients\n+    # send clone_from=\"default\" (or another profile name) explicitly.\n     clone_from_default: bool = False\n     clone_all: bool = False\n     no_skills: bool = False\n     description: Optional[str] = None\n-    # Explicit source profile to clone from (e.g. duplicating an existing\n-    # profile). When set, it takes precedence over ``clone_from_default``,\n-    # which always sources from \"default\". ``clone_all`` still selects a full\n-    # state copytree vs. a config/skills/SOUL copy.\n-    clone_from: Optional[str] = None\n     provider: Optional[str] = None\n     model: Optional[str] = None\n     # Profile-builder additions — all optional, all applied best-effort AFTER","@@ -8773,10 +8771,16 @@ async def create_profile_endpoint(body: ProfileCreate):\n         clone = True\n         clone_from = explicit_source\n         clone_config = not body.clone_all\n+    elif body.clone_all:\n+        # Preserve the dashboard's historical clone-all behavior: a full-copy\n+        # request with no explicit dropdown source copies from default.\n+        clone = True\n+        clone_from = \"default\"\n+        clone_config = False\n     else:\n-        clone = body.clone_from_default or body.clone_all\n+        clone = body.clone_from_default\n         clone_from = \"default\" if clone else None\n-        clone_config = body.clone_from_default and not body.clone_all\n+        clone_config = clone\n     try:\n         path = profiles_mod.create_profile(\n             name=body.name,"]},{"file":"scripts/release.py","hunks":["@@ -494,6 +494,7 @@\n     \"[redacted:email]\": \"nik1t7n\",\n     \"90299797+nik1t7n@users.noreply.github.com\": \"nik1t7n\",\n     \"[redacted:email]\": \"suncokret12\",\n+    \"[redacted:email]\": \"WompaJango\",\n     \"[redacted:email]\": \"mioimotoai-lgtm\",\n     \"[redacted:email]\": \"heyitsaamir\",\n     \"[redacted:email]\": \"johnncenae\","]},{"file":"tests/hermes_cli/test_web_server.py","hunks":["@@ -2633,7 +2633,7 @@ def test_profiles_create_creates_wrapper_alias_when_safe(self, monkeypatch, tmp_\n \n         resp = self.client.post(\n             \"/api/profiles\",\n-            json={\"name\": \"writer\", \"clone_from_default\": False},\n+            json={\"name\": \"writer\", \"clone_from\": None},\n         )\n \n         assert resp.status_code == 200","@@ -2641,7 +2641,7 @@ def test_profiles_create_creates_wrapper_alias_when_safe(self, monkeypatch, tmp_\n         assert wrapper_path.exists()\n         assert wrapper_path.read_text() == '#!/bin/sh\\nexec hermes -p writer \"$@\"\\n'\n \n-    def test_profiles_create_with_clone_from_default_copies_default_skills(self, monkeypatch):\n+    def test_profiles_create_with_clone_from_copies_source_skills(self, monkeypatch):\n         from hermes_constants import get_hermes_home\n         import hermes_cli.profiles as profiles_mod\n ","@@ -2652,7 +2652,7 @@ def test_profiles_create_with_clone_from_default_copies_default_skills(self, mon\n \n         resp = self.client.post(\n             \"/api/profiles\",\n-            json={\"name\": \"cloned\", \"clone_from_default\": True},\n+            json={\"name\": \"cloned\", \"clone_from\": \"default\"},\n         )\n \n         assert resp.status_code == 200","@@ -2685,6 +2685,28 @@ def test_profiles_create_with_clone_from_duplicates_source(self, monkeypatch):\n         )\n         assert cloned_skill.exists()\n \n+    def test_profiles_create_clone_all_from_named_source(self, monkeypatch):\n+        from hermes_constants import get_hermes_home\n+        import hermes_cli.profiles as profiles_mod\n+\n+        monkeypatch.setattr(profiles_mod, \"create_wrapper_script\", lambda name: None)\n+\n+        assert self.client.post(\"/api/profiles\", json={\"name\": \"full-src\"}).status_code == 200\n+        source_dir = get_hermes_home() / \"profiles\" / \"full-src\"\n+        (source_dir / \"config.yaml\").write_text(\"model:\\n  provider: source-only\\n\", encoding=\"utf-8\")\n+        (source_dir / \"workspace\" / \"artifact.txt\").parent.mkdir(parents=True, exist_ok=True)\n+        (source_dir / \"workspace\" / \"artifact.txt\").write_text(\"copied\", encoding=\"utf-8\")\n+\n+        resp = self.client.post(\n+            \"/api/profiles\",\n+            json={\"name\": \"full-copy\", \"clone_from\": \"full-src\", \"clone_all\": True},\n+        )\n+\n+        assert resp.status_code == 200\n+        target_dir = get_hermes_home() / \"profiles\" / \"full-copy\"\n+        assert (target_dir / \"config.yaml\").read_text(encoding=\"utf-8\") == \"model:\\n  provider: source-only\\n\"\n+        assert (target_dir / \"workspace\" / \"artifact.txt\").read_text(encoding=\"utf-8\") == \"copied\"\n+\n     def test_profiles_create_without_clone_seeds_bundled_skills(self, monkeypatch):\n         from hermes_constants import get_hermes_home\n         import hermes_cli.profiles as profiles_mod","@@ -2701,7 +2723,7 @@ def fake_seed(profile_dir, quiet=False):\n \n         resp = self.client.post(\n             \"/api/profiles\",\n-            json={\"name\": \"fresh\", \"clone_from_default\": False},\n+            json={\"name\": \"fresh\", \"clone_from\": None},\n         )\n \n         assert resp.status_code == 200"]},{"file":"web/src/i18n/af.ts","hunks":["@@ -286,8 +286,8 @@ export const af: Translations = {\n     nameRequired: \"Naam word vereis\",\n     nameRule:\n       \"Slegs kleinletters, syfers, _ en -; moet met 'n letter of syfer begin; tot 64 karakters.\",\n-    invalidName: \"Ongeldige profielnaam\",\n-    cloneFromDefault: \"Kloon konfigurasie vanaf verstekprofiel\",\n+    invalidName: \"Ongeldige profielnaam\",    cloneFrom: \"Kloon konfigurasie vanaf profiel\",\n+    cloneFromNone: \"Geen (leeg)\",\n     allProfiles: \"Profiele\",\n     noProfiles: \"Geen profiele gevind nie.\",\n     defaultBadge: \"verstek\","]},{"file":"web/src/i18n/de.ts","hunks":["@@ -286,8 +286,8 @@ export const de: Translations = {\n     nameRequired: \"Name ist erforderlich\",\n     nameRule:\n       \"Nur Kleinbuchstaben, Ziffern, _ und -; muss mit einem Buchstaben oder einer Ziffer beginnen; maximal 64 Zeichen.\",\n-    invalidName: \"Ungültiger Profilname\",\n-    cloneFromDefault: \"Konfiguration vom Standardprofil klonen\",\n+    invalidName: \"Ungültiger Profilname\",    cloneFrom: \"Konfiguration klonen von\",\n+    cloneFromNone: \"Keine (leer)\",\n     allProfiles: \"Profile\",\n     noProfiles: \"Keine Profile gefunden.\",\n     defaultBadge: \"Standard\","]},{"file":"web/src/i18n/en.ts","hunks":["@@ -297,7 +297,8 @@ export const en: Translations = {\n     nameRule:\n       \"Lowercase letters, digits, _ and - only; must start with a letter or digit; up to 64 characters.\",\n     invalidName: \"Invalid profile name\",\n-    cloneFromDefault: \"Clone config from default profile\",\n+    cloneFrom: \"Clone config from\",\n+    cloneFromNone: \"None (blank)\",\n     allProfiles: \"Profiles\",\n     noProfiles: \"No profiles found.\",\n     defaultBadge: \"default\","]},{"file":"web/src/i18n/es.ts","hunks":["@@ -287,7 +287,8 @@ export const es: Translations = {\n     nameRule:\n       \"Solo letras minúsculas, dígitos, _ y -; debe comenzar con una letra o dígito; hasta 64 caracteres.\",\n     invalidName: \"Nombre de perfil no válido\",\n-    cloneFromDefault: \"Clonar configuración del perfil predeterminado\",\n+    cloneFrom: \"Clonar desde el perfil\",\n+    cloneFromNone: \"Ninguno (vacío)\",\n     allProfiles: \"Perfiles\",\n     noProfiles: \"No se encontraron perfiles.\",\n     defaultBadge: \"predeterminado\","]},{"file":"web/src/i18n/fr.ts","hunks":["@@ -287,7 +287,8 @@ export const fr: Translations = {\n     nameRule:\n       \"Lettres minuscules, chiffres, _ et - uniquement ; doit commencer par une lettre ou un chiffre ; jusqu'à 64 caractères.\",\n     invalidName: \"Nom de profil invalide\",\n-    cloneFromDefault: \"Cloner la configuration du profil par défaut\",\n+    cloneFrom: \"Cloner depuis le profil\",\n+    cloneFromNone: \"Aucun (vide)\",\n     allProfiles: \"Profils\",\n     noProfiles: \"Aucun profil trouvé.\",\n     defaultBadge: \"défaut\","]},{"file":"web/src/i18n/ga.ts","hunks":["@@ -294,8 +294,8 @@ export const ga: Translations = {\n     nameRequired: \"Tá ainm riachtanach\",\n     nameRule:\n       \"Litreacha cás íochtair, digití, _ agus - amháin; caithfidh tús a chur le litir nó digit; suas le 64 carachtar.\",\n-    invalidName: \"Ainm próifíle neamhbhailí\",\n-    cloneFromDefault: \"Clónáil cumraíocht ón bpróifíl réamhshocraithe\",\n+    invalidName: \"Ainm próifíle neamhbhailí\",    cloneFrom: \"Clónáil cumraíocht ón bpróifíl\",\n+    cloneFromNone: \"Dada (folamh)\",\n     allProfiles: \"Próifílí\",\n     noProfiles: \"Níor aimsíodh próifílí.\",\n     defaultBadge: \"réamhshocraithe\","]},{"file":"web/src/i18n/hu.ts","hunks":["@@ -286,8 +286,8 @@ export const hu: Translations = {\n     nameRequired: \"A név kötelező\",\n     nameRule:\n       \"Csak kisbetűk, számjegyek, _ és - karakterek; betűvel vagy számjeggyel kell kezdődnie; legfeljebb 64 karakter.\",\n-    invalidName: \"Érvénytelen profilnév\",\n-    cloneFromDefault: \"Konfiguráció klónozása az alapértelmezett profilból\",\n+    invalidName: \"Érvénytelen profilnév\",    cloneFrom: \"Konfiguráció klónozása ebből a profilból\",\n+    cloneFromNone: \"Nincs (üres)\",\n     allProfiles: \"Profilok\",\n     noProfiles: \"Nem található profil.\",\n     defaultBadge: \"alapértelmezett\","]},{"file":"web/src/i18n/it.ts","hunks":["@@ -286,8 +286,8 @@ export const it: Translations = {\n     nameRequired: \"Il nome è obbligatorio\",\n     nameRule:\n       \"Solo lettere minuscole, cifre, _ e -; deve iniziare con una lettera o cifra; fino a 64 caratteri.\",\n-    invalidName: \"Nome del profilo non valido\",\n-    cloneFromDefault: \"Clona la configurazione dal profilo predefinito\",\n+    invalidName: \"Nome del profilo non valido\",    cloneFrom: \"Clona configurazione dal profilo\",\n+    cloneFromNone: \"Nessuno (vuoto)\",\n     allProfiles: \"Profili\",\n     noProfiles: \"Nessun profilo trovato.\",\n     defaultBadge: \"predefinito\","]},{"file":"web/src/i18n/ja.ts","hunks":["@@ -285,8 +285,8 @@ export const ja: Translations = {\n     nameRequired: \"名前は必須です\",\n     nameRule:\n       \"小文字、数字、_ および - のみ使用可能。最初は文字または数字で始める必要があります。最大 64 文字。\",\n-    invalidName: \"無効なプロファイル名\",\n-    cloneFromDefault: \"デフォルトプロファイルから設定を複製\",\n+    invalidName: \"無効なプロファイル名\",    cloneFrom: \"プロファイルから複製\",\n+    cloneFromNone: \"なし（空）\",\n     allProfiles: \"プロファイル\",\n     noProfiles: \"プロファイルが見つかりません。\",\n     defaultBadge: \"デフォルト\","]},{"file":"web/src/i18n/ko.ts","hunks":["@@ -285,8 +285,8 @@ export const ko: Translations = {\n     nameRequired: \"이름은 필수입니다\",\n     nameRule:\n       \"소문자, 숫자, _ 및 - 만 사용 가능합니다. 문자나 숫자로 시작해야 하며 최대 64자입니다.\",\n-    invalidName: \"잘못된 프로필 이름입니다\",\n-    cloneFromDefault: \"기본 프로필에서 설정 복제\",\n+    invalidName: \"잘못된 프로필 이름입니다\",    cloneFrom: \"프로필에서 복제\",\n+    cloneFromNone: \"없음 (빈 상태)\",\n     allProfiles: \"프로필\",\n     noProfiles: \"프로필을 찾을 수 없습니다.\",\n     defaultBadge: \"기본\","]},{"file":"web/src/i18n/pt.ts","hunks":["@@ -287,7 +287,8 @@ export const pt: Translations = {\n     nameRule:\n       \"Apenas letras minúsculas, dígitos, _ e -; deve começar com letra ou dígito; até 64 caracteres.\",\n     invalidName: \"Nome de perfil inválido\",\n-    cloneFromDefault: \"Clonar configuração do perfil predefinido\",\n+    cloneFrom: \"Clonar a partir do perfil\",\n+    cloneFromNone: \"Nenhum (vazio)\",\n     allProfiles: \"Perfis\",\n     noProfiles: \"Não foram encontrados perfis.\",\n     defaultBadge: \"predefinido\","]},{"file":"web/src/i18n/ru.ts","hunks":["@@ -286,8 +286,8 @@ export const ru: Translations = {\n     nameRequired: \"Имя обязательно\",\n     nameRule:\n       \"Только строчные буквы, цифры, _ и -; должно начинаться с буквы или цифры; до 64 символов.\",\n-    invalidName: \"Недопустимое имя профиля\",\n-    cloneFromDefault: \"Клонировать конфигурацию из профиля по умолчанию\",\n+    invalidName: \"Недопустимое имя профиля\",    cloneFrom: \"Клонировать конфигурацию из профиля\",\n+    cloneFromNone: \"Нет (пусто)\",\n     allProfiles: \"Профили\",\n     noProfiles: \"Профили не найдены.\",\n     defaultBadge: \"по умолчанию\","]},{"file":"web/src/i18n/tr.ts","hunks":["@@ -286,8 +286,8 @@ export const tr: Translations = {\n     nameRequired: \"Ad gereklidir\",\n     nameRule:\n       \"Yalnızca küçük harfler, rakamlar, _ ve - kullanılabilir; harf veya rakamla başlamalı; en fazla 64 karakter.\",\n-    invalidName: \"Geçersiz profil adı\",\n-    cloneFromDefault: \"Varsayılan profilden yapılandırmayı klonla\",\n+    invalidName: \"Geçersiz profil adı\",    cloneFrom: \"Profilden yapılandırmayı klonla\",\n+    cloneFromNone: \"Hiçbiri (boş)\",\n     allProfiles: \"Profiller\",\n     noProfiles: \"Profil bulunamadı.\",\n     defaultBadge: \"varsayılan\","]},{"file":"web/src/i18n/types.ts","hunks":["@@ -354,7 +354,8 @@ export interface Translations {\n     nameRequired: string;\n     nameRule: string;\n     invalidName: string;\n-    cloneFromDefault: string;\n+    cloneFrom: string;\n+    cloneFromNone: string;\n     allProfiles: string;\n     noProfiles: string;\n     defaultBadge: string;"]},{"file":"web/src/i18n/uk.ts","hunks":["@@ -287,7 +287,8 @@ export const uk: Translations = {\n     nameRule:\n       \"Лише малі літери, цифри, _ та -; має починатися з літери або цифри; до 64 символів.\",\n     invalidName: \"Недопустима назва профілю\",\n-    cloneFromDefault: \"Клонувати конфігурацію з профілю за замовчуванням\",\n+    cloneFrom: \"Клонувати з профілю\",\n+    cloneFromNone: \"Жоден (порожній)\",\n     allProfiles: \"Профілі\",\n     noProfiles: \"Профілів не знайдено.\",\n     defaultBadge: \"за замовчуванням\","]},{"file":"web/src/i18n/zh-hant.ts","hunks":["@@ -285,8 +285,8 @@ export const zhHant: Translations = {\n     nameRequired: \"名稱為必填\",\n     nameRule:\n       \"僅允許小寫字母、數字、底線及連字號；首字必須為字母或數字；最多 64 個字元。\",\n-    invalidName: \"設定檔名稱無效\",\n-    cloneFromDefault: \"從預設設定檔複製設定\",\n+    invalidName: \"設定檔名稱無效\",    cloneFrom: \"從設定檔複製\",\n+    cloneFromNone: \"無（空白）\",\n     allProfiles: \"設定檔\",\n     noProfiles: \"找不到設定檔。\",\n     defaultBadge: \"預設\","]},{"file":"web/src/i18n/zh.ts","hunks":["@@ -282,8 +282,8 @@ export const zh: Translations = {\n     nameRequired: \"名称必填\",\n     nameRule:\n       \"仅允许小写字母、数字、下划线和短横线；首字符必须是字母或数字；最多 64 个字符。\",\n-    invalidName: \"多Agent配置名称非法\",\n-    cloneFromDefault: \"从默认多Agent配置克隆配置\",\n+    invalidName: \"多Agent配置名称非法\",    cloneFrom: \"从配置文件克隆\",\n+    cloneFromNone: \"无（空白）\",\n     allProfiles: \"多Agent配置列表\",\n     noProfiles: \"暂无多Agent配置。\",\n     defaultBadge: \"默认\","]},{"file":"web/src/lib/api.ts","hunks":["@@ -552,7 +552,8 @@ export const api = {\n     }),\n   createProfile: (body: {\n     name: string;\n-    clone_from_default: boolean;\n+    clone_from?: string | null;\n+    clone_from_default?: boolean;\n     clone_all?: boolean;\n     no_skills?: boolean;\n     description?: string;"]},{"file":"web/src/pages/ProfileBuilderPage.tsx","hunks":["@@ -220,7 +220,7 @@ export default function ProfileBuilderPage() {\n     try {\n       const res = await api.createProfile({\n         name: n,\n-        clone_from_default: false,\n+        clone_from: null,\n         description: description.trim() || undefined,\n         provider: pickedModel?.provider,\n         model: pickedModel?.model,"]},{"file":"web/src/pages/ProfilesPage.tsx","hunks":["@@ -35,11 +35,11 @@ import { Badge } from \"@nous-research/ui/ui/components/badge\";\n import { Button } from \"@nous-research/ui/ui/components/button\";\n import { Input } from \"@nous-research/ui/ui/components/input\";\n import { Label } from \"@nous-research/ui/ui/components/label\";\n-import { Checkbox } from \"@nous-research/ui/ui/components/checkbox\";\n import {\n   Select,\n   SelectOption,\n } from \"@nous-research/ui/ui/components/select\";\n+import { Checkbox } from \"@nous-research/ui/ui/components/checkbox\";\n import { useI18n } from \"@/i18n\";\n import { usePageHeader } from \"@/contexts/usePageHeader\";\n import { cn, themedBody } from \"@/lib/utils\";","@@ -312,7 +312,7 @@ export default function ProfilesPage() {\n   // Create modal\n   const [createModalOpen, setCreateModalOpen] = useState(false);\n   const [newName, setNewName] = useState(\"\");\n-  const [cloneFromDefault, setCloneFromDefault] = useState(true);\n+  const [cloneFrom, setCloneFrom] = useState<string | null>(\"default\");\n   const [cloneAll, setCloneAll] = useState(false);\n   const [noSkills, setNoSkills] = useState(false);\n   const [newDescription, setNewDescription] = useState(\"\");","@@ -429,7 +429,7 @@ export default function ProfilesPage() {\n     }\n     setCreating(true);\n     try {\n-      const cloning = cloneAll || cloneFromDefault;\n+      const cloning = cloneFrom !== null;\n       const picked = modelChoice\n         ? modelChoices?.find(\n             (c) => `${c.provider}\\u0000${c.model}` === modelChoice,","@@ -437,8 +437,8 @@ export default function ProfilesPage() {\n         : undefined;\n       const res = await api.createProfile({\n         name,\n-        clone_from_default: cloneAll ? false : cloneFromDefault,\n-        clone_all: cloneAll,\n+        clone_from: cloneFrom,\n+        clone_all: cloning && cloneAll,\n         no_skills: cloning ? false : noSkills,\n         description: newDescription.trim() || undefined,\n         provider: picked?.provider,","@@ -455,7 +455,7 @@ export default function ProfilesPage() {\n       setNewDescription(\"\");\n       setNoSkills(false);\n       setCloneAll(false);\n-      setCloneFromDefault(true);\n+      setCloneFrom(\"default\");\n       setModelChoice(\"\");\n       setCreateModalOpen(false);\n       load();","@@ -772,7 +772,7 @@ export default function ProfilesPage() {\n     };\n   }, [setEnd, t.common.create, loading, navigate]);\n \n-  const cloning = cloneAll || cloneFromDefault;\n+  const cloning = cloneFrom !== null;\n \n   if (loading) {\n     return (","@@ -862,6 +862,26 @@ export default function ProfilesPage() {\n                 </p>\n               </div>\n \n+              <div className=\"grid gap-2\">\n+                <Label htmlFor=\"clone-from\">{t.profiles.cloneFrom}</Label>\n+                <Select\n+                  id=\"clone-from\"\n+                  value={cloneFrom ?? \"\"}\n+                  onValueChange={(v) => {\n+                    const next = v || null;\n+                    setCloneFrom(next);\n+                    if (next === null) setCloneAll(false);\n+                  }}\n+                >\n+                  <SelectOption value=\"\">{t.profiles.cloneFromNone}</SelectOption>\n+                  {profiles.map((profile) => (\n+                    <SelectOption key={profile.name} value={profile.name}>\n+                      {profile.name}\n+                    </SelectOption>\n+                  ))}\n+                </Select>\n+              </div>\n+\n               <div className=\"grid gap-2\">\n                 <Label htmlFor=\"profile-description\">\n                   {L.descriptionOptional}","@@ -909,33 +929,19 @@ export default function ProfilesPage() {\n                   {L.advancedOptions}\n                 </legend>\n \n-                <div className=\"flex items-center gap-2.5\">\n-                  <Checkbox\n-                    checked={cloneFromDefault}\n-                    id=\"clone-from-default\"\n-                    disabled={cloneAll}\n-                    onCheckedChange={(checked) =>\n-                      setCloneFromDefault(checked === true)\n-                    }\n-                  />\n-\n-                  <Label\n-                    className=\"font-mondwest normal-case tracking-normal text-sm cursor-pointer\"\n-                    htmlFor=\"clone-from-default\"\n-                  >\n-                    {t.profiles.cloneFromDefault}\n-                  </Label>\n-                </div>\n-\n                 <div className=\"flex items-center gap-2.5\">\n                   <Checkbox\n                     checked={cloneAll}\n+                    disabled={!cloning}\n                     id=\"clone-all\"\n                     onCheckedChange={(checked) => setCloneAll(checked === true)}\n                   />\n \n                   <Label\n-                    className=\"font-mondwest normal-case tracking-normal text-sm cursor-pointer\"\n+                    className={cn(\n+                      \"font-mondwest normal-case tracking-normal text-sm cursor-pointer\",\n+                      !cloning && \"opacity-50\",\n+                    )}\n                     htmlFor=\"clone-all\"\n                   >\n                     {L.cloneAll}"]},{"file":"website/docs/reference/cli-commands.md","hunks":["@@ -1396,7 +1396,7 @@ Manage profiles — multiple isolated Hermes instances, each with its own config\n |------------|-------------|\n | `list` | List all profiles. |\n | `use <name>` | Set a sticky default profile. |\n-| `create <name> [--clone] [--clone-all] [--clone-from <source>] [--no-alias]` | Create a new profile. `--clone` copies config, `.env`, and `SOUL.md` from the active profile. `--clone-all` copies all state. `--clone-from` specifies a source profile. |\n+| `create <name> [--clone] [--clone-all] [--clone-from <source>] [--no-alias]` | Create a new profile. `--clone` copies config, `.env`, `SOUL.md`, and skills from the active profile. `--clone-all` copies all state. `--clone-from` specifies a source profile and implies config clone unless paired with `--clone-all`. |\n | `delete <name> [-y]` | Delete a profile. |\n | `show <name>` | Show profile details (home directory, config, etc.). |\n | `alias <name> [--remove] [--name NAME]` | Manage wrapper scripts for quick profile access. |"]},{"file":"website/docs/reference/faq.md","hunks":["@@ -634,7 +634,7 @@ No. Each messaging platform (Telegram, Discord, etc.) requires exclusive access\n \n ### Do profiles share memory or sessions?\n \n-No. Each profile has its own memory store, session database, and skills directory. They are completely isolated. If you want to start a new profile with existing memories and sessions, use `hermes profile create newname --clone-all` to copy everything from the current profile.\n+No. Each profile has its own memory store, session database, and skills directory. They are completely isolated. If you want to start a new profile with existing memories and sessions, use `hermes profile create newname --clone-all` to copy everything from the current profile, or add `--clone-from <profile>` to copy from a specific source profile.\n \n ### What happens when I run `hermes update`?\n "]},{"file":"website/docs/reference/profile-commands.md","hunks":["@@ -80,12 +80,12 @@ Creates a new profile.\n | Argument / Option | Description |\n |-------------------|-------------|\n | `<name>` | Name for the new profile. Must be a valid directory name (alphanumeric, hyphens, underscores). |\n-| `--clone` | Copy `config.yaml`, `.env`, and `SOUL.md` from the current profile. |\n+| `--clone` | Copy `config.yaml`, `.env`, `SOUL.md`, and skills from the current profile. |\n | `--clone-all` | Copy everything (config, memories, skills, cron, plugins) from the current profile. Excludes per-profile history: sessions, `state.db`, backups, state-snapshots, checkpoints. |\n-| `--clone-from <profile>` | Clone from a specific profile instead of the current one. Used with `--clone` or `--clone-all`. |\n+| `--clone-from <profile>` | Clone config/skills/SOUL from a specific profile instead of the current one. Implies `--clone` unless paired with `--clone-all`. |\n | `--no-alias` | Skip wrapper script creation. |\n | `--description \"<text>\"` | One- or two-sentence description of what this profile is good at. Used by the kanban orchestrator to route tasks based on role instead of profile name alone. Skip and add later via `hermes profile describe`. Persisted in `<profile_dir>/profile.yaml`. |\n-| `--no-skills` | Create an **empty** profile with zero bundled skills enabled. Writes a `.no-bundled-skills` marker into the profile so future `hermes update` runs won't re-seed the bundled set, and refuses to combine with `--clone` / `--clone-all` (which would copy skills in anyway). Useful for narrow orchestrator profiles or sandbox profiles that should not inherit the full skill catalog. To toggle this on an already-created profile (including the default `~/.hermes`), use `hermes skills opt-out` / `hermes skills opt-in`. |\n+| `--no-skills` | Create an **empty** profile with zero bundled skills enabled. Writes a `.no-bundled-skills` marker into the profile so future `hermes update` runs won't re-seed the bundled set, and refuses to combine with `--clone`, `--clone-from`, or `--clone-all` (which would copy skills in anyway). Useful for narrow orchestrator profiles or sandbox profiles that should not inherit the full skill catalog. To toggle this on an already-created profile (including the default `~/.hermes`), use `hermes skills opt-out` / `hermes skills opt-in`. |\n \n Creating a profile does **not** make that profile directory the default project/workspace directory for terminal commands. If you want a profile to start in a specific project, set `terminal.cwd` in that profile's `config.yaml`.\n ","@@ -102,7 +102,10 @@ hermes profile create work --clone\n hermes profile create backup --clone-all\n \n # Clone config from a specific profile\n-hermes profile create work2 --clone --clone-from work\n+hermes profile create work2 --clone-from work\n+\n+# Clone everything from a specific profile\n+hermes profile create work2-backup --clone-from work --clone-all\n ```\n \n ## `hermes profile describe`"]},{"file":"website/docs/user-guide/profiles.md","hunks":["@@ -50,7 +50,7 @@ You can also set or auto-generate the description later with `hermes profile des\n hermes profile create work --clone\n ```\n \n-Copies your current profile's `config.yaml`, `.env`, and `SOUL.md` into the new profile. Same API keys and model, but fresh sessions and memory. Edit `~/.hermes/profiles/work/.env` for different API keys, or `~/.hermes/profiles/work/SOUL.md` for a different personality.\n+Copies your current profile's `config.yaml`, `.env`, `SOUL.md`, and skills into the new profile. Same API keys, model, and capabilities, but fresh sessions and memory. Edit `~/.hermes/profiles/work/.env` for different API keys, or `~/.hermes/profiles/work/SOUL.md` for a different personality.\n \n ### Clone everything (`--clone-all`)\n ","@@ -63,11 +63,17 @@ Copies **everything** — config, API keys, personality, all memories, skills, c\n ### Clone from a specific profile\n \n ```bash\n-hermes profile create work --clone --clone-from coder\n+hermes profile create work --clone-from coder\n+```\n+\n+`--clone-from <source>` selects the source profile directly and implies a config/skills/SOUL clone. Combine it with `--clone-all` when you want a full copy of that source profile:\n+\n+```bash\n+hermes profile create work-backup --clone-from coder --clone-all\n ```\n \n :::tip Honcho memory + profiles\n-When Honcho is enabled, `--clone` automatically creates a dedicated AI peer for the new profile while sharing the same user workspace. Each profile builds its own observations and identity. See [Honcho -- Multi-agent / Profiles](./features/memory-providers.md#honcho) for details.\n+When Honcho is enabled, clone operations automatically create a dedicated AI peer for the new profile while sharing the same user workspace. Each profile builds its own observations and identity. See [Honcho -- Multi-agent / Profiles](./features/memory-providers.md#honcho) for details.\n :::\n \n ## Using profiles"]},{"file":"website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/cli-commands.md","hunks":["@@ -1175,7 +1175,7 @@ hermes profile <subcommand>\n |------------|-------------|\n | `list` | 列出所有 profile。 |\n | `use <name>` | 设置粘性默认 profile。 |\n-| `create <name> [--clone] [--clone-all] [--clone-from <source>] [--no-alias]` | 创建新 profile。`--clone` 从活跃 profile 复制 config、`.env` 和 `SOUL.md`。`--clone-all` 复制所有状态。`--clone-from` 指定源 profile。 |\n+| `create <name> [--clone] [--clone-all] [--clone-from <source>] [--no-alias]` | 创建新 profile。`--clone` 从活跃 profile 复制 config、`.env`、`SOUL.md` 和 skills。`--clone-all` 复制所有状态。`--clone-from` 指定源 profile，除非与 `--clone-all` 配合使用，否则会隐含 config 克隆。 |\n | `delete <name> [-y]` | 删除 profile。 |\n | `show <name>` | 显示 profile 详情（主目录、config 等）。 |\n | `alias <name> [--remove] [--name NAME]` | 管理快速访问 profile 的包装脚本。 |"]},{"file":"website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/faq.md","hunks":["@@ -626,7 +626,7 @@ Profiles 是构建在 `HERMES_HOME` 之上的托管层。您*可以*在每次命\n \n ### Profiles 共享记忆或会话吗？\n \n-不共享。每个 profile 都有自己独立的记忆存储、会话数据库和技能目录，完全隔离。如果您想用现有的记忆和会话创建新 profile，请使用 `hermes profile create newname --clone-all` 从当前 profile 复制所有内容。\n+不共享。每个 profile 都有自己独立的记忆存储、会话数据库和技能目录，完全隔离。如果您想用现有的记忆和会话创建新 profile，请使用 `hermes profile create newname --clone-all` 从当前 profile 复制所有内容，或添加 `--clone-from <profile>` 从指定源 profile 复制。\n \n ### 运行 `hermes update` 时会发生什么？\n "]},{"file":"website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/profile-commands.md","hunks":["@@ -79,12 +79,12 @@ hermes profile create <name> [options]\n | 参数 / 选项 | 描述 |\n |-------------------|-------------|\n | `<name>` | 新 profile 的名称。必须是合法的目录名（字母数字、连字符、下划线）。 |\n-| `--clone` | 从当前 profile 复制 `config.yaml`、`.env` 和 `SOUL.md`。 |\n-| `--clone-all` | 从当前 profile 复制所有内容（config、memories、skills、sessions、state）。 |\n-| `--clone-from <profile>` | 从指定 profile 克隆，而非当前 profile。与 `--clone` 或 `--clone-all` 配合使用。 |\n+| `--clone` | 从当前 profile 复制 `config.yaml`、`.env`、`SOUL.md` 和 skills。 |\n+| `--clone-all` | 从当前 profile 复制所有内容（config、memories、skills、cron、plugins）。会排除每个 profile 自己的历史数据：sessions、`state.db`、backups、state-snapshots、checkpoints。 |\n+| `--clone-from <profile>` | 从指定 profile 克隆 config/skills/SOUL，而非当前 profile。除非与 `--clone-all` 配合使用，否则会隐含 `--clone`。 |\n | `--no-alias` | 跳过 wrapper 脚本创建。 |\n | `--description \"<text>\"` | 一到两句话描述该 profile 的用途。供 kanban 编排器根据角色而非仅凭 profile 名称来路由任务。可跳过，稍后通过 `hermes profile describe` 添加。持久化保存在 `<profile_dir>/profile.yaml` 中。 |\n-| `--no-skills` | 创建一个**空** profile，不启用任何内置 skill。会在 profile 目录中写入 `.no-skills` 标记，使后续 `hermes update` 不再重新植入内置 skill 集，且拒绝与 `--clone` / `--clone-all` 组合使用（因为后者会复制 skill）。适用于不应继承完整 skill 目录的窄化编排器 profile 或沙箱 profile。 |\n+| `--no-skills` | 创建一个**空** profile，不启用任何内置 skill。会在 profile 目录中写入 `.no-bundled-skills` 标记，使后续 `hermes update` 不再重新植入内置 skill 集，且拒绝与 `--clone`、`--clone-from` 或 `--clone-all` 组合使用（因为这些选项会复制 skill）。适用于不应继承完整 skill 目录的窄化编排器 profile 或沙箱 profile。 |\n \n 创建 profile **不会**将该 profile 目录设为终端命令的默认项目/工作目录。如需让某个 profile 从特定项目目录启动，请在该 profile 的 `config.yaml` 中设置 `terminal.cwd`。\n ","@@ -101,7 +101,10 @@ hermes profile create work --clone\n hermes profile create backup --clone-all\n \n # 从指定 profile 克隆 config\n-hermes profile create work2 --clone --clone-from work\n+hermes profile create work2 --clone-from work\n+\n+# 从指定 profile 克隆所有内容\n+hermes profile create work2-backup --clone-from work --clone-all\n ```\n \n ## `hermes profile describe`"]},{"file":"website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/profiles.md","hunks":["@@ -46,7 +46,7 @@ hermes profile create researcher --description \"Reads source code and external d\n hermes profile create work --clone\n ```\n \n-将当前 profile 的 `config.yaml`、`.env` 和 `SOUL.md` 复制到新 profile。API 密钥和模型相同，但会话和记忆是全新的。编辑 `~/.hermes/profiles/work/.env` 可使用不同的 API 密钥，编辑 `~/.hermes/profiles/work/SOUL.md` 可设置不同的人格。\n+将当前 profile 的 `config.yaml`、`.env`、`SOUL.md` 和 skills 复制到新 profile。API 密钥、模型和能力相同，但会话和记忆是全新的。编辑 `~/.hermes/profiles/work/.env` 可使用不同的 API 密钥，编辑 `~/.hermes/profiles/work/SOUL.md` 可设置不同的人格。\n \n ### 克隆全部内容（`--clone-all`）\n ","@@ -54,16 +54,22 @@ hermes profile create work --clone\n hermes profile create backup --clone-all\n ```\n \n-复制**所有内容**——配置、API 密钥、人格、所有记忆、完整会话历史、技能、cron 任务、插件。完整快照。适用于备份或 fork 已有上下文的 agent。\n+复制**所有内容**——配置、API 密钥、人格、记忆、技能、cron 任务、插件。会排除每个 profile 自己的历史数据（会话历史、`state.db`、`backups/`、`state-snapshots/`、`checkpoints/`），这些数据属于源 profile 且可能达到数十 GB。若要包含历史的完整备份，请使用 `hermes profile export` 或 `hermes backup`。\n \n ### 从指定 profile 克隆\n \n ```bash\n-hermes profile create work --clone --clone-from coder\n+hermes profile create work --clone-from coder\n+```\n+\n+`--clone-from <source>` 会直接选择源 profile，并隐含执行 config/skills/SOUL 克隆。若要完整复制该源 profile，请与 `--clone-all` 组合使用：\n+\n+```bash\n+hermes profile create work-backup --clone-from coder --clone-all\n ```\n \n :::tip Honcho 记忆 + profiles\n-启用 Honcho 后，`--clone` 会自动为新 profile 创建专属 AI 对等体，同时共享同一用户工作区。每个 profile 构建各自的观察记录和身份标识。详见 [Honcho——多 agent / Profiles](./features/memory-providers.md#honcho)。\n+启用 Honcho 后，克隆操作会自动为新 profile 创建专属 AI 对等体，同时共享同一用户工作区。每个 profile 构建各自的观察记录和身份标识。详见 [Honcho——多 agent / Profiles](./features/memory-providers.md#honcho)。\n :::\n \n ## 使用 profile\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}