diff --git a/10-workflow/workflow-assistance/README.md b/10-workflow/workflow-assistance/README.md index 609b0d2..ddb16ba 100644 --- a/10-workflow/workflow-assistance/README.md +++ b/10-workflow/workflow-assistance/README.md @@ -564,6 +564,7 @@ python scripts/security/scan_agent_rules.py templates skills docs scripts - `docs/workflow/token-monitor.md`:本地 Token Monitor 的真实 usage 口径、启动方式和 Codex OAuth 限制; - `docs/workflow/hermes-runtime-layout.md`:Hermes 全局运行目录分层、可恢复迁移、升级验证与清理边界; - `docs/workflow/gateway-cron-delivery.md`:Gateway、cron、sleep-mode、TUI 与外部消息平台的投递边界; +- `docs/workflow/user-environment-profile.md`:Hermes/Codex 用户配置与技能清单的无密画像、导出器与跨机器恢复流程; - `docs/workflow/gpt-deepseek-ccswitch-codex-upgrade.md`:全链路工作流和路由矩阵; - `docs/workflow/error-fixes-2026-07-04.md`:Windows/Git/Python/GitHub CLI 实际故障记录; - `docs/mcp/workflow-mcp-stack.md`:MCP 默认策略; diff --git a/10-workflow/workflow-assistance/codex-assets/skills/workflow-assistance-self-improvement/SKILL.md b/10-workflow/workflow-assistance/codex-assets/skills/workflow-assistance-self-improvement/SKILL.md index 26c169b..c7de8da 100644 --- a/10-workflow/workflow-assistance/codex-assets/skills/workflow-assistance-self-improvement/SKILL.md +++ b/10-workflow/workflow-assistance/codex-assets/skills/workflow-assistance-self-improvement/SKILL.md @@ -65,6 +65,23 @@ python scripts/workflow/skill_lifecycle.py --root backup - Auto-grown knowledge persists by promoting it into the module's `codex-assets` skills (via PR) — never only in a machine-local sidecar. +## User environment preservation + +Beyond skills, preserve the user's Hermes/Codex configuration and skill lists +in neutral, secret-free form so a machine change does not start from zero: + +- Export: `python scripts/workflow/user_profile_export.py` — read-only against + user homes; writes `config/user-environment-profile.json` (tracked) with + non-secret config values, `.env` key names only, and skill inventories + (Hermes skills, Codex `~/.agents/skills`). +- Redaction is fail-closed: any value matching a secret pattern is + `[REDACTED]`; an unredacted value makes the export refuse to write. +- Restore: see `docs/workflow/user-environment-profile.md` — `sync` deploys + the module skills; the profile tells you which config keys exist and which + secrets must be re-entered on the new machine. +- The profile is a snapshot: re-run the exporter after meaningful config or + skill changes and commit the refresh. + ## Pitfalls - Archiving a repository-owned skill (the provenance filter blocks it — diff --git a/10-workflow/workflow-assistance/config/codex-enhancement-boundary.json b/10-workflow/workflow-assistance/config/codex-enhancement-boundary.json index 369076a..e1d3ecd 100644 --- a/10-workflow/workflow-assistance/config/codex-enhancement-boundary.json +++ b/10-workflow/workflow-assistance/config/codex-enhancement-boundary.json @@ -23,7 +23,7 @@ "capabilities": { "detect": { "mode": "READ_ONLY", - "allowed": ["Codex executable version when available", "declared target paths", "managed asset hashes", "owned-state metadata"], + "allowed": ["Codex executable version when available", "declared target paths", "managed asset hashes", "owned-state metadata", "secret-free user environment inventory (Hermes/Codex config keys + skill lists via user_profile_export.py)"], "forbidden": ["private config body disclosure", "credential or session inspection"] }, "plan": { diff --git a/10-workflow/workflow-assistance/config/user-environment-profile.json b/10-workflow/workflow-assistance/config/user-environment-profile.json new file mode 100644 index 0000000..f65a5d1 --- /dev/null +++ b/10-workflow/workflow-assistance/config/user-environment-profile.json @@ -0,0 +1,1703 @@ +{ + "schema_version": "worklab/user-environment-profile/v1", + "generated_at": "2026-08-10T13:21:02+00:00", + "paths": { + "hermes_home": "C:\\Users\\ALEX\\AppData\\Local\\hermes", + "codex_home": "C:\\Users\\ALEX\\.codex", + "agents_skills_root": "C:\\Users\\ALEX\\.agents\\skills" + }, + "hermes": { + "config_yaml": { + "model": { + "default": "gpt-5.6-sol", + "provider": "openai-codex", + "base_url": "[REDACTED]", + "max_tokens": "[REDACTED]", + "api_key": "[REDACTED]" + }, + "fallback_providers": [], + "toolsets": [ + "hermes-cli" + ], + "max_live_sessions": "[REDACTED]", + "agent": { + "max_turns": 60, + "gateway_timeout": 900, + "restart_drain_timeout": 0, + "api_max_retries": 3, + "service_tier": "fast", + "tool_use_enforcement": "auto", + "intent_ack_continuation": "auto", + "task_completion_guidance": true, + "parallel_tool_call_guidance": true, + "environment_probe": true, + "environment_hint": "", + "coding_context": "auto", + "coding_instructions": "", + "verify_guidance": true, + "max_verify_nudges": 3, + "verify_on_stop": false, + "gateway_timeout_warning": 900, + "clarify_timeout": 3600, + "gateway_notify_interval": 180, + "gateway_auto_continue_freshness": 3600, + "image_input_mode": "auto", + "disabled_toolsets": [], + "reasoning_effort": "low" + }, + "terminal": { + "backend": "local", + "modal_mode": "auto", + "cwd": ".", + "timeout": 180, + "daemon_term_grace_seconds": 2, + "env_passthrough": [], + "home_mode": "auto", + "shell_init_files": [], + "auto_source_bashrc": true, + "docker_image": "nikolaik/python-nodejs:python3.11-nodejs20", + "docker_forward_env": [], + "singularity_image": "docker://nikolaik/python-nodejs:python3.11-nodejs20", + "modal_image": "nikolaik/python-nodejs:python3.11-nodejs20", + "daytona_image": "nikolaik/python-nodejs:python3.11-nodejs20", + "container_cpu": 1, + "container_memory": 5120, + "container_disk": 51200, + "container_persistent": true, + "docker_volumes": [], + "docker_mount_cwd_to_workspace": false, + "docker_network": true, + "docker_extra_args": [], + "docker_run_as_host_user": false, + "persistent_shell": true + }, + "web": { + "backend": "", + "search_backend": "", + "extract_backend": "", + "extract_char_limit": 15000 + }, + "browser": { + "inactivity_timeout": 120, + "command_timeout": 30, + "record_sessions": "[REDACTED]", + "allow_private_urls": "[REDACTED]", + "engine": "auto", + "auto_local_for_private_urls": "[REDACTED]", + "cdp_url": "", + "allow_unsafe_evaluate": false, + "dialog_policy": "must_respond", + "dialog_timeout_s": 300, + "camofox": { + "managed_persistence": false, + "user_id": "", + "session_key": "[REDACTED]", + "adopt_existing_tab": false, + "rewrite_loopback_urls": false, + "loopback_host_alias": "host.docker.internal" + } + }, + "checkpoints": { + "enabled": false, + "max_snapshots": 20, + "max_total_size_mb": 500, + "max_file_size_mb": 10, + "auto_prune": true, + "retention_days": 7, + "min_interval_hours": 24, + "delete_orphans": true + }, + "file_read_max_chars": 100000, + "mcp_discovery_timeout": 1.5, + "tool_output": { + "max_bytes": 50000, + "max_lines": 2000, + "max_line_length": 2000 + }, + "tool_loop_guardrails": { + "warnings_enabled": true, + "hard_stop_enabled": false, + "warn_after": { + "exact_failure": 2, + "same_tool_failure": 3, + "idempotent_no_progress": 2 + }, + "hard_stop_after": { + "exact_failure": 5, + "same_tool_failure": 8, + "idempotent_no_progress": 5 + } + }, + "compression": { + "enabled": true, + "threshold": 0.35, + "target_ratio": 0.15, + "protect_last_n": 20, + "hygiene_hard_message_limit": 5000, + "protect_first_n": 3, + "abort_on_summary_failure": false, + "codex_gpt55_autoraise": true, + "codex_gpt55_autoraise_notice": true, + "codex_app_server_auto": "native", + "in_place": true + }, + "prompt_caching": { + "cache_ttl": "5m" + }, + "openrouter": { + "response_cache": true, + "response_cache_ttl": 300, + "min_coding_score": 0.65 + }, + "bedrock": { + "region": "", + "discovery": { + "enabled": true, + "provider_filter": [], + "refresh_interval": 3600 + }, + "guardrail": { + "guardrail_identifier": "", + "guardrail_version": "", + "stream_processing_mode": "async", + "trace": "disabled" + } + }, + "auxiliary": { + "transient_retries": 2, + "vision": { + "provider": "auto", + "model": "", + "timeout": 120, + "download_timeout": 30 + }, + "web_extract": { + "provider": "auto", + "model": "", + "timeout": 360 + }, + "compression": { + "provider": "auto", + "model": "", + "timeout": 120 + }, + "skills_hub": { + "provider": "auto", + "model": "", + "timeout": 30 + }, + "approval": { + "provider": "auto", + "model": "", + "timeout": 30 + }, + "mcp": { + "provider": "auto", + "model": "", + "timeout": 30 + }, + "title_generation": { + "provider": "auto", + "model": "", + "timeout": 30, + "language": "" + }, + "tts_audio_tags": { + "provider": "auto", + "model": "", + "base_url": "[REDACTED]", + "api_key": "[REDACTED]", + "timeout": 30 + }, + "triage_specifier": { + "provider": "auto", + "model": "", + "timeout": 120 + }, + "kanban_decomposer": { + "provider": "auto", + "model": "", + "timeout": 180 + }, + "profile_describer": { + "provider": "auto", + "model": "", + "timeout": 60 + }, + "curator": { + "provider": "auto", + "model": "", + "timeout": 600 + }, + "monitor": { + "provider": "auto", + "model": "", + "base_url": "[REDACTED]", + "api_key": "[REDACTED]", + "timeout": 60 + }, + "background_review": { + "provider": "auto", + "model": "", + "base_url": "[REDACTED]", + "api_key": "[REDACTED]", + "timeout": 120 + }, + "moa_reference": { + "provider": "auto", + "model": "", + "base_url": "[REDACTED]", + "api_key": "[REDACTED]", + "timeout": 900 + }, + "moa_aggregator": { + "provider": "auto", + "model": "", + "base_url": "[REDACTED]", + "api_key": "[REDACTED]", + "timeout": 900 + } + }, + "display": { + "compact": false, + "personality": "", + "resume_display": "full", + "resume_exchanges": 10, + "resume_max_user_chars": 300, + "resume_max_assistant_chars": 200, + "resume_max_assistant_lines": 3, + "resume_skip_tool_only": true, + "busy_input_mode": "queue", + "busy_steer_ack_enabled": true, + "interface": "cli", + "tui_auto_resume_recent": false, + "tui_agents_nudge": true, + "bell_on_complete": false, + "show_reasoning": true, + "reasoning_full": false, + "memory_notifications": "on", + "streaming": true, + "timestamps": false, + "timestamp_format": "%H:%M", + "final_response_markdown": "strip", + "persistent_output": true, + "persistent_output_max_lines": 200, + "persist_prompts": true, + "inline_diffs": true, + "file_mutation_verifier": true, + "credits_notices": true, + "turn_completion_explainer": true, + "show_cost": false, + "skin": "purple-gemstone", + "language": "zh", + "tui_status_indicator": "kaomoji", + "cli_refresh_interval": 1, + "user_message_preview": { + "first_lines": 2, + "last_lines": 2 + }, + "interim_assistant_messages": true, + "tool_progress_command": false, + "tool_preview_length": 0, + "friendly_tool_labels": true, + "tool_progress_grouping": "accumulate", + "reasoning_style": "code", + "ephemeral_system_ttl": 0, + "platforms": { + "telegram": { + "streaming": true + }, + "discord": { + "streaming": false + } + }, + "runtime_footer": { + "enabled": false, + "fields": [ + "model", + "context_pct", + "cwd" + ] + }, + "copy_shortcut": "auto", + "pet": { + "enabled": false, + "slug": "", + "render_mode": "auto", + "scale": 0.33, + "unicode_cols": 0 + }, + "tool_progress": "all" + }, + "dashboard": { + "theme": "default", + "show_token_analytics": "[REDACTED]", + "oauth": "[REDACTED]", + "basic_auth": "[REDACTED]", + "drain_auth": "[REDACTED]", + "public_url": "" + }, + "privacy": { + "redact_pii": false + }, + "tts": { + "provider": "edge", + "edge": { + "voice": "en-US-AriaNeural" + }, + "elevenlabs": { + "voice_id": "pNInz6obpgDQGcFmaJgB", + "model_id": "eleven_multilingual_v2" + }, + "openai": { + "model": "gpt-4o-mini-tts", + "voice": "alloy" + }, + "gemini": { + "model": "gemini-2.5-flash-preview-tts", + "voice": "Kore", + "audio_tags": false, + "persona_prompt_file": "" + }, + "xai": { + "voice_id": "eve", + "language": "en", + "sample_rate": 24000, + "bit_rate": 128000 + }, + "mistral": { + "model": "voxtral-mini-tts-2603", + "voice_id": "c69964a6-ab8b-4f8a-9465-ec0925096ec8" + }, + "neutts": { + "ref_audio": "", + "ref_text": "", + "model": "neuphonic/neutts-air-q4-gguf", + "device": "cpu" + }, + "piper": { + "voice": "en_US-lessac-medium" + } + }, + "stt": { + "enabled": true, + "echo_transcripts": true, + "provider": "local", + "local": { + "model": "base", + "language": "" + }, + "openai": { + "model": "whisper-1" + }, + "mistral": { + "model": "voxtral-mini-latest" + }, + "elevenlabs": { + "model_id": "scribe_v2", + "language_code": "", + "tag_audio_events": false, + "diarize": false + } + }, + "voice": { + "record_key": "ctrl+b", + "max_recording_seconds": 120, + "auto_tts": false, + "beep_enabled": true, + "silence_threshold": 200, + "silence_duration": 3 + }, + "human_delay": { + "mode": "off", + "min_ms": 800, + "max_ms": 2500 + }, + "context": { + "engine": "compressor" + }, + "memory": { + "memory_enabled": true, + "user_profile_enabled": true, + "write_approval": false, + "memory_char_limit": 2200, + "user_char_limit": 1375, + "provider": "" + }, + "delegation": { + "model": "", + "provider": "", + "base_url": "[REDACTED]", + "api_key": "[REDACTED]", + "api_mode": "", + "inherit_mcp_toolsets": true, + "max_iterations": 50, + "max_summary_chars": 24000, + "child_timeout_seconds": 0, + "reasoning_effort": "", + "max_concurrent_children": 3, + "max_spawn_depth": 1, + "orchestrator_enabled": true, + "subagent_auto_approve": false + }, + "prefill_messages_file": "", + "goals": { + "max_turns": 20 + }, + "moa": { + "default_preset": "default", + "active_preset": "", + "save_traces": false, + "trace_dir": "", + "presets": { + "default": { + "reference_models": [ + { + "provider": "openai-codex", + "model": "gpt-5.5" + }, + { + "provider": "openrouter", + "model": "deepseek/deepseek-v4-pro" + } + ], + "aggregator": { + "provider": "openrouter", + "model": "anthropic/claude-opus-4.8" + }, + "max_tokens": "[REDACTED]", + "enabled": true + } + } + }, + "skills": { + "external_dirs": [], + "template_vars": true, + "inline_shell": false, + "inline_shell_timeout": 10, + "guard_agent_created": false, + "write_approval": false + }, + "curator": { + "enabled": true, + "interval_hours": 168, + "min_idle_hours": 2, + "stale_after_days": 30, + "archive_after_days": 90, + "consolidate": false, + "prune_builtins": true, + "backup": { + "enabled": true, + "keep": 5 + } + }, + "timezone": "", + "slack": { + "require_mention": true, + "free_response_channels": "", + "allowed_channels": "" + }, + "discord": { + "require_mention": true, + "free_response_channels": "", + "allowed_channels": "", + "auto_thread": true, + "thread_require_mention": false, + "bots_require_inline_mention": false, + "history_backfill": true, + "history_backfill_limit": 50, + "reactions": true, + "dm_role_auth_guild": "[REDACTED]", + "server_actions": "", + "allow_any_attachment": false, + "max_attachment_bytes": 33554432, + "approval_mentions": false, + "voice_fx": { + "enabled": false, + "ambient_enabled": true, + "ambient_path": "", + "ambient_gain": 0.18, + "duck_gain": 0.06, + "speech_gain": 1, + "ack_enabled": true, + "ack_phrases": [ + "Let me look into that.", + "One moment.", + "Checking on that now.", + "Give me a sec.", + "On it." + ] + } + }, + "telegram": { + "reactions": false, + "allowed_chats": "", + "extra": { + "rich_messages": false, + "rich_drafts": false + } + }, + "mattermost": { + "require_mention": true, + "free_response_channels": "", + "allowed_channels": "" + }, + "matrix": { + "require_mention": true, + "free_response_rooms": "", + "allowed_rooms": "" + }, + "approvals": { + "mode": "off", + "timeout": 60, + "cron_mode": "deny", + "deny": [], + "mcp_reload_confirm": true, + "destructive_slash_confirm": true + }, + "command_allowlist": [], + "quick_commands": { + "切换kimi": { + "type": "alias", + "target": "/model kimi-k3 --provider kimi-coding", + "description": "切换到 KIMI K3" + }, + "切换kimi稳": { + "type": "alias", + "target": "/model kimi-k3 --provider kimi-coding", + "description": "切换到 KIMI K3 旗舰模型" + }, + "切换kimi快": { + "type": "alias", + "target": "/model kimi-k2.7-code --provider kimi-coding", + "description": "切换到 KIMI 快速模型 kimi-k2.7-code" + }, + "切换kimi极速": { + "type": "alias", + "target": "/model kimi-k2.7-code-highspeed --provider kimi-coding", + "description": "切换到 KIMI 官方高速模型 kimi-k2.7-code-highspeed" + }, + "切换dp": { + "type": "alias", + "target": "/model deepseek-v4-flash --provider deepseek", + "description": "切换到 DEEPSEEK V4 Flash" + }, + "切换gpt": { + "type": "alias", + "target": "/model gpt-5.6-sol --provider openai-codex", + "description": "切换到 CHATGPT 5.6 Sol" + } + }, + "hooks": { + "pre_tool_call": [ + { + "matcher": "terminal", + "command": "python \"C:/Users/ALEX/AppData/Local/hermes/bin/hermes-project-terminal-guard.py\"", + "timeout": 10 + } + ] + }, + "hooks_auto_accept": false, + "security": { + "allow_private_urls": "[REDACTED]", + "redact_secrets": "[REDACTED]", + "tirith_enabled": true, + "tirith_path": "tirith", + "tirith_timeout": 5, + "tirith_fail_open": true, + "website_blocklist": { + "enabled": false, + "domains": [], + "shared_files": [] + }, + "acked_advisories": [], + "allow_lazy_installs": true + }, + "cron": { + "provider": "", + "chronos": { + "portal_url": "https://portal.nousresearch.com", + "callback_url": "", + "expected_audience": "", + "nas_jwks_url": "" + }, + "wrap_response": true, + "mirror_delivery": false, + "output_retention": 7 + }, + "kanban": { + "dispatch_in_gateway": true, + "dispatch_interval_seconds": 60, + "failure_limit": 2, + "worker_log_rotate_bytes": 2097152, + "worker_log_backup_count": 1, + "orchestrator_profile": "", + "default_assignee": "", + "auto_decompose": true, + "auto_decompose_per_tick": 3, + "dispatch_stale_timeout_seconds": 14400 + }, + "code_execution": { + "mode": "project" + }, + "tools": { + "tool_search": { + "enabled": "auto", + "threshold_pct": 10, + "search_default_limit": 5, + "max_search_limit": 20 + } + }, + "logging": { + "level": "INFO", + "max_size_mb": 5, + "backup_count": 3 + }, + "model_catalog": { + "enabled": true, + "url": "https://hermes-agent.nousresearch.com/docs/api/model-catalog.json", + "ttl_hours": 1 + }, + "network": { + "force_ipv4": false + }, + "gateway": { + "platform_connect_timeout": 30, + "write_sessions_json": "[REDACTED]", + "scale_to_zero": { + "idle_timeout_minutes": 5 + }, + "restart_loop_guard": { + "max_restarts": 3, + "window_seconds": 60 + }, + "message_timestamps": { + "enabled": false + }, + "max_inbound_media_bytes": 134217728, + "strict": false, + "media_delivery_allow_dirs": [], + "trust_recent_files": true, + "trust_recent_files_seconds": 600, + "api_server": { + "max_concurrent_runs": 10 + } + }, + "streaming": { + "enabled": false, + "transport": "auto", + "edit_interval": 0.8, + "buffer_threshold": 24, + "cursor": " ▉", + "fresh_final_after_seconds": 0 + }, + "sessions": "[REDACTED]", + "onboarding": { + "profile_build": "ask" + }, + "updates": { + "pre_update_backup": false, + "backup_keep": 2, + "non_interactive_local_changes": "stash", + "refresh_cua_driver": true + }, + "lsp": { + "enabled": true, + "wait_mode": "document", + "wait_timeout": 5, + "install_strategy": "auto" + }, + "x_search": { + "model": "grok-4.20-reasoning", + "timeout_seconds": 180, + "retries": 2 + }, + "secrets": "[REDACTED]", + "paste_collapse_threshold": 5, + "paste_collapse_threshold_fallback": 5, + "paste_collapse_char_threshold": 2000, + "computer_use": { + "cua_telemetry": false + }, + "desktop": { + "electron_flags": [], + "disable_gpu": "auto" + }, + "vertex": { + "project_id": "", + "region": "global" + }, + "_config_version": 33, + "mcp_servers": { + "context7": { + "command": "C:/Users/ALEX/AppData/Local/hermes/bin/hermes-npx.cmd", + "args": [ + "-y", + "@upstash/context7-mcp@3.2.2" + ], + "env": { + "HERMES_NPX_ALLOW_PATH_FALLBACK": "1" + }, + "timeout": 120, + "connect_timeout": 120 + } + }, + "plugins": { + "enabled": [ + "security-guidance", + "web/ddgs" + ], + "disabled": [ + "disk-cleanup", + "google_meet", + "spotify" + ] + }, + "platform_toolsets": { + "cli": [ + "browser", + "clarify", + "code_execution", + "computer_use", + "cronjob", + "delegation", + "file", + "image_gen", + "memory", + "session_search", + "skills", + "terminal", + "todo", + "vision", + "web" + ] + }, + "model_picker": { + "custom_lanes": { + "enabled": true, + "lanes": [ + { + "label": "KIMI 系列", + "provider": "kimi-coding", + "models": [ + "kimi-k3", + "kimi-k2.7-code-highspeed", + "kimi-k2.7-code" + ] + }, + { + "label": "DEEPSEEK 系列", + "provider": "deepseek", + "models": [ + "deepseek-v4-pro", + "deepseek-v4-flash" + ] + }, + { + "label": "CHATGPT 系列", + "provider": "openai-codex", + "models": [ + "gpt-5.6-sol", + "gpt-5.6-terra", + "gpt-5.6-luna" + ] + } + ] + } + }, + "custom_providers": [] + }, + "env_key_names": [ + "BROWSERBASE_ADVANCED_STEALTH", + "BROWSERBASE_PROXIES", + "BROWSER_INACTIVITY_TIMEOUT", + "BROWSER_SESSION_TIMEOUT", + "DEEPSEEK_API_KEY", + "HTTPS_PROXY", + "HTTP_PROXY", + "IMAGE_TOOLS_DEBUG", + "KILOCODE_API_KEY", + "KIMI_API_KEY", + "KIMI_BASE_URL", + "KIMI_CN_API_KEY", + "MOA_TOOLS_DEBUG", + "NO_PROXY", + "TERMINAL_LIFETIME_SECONDS", + "TERMINAL_MODAL_IMAGE", + "TERMINAL_TIMEOUT", + "VISION_TOOLS_DEBUG", + "WEB_TOOLS_DEBUG" + ], + "skills": [ + { + "name": "apple-notes", + "description": "Manage Apple Notes via memo CLI: create, search, edit.", + "path": "apple/apple-notes" + }, + { + "name": "apple-reminders", + "description": "Apple Reminders via remindctl: add, list, complete.", + "path": "apple/apple-reminders" + }, + { + "name": "findmy", + "description": "Track Apple devices/AirTags via FindMy.app on macOS.", + "path": "apple/findmy" + }, + { + "name": "imessage", + "description": "Send and receive iMessages/SMS via the imsg CLI on macOS.", + "path": "apple/imessage" + }, + { + "name": "claude-code", + "description": "Delegate coding to Claude Code CLI (features, PRs).", + "path": "autonomous-ai-agents/claude-code" + }, + { + "name": "codex", + "description": "Delegate bounded coding or read-only review tasks to the OpenAI Codex CLI; use isolated worktrees for writers.", + "path": "autonomous-ai-agents/codex" + }, + { + "name": "computer-use", + "description": "|", + "path": "autonomous-ai-agents/computer-use" + }, + { + "name": "hermes-agent", + "description": "Use, configure, theme, extend, and orchestrate Hermes Agent.", + "path": "autonomous-ai-agents/hermes-agent" + }, + { + "name": "hermes-runtime-auditing", + "description": "Use when auditing Hermes runtime state safely and read-only.", + "path": "autonomous-ai-agents/hermes-runtime-auditing" + }, + { + "name": "opencode", + "description": "Delegate coding to OpenCode CLI (features, PR review).", + "path": "autonomous-ai-agents/opencode" + }, + { + "name": "architecture-diagram", + "description": "Dark-themed SVG architecture/cloud/infra diagrams as HTML.", + "path": "creative/architecture-diagram" + }, + { + "name": "ascii-art", + "description": "ASCII art: pyfiglet, cowsay, boxes, image-to-ascii.", + "path": "creative/ascii-art" + }, + { + "name": "ascii-video", + "description": "ASCII video: convert video/audio to colored ASCII MP4/GIF.", + "path": "creative/ascii-video" + }, + { + "name": "baoyu-infographic", + "description": "Infographics: 21 layouts x 21 styles (信息图, 可视化).", + "path": "creative/baoyu-infographic" + }, + { + "name": "claude-design", + "description": "Design one-off HTML artifacts (landing, deck, prototype).", + "path": "creative/claude-design" + }, + { + "name": "comfyui", + "description": "Generate images, video, and audio via diffusion workflows.", + "path": "creative/comfyui" + }, + { + "name": "design-md", + "description": "Author/validate/export Google's DESIGN.md token spec files.", + "path": "creative/design-md" + }, + { + "name": "excalidraw", + "description": "Hand-drawn Excalidraw JSON diagrams (arch, flow, seq).", + "path": "creative/excalidraw" + }, + { + "name": "humanizer", + "description": "Humanize text: strip AI-isms and add real voice.", + "path": "creative/humanizer" + }, + { + "name": "manim-video", + "description": "Manim CE animations: 3Blue1Brown math/algo videos.", + "path": "creative/manim-video" + }, + { + "name": "p5js", + "description": "p5.js sketches: gen art, shaders, interactive, 3D.", + "path": "creative/p5js" + }, + { + "name": "popular-web-designs", + "description": "54 real design systems (Stripe, Linear, Vercel) as HTML/CSS.", + "path": "creative/popular-web-designs" + }, + { + "name": "pretext", + "description": "Build creative browser demos with DOM-free text layout.", + "path": "creative/pretext" + }, + { + "name": "sketch", + "description": "Throwaway HTML mockups: 2-3 design variants to compare.", + "path": "creative/sketch" + }, + { + "name": "songwriting-and-ai-music", + "description": "Songwriting craft and Suno AI music prompts.", + "path": "creative/songwriting-and-ai-music" + }, + { + "name": "touchdesigner-mcp", + "description": "Control TouchDesigner via twozero MCP.", + "path": "creative/touchdesigner-mcp" + }, + { + "name": "jupyter-live-kernel", + "description": "Iterative Python via live Jupyter kernel (hamelnb).", + "path": "data-science/jupyter-live-kernel" + }, + { + "name": "himalaya", + "description": "Himalaya CLI: IMAP/SMTP email from terminal.", + "path": "email/himalaya" + }, + { + "name": "codebase-inspection", + "description": "Inspect codebases w/ pygount: LOC, languages, ratios.", + "path": "github/codebase-inspection" + }, + { + "name": "github-auth", + "description": "GitHub auth setup: HTTPS tokens, SSH keys, gh CLI login.", + "path": "github/github-auth" + }, + { + "name": "github-code-review", + "description": "Review PRs: diffs, inline comments via gh or REST.", + "path": "github/github-code-review" + }, + { + "name": "github-issues", + "description": "Create, triage, label, assign GitHub issues via gh or REST.", + "path": "github/github-issues" + }, + { + "name": "github-pr-workflow", + "description": "GitHub PR lifecycle: branch, commit, open, CI, merge.", + "path": "github/github-pr-workflow" + }, + { + "name": "github-repo-management", + "description": "Clone/create/fork repos; manage remotes, releases.", + "path": "github/github-repo-management" + }, + { + "name": "repository-bootstrap-recovery", + "description": "Use for slow GitHub checkout bootstrap.", + "path": "github/repository-bootstrap-recovery" + }, + { + "name": "hermes-desktop-plugins", + "description": "Write desktop app plugins that add UI panes and commands.", + "path": "hermes-desktop-plugins" + }, + { + "name": "hermes-themes", + "description": "Author a Hermes color theme that skins every surface.", + "path": "hermes-themes" + }, + { + "name": "gif-search", + "description": "Search/download GIFs from Tenor via curl + jq.", + "path": "media/gif-search" + }, + { + "name": "heartmula", + "description": "HeartMuLa: Suno-like song generation from lyrics + tags.", + "path": "media/heartmula" + }, + { + "name": "songsee", + "description": "Audio spectrograms/features (mel, chroma, MFCC) via CLI.", + "path": "media/songsee" + }, + { + "name": "youtube-content", + "description": "YouTube transcripts to summaries, threads, blogs.", + "path": "media/youtube-content" + }, + { + "name": "evaluating-llms-harness", + "description": "lm-eval-harness: benchmark LLMs (MMLU, GSM8K, etc.).", + "path": "mlops/evaluation/evaluating-llms-harness" + }, + { + "name": "weights-and-biases", + "description": "W&B: log ML experiments, sweeps, model registry, dashboards.", + "path": "mlops/evaluation/weights-and-biases" + }, + { + "name": "huggingface-hub", + "description": "HuggingFace hf CLI: search/download/upload models, datasets.", + "path": "mlops/huggingface-hub" + }, + { + "name": "llama-cpp", + "description": "llama.cpp local GGUF inference + HF Hub model discovery.", + "path": "mlops/inference/llama-cpp" + }, + { + "name": "serving-llms-vllm", + "description": "vLLM: high-throughput LLM serving, OpenAI API, quantization.", + "path": "mlops/inference/serving-llms-vllm" + }, + { + "name": "audiocraft", + "description": "AudioCraft: MusicGen text-to-music, AudioGen text-to-sound.", + "path": "mlops/models/audiocraft" + }, + { + "name": "segment-anything", + "description": "SAM: zero-shot image segmentation via points, boxes, masks.", + "path": "mlops/models/segment-anything" + }, + { + "name": "model-switch", + "description": "在 Hermes 的用户自选 Provider/模型之间安全切换,并用真实 marker 诊断 Hermes/Codex/CC Switch 路由。", + "path": "model-switch" + }, + { + "name": "obsidian", + "description": "Read, search, create, and edit notes in the Obsidian vault.", + "path": "note-taking/obsidian" + }, + { + "name": "obsidian-course-processing", + "description": "Process external course materials (audio/video/PDF/docs) into an Obsidian knowledge base — transcription, OCR, structured summaries, term indexing, image embedding, template management, and vault git backup.", + "path": "note-taking/obsidian-course-processing" + }, + { + "name": "obsidian-knowledge-pipeline", + "description": "从原始课程素材(音频/视频/PDF)到 Obsidian 知识库的全自动处理管线:转写、OCR、核验、总结、卡片、内容过滤、导入报告、UI 配置。", + "path": "note-taking/obsidian-knowledge-pipeline" + }, + { + "name": "obsidian-web-crosscheck", + "description": "对已入库 Obsidian 课程进行公开网络资料交叉校验:生成可信度等级、权威来源清单、待转写确认项和修正建议;不以网络内容替代课程本地源。", + "path": "note-taking/obsidian-web-crosscheck" + }, + { + "name": "airtable", + "description": "Airtable REST API via curl. Records CRUD, filters, upserts.", + "path": "productivity/airtable" + }, + { + "name": "docx", + "description": "Create, read, edit Word .docx documents and templates.", + "path": "productivity/docx" + }, + { + "name": "google-workspace", + "description": "Gmail, Calendar, Drive, Docs, Sheets via gws CLI or Python.", + "path": "productivity/google-workspace" + }, + { + "name": "hermes-skins-and-themes", + "description": "Install, audit, switch, and design Hermes Agent CLI/TUI skins and Desktop themes.", + "path": "productivity/hermes-skins-and-themes" + }, + { + "name": "maps", + "description": "Geocode, POIs, routes, timezones via OpenStreetMap/OSRM.", + "path": "productivity/maps" + }, + { + "name": "nano-pdf", + "description": "Edit text in existing PDFs via natural-language prompts.", + "path": "productivity/nano-pdf" + }, + { + "name": "notion", + "description": "Notion API + ntn CLI: pages, databases, markdown, Workers.", + "path": "productivity/notion" + }, + { + "name": "obsidian-knowledge-base", + "description": "Build and maintain Obsidian knowledge bases from course materials — transcribe, OCR, verify, summarize, card-ify, and import. Covers vault structure, plugin config, UI/CSS, template registration, and Windows-specific encoding fixes.", + "path": "productivity/obsidian-knowledge-base" + }, + { + "name": "ocr-and-documents", + "description": "Extract text from PDFs/scans (pymupdf, marker-pdf).", + "path": "productivity/ocr-and-documents" + }, + { + "name": "pdf", + "description": "Create, merge, split, fill, and secure PDF files.", + "path": "productivity/pdf" + }, + { + "name": "petdex", + "description": "Install and select animated petdex mascots for Hermes.", + "path": "productivity/petdex" + }, + { + "name": "powerpoint", + "description": "Create, read, edit .pptx decks, slides, notes, templates.", + "path": "productivity/powerpoint" + }, + { + "name": "teams-meeting-pipeline", + "description": "Teams meeting summaries, job replay, Graph subscriptions.", + "path": "productivity/teams-meeting-pipeline" + }, + { + "name": "tui-widgets", + "description": "Author live widget apps for the Hermes TUI dock.", + "path": "productivity/tui-widgets" + }, + { + "name": "xlsx", + "description": "Create, read, edit Excel .xlsx spreadsheets and CSVs.", + "path": "productivity/xlsx" + }, + { + "name": "code-backed-ui-audit", + "description": "Read-only UI/UX audits for web games and applications where browser behavior must be reconciled with source, assets, responsive CSS, tests, and alternate runtimes such as Canvas, WebView, or mini-game platforms.", + "path": "quality-assurance/code-backed-ui-audit" + }, + { + "name": "arxiv", + "description": "Search arXiv papers by keyword, author, category, or ID.", + "path": "research/arxiv" + }, + { + "name": "blogwatcher", + "description": "Monitor blogs and RSS/Atom feeds via blogwatcher-cli tool.", + "path": "research/blogwatcher" + }, + { + "name": "grounded-citations", + "description": "Ground answers and documents in cited, verifiable sources.", + "path": "research/grounded-citations" + }, + { + "name": "llm-wiki", + "description": "Karpathy's LLM Wiki: build/query interlinked markdown KB.", + "path": "research/llm-wiki" + }, + { + "name": "polymarket", + "description": "Query Polymarket: markets, prices, orderbooks, history.", + "path": "research/polymarket" + }, + { + "name": "research-paper-writing", + "description": "Write ML papers for NeurIPS/ICML/ICLR: design→submit.", + "path": "research/research-paper-writing" + }, + { + "name": "openhue", + "description": "Control Philips Hue lights, scenes, rooms via OpenHue CLI.", + "path": "smart-home/openhue" + }, + { + "name": "xurl", + "description": "X/Twitter via xurl CLI: raw post search, posting, DM, media.", + "path": "social-media/xurl" + }, + { + "name": "absorption-package-name-resolution", + "description": "Resolve misspelled PyPI names in absorption queues.", + "path": "software-development/absorption-package-name-resolution" + }, + { + "name": "agent-update-safety", + "description": "Use when checking Hermes/Codex upgrades and rule safety.", + "path": "software-development/agent-update-safety" + }, + { + "name": "agent-workflow-fortress", + "description": "Use when strengthening Hermes/Codex/CC Switch work loops, absorbing open-source workflow ideas, running autonomous project iterations, or deciding what tools/skills/MCPs should become part of the portable Hermes pack.", + "path": "software-development/agent-workflow-fortress" + }, + { + "name": "audited-project-delivery", + "description": "Use for project audit, handoff, exact-evidence Git delivery.", + "path": "software-development/audited-project-delivery" + }, + { + "name": "autonomous-evaluation-fallback", + "description": "Build trace redaction and local evaluation for agent loops.", + "path": "software-development/autonomous-evaluation-fallback" + }, + { + "name": "boundary-publication-verification", + "description": "Use when project boundaries or cloud publication need proof.", + "path": "software-development/boundary-publication-verification" + }, + { + "name": "checkout-ownership-reconciliation", + "description": "Use when resuming durable work in a dirty Git checkout.", + "path": "software-development/checkout-ownership-reconciliation" + }, + { + "name": "ci-release-triage", + "description": "Diagnose and close exact-SHA CI release trains without speculative fixes or stale-result reuse.", + "path": "software-development/ci-release-triage" + }, + { + "name": "cloud-delivery-boundary-closure", + "description": "Use when closing project data boundaries and cloud delivery.", + "path": "software-development/cloud-delivery-boundary-closure" + }, + { + "name": "codex-project-workflow-integration", + "description": "Use when integrating repository or user-layer workflows into Codex without taking over private provider, model, authentication, MCP, plugin, session, or Desktop state.", + "path": "software-development/codex-project-workflow-integration" + }, + { + "name": "codex-surface-recovery", + "description": "Use when Codex launch is slow or broken.", + "path": "software-development/codex-surface-recovery" + }, + { + "name": "cognitive-loop-os-delivery-boundaries", + "description": "Use for Cognitive-Loop-OS delivery and CI.", + "path": "software-development/cognitive-loop-os-delivery-boundaries" + }, + { + "name": "cron-scheduler-reliability", + "description": "Use when durable cron jobs must keep project work running.", + "path": "software-development/cron-scheduler-reliability" + }, + { + "name": "desktop-build-verification", + "description": "Verify desktop builds across Rust+Python runtimes.", + "path": "software-development/desktop-build-verification" + }, + { + "name": "desktop-lifecycle-evidence", + "description": "Use for desktop/WebView evidence separation.", + "path": "software-development/desktop-lifecycle-evidence" + }, + { + "name": "desktop-runtime-provenance", + "description": "Prove desktop bundle provenance before readiness acceptance.", + "path": "software-development/desktop-runtime-provenance" + }, + { + "name": "dogfood", + "description": "Exploratory QA of web apps: find bugs, evidence, reports.", + "path": "software-development/dogfood" + }, + { + "name": "durable-event-delivery", + "description": "Build and review SQLite-backed outbox consumers with lease fencing, durable receipts, migrations, and exact-SHA delivery gates.", + "path": "software-development/durable-event-delivery" + }, + { + "name": "durable-execution-boundaries", + "description": "Design, debug, test, and release scheduler/worker authorization boundaries using durable claims, leases, receipts, and execution-time revalidation.", + "path": "software-development/durable-execution-boundaries" + }, + { + "name": "durable-isolated-writer-queues", + "description": "Use when durable cron writers need isolated worktrees.", + "path": "software-development/durable-isolated-writer-queues" + }, + { + "name": "durable-queue-reconciliation", + "description": "Resume sleep loop: verify-don't-redo, no write_file jsonl.", + "path": "software-development/durable-queue-reconciliation" + }, + { + "name": "exact-sha-ci-delivery", + "description": "Use for exact-SHA CI delivery.", + "path": "software-development/exact-sha-ci-delivery" + }, + { + "name": "frozen-release-verification", + "description": "Use for exact-tree release review and CI verification.", + "path": "software-development/frozen-release-verification" + }, + { + "name": "frozen-taskpack-execution", + "description": "Resume frozen TaskPack baselines with append-only status.", + "path": "software-development/frozen-taskpack-execution" + }, + { + "name": "full-stack-absorption-verification", + "description": "Use when proving every real case is wired frontend-to-backend end to end.", + "path": "software-development/full-stack-absorption-verification" + }, + { + "name": "h5-game-production", + "description": "Use when building or iterating on H5/Canvas indie games with AI. Covers phase-prioritized development (P0→P3), design-first workflow, architecture patterns, and platform adaptation for WeChat/Douyin mini-games.", + "path": "software-development/h5-game-production" + }, + { + "name": "hermes-agent-skill-authoring", + "description": "Author in-repo SKILL.md files: frontmatter and structure.", + "path": "software-development/hermes-agent-skill-authoring" + }, + { + "name": "hermes-codex-config-drift", + "description": "Use when Hermes or Codex settings appear to reset.", + "path": "software-development/hermes-codex-config-drift" + }, + { + "name": "hermes-jsonl-ledger-care", + "description": "避免 write_file 覆盖 JSONL/活动账本;追加语法、恢复模式和 Python venv 发现", + "path": "software-development/hermes-jsonl-ledger-care" + }, + { + "name": "inspecting-hermes-desktop-dom", + "description": "Read the live Hermes desktop DOM/CSS over CDP.", + "path": "software-development/inspecting-hermes-desktop-dom" + }, + { + "name": "lease-fenced-event-delivery", + "description": "Design, implement, and review SQLite outbox dispatchers and consumers whose durable receipts are fenced by expiring leases.", + "path": "software-development/lease-fenced-event-delivery" + }, + { + "name": "library-adapter-absorption", + "description": "Use when absorbing a lib into an existing adapter contract.", + "path": "software-development/library-adapter-absorption" + }, + { + "name": "merge-verification-workflow", + "description": "Use for stale-PR slicing, safe merges, and real verification.", + "path": "software-development/merge-verification-workflow" + }, + { + "name": "node-inspect-debugger", + "description": "Debug Node.js via --inspect + Chrome DevTools Protocol CLI.", + "path": "software-development/node-inspect-debugger" + }, + { + "name": "plan", + "description": "Write a markdown plan to .hermes/plans/; no execution.", + "path": "software-development/plan" + }, + { + "name": "portable-agent-boundary-hardening", + "description": "Use when portable agent boundaries fail.", + "path": "software-development/portable-agent-boundary-hardening" + }, + { + "name": "project-data-boundary", + "description": "将 Agent 任务的临时文件、缓存、日志与产物锁定在当前 Git 项目的忽略目录;用于执行、审查、睡眠模式和修复任务。", + "path": "software-development/project-data-boundary" + }, + { + "name": "project-gap-analysis", + "description": "Evaluate a codebase's current state against its own design specifications — read design docs, audit source code + tests, cross-reference acceptance criteria, produce prioritized gap analysis with actionable roadmap.", + "path": "software-development/project-gap-analysis" + }, + { + "name": "project-init-from-spec", + "description": "Turn a product specification document into a complete project scaffold — directory structure, documentation, data models, shared code, git init + GitHub push.", + "path": "software-development/project-init-from-spec" + }, + { + "name": "provider-routing-safety", + "description": "Use when routing API models through local routers.", + "path": "software-development/provider-routing-safety" + }, + { + "name": "python-debugpy", + "description": "Debug Python: pdb REPL + debugpy remote (DAP).", + "path": "software-development/python-debugpy" + }, + { + "name": "python-testing", + "description": "Python testing patterns, gotchas, and conventions for unittest/pytest.", + "path": "software-development/python-testing" + }, + { + "name": "release-qualification-closure", + "description": "Use for exact-SHA release qualification.", + "path": "software-development/release-qualification-closure" + }, + { + "name": "requesting-code-review", + "description": "Thin compatibility entry for pre-commit or release review; delegates all review, frozen-tree, writer, commit and CI rules to agent-workflow-fortress.", + "path": "software-development/requesting-code-review" + }, + { + "name": "reuse-license-compliance", + "description": "Use when backfilling SPDX/REUSE headers or license gates.", + "path": "software-development/reuse-license-compliance" + }, + { + "name": "risk-selective-ci-gating", + "description": "Design deterministic path-classifier CI that fails closed.", + "path": "software-development/risk-selective-ci-gating" + }, + { + "name": "runtime-continuity-governance", + "description": "Use when validating live runtime continuity and recovery.", + "path": "software-development/runtime-continuity-governance" + }, + { + "name": "runtime-deployment-audit", + "description": "Audit deployable agent workflow packages and active runtimes for source/live drift, scheduler references, and Desktop/CLI release splits without changing user state.", + "path": "software-development/runtime-deployment-audit" + }, + { + "name": "simplify-code", + "description": "Parallel 4-agent cleanup of recent code changes.", + "path": "software-development/simplify-code" + }, + { + "name": "skill-library-curation", + "description": "Use when curating Hermes skills by ownership and overlap.", + "path": "software-development/skill-library-curation" + }, + { + "name": "sleep-mode", + "description": "为当前项目启动、恢复或停止可持续自动推进的单写者任务队列;由用户说‘开启睡眠模式’和‘停止任务’触发。", + "path": "software-development/sleep-mode" + }, + { + "name": "spike", + "description": "Throwaway experiments to validate an idea before build.", + "path": "software-development/spike" + }, + { + "name": "sqlite-migration-governance", + "description": "Safely evolve SQLite schemas governed by exact schema validation, migration provenance, backups, and rollback receipts.", + "path": "software-development/sqlite-migration-governance" + }, + { + "name": "sqlite-schema-migrations", + "description": "Safely evolve SQLite schemas with recorded migration provenance, exact schema validation, rollback backups, and test-first compatibility upgrades.", + "path": "software-development/sqlite-schema-migrations" + }, + { + "name": "stateful-workflow-security", + "description": "Secure stateful schedulers and workflow execution against authorization bypasses, stale leases, and review drift.", + "path": "software-development/stateful-workflow-security" + }, + { + "name": "systematic-debugging", + "description": "4-phase root cause debugging: understand bugs before fixing.", + "path": "software-development/systematic-debugging" + }, + { + "name": "test-driven-development", + "description": "TDD: enforce RED-GREEN-REFACTOR, tests before code.", + "path": "software-development/test-driven-development" + }, + { + "name": "user-facing-ingestion-workflows", + "description": "Build local-first user interfaces for importing real source material (URLs and files) into knowledge or document-processing systems without exposing backend workflow identifiers.", + "path": "software-development/user-facing-ingestion-workflows" + }, + { + "name": "web-dashboard-delivery", + "description": "Build and deliver local web dashboards for this user.", + "path": "software-development/web-dashboard-delivery" + }, + { + "name": "windows-development-environment", + "description": "Use when debugging Windows Node, Python, Git-Bash, PowerShell, path, encoding, or local-server failures.", + "path": "software-development/windows-development-environment" + }, + { + "name": "windows-portable-toolchain-boundaries", + "description": "Configure shared Windows portable toolchains without leaking project runtime state, credentials, or package-manager caches across roots.", + "path": "software-development/windows-portable-toolchain-boundaries" + }, + { + "name": "windows-project-runtime-relocation", + "description": "Safely relocate Windows project-owned runtime data, delivery artifacts, and portable toolchains from user-profile paths to a project or configuration root on another drive.", + "path": "software-development/windows-project-runtime-relocation" + }, + { + "name": "windows-runtime-state-recovery", + "description": "在 Windows 上盘点、迁移或清理项目外溢数据时,保护共享桌面应用运行时状态并提供可验证恢复流程。", + "path": "software-development/windows-runtime-state-recovery" + }, + { + "name": "workflow-verification-and-risk-controls", + "description": "Use for fail-closed workflow verification and rollback.", + "path": "software-development/workflow-verification-and-risk-controls" + }, + { + "name": "workspace-hygiene", + "description": "Audit and safely reclaim project-generated external artifacts, temporary test data, duplicate worktree-like copies, and stale build caches without touching protected data or active runtime assets.", + "path": "software-development/workspace-hygiene" + }, + { + "name": "yuanbao", + "description": "Yuanbao (元宝) groups: @mention users, query info/members.", + "path": "yuanbao" + } + ] + }, + "codex": { + "config_toml": { + "model_provider": "cc-switch-official", + "notify": [ + "C:\\Users\\ALEX\\AppData\\Local\\OpenAI\\Codex\\runtimes\\cua_node\\f1bf3cd3a5929acd\\bin\\node_modules\\@oai\\sky\\bin\\windows\\codex-computer-use.exe", + "turn-ended" + ], + "model": "gpt-5.6-sol", + "model_reasoning_effort": "medium", + "approval_policy": "on-request", + "sandbox_mode": "workspace-write", + "project_doc_max_bytes": 65536, + "mcp_servers": { + "node_repl": { + "args": [], + "command": "C:\\Users\\ALEX\\AppData\\Local\\OpenAI\\Codex\\runtimes\\cua_node\\f1bf3cd3a5929acd\\bin\\node_repl.exe", + "startup_timeout_sec": 120, + "env": { + "NODE_REPL_NATIVE_PIPE_CONNECT_TIMEOUT_MS": "1000", + "NODE_REPL_NODE_MODULE_DIRS": "C:\\Users\\ALEX\\AppData\\Local\\OpenAI\\Codex\\runtimes\\cua_node\\f1bf3cd3a5929acd\\bin\\node_modules", + "NODE_REPL_NODE_PATH": "C:\\Users\\ALEX\\AppData\\Local\\OpenAI\\Codex\\runtimes\\cua_node\\f1bf3cd3a5929acd\\bin\\node.exe", + "NODE_REPL_TRUSTED_CODE_PATHS": "C:\\Users\\ALEX\\.codex;C:\\Users\\ALEX\\AppData\\Local\\OpenAI\\Codex\\runtimes\\cua_node\\f1bf3cd3a5929acd\\bin\\node_modules", + "CODEX_HOME": "C:\\Users\\ALEX\\.codex", + "NODE_REPL_TRUSTED_BROWSER_CLIENT_SHA256S": "e7f98a8ce324234ed7f3be8fa39ba54b26e2e8fc79feed2470dcd0871af4a5b3", + "BROWSER_USE_AVAILABLE_BACKENDS": "chrome,iab", + "NODE_REPL_INSTRUCTIONS_USE_CASE_BROWSER": "Control the in-app browser in conjunction with the Browser Plugin.", + "NODE_REPL_INSTRUCTIONS_USE_CASE_CHROME": "Control the Chrome browser in conjunction with the Chrome Plugin. Prefer this method of controlling Chrome over alternatives (such as Computer Use) unless the user explicitly mentions an alternative.", + "BROWSER_USE_CODEX_APP_BUILD_FLAVOR": "prod", + "BROWSER_USE_CODEX_APP_VERSION": "26.803.41515", + "SKY_CUA_NATIVE_PIPE": "1", + "SKY_CUA_NATIVE_PIPE_DIRECTORY": "\\\\.\\pipe\\codex-computer-use-a06e8819-30f3-4e6d-b54e-c4e8f759b389", + "CODEX_CLI_PATH": "C:\\Users\\ALEX\\AppData\\Local\\OpenAI\\Codex\\bin\\cfac6bda2d141e07\\codex.exe" + } + } + }, + "model_providers": { + "custom": { + "name": "OpenAI", + "requires_openai_auth": "[REDACTED]", + "supports_websockets": true, + "wire_api": "responses" + }, + "cc-switch-official": { + "name": "OpenAI", + "requires_openai_auth": "[REDACTED]", + "supports_websockets": false, + "wire_api": "responses", + "base_url": "[REDACTED]" + } + }, + "desktop": { + "followUpQueueMode": "queue", + "appearanceTheme": "dark", + "usePointerCursors": true + }, + "marketplaces": { + "openai-bundled": { + "last_updated": "2026-08-10T10:57:14Z", + "source_type": "local", + "source": "\\\\?\\C:\\Users\\ALEX\\.codex\\.tmp\\bundled-marketplaces\\openai-bundled" + } + }, + "plugins": { + "sites@openai-bundled": { + "enabled": true + }, + "browser@openai-bundled": { + "enabled": true + }, + "visualize@openai-bundled": { + "enabled": true + } + }, + "features": { + "js_repl": false, + "memories": true + }, + "shell_environment_policy": { + "set": { + "BROWSER_USE_AVAILABLE_BACKENDS": "chrome,iab", + "NODE_REPL_TRUSTED_BROWSER_CLIENT_SHA256S": "e7f98a8ce324234ed7f3be8fa39ba54b26e2e8fc79feed2470dcd0871af4a5b3", + "NODE_REPL_TRUSTED_CODE_PATHS": "C:\\Users\\ALEX\\.codex;C:\\Users\\ALEX\\AppData\\Local\\OpenAI\\Codex\\runtimes\\cua_node\\f1bf3cd3a5929acd\\bin\\node_modules" + } + }, + "windows": { + "sandbox": "elevated" + }, + "memories": { + "generate_memories": true, + "use_memories": true + }, + "projects": { + "d:\\all projects\\cognitive-loop-os": { + "trust_level": "trusted" + } + } + }, + "rules": [ + "rules/default.rules", + "rules/workflow-assistance.rules" + ], + "agents_skills": [ + { + "name": "workflow-assistance-evidence-verification", + "description": "Use when verifying implementation, builds, tests, desktop/runtime behavior, CI, publication, releases, or completion claims.", + "path": "workflow-assistance-evidence-verification" + }, + { + "name": "workflow-assistance-github-delivery", + "description": "Use for GitHub repositories, issues, pull requests, checks, Actions, releases, remotes, or exact-SHA cloud readback.", + "path": "workflow-assistance-github-delivery" + }, + { + "name": "workflow-assistance-openhuman-integration", + "description": "Use when OpenHuman scans or audits the workspace.", + "path": "workflow-assistance-openhuman-integration" + }, + { + "name": "workflow-assistance-project-data-boundary", + "description": "Use when a task creates caches, logs, evidence, temporary environments, generated artifacts, downloads, or agent runtime state.", + "path": "workflow-assistance-project-data-boundary" + }, + { + "name": "workflow-assistance-python-testing", + "description": "Use when writing, changing, debugging, or running Python tests with unittest, pytest, virtual environments, or Windows path constraints.", + "path": "workflow-assistance-python-testing" + }, + { + "name": "workflow-assistance-safe-project-execution", + "description": "Use for any coding or project task that needs bounded scope, preserved user work, real execution, and honest completion evidence.", + "path": "workflow-assistance-safe-project-execution" + }, + { + "name": "workflow-assistance-self-improvement", + "description": "Use when maintaining or growing the skill collection.", + "path": "workflow-assistance-self-improvement" + }, + { + "name": "workflow-assistance-single-writer-delivery", + "description": "Use for Git changes, parallel agents, code review, commits, pull requests, CI, merge, release, or delivery closure.", + "path": "workflow-assistance-single-writer-delivery" + }, + { + "name": "workflow-assistance-systematic-debugging", + "description": "Use for bugs, failing tests, crashes, regressions, flaky behavior, incorrect output, or environment-specific failures.", + "path": "workflow-assistance-systematic-debugging" + }, + { + "name": "workflow-assistance-windows-development", + "description": "Use for Windows development failures involving PowerShell, Git Bash, paths, quoting, Node, Python, ports, processes, encoding, or desktop runtimes.", + "path": "workflow-assistance-windows-development" + } + ] + } +} diff --git a/10-workflow/workflow-assistance/docs/workflow/codex-global-enhancement.md b/10-workflow/workflow-assistance/docs/workflow/codex-global-enhancement.md index 37db714..3c7f8ef 100644 --- a/10-workflow/workflow-assistance/docs/workflow/codex-global-enhancement.md +++ b/10-workflow/workflow-assistance/docs/workflow/codex-global-enhancement.md @@ -53,6 +53,10 @@ project_doc_max_bytes = 65536 `workflow-assistance-self-improvement` 以中立形态吸收个人 agent 的技能自动成长模式(usage sidecar + active/stale/archived + pin 豁免 + 只归档不删除 + 转变前备份 + provenance 过滤),配套 `scripts/workflow/skill_lifecycle.py`(stdlib-only,可对任意 skills 根运行);自动生长的知识通过 PR 提升进模块 codex-assets,仓库即跨机器持久存储。 +## 用户环境画像(跨机器留存) + +`scripts/workflow/user_profile_export.py` 以只读、无密方式导出 Hermes/Codex 用户配置与技能清单到 tracked `config/user-environment-profile.json`(hermes config 键值脱敏、`.env` 仅键名、143 个 Hermes skills + 10 个 Codex skills 清单;凭据一律 `[REDACTED]`,发现未脱敏值即拒绝写入)。恢复流程见 `docs/workflow/user-environment-profile.md`:新机器 `sync apply` 部署模块 skills 后,按画像键名重建配置、重填凭据。 + ## 命令策略 `workflow-assistance.rules` 提供以下边界: diff --git a/10-workflow/workflow-assistance/docs/workflow/user-environment-profile.md b/10-workflow/workflow-assistance/docs/workflow/user-environment-profile.md new file mode 100644 index 0000000..ae8dd24 --- /dev/null +++ b/10-workflow/workflow-assistance/docs/workflow/user-environment-profile.md @@ -0,0 +1,44 @@ +# 用户环境画像(User Environment Profile) + +## 目的 + +跨机器保留 Hermes 与 Codex 的用户级配置与技能清单,避免换电脑后从零积攒。本画像以**中立、无密**形态随增强模块仓库留存:只记录非密配置值与技能清单,所有凭据值统一为 `[REDACTED]`。 + +## 内容 + +机器可读画像:`config/user-environment-profile.json`(tracked,由导出器生成): + +```text +hermes: + config_yaml Hermes config.yaml 的非密键值(秘密键值脱敏为 [REDACTED]) + env_key_names ~/.env 的键名清单(绝不含值) + skills 用户级 skills 清单(143 个:名称 + description + 路径) +codex: + config_toml Codex config.toml 的非密键值(provider/model 名保留,base_url/凭据脱敏) + rules $CODEX_HOME/rules/*.rules 清单 + agents_skills ~/.agents/skills 技能清单(10 个 workflow-assistance-*) +paths hermes_home / codex_home / agents_skills_root +``` + +技能内容本身不入画像 —— 技能文件随各自运行时存在;增强模块的 10 个 skill 已随本模块仓库携带。 + +## 刷新 + +```bash +python 10-workflow/workflow-assistance/scripts/workflow/user_profile_export.py +``` + +导出器读取真实用户 Home,重写 `config/user-environment-profile.json`(脱敏 fail-closed:发现未脱敏秘密值则拒绝写入)。生成后 `git diff --check` + 提交。 + +## 新机器恢复 + +1. 克隆 WORK-LAB → `python 10-workflow/workflow-assistance/scripts/workflow/sync_codex_global_assets.py apply`(部署 10 个 skill + 规则 + guidance + 3 个 config 缺省字段); +2. 读取画像:`config/user-environment-profile.json` 对照各运行时配置(键名 + 脱敏值,提示哪些位置需要重新填写凭据); +3. Hermes:按画像重建非密配置项(display/terminal 等),凭据按 `env_key_names` 键名重新填入; +4. Codex:provider/model 名照画像;base_url/密钥等 [REDACTED] 项重新配置。 + +## 安全边界 + +- 导出器只读用户 Home,绝不读取会话库、记忆库、keychain、auth 存储; +- 任何键名含 api_key/token/secret/password/credential/auth/connection/base_url 等 → 值 `[REDACTED]`;值匹配 sk-/gh_/AKIA/私钥/Bearer/URL 内嵌凭据 → `[REDACTED]`; +- 画像可安全提交(无凭据值);发现未脱敏值导出器直接失败。 diff --git a/10-workflow/workflow-assistance/scripts/workflow/user_profile_export.py b/10-workflow/workflow-assistance/scripts/workflow/user_profile_export.py new file mode 100644 index 0000000..359fabd --- /dev/null +++ b/10-workflow/workflow-assistance/scripts/workflow/user_profile_export.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python3 +"""Secret-free user environment profile export (neutral, client-agnostic). + +Inventories the user's Hermes and Codex user-level configuration and skills +into a tracked manifest for cross-machine restoration. It is read-only +against user homes and NEVER records secret values: any key or value matching +a secret pattern is replaced with [REDACTED]. + +Output: config/user-environment-profile.json (tracked, secret-free). +""" +from __future__ import annotations + +import json +import re +import sys +import tomllib +from pathlib import Path +from typing import Any + +try: + import yaml # pyyaml +except ImportError: # pragma: no cover + yaml = None + +SECRET_KEY = re.compile( + r"(?i)(api[_-]?key|token|secret|password|passwd|credential|auth|cookie|cookie|keyring|private|session|connection|endpoint|base_url|webhook|signing)" +) +SECRET_VALUE = re.compile( + r"(?i)(sk-[A-Za-z0-9]{12,}|gh[pousr]_[A-Za-z0-9]{20,}|AKIA[0-9A-Z]{16}|" + r"-----BEGIN|Bearer\s+[A-Za-z0-9._~+/=-]{16,}|" + r"https?://[^\s/:@]{3,}:[^\s/@]{8,}@)" +) +REDACTED = "[REDACTED]" + + +def _redact_key(key: str) -> str: + return REDACTED if SECRET_KEY.search(key) else key + + +def _redact_value(key: str, value: Any) -> Any: + if isinstance(value, (dict, list)): + return value # handled by the walker + text = str(value) + if SECRET_KEY.search(key) or SECRET_VALUE.search(text): + return REDACTED + return value + + +def _redact_walk(data: Any, key: str = "") -> Any: + if isinstance(data, dict): + return { + str(k): (REDACTED if SECRET_KEY.search(str(k)) else _redact_walk(v, str(k))) + for k, v in data.items() + } + if isinstance(data, list): + return [_redact_walk(v, key) for v in data] + return _redact_value(key, data) + + +def _frontmatter_description(skill_md: Path) -> str: + try: + text = skill_md.read_text(encoding="utf-8", errors="replace") + except OSError: + return "" + if not text.startswith("---"): + return "" + end = text.find("\n---", 3) + if end < 0: + return "" + fm = text[3:end] + for line in fm.splitlines(): + if line.startswith("description:"): + return line.split(":", 1)[1].strip().strip("\"'").strip() + return "" + + +def _inventory_skills(root: Path) -> list[dict[str, str]]: + out: list[dict[str, str]] = [] + if not root.is_dir(): + return out + for skill_md in sorted(root.rglob("SKILL.md")): + if any(part in {"node_modules", ".git", ".archive", "__pycache__"} for part in skill_md.parts): + continue + out.append( + { + "name": skill_md.parent.name, + "description": _frontmatter_description(skill_md), + "path": str(skill_md.parent.relative_to(root)).replace("\\", "/"), + } + ) + return out + + +def _config_yaml(path: Path) -> dict[str, Any]: + if not path.is_file() or yaml is None: + return {} + try: + data = yaml.safe_load(path.read_text(encoding="utf-8", errors="replace")) + return data if isinstance(data, dict) else {} + except Exception: # noqa: BLE001 - best-effort + return {} + + +def _config_toml(path: Path) -> dict[str, Any]: + if not path.is_file(): + return {} + try: + data = tomllib.loads(path.read_text(encoding="utf-8", errors="replace")) + return data if isinstance(data, dict) else {} + except tomllib.TOMLDecodeError: + return {} + + +def _env_key_names(path: Path) -> list[str]: + if not path.is_file(): + return [] + names: list[str] = [] + for line in path.read_text(encoding="utf-8", errors="replace").splitlines(): + line = line.strip() + if line and not line.startswith("#") and "=" in line: + names.append(line.split("=", 1)[0].strip()) + return sorted(set(names)) + + +def _redact_toml_keys(data: dict[str, Any]) -> dict[str, Any]: + """Redact secret keys in a nested TOML config, keep provider/model names.""" + out: dict[str, Any] = {} + for key, value in data.items(): + if SECRET_KEY.search(key): + out[key] = REDACTED + elif isinstance(value, dict): + out[key] = _redact_toml_keys(value) + elif isinstance(value, list): + out[key] = [_redact_toml_keys(v) if isinstance(v, dict) else _redact_value(key, v) for v in value] + else: + out[key] = _redact_value(key, value) + return out + + +def _profile(home: Path, codex_home: Path, agent_home: Path) -> dict[str, Any]: + hermes_config = _config_yaml(home / "config.yaml") + codex_config = _config_toml(codex_home / "config.toml") + return { + "schema_version": "worklab/user-environment-profile/v1", + "generated_at": __import__("datetime").datetime.now(__import__("datetime").timezone.utc).isoformat(timespec="seconds"), + "paths": { + "hermes_home": str(home), + "codex_home": str(codex_home), + "agents_skills_root": str(agent_home / "skills"), + }, + "hermes": { + "config_yaml": _redact_walk(hermes_config), + "env_key_names": _env_key_names(home / ".env"), + "skills": _inventory_skills(home / "skills"), + }, + "codex": { + "config_toml": _redact_toml_keys(codex_config), + "rules": sorted(p.relative_to(codex_home).as_posix() for p in (codex_home / "rules").glob("*.rules")) if (codex_home / "rules").is_dir() else [], + "agents_skills": _inventory_skills(agent_home / "skills"), + }, + } + + +def main(argv: list[str]) -> int: + home = Path(argv[1]) if len(argv) > 1 else Path.home() / "AppData/Local/hermes" + codex_home = Path(argv[2]) if len(argv) > 2 else Path.home() / ".codex" + agent_home = Path(argv[3]) if len(argv) > 3 else Path.home() / ".agents" + out = Path(argv[4]) if len(argv) > 4 else Path(__file__).resolve().parents[2] / "config/user-environment-profile.json" + + profile = _profile(home, codex_home, agent_home) + payload = json.dumps(profile, ensure_ascii=False, indent=2) + if REDACTED not in payload and any( + SECRET_VALUE.search(line) for line in payload.splitlines() if "generated_at" not in line + ): + print("FAIL: unredacted secret value found in profile", file=sys.stderr) + return 1 + out.parent.mkdir(parents=True, exist_ok=True) + out.write_text(payload + "\n", encoding="utf-8") + print( + f"USER_ENVIRONMENT_PROFILE_WRITTEN path={out} " + f"hermes_skills={len(profile['hermes']['skills'])} " + f"codex_skills={len(profile['codex']['agents_skills'])} " + f"env_keys={len(profile['hermes']['env_key_names'])}" + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv[1:])) diff --git a/10-workflow/workflow-assistance/tests/test_user_profile_export.py b/10-workflow/workflow-assistance/tests/test_user_profile_export.py new file mode 100644 index 0000000..8f72715 --- /dev/null +++ b/10-workflow/workflow-assistance/tests/test_user_profile_export.py @@ -0,0 +1,102 @@ +from __future__ import annotations + +import importlib.util +import json +import sys +import tempfile +import unittest +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +SCRIPT = ROOT / "scripts/workflow/user_profile_export.py" +spec = importlib.util.spec_from_file_location("user_profile_export", SCRIPT) +assert spec and spec.loader +module = importlib.util.module_from_spec(spec) +sys.modules[spec.name] = module +spec.loader.exec_module(module) + + +class UserProfileExportTests(unittest.TestCase): + def test_redact_walk_redacts_secret_keys_and_values(self) -> None: + data = { + "display": {"theme": "dark", "skin": "default"}, + "model": {"provider": "deepseek", "model": "deepseek-v4-flash"}, + "api_key": "sk-real-value-1234567890", + "providers": {"p": {"token": "abcdefghijklmnop"}}, + "description": "contains sk-abcdefghijklmnop literal", + } + out = module._redact_walk(data) + self.assertEqual(out["display"]["theme"], "dark") + self.assertEqual(out["model"]["provider"], "deepseek") + self.assertEqual(out["api_key"], module.REDACTED) + self.assertEqual(out["providers"]["p"]["token"], module.REDACTED) + self.assertEqual(out["description"], module.REDACTED) + + def test_env_key_names_only(self) -> None: + with tempfile.TemporaryDirectory() as raw: + p = Path(raw) / ".env" + p.write_text("OPENAI_API_KEY=sk-secret-value-abcdefghij\nDEEPSEEK_API_KEY=sk-other-value\n# comment\nEMPTY=\n", encoding="utf-8") + names = module._env_key_names(p) + self.assertEqual(names, ["DEEPSEEK_API_KEY", "EMPTY", "OPENAI_API_KEY"]) + self.assertTrue(all("=" not in n for n in names)) + + def test_toml_redaction_keeps_provider_model_redacts_credentials(self) -> None: + data = { + "model_provider": "cc-switch-official", + "model": "gpt-5.6-luna", + "base_url": "https://user:pass@example.invalid/v1", + "mcp_servers": {"custom": {"command": "safe-placeholder", "api_key": "xyz123"}}, + } + out = module._redact_toml_keys(data) + self.assertEqual(out["model_provider"], "cc-switch-official") + self.assertEqual(out["model"], "gpt-5.6-luna") + self.assertEqual(out["base_url"], module.REDACTED) + self.assertEqual(out["mcp_servers"]["custom"]["api_key"], module.REDACTED) + self.assertEqual(out["mcp_servers"]["custom"]["command"], "safe-placeholder") + + def test_skills_inventory_reads_description(self) -> None: + with tempfile.TemporaryDirectory() as raw: + root = Path(raw) + d = root / "my-skill" + d.mkdir() + (d / "SKILL.md").write_text( + "---\nname: my-skill\ndescription: 'Use for testing only.'\n---\n\n# body\n", encoding="utf-8" + ) + inv = module._inventory_skills(root) + self.assertEqual(len(inv), 1) + self.assertEqual(inv[0]["name"], "my-skill") + self.assertEqual(inv[0]["description"], "Use for testing only.") + + def test_profile_output_is_secret_free(self) -> None: + with tempfile.TemporaryDirectory() as raw: + base = Path(raw) + home = base / "hermes" + codex = base / "codex" + agents = base / "agents" + (home / "skills").mkdir(parents=True) + (codex / "rules").mkdir(parents=True) + (agents / "skills").mkdir(parents=True) + (home / "config.yaml").write_text( + "display:\n theme: dark\nmodel:\n provider: deepseek\napi_key: sk-literal-abcdefghijklmnop\n", + encoding="utf-8", + ) + (home / ".env").write_text("OPENAI_API_KEY=sk-abcdefghijklmnop\n", encoding="utf-8") + (codex / "config.toml").write_text( + 'model_provider = "cc-switch-official"\nbase_url = "https://u:p@example.invalid"\n', encoding="utf-8" + ) + (codex / "rules" / "a.rules").write_text("# rule\n", encoding="utf-8") + (home / "skills" / "s1").mkdir(parents=True) + (home / "skills" / "s1" / "SKILL.md").write_text("---\nname: s1\ndescription: 'D.'\n---\n", encoding="utf-8") + + profile = module._profile(home, codex, agents) + payload = json.dumps(profile, ensure_ascii=False) + self.assertNotIn("sk-literal", payload) + self.assertNotIn("sk-abcdefghijklmnop", payload) + self.assertNotIn("user:pass", payload) + self.assertIn("deepseek", payload) # provider name kept + self.assertIn("cc-switch-official", payload) + self.assertEqual(len(profile["hermes"]["skills"]), 1) + + +if __name__ == "__main__": + unittest.main()