calvyn-code 0.14.0 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,20 +1,20 @@
1
1
  <p align="center">
2
- <img src="assets/banner.png" alt="Hermes Agent" width="100%">
2
+ <img src="assets/banner.png" alt="Calvyn Code" width="100%">
3
3
  </p>
4
4
 
5
- # Hermes Agent
5
+ # Calvyn Code
6
6
 
7
7
  <p align="center">
8
- <a href="https://hermes-agent.nousresearch.com/docs/"><img src="https://img.shields.io/badge/Docs-hermes--agent.nousresearch.com-FFD700?style=for-the-badge" alt="Documentation"></a>
8
+ <a href="https://calvyn-code.nousresearch.com/docs/"><img src="https://img.shields.io/badge/Docs-calvyn--code.nousresearch.com-FFD700?style=for-the-badge" alt="Documentation"></a>
9
9
  <a href="https://discord.gg/NousResearch"><img src="https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" alt="Discord"></a>
10
- <a href="https://github.com/NousResearch/hermes-agent/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-green?style=for-the-badge" alt="License: MIT"></a>
10
+ <a href="https://github.com/calvyns/calvyn-code/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-green?style=for-the-badge" alt="License: MIT"></a>
11
11
  <a href="https://nousresearch.com"><img src="https://img.shields.io/badge/Built%20by-Nous%20Research-blueviolet?style=for-the-badge" alt="Built by Nous Research"></a>
12
12
  <a href="README.zh-CN.md"><img src="https://img.shields.io/badge/Lang-中文-red?style=for-the-badge" alt="中文"></a>
13
13
  </p>
14
14
 
15
15
  **The self-improving AI agent built by [Nous Research](https://nousresearch.com).** It's the only agent with a built-in learning loop — it creates skills from experience, improves them during use, nudges itself to persist knowledge, searches its own past conversations, and builds a deepening model of who you are across sessions. Run it on a $5 VPS, a GPU cluster, or serverless infrastructure that costs nearly nothing when idle. It's not tied to your laptop — talk to it from Telegram while it works on a cloud VM.
16
16
 
17
- Use any model you want — [Nous Portal](https://portal.nousresearch.com), [OpenRouter](https://openrouter.ai) (200+ models), [NovitaAI](https://novita.ai) (AI-native cloud for Model API, Agent Sandbox, and GPU Cloud), [NVIDIA NIM](https://build.nvidia.com) (Nemotron), [Xiaomi MiMo](https://platform.xiaomimimo.com), [z.ai/GLM](https://z.ai), [Kimi/Moonshot](https://platform.moonshot.ai), [MiniMax](https://www.minimax.io), [Hugging Face](https://huggingface.co), OpenAI, or your own endpoint. Switch with `hermes model` — no code changes, no lock-in.
17
+ Use any model you want — [Nous Portal](https://portal.nousresearch.com), [OpenRouter](https://openrouter.ai) (200+ models), [NovitaAI](https://novita.ai) (AI-native cloud for Model API, Agent Sandbox, and GPU Cloud), [NVIDIA NIM](https://build.nvidia.com) (Nemotron), [Xiaomi MiMo](https://platform.xiaomimimo.com), [z.ai/GLM](https://z.ai), [Kimi/Moonshot](https://platform.moonshot.ai), [MiniMax](https://www.minimax.io), [Hugging Face](https://huggingface.co), OpenAI, or your own endpoint. Switch with `calvyn model` — no code changes, no lock-in.
18
18
 
19
19
  <table>
20
20
  <tr><td><b>A real terminal interface</b></td><td>Full TUI with multiline editing, slash-command autocomplete, conversation history, interrupt-and-redirect, and streaming tool output.</td></tr>
@@ -28,61 +28,61 @@ Use any model you want — [Nous Portal](https://portal.nousresearch.com), [Open
28
28
 
29
29
  ---
30
30
 
31
- ## Quick Install
32
-
33
- ### npm install -g
34
-
35
- Если хочешь ставить через `npm`, теперь можно так
36
-
37
- ```bash
38
- npm install -g calvyn-code
39
- calvyn
40
- ```
41
-
42
- Что важно
43
-
44
- - внутри это все равно Python-проект, не Node.js-перепись
45
- - нужен `Python 3.11+`
46
- - на Linux, macOS, Windows и Termux эта npm-обертка сама создаст `.venv` и поставит Calvyn
47
- - на телефоне лучше запускать через Termux где есть и `node`, и `python`
48
- - публикация в npm требует, чтобы пакет `calvyn-code` был реально выложен в registry
49
-
50
- Если после установки что-то сломалось
51
-
52
- ```bash
53
- npm rebuild -g calvyn-code
54
- calvyn
55
- ```
56
-
57
- ### Linux, macOS, WSL2, Termux
31
+ ## Quick Install
32
+
33
+ ### npm install -g
34
+
35
+ Если хочешь ставить через `npm`, теперь можно так
36
+
37
+ ```bash
38
+ npm install -g calvyn-code
39
+ calvyn
40
+ ```
41
+
42
+ Что важно
43
+
44
+ - внутри это все равно Python-проект, не Node.js-перепись
45
+ - нужен `Python 3.11+`
46
+ - на Linux, macOS, Windows и Termux эта npm-обертка сама создаст `.venv` и поставит Calvyn
47
+ - на телефоне лучше запускать через Termux где есть и `node`, и `python`
48
+ - публикация в npm требует, чтобы пакет `calvyn-code` был реально выложен в registry
49
+
50
+ Если после установки что-то сломалось
51
+
52
+ ```bash
53
+ npm rebuild -g calvyn-code
54
+ calvyn
55
+ ```
56
+
57
+ ### Linux, macOS, WSL2, Termux
58
58
 
59
59
  ```bash
60
- curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
60
+ curl -fsSL https://raw.githubusercontent.com/calvyns/calvyn-code/main/scripts/install.sh | bash
61
61
  ```
62
62
 
63
63
  ### Windows (native, PowerShell) — Early Beta
64
64
 
65
- > **Heads up:** Native Windows support is **early beta**. It installs and runs, but hasn't been road-tested as broadly as our Linux/macOS/WSL2 paths. Please [file issues](https://github.com/NousResearch/hermes-agent/issues) when you hit rough edges. For the most battle-tested Windows setup today, run the Linux/macOS one-liner above inside **WSL2**.
65
+ > **Heads up:** Native Windows support is **early beta**. It installs and runs, but hasn't been road-tested as broadly as our Linux/macOS/WSL2 paths. Please [file issues](https://github.com/calvyns/calvyn-code/issues) when you hit rough edges. For the most battle-tested Windows setup today, run the Linux/macOS one-liner above inside **WSL2**.
66
66
 
67
67
  Run this in PowerShell:
68
68
 
69
69
  ```powershell
70
- irm https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1 | iex
70
+ irm https://raw.githubusercontent.com/calvyns/calvyn-code/main/scripts/install.ps1 | iex
71
71
  ```
72
72
 
73
- The installer handles everything: uv, Python 3.11, Node.js, ripgrep, ffmpeg, **and a portable Git Bash** (MinGit, unpacked to `%LOCALAPPDATA%\hermes\git` — no admin required, completely isolated from any system Git install). Hermes uses this bundled Git Bash to run shell commands.
73
+ The installer handles everything: uv, Python 3.11, Node.js, ripgrep, ffmpeg, **and a portable Git Bash** (MinGit, unpacked to `%LOCALAPPDATA%\calvyn\git` — no admin required, completely isolated from any system Git install). Calvyn uses this bundled Git Bash to run shell commands.
74
74
 
75
75
  If you already have Git installed, the installer detects it and uses that instead. Otherwise a ~45MB MinGit download is all you need — it won't touch or interfere with any system Git.
76
76
 
77
- > **Android / Termux:** The tested manual path is documented in the [Termux guide](https://hermes-agent.nousresearch.com/docs/getting-started/termux). On Termux, Hermes installs a curated `.[termux]` extra because the full `.[all]` extra currently pulls Android-incompatible voice dependencies.
77
+ > **Android / Termux:** The tested manual path is documented in the [Termux guide](https://calvyn-code.nousresearch.com/docs/getting-started/termux). On Termux, Calvyn installs a curated `.[termux]` extra because the full `.[all]` extra currently pulls Android-incompatible voice dependencies.
78
78
  >
79
- > **Windows:** Native Windows is supported as an **early beta** — the PowerShell one-liner above installs everything, but expect rough edges and please file issues when you hit them. If you'd rather use WSL2 (our most battle-tested Windows path), the Linux command works there too. Native Windows install lives under `%LOCALAPPDATA%\hermes`; WSL2 installs under `~/.hermes` as on Linux. The only Hermes feature that currently needs WSL2 specifically is the browser-based dashboard chat pane (it uses a POSIX PTY — classic CLI and gateway both run natively).
79
+ > **Windows:** Native Windows is supported as an **early beta** — the PowerShell one-liner above installs everything, but expect rough edges and please file issues when you hit them. If you'd rather use WSL2 (our most battle-tested Windows path), the Linux command works there too. Native Windows install lives under `%LOCALAPPDATA%\calvyn`; WSL2 installs under `~/.calvyn` as on Linux. The only Calvyn feature that currently needs WSL2 specifically is the browser-based dashboard chat pane (it uses a POSIX PTY — classic CLI and gateway both run natively).
80
80
 
81
81
  After installation:
82
82
 
83
83
  ```bash
84
84
  source ~/.bashrc # reload shell (or: source ~/.zshrc)
85
- hermes # start chatting!
85
+ calvyn # start chatting!
86
86
  ```
87
87
 
88
88
  ---
@@ -90,26 +90,26 @@ hermes # start chatting!
90
90
  ## Getting Started
91
91
 
92
92
  ```bash
93
- hermes # Interactive CLI — start a conversation
94
- hermes model # Choose your LLM provider and model
95
- hermes tools # Configure which tools are enabled
96
- hermes config set # Set individual config values
97
- hermes gateway # Start the messaging gateway (Telegram, Discord, etc.)
98
- hermes setup # Run the full setup wizard (configures everything at once)
99
- hermes claw migrate # Migrate from OpenClaw (if coming from OpenClaw)
100
- hermes update # Update to the latest version
101
- hermes doctor # Diagnose any issues
93
+ calvyn # Interactive CLI — start a conversation
94
+ calvyn model # Choose your LLM provider and model
95
+ calvyn tools # Configure which tools are enabled
96
+ calvyn config set # Set individual config values
97
+ calvyn gateway # Start the messaging gateway (Telegram, Discord, etc.)
98
+ calvyn setup # Run the full setup wizard (configures everything at once)
99
+ calvyn claw migrate # Migrate from OpenClaw (if coming from OpenClaw)
100
+ calvyn update # Update to the latest version
101
+ calvyn doctor # Diagnose any issues
102
102
  ```
103
103
 
104
- 📖 **[Full documentation →](https://hermes-agent.nousresearch.com/docs/)**
104
+ 📖 **[Full documentation →](https://calvyn-code.nousresearch.com/docs/)**
105
105
 
106
106
  ## CLI vs Messaging Quick Reference
107
107
 
108
- Hermes has two entry points: start the terminal UI with `hermes`, or run the gateway and talk to it from Telegram, Discord, Slack, WhatsApp, Signal, or Email. Once you're in a conversation, many slash commands are shared across both interfaces.
108
+ Calvyn has two entry points: start the terminal UI with `calvyn`, or run the gateway and talk to it from Telegram, Discord, Slack, WhatsApp, Signal, or Email. Once you're in a conversation, many slash commands are shared across both interfaces.
109
109
 
110
110
  | Action | CLI | Messaging platforms |
111
111
  |---------|-----|---------------------|
112
- | Start chatting | `hermes` | Run `hermes gateway setup` + `hermes gateway start`, then send the bot a message |
112
+ | Start chatting | `calvyn` | Run `calvyn gateway setup` + `calvyn gateway start`, then send the bot a message |
113
113
  | Start fresh conversation | `/new` or `/reset` | `/new` or `/reset` |
114
114
  | Change model | `/model [provider:model]` | `/model [provider:model]` |
115
115
  | Set a personality | `/personality [name]` | `/personality [name]` |
@@ -119,47 +119,47 @@ Hermes has two entry points: start the terminal UI with `hermes`, or run the gat
119
119
  | Interrupt current work | `Ctrl+C` or send a new message | `/stop` or send a new message |
120
120
  | Platform-specific status | `/platforms` | `/status`, `/sethome` |
121
121
 
122
- For the full command lists, see the [CLI guide](https://hermes-agent.nousresearch.com/docs/user-guide/cli) and the [Messaging Gateway guide](https://hermes-agent.nousresearch.com/docs/user-guide/messaging).
122
+ For the full command lists, see the [CLI guide](https://calvyn-code.nousresearch.com/docs/user-guide/cli) and the [Messaging Gateway guide](https://calvyn-code.nousresearch.com/docs/user-guide/messaging).
123
123
 
124
124
  ---
125
125
 
126
126
  ## Documentation
127
127
 
128
- All documentation lives at **[hermes-agent.nousresearch.com/docs](https://hermes-agent.nousresearch.com/docs/)**:
128
+ All documentation lives at **[calvyn-code.nousresearch.com/docs](https://calvyn-code.nousresearch.com/docs/)**:
129
129
 
130
130
  | Section | What's Covered |
131
131
  |---------|---------------|
132
- | [Quickstart](https://hermes-agent.nousresearch.com/docs/getting-started/quickstart) | Install → setup → first conversation in 2 minutes |
133
- | [CLI Usage](https://hermes-agent.nousresearch.com/docs/user-guide/cli) | Commands, keybindings, personalities, sessions |
134
- | [Configuration](https://hermes-agent.nousresearch.com/docs/user-guide/configuration) | Config file, providers, models, all options |
135
- | [Messaging Gateway](https://hermes-agent.nousresearch.com/docs/user-guide/messaging) | Telegram, Discord, Slack, WhatsApp, Signal, Home Assistant |
136
- | [Security](https://hermes-agent.nousresearch.com/docs/user-guide/security) | Command approval, DM pairing, container isolation |
137
- | [Tools & Toolsets](https://hermes-agent.nousresearch.com/docs/user-guide/features/tools) | 40+ tools, toolset system, terminal backends |
138
- | [Skills System](https://hermes-agent.nousresearch.com/docs/user-guide/features/skills) | Procedural memory, Skills Hub, creating skills |
139
- | [Memory](https://hermes-agent.nousresearch.com/docs/user-guide/features/memory) | Persistent memory, user profiles, best practices |
140
- | [MCP Integration](https://hermes-agent.nousresearch.com/docs/user-guide/features/mcp) | Connect any MCP server for extended capabilities |
141
- | [Cron Scheduling](https://hermes-agent.nousresearch.com/docs/user-guide/features/cron) | Scheduled tasks with platform delivery |
142
- | [Context Files](https://hermes-agent.nousresearch.com/docs/user-guide/features/context-files) | Project context that shapes every conversation |
143
- | [Architecture](https://hermes-agent.nousresearch.com/docs/developer-guide/architecture) | Project structure, agent loop, key classes |
144
- | [Contributing](https://hermes-agent.nousresearch.com/docs/developer-guide/contributing) | Development setup, PR process, code style |
145
- | [CLI Reference](https://hermes-agent.nousresearch.com/docs/reference/cli-commands) | All commands and flags |
146
- | [Environment Variables](https://hermes-agent.nousresearch.com/docs/reference/environment-variables) | Complete env var reference |
132
+ | [Quickstart](https://calvyn-code.nousresearch.com/docs/getting-started/quickstart) | Install → setup → first conversation in 2 minutes |
133
+ | [CLI Usage](https://calvyn-code.nousresearch.com/docs/user-guide/cli) | Commands, keybindings, personalities, sessions |
134
+ | [Configuration](https://calvyn-code.nousresearch.com/docs/user-guide/configuration) | Config file, providers, models, all options |
135
+ | [Messaging Gateway](https://calvyn-code.nousresearch.com/docs/user-guide/messaging) | Telegram, Discord, Slack, WhatsApp, Signal, Home Assistant |
136
+ | [Security](https://calvyn-code.nousresearch.com/docs/user-guide/security) | Command approval, DM pairing, container isolation |
137
+ | [Tools & Toolsets](https://calvyn-code.nousresearch.com/docs/user-guide/features/tools) | 40+ tools, toolset system, terminal backends |
138
+ | [Skills System](https://calvyn-code.nousresearch.com/docs/user-guide/features/skills) | Procedural memory, Skills Hub, creating skills |
139
+ | [Memory](https://calvyn-code.nousresearch.com/docs/user-guide/features/memory) | Persistent memory, user profiles, best practices |
140
+ | [MCP Integration](https://calvyn-code.nousresearch.com/docs/user-guide/features/mcp) | Connect any MCP server for extended capabilities |
141
+ | [Cron Scheduling](https://calvyn-code.nousresearch.com/docs/user-guide/features/cron) | Scheduled tasks with platform delivery |
142
+ | [Context Files](https://calvyn-code.nousresearch.com/docs/user-guide/features/context-files) | Project context that shapes every conversation |
143
+ | [Architecture](https://calvyn-code.nousresearch.com/docs/developer-guide/architecture) | Project structure, agent loop, key classes |
144
+ | [Contributing](https://calvyn-code.nousresearch.com/docs/developer-guide/contributing) | Development setup, PR process, code style |
145
+ | [CLI Reference](https://calvyn-code.nousresearch.com/docs/reference/cli-commands) | All commands and flags |
146
+ | [Environment Variables](https://calvyn-code.nousresearch.com/docs/reference/environment-variables) | Complete env var reference |
147
147
 
148
148
  ---
149
149
 
150
150
  ## Migrating from OpenClaw
151
151
 
152
- If you're coming from OpenClaw, Hermes can automatically import your settings, memories, skills, and API keys.
152
+ If you're coming from OpenClaw, Calvyn can automatically import your settings, memories, skills, and API keys.
153
153
 
154
- **During first-time setup:** The setup wizard (`hermes setup`) automatically detects `~/.openclaw` and offers to migrate before configuration begins.
154
+ **During first-time setup:** The setup wizard (`calvyn setup`) automatically detects `~/.openclaw` and offers to migrate before configuration begins.
155
155
 
156
156
  **Anytime after install:**
157
157
 
158
158
  ```bash
159
- hermes claw migrate # Interactive migration (full preset)
160
- hermes claw migrate --dry-run # Preview what would be migrated
161
- hermes claw migrate --preset user-data # Migrate without secrets
162
- hermes claw migrate --overwrite # Overwrite existing conflicts
159
+ calvyn claw migrate # Interactive migration (full preset)
160
+ calvyn claw migrate --dry-run # Preview what would be migrated
161
+ calvyn claw migrate --preset user-data # Migrate without secrets
162
+ calvyn claw migrate --overwrite # Overwrite existing conflicts
163
163
  ```
164
164
 
165
165
  What gets imported:
@@ -172,21 +172,21 @@ What gets imported:
172
172
  - **TTS assets** — workspace audio files
173
173
  - **Workspace instructions** — AGENTS.md (with `--workspace-target`)
174
174
 
175
- See `hermes claw migrate --help` for all options, or use the `openclaw-migration` skill for an interactive agent-guided migration with dry-run previews.
175
+ See `calvyn claw migrate --help` for all options, or use the `openclaw-migration` skill for an interactive agent-guided migration with dry-run previews.
176
176
 
177
177
  ---
178
178
 
179
179
  ## Contributing
180
180
 
181
- We welcome contributions! See the [Contributing Guide](https://hermes-agent.nousresearch.com/docs/developer-guide/contributing) for development setup, code style, and PR process.
181
+ We welcome contributions! See the [Contributing Guide](https://calvyn-code.nousresearch.com/docs/developer-guide/contributing) for development setup, code style, and PR process.
182
182
 
183
- Quick start for contributors — clone and go with `setup-hermes.sh`:
183
+ Quick start for contributors — clone and go with `setup-calvyn.sh`:
184
184
 
185
185
  ```bash
186
- git clone https://github.com/NousResearch/hermes-agent.git
187
- cd hermes-agent
188
- ./setup-hermes.sh # installs uv, creates venv, installs .[all], symlinks ~/.local/bin/hermes
189
- ./hermes # auto-detects the venv, no need to `source` first
186
+ git clone https://github.com/calvyns/calvyn-code.git
187
+ cd calvyn-code
188
+ ./setup-calvyn.sh # installs uv, creates venv, installs .[all], symlinks ~/.local/bin/calvyn
189
+ ./calvyn # auto-detects the venv, no need to `source` first
190
190
  ```
191
191
 
192
192
  Manual path (equivalent to the above):
@@ -205,8 +205,8 @@ scripts/run_tests.sh
205
205
 
206
206
  - 💬 [Discord](https://discord.gg/NousResearch)
207
207
  - 📚 [Skills Hub](https://agentskills.io)
208
- - 🐛 [Issues](https://github.com/NousResearch/hermes-agent/issues)
209
- - 🔌 [HermesClaw](https://github.com/AaronWong1999/hermesclaw) — Community WeChat bridge: Run Hermes Agent and OpenClaw on the same WeChat account.
208
+ - 🐛 [Issues](https://github.com/calvyns/calvyn-code/issues)
209
+ - 🔌 [HermesClaw](https://github.com/AaronWong1999/hermesclaw) — Community WeChat bridge: Run Calvyn Code and OpenClaw on the same WeChat account.
210
210
 
211
211
  ---
212
212
 
package/bin/calvyn.js CHANGED
@@ -49,14 +49,36 @@ function runPostinstallIfNeeded() {
49
49
  return calvynBinary
50
50
  }
51
51
 
52
+ function shouldShowBanner(args) {
53
+ if (!args.length) return true
54
+ const first = String(args[0] || "").trim().toLowerCase()
55
+ return !["-h", "--help", "-v", "--version", "version"].includes(first)
56
+ }
57
+
58
+ function printNpmLaunchHeader() {
59
+ console.log("")
60
+ console.log("")
61
+ console.log("")
62
+ console.log(" ╔════════════════════════════════════════════════════════════════════════════╗")
63
+ console.log(" ║ ✦ CALVYN CODE ║")
64
+ console.log(" ║ Запуск через npm ║")
65
+ console.log(" ╚════════════════════════════════════════════════════════════════════════════╝")
66
+ console.log("")
67
+ }
68
+
69
+ const args = process.argv.slice(2)
52
70
  const calvynBinary = runPostinstallIfNeeded()
53
- const result = spawnSync(calvynBinary, process.argv.slice(2), {
71
+ if (shouldShowBanner(args)) {
72
+ printNpmLaunchHeader()
73
+ }
74
+ const result = spawnSync(calvynBinary, args, {
54
75
  stdio: "inherit",
55
76
  shell: false,
56
77
  env: {
57
78
  ...process.env,
58
79
  CALVYN_LAUNCHED_FROM_NPM: "1",
59
80
  CALVYN_REPO_ROOT: packageRoot,
81
+ CALVYN_HOME: process.env.CALVYN_HOME || path.join(require("os").homedir(), ".calvyn"),
60
82
  },
61
83
  })
62
84
 
@@ -1,4 +1,4 @@
1
- """Shared constants for Hermes Agent.
1
+ """Shared constants for Calvyn Code.
2
2
 
3
3
  Import-safe module with no dependencies — can be imported from anywhere
4
4
  without risk of circular imports.
@@ -8,14 +8,24 @@ import os
8
8
  from pathlib import Path
9
9
 
10
10
 
11
- _profile_fallback_warned: bool = False
11
+ _profile_fallback_warned: bool = False
12
+ _CALVYN_HOME_ENV = "CALVYN_HOME"
13
+ _LEGACY_HOME_ENV = "HERMES_HOME"
14
+ _DEFAULT_HOME_DIRNAME = ".calvyn"
15
+ _LEGACY_HOME_DIRNAME = ".hermes"
12
16
 
13
17
 
14
- def get_hermes_home() -> Path:
15
- """Return the Hermes home directory (default: ~/.hermes).
16
-
17
- Reads HERMES_HOME env var, falls back to ~/.hermes.
18
- This is the single source of truth — all other copies should import this.
18
+ def get_hermes_home() -> Path:
19
+ """Return the Calvyn home directory.
20
+
21
+ Preference order:
22
+ 1. ``CALVYN_HOME``
23
+ 2. ``HERMES_HOME`` for legacy compatibility
24
+ 3. ``~/.calvyn``
25
+ 4. ``~/.hermes`` only when it already exists and ``~/.calvyn`` does not
26
+
27
+ This keeps Calvyn isolated from Hermes by default while still allowing
28
+ explicit legacy overrides.
19
29
 
20
30
  When ``HERMES_HOME`` is unset but an ``active_profile`` file indicates
21
31
  a non-default profile is active, logs a loud one-shot warning to
@@ -27,22 +37,26 @@ def get_hermes_home() -> Path:
27
37
  template in ``hermes_cli/gateway.py`` and the kanban dispatcher in
28
38
  ``hermes_cli/kanban_db.py``). See https://github.com/NousResearch/hermes-agent/issues/18594.
29
39
  """
30
- val = os.environ.get("HERMES_HOME", "").strip()
31
- if val:
32
- return Path(val)
40
+ val = os.environ.get(_CALVYN_HOME_ENV, "").strip()
41
+ if val:
42
+ return Path(val)
43
+
44
+ val = os.environ.get(_LEGACY_HOME_ENV, "").strip()
45
+ if val:
46
+ return Path(val)
33
47
 
34
48
  # Guard: if a non-default profile is sticky-active, warn once that
35
49
  # the fallback to the default profile is almost certainly wrong.
36
50
  global _profile_fallback_warned
37
51
  if not _profile_fallback_warned:
38
52
  try:
39
- # Inline the default-root resolution from get_default_hermes_root()
40
- # to stay import-safe (this function is called from module scope
41
- # in 30+ files; we cannot afford to trigger logging setup here).
42
- active_path = (Path.home() / ".hermes" / "active_profile")
43
- active = active_path.read_text().strip() if active_path.exists() else ""
44
- except (UnicodeDecodeError, OSError):
45
- active = ""
53
+ # Inline the default-root resolution from get_default_hermes_root()
54
+ # to stay import-safe (this function is called from module scope
55
+ # in 30+ files; we cannot afford to trigger logging setup here).
56
+ active_path = (Path.home() / _DEFAULT_HOME_DIRNAME / "active_profile")
57
+ active = active_path.read_text().strip() if active_path.exists() else ""
58
+ except (UnicodeDecodeError, OSError):
59
+ active = ""
46
60
  if active and active != "default":
47
61
  _profile_fallback_warned = True
48
62
  # Write directly to stderr. We intentionally do NOT route this
@@ -52,24 +66,28 @@ def get_hermes_home() -> Path:
52
66
  # on consoles where a StreamHandler is already attached.
53
67
  import sys
54
68
  msg = (
55
- f"[HERMES_HOME fallback] HERMES_HOME is unset but active "
56
- f"profile is {active!r}. Falling back to ~/.hermes, which "
57
- f"is the DEFAULT profile — not {active!r}. Any data this "
58
- f"process writes will land in the wrong profile. The "
59
- f"subprocess spawner should pass HERMES_HOME explicitly "
60
- f"(see issue #18594)."
61
- )
69
+ f"[CALVYN_HOME fallback] CALVYN_HOME is unset but active "
70
+ f"profile is {active!r}. Falling back to ~/{_DEFAULT_HOME_DIRNAME}, which "
71
+ f"is the DEFAULT profile — not {active!r}. Any data this "
72
+ f"process writes will land in the wrong profile. The "
73
+ f"subprocess spawner should pass CALVYN_HOME explicitly "
74
+ f"(see issue #18594)."
75
+ )
62
76
  try:
63
77
  sys.stderr.write(msg + "\n")
64
78
  sys.stderr.flush()
65
79
  except Exception:
66
80
  pass
67
81
 
68
- return Path.home() / ".hermes"
82
+ calvyn_home = Path.home() / _DEFAULT_HOME_DIRNAME
83
+ legacy_home = Path.home() / _LEGACY_HOME_DIRNAME
84
+ if calvyn_home.exists() or not legacy_home.exists():
85
+ return calvyn_home
86
+ return legacy_home
69
87
 
70
88
 
71
- def get_default_hermes_root() -> Path:
72
- """Return the root Hermes directory for profile-level operations.
89
+ def get_default_hermes_root() -> Path:
90
+ """Return the root Calvyn directory for profile-level operations.
73
91
 
74
92
  In standard deployments this is ``~/.hermes``.
75
93
 
@@ -84,8 +102,8 @@ def get_default_hermes_root() -> Path:
84
102
 
85
103
  Import-safe — no dependencies beyond stdlib.
86
104
  """
87
- native_home = Path.home() / ".hermes"
88
- env_home = os.environ.get("HERMES_HOME", "")
105
+ native_home = Path.home() / _DEFAULT_HOME_DIRNAME
106
+ env_home = os.environ.get(_CALVYN_HOME_ENV, "") or os.environ.get(_LEGACY_HOME_ENV, "")
89
107
  if not env_home:
90
108
  return native_home
91
109
  env_path = Path(env_home)
@@ -110,10 +128,11 @@ def get_default_hermes_root() -> Path:
110
128
  def get_optional_skills_dir(default: Path | None = None) -> Path:
111
129
  """Return the optional-skills directory, honoring package-manager wrappers.
112
130
 
113
- Packaged installs may ship ``optional-skills`` outside the Python package
114
- tree and expose it via ``HERMES_OPTIONAL_SKILLS``.
115
- """
116
- override = os.getenv("HERMES_OPTIONAL_SKILLS", "").strip()
131
+ Packaged installs may ship ``optional-skills`` outside the Python package
132
+ tree and expose it via ``CALVYN_OPTIONAL_SKILLS`` or the legacy
133
+ ``HERMES_OPTIONAL_SKILLS``.
134
+ """
135
+ override = os.getenv("CALVYN_OPTIONAL_SKILLS", "").strip() or os.getenv("HERMES_OPTIONAL_SKILLS", "").strip()
117
136
  if override:
118
137
  return Path(override)
119
138
  if default is not None:
@@ -122,7 +141,7 @@ def get_optional_skills_dir(default: Path | None = None) -> Path:
122
141
 
123
142
 
124
143
  def get_hermes_dir(new_subpath: str, old_name: str) -> Path:
125
- """Resolve a Hermes subdirectory with backward compatibility.
144
+ """Resolve a Calvyn subdirectory with backward compatibility.
126
145
 
127
146
  New installs get the consolidated layout (e.g. ``cache/images``).
128
147
  Existing installs that already have the old path (e.g. ``image_cache``)
@@ -143,17 +162,17 @@ def get_hermes_dir(new_subpath: str, old_name: str) -> Path:
143
162
 
144
163
 
145
164
  def display_hermes_home() -> str:
146
- """Return a user-friendly display string for the current HERMES_HOME.
165
+ """Return a user-friendly display string for the current Calvyn home.
147
166
 
148
167
  Uses ``~/`` shorthand for readability::
149
168
 
150
- default: ``~/.hermes``
151
- profile: ``~/.hermes/profiles/coder``
152
- custom: ``/opt/hermes-custom``
169
+ default: ``~/.calvyn``
170
+ profile: ``~/.calvyn/profiles/coder``
171
+ custom: ``/opt/hermes-custom``
153
172
 
154
- Use this in **user-facing** print/log messages instead of hardcoding
155
- ``~/.hermes``. For code that needs a real ``Path``, use
156
- :func:`get_hermes_home` instead.
173
+ Use this in **user-facing** print/log messages instead of hardcoding
174
+ ``~/.calvyn``. For code that needs a real ``Path``, use
175
+ :func:`get_hermes_home` instead.
157
176
  """
158
177
  home = get_hermes_home()
159
178
  try:
@@ -165,7 +184,7 @@ def display_hermes_home() -> str:
165
184
  def get_subprocess_home() -> str | None:
166
185
  """Return a per-profile HOME directory for subprocesses, or None.
167
186
 
168
- When ``{HERMES_HOME}/home/`` exists on disk, subprocesses should use it
187
+ When ``{CALVYN_HOME}/home/`` exists on disk, subprocesses should use it
169
188
  as ``HOME`` so system tools (git, ssh, gh, npm …) write their configs
170
189
  inside the Hermes data directory instead of the OS-level ``/root`` or
171
190
  ``~/``. This provides:
@@ -179,7 +198,7 @@ def get_subprocess_home() -> str | None:
179
198
  Activation is directory-based: if the ``home/`` subdirectory doesn't
180
199
  exist, returns ``None`` and behavior is unchanged.
181
200
  """
182
- hermes_home = os.getenv("HERMES_HOME")
201
+ hermes_home = os.getenv(_CALVYN_HOME_ENV) or os.getenv(_LEGACY_HOME_ENV)
183
202
  if not hermes_home:
184
203
  return None
185
204
  profile_home = os.path.join(hermes_home, "home")
@@ -0,0 +1,21 @@
1
+ model:
2
+ provider: "freemodel"
3
+ default: "gpt-5.5"
4
+ base_url: "https://api.freemodel.dev"
5
+ api_mode: "codex_responses"
6
+
7
+ agent:
8
+ reasoning_effort: "xhigh"
9
+
10
+ providers:
11
+ freemodel:
12
+ name: "freemodel"
13
+ base_url: "https://api.freemodel.dev"
14
+ key_env: "FREEMODEL_API_KEY"
15
+ api_mode: "codex_responses"
16
+ model: "gpt-5.5"
17
+
18
+ model_provider: "freemodel"
19
+ model_reasoning_effort: "xhigh"
20
+ disable_response_storage: true
21
+ preferred_auth_method: "apikey"
package/cli.py CHANGED
@@ -11542,12 +11542,18 @@ class HermesCLI:
11542
11542
  # responses, and prompt all appear pinned to the bottom — empty
11543
11543
  # space stays above, not below. This prints enough blank lines to
11544
11544
  # scroll the cursor to the last row before any content is rendered.
11545
- try:
11546
- _term_lines = shutil.get_terminal_size().lines
11547
- if _term_lines > 2:
11548
- print("\n" * (_term_lines - 1), end="", flush=True)
11549
- except Exception:
11550
- pass
11545
+ try:
11546
+ if os.getenv("CALVYN_LAUNCHED_FROM_NPM", "").strip().lower() not in {
11547
+ "1",
11548
+ "true",
11549
+ "yes",
11550
+ "on",
11551
+ }:
11552
+ _term_lines = shutil.get_terminal_size().lines
11553
+ if _term_lines > 2:
11554
+ print("\n" * (_term_lines - 1), end="", flush=True)
11555
+ except Exception:
11556
+ pass
11551
11557
 
11552
11558
  self.show_banner()
11553
11559
  # Surface any active supply-chain security advisories right after the
@@ -0,0 +1 @@
1
+ from calvyn_bootstrap import * # noqa: F401,F403
@@ -14,7 +14,7 @@ Provides subcommands for:
14
14
  import os
15
15
  import sys
16
16
 
17
- __version__ = "0.14.0"
17
+ __version__ = "0.14.1"
18
18
  __release_date__ = "2026.5.16"
19
19
 
20
20
 
@@ -1387,8 +1387,9 @@ def resolve_provider(
1387
1387
  "kimi": "kimi-coding", "kimi-for-coding": "kimi-coding", "moonshot": "kimi-coding",
1388
1388
  "kimi-cn": "kimi-coding-cn", "moonshot-cn": "kimi-coding-cn",
1389
1389
  "step": "stepfun", "stepfun-coding-plan": "stepfun",
1390
- "arcee-ai": "arcee", "arceeai": "arcee",
1391
- "gmi-cloud": "gmi", "gmicloud": "gmi",
1390
+ "arcee-ai": "arcee", "arceeai": "arcee",
1391
+ "gmi-cloud": "gmi", "gmicloud": "gmi",
1392
+ "freemodel": "freemodel", "free-model": "freemodel", "free_model": "freemodel",
1392
1393
  "minimax-china": "minimax-cn", "minimax_cn": "minimax-cn",
1393
1394
  "minimax-portal": "minimax-oauth", "minimax-global": "minimax-oauth", "minimax_oauth": "minimax-oauth",
1394
1395
  "alibaba_coding": "alibaba-coding-plan", "alibaba-coding": "alibaba-coding-plan",
@@ -2011,11 +2011,11 @@ def select_provider_and_model(args=None):
2011
2011
  _model_flow_bedrock(config, current_model)
2012
2012
  elif selected_provider == "azure-foundry":
2013
2013
  _model_flow_azure_foundry(config, current_model)
2014
- elif selected_provider in {
2015
- "gemini",
2016
- "deepseek",
2017
- "xai",
2018
- "zai",
2014
+ elif selected_provider in {
2015
+ "gemini",
2016
+ "deepseek",
2017
+ "xai",
2018
+ "zai",
2019
2019
  "kimi-coding-cn",
2020
2020
  "minimax",
2021
2021
  "minimax-cn",
@@ -2024,14 +2024,15 @@ def select_provider_and_model(args=None):
2024
2024
  "opencode-go",
2025
2025
  "alibaba",
2026
2026
  "huggingface",
2027
- "xiaomi",
2028
- "arcee",
2029
- "gmi",
2030
- "nvidia",
2031
- "ollama-cloud",
2032
- "tencent-tokenhub",
2033
- "lmstudio",
2034
- } or _is_profile_api_key_provider(selected_provider):
2027
+ "xiaomi",
2028
+ "arcee",
2029
+ "gmi",
2030
+ "freemodel",
2031
+ "nvidia",
2032
+ "ollama-cloud",
2033
+ "tencent-tokenhub",
2034
+ "lmstudio",
2035
+ } or _is_profile_api_key_provider(selected_provider):
2035
2036
  _model_flow_api_key_provider(config, selected_provider, current_model)
2036
2037
 
2037
2038
  # ── Post-switch cleanup: clear stale OPENAI_BASE_URL ──────────────
@@ -949,7 +949,8 @@ CANONICAL_PROVIDERS: list[ProviderEntry] = [
949
949
  ProviderEntry("minimax-cn", "MiniMax (China)", "MiniMax China (domestic direct API)"),
950
950
  ProviderEntry("ollama-cloud", "Ollama Cloud", "Ollama Cloud (cloud-hosted open models — ollama.com)"),
951
951
  ProviderEntry("arcee", "Arcee AI", "Arcee AI (Trinity models — direct API)"),
952
- ProviderEntry("gmi", "GMI Cloud", "GMI Cloud (multi-model direct API)"),
952
+ ProviderEntry("gmi", "GMI Cloud", "GMI Cloud (multi-model direct API)"),
953
+ ProviderEntry("freemodel", "FreeModel", "FreeModel (OpenAI-compatible direct API)"),
953
954
  ProviderEntry("kilocode", "Kilo Code", "Kilo Code (Kilo Gateway API)"),
954
955
  ProviderEntry("opencode-zen", "OpenCode Zen", "OpenCode Zen (35+ curated models, pay-as-you-go)"),
955
956
  ProviderEntry("opencode-go", "OpenCode Go", "OpenCode Go (open models, $10/month subscription)"),
@@ -1005,8 +1006,11 @@ _PROVIDER_ALIASES = {
1005
1006
  "stepfun-coding-plan": "stepfun",
1006
1007
  "arcee-ai": "arcee",
1007
1008
  "arceeai": "arcee",
1008
- "gmi-cloud": "gmi",
1009
- "gmicloud": "gmi",
1009
+ "gmi-cloud": "gmi",
1010
+ "gmicloud": "gmi",
1011
+ "freemodel": "freemodel",
1012
+ "free-model": "freemodel",
1013
+ "free_model": "freemodel",
1010
1014
  "minimax-china": "minimax-cn",
1011
1015
  "minimax_cn": "minimax-cn",
1012
1016
  "minimax-portal": "minimax-oauth",
@@ -190,12 +190,18 @@ HERMES_OVERLAYS: Dict[str, HermesOverlay] = {
190
190
  base_url_override="https://api.arcee.ai/api/v1",
191
191
  base_url_env_var="ARCEE_BASE_URL",
192
192
  ),
193
- "gmi": HermesOverlay(
194
- transport="openai_chat",
195
- extra_env_vars=("GMI_API_KEY",),
196
- base_url_override="https://api.gmi-serving.com/v1",
197
- base_url_env_var="GMI_BASE_URL",
198
- ),
193
+ "gmi": HermesOverlay(
194
+ transport="openai_chat",
195
+ extra_env_vars=("GMI_API_KEY",),
196
+ base_url_override="https://api.gmi-serving.com/v1",
197
+ base_url_env_var="GMI_BASE_URL",
198
+ ),
199
+ "freemodel": HermesOverlay(
200
+ transport="openai_chat",
201
+ extra_env_vars=("FREEMODEL_API_KEY",),
202
+ base_url_override="https://api.freemodel.xyz/v1",
203
+ base_url_env_var="FREEMODEL_BASE_URL",
204
+ ),
199
205
  "ollama-cloud": HermesOverlay(
200
206
  transport="openai_chat",
201
207
  base_url_env_var="OLLAMA_BASE_URL",
@@ -349,8 +355,11 @@ ALIASES: Dict[str, str] = {
349
355
  "arceeai": "arcee",
350
356
 
351
357
  # gmi
352
- "gmi-cloud": "gmi",
353
- "gmicloud": "gmi",
358
+ "gmi-cloud": "gmi",
359
+ "gmicloud": "gmi",
360
+ "freemodel": "freemodel",
361
+ "free-model": "freemodel",
362
+ "free_model": "freemodel",
354
363
 
355
364
  # Local server aliases → virtual "local" concept (resolved via user config)
356
365
  "lmstudio": "lmstudio",
@@ -374,7 +383,8 @@ _LABEL_OVERRIDES: Dict[str, str] = {
374
383
  "copilot-acp": "GitHub Copilot ACP",
375
384
  "stepfun": "StepFun Step Plan",
376
385
  "xiaomi": "Xiaomi MiMo",
377
- "gmi": "GMI Cloud",
386
+ "gmi": "GMI Cloud",
387
+ "freemodel": "FreeModel",
378
388
  "tencent-tokenhub": "Tencent TokenHub",
379
389
  "lmstudio": "LM Studio",
380
390
  "local": "Local endpoint",
@@ -0,0 +1 @@
1
+ from calvyn_constants import * # noqa: F401,F403
@@ -0,0 +1 @@
1
+ from calvyn_logging import * # noqa: F401,F403
@@ -0,0 +1 @@
1
+ from calvyn_state import * # noqa: F401,F403
package/hermes_time.py ADDED
@@ -0,0 +1 @@
1
+ from calvyn_time import * # noqa: F401,F403
package/package.json CHANGED
@@ -1,78 +1,87 @@
1
1
  {
2
- "name": "calvyn-code",
3
- "version": "0.14.0",
4
- "description": "Calvyn Code — AI агент с инструментами, мессенджерами и локальным CLI",
5
- "bin": {
6
- "calvyn": "./bin/calvyn.js"
7
- },
8
- "main": "./bin/calvyn.js",
9
- "keywords": [
10
- "ai",
11
- "agent",
12
- "cli",
13
- "calvyn",
14
- "python",
15
- "telegram",
16
- "discord",
17
- "slack",
18
- "whatsapp"
19
- ],
20
- "author": "Calvyn Code Contributors",
21
- "homepage": "https://github.com/NousResearch/hermes-agent#readme",
22
- "scripts": {
23
- "postinstall": "node ./scripts/postinstall.js"
24
- },
25
- "repository": {
26
- "type": "git",
27
- "url": "git+https://github.com/NousResearch/hermes-agent.git"
28
- },
29
- "license": "MIT",
30
- "bugs": {
31
- "url": "https://github.com/NousResearch/hermes-agent/issues"
32
- },
33
- "dependencies": {
34
- "@askjo/camofox-browser": "^1.5.2",
35
- "agent-browser": "^0.26.0"
36
- },
37
- "overrides": {
38
- "lodash": "4.18.1"
39
- },
40
- "engines": {
41
- "node": ">=20.0.0"
42
- },
43
- "files": [
44
- "bin",
45
- "scripts",
46
- "hermes_cli",
47
- "agent",
48
- "gateway",
49
- "tui_gateway",
50
- "cron",
51
- "acp_adapter",
52
- "plugins",
53
- "providers",
54
- "tools",
55
- "assets",
56
- "locales",
57
- "optional-skills",
58
- "skills",
59
- "run_agent.py",
60
- "model_tools.py",
61
- "toolsets.py",
62
- "batch_runner.py",
63
- "trajectory_compressor.py",
64
- "toolset_distributions.py",
65
- "cli.py",
66
- "calvyn_bootstrap.py",
67
- "calvyn_constants.py",
68
- "calvyn_state.py",
69
- "calvyn_time.py",
70
- "calvyn_logging.py",
71
- "mcp_serve.py",
72
- "utils.py",
73
- "pyproject.toml",
74
- "README.md",
75
- "LICENSE"
76
- ]
77
- }
78
-
2
+ "name": "calvyn-code",
3
+ "version": "0.14.2",
4
+ "description": "Calvyn Code — AI агент с инструментами, мессенджерами и локальным CLI",
5
+ "bin": {
6
+ "calvyn": "./bin/calvyn.js",
7
+ "calvyn-code": "./bin/calvyn.js"
8
+ },
9
+ "main": "./bin/calvyn.js",
10
+ "keywords": [
11
+ "ai",
12
+ "agent",
13
+ "cli",
14
+ "calvyn",
15
+ "python",
16
+ "telegram",
17
+ "discord",
18
+ "slack",
19
+ "whatsapp"
20
+ ],
21
+ "author": "Calvyn Code Contributors",
22
+ "homepage": "https://github.com/calvyns/calvyn-code#readme",
23
+ "scripts": {
24
+ "postinstall": "node ./scripts/postinstall.js"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/calvyns/calvyn-code.git"
29
+ },
30
+ "license": "MIT",
31
+ "bugs": {
32
+ "url": "https://github.com/calvyns/calvyn-code/issues"
33
+ },
34
+ "dependencies": {
35
+ "@askjo/camofox-browser": "^1.5.2",
36
+ "agent-browser": "^0.26.0"
37
+ },
38
+ "overrides": {
39
+ "lodash": "4.18.1"
40
+ },
41
+ "engines": {
42
+ "node": ">=20.0.0"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
47
+ "files": [
48
+ "bin",
49
+ "scripts",
50
+ "hermes_cli",
51
+ "agent",
52
+ "gateway",
53
+ "tui_gateway",
54
+ "cron",
55
+ "acp_adapter",
56
+ "plugins",
57
+ "providers",
58
+ "tools",
59
+ "assets",
60
+ "locales",
61
+ "optional-skills",
62
+ "skills",
63
+ "run_agent.py",
64
+ "model_tools.py",
65
+ "toolsets.py",
66
+ "batch_runner.py",
67
+ "trajectory_compressor.py",
68
+ "toolset_distributions.py",
69
+ "cli.py",
70
+ "calvyn_bootstrap.py",
71
+ "calvyn_constants.py",
72
+ "calvyn_state.py",
73
+ "calvyn_time.py",
74
+ "calvyn_logging.py",
75
+ "hermes_bootstrap.py",
76
+ "hermes_constants.py",
77
+ "hermes_state.py",
78
+ "hermes_time.py",
79
+ "hermes_logging.py",
80
+ "mcp_serve.py",
81
+ "utils.py",
82
+ "pyproject.toml",
83
+ "cli-config.yaml",
84
+ "README.md",
85
+ "LICENSE"
86
+ ]
87
+ }
@@ -0,0 +1,16 @@
1
+ """FreeModel provider profile."""
2
+
3
+ from providers import register_provider
4
+ from providers.base import ProviderProfile
5
+
6
+ freemodel = ProviderProfile(
7
+ name="freemodel",
8
+ aliases=("free-model", "free_model"),
9
+ display_name="FreeModel",
10
+ description="FreeModel — OpenAI-compatible direct API",
11
+ signup_url="https://freemodel.xyz/",
12
+ env_vars=("FREEMODEL_API_KEY", "FREEMODEL_BASE_URL"),
13
+ base_url="https://api.freemodel.xyz/v1",
14
+ )
15
+
16
+ register_provider(freemodel)
@@ -0,0 +1,5 @@
1
+ name: freemodel-profile
2
+ kind: model-provider
3
+ version: 1.0.0
4
+ description: FreeModel direct API provider profile
5
+ author: Calvyn Code Contributors
package/pyproject.toml CHANGED
@@ -3,8 +3,8 @@ requires = ["setuptools>=61.0"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
- name = "hermes-agent"
7
- version = "0.14.0"
6
+ name = "calvyn-code"
7
+ version = "0.14.1"
8
8
  description = "The self-improving AI agent — creates skills from experience, improves them during use, and runs anywhere"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -128,23 +128,23 @@ bedrock = ["boto3==1.42.89"]
128
128
  termux = [
129
129
  # Baseline Android / Termux path for reliable fresh installs.
130
130
  "python-telegram-bot[webhooks]==22.6",
131
- "hermes-agent[cron]",
132
- "hermes-agent[cli]",
133
- "hermes-agent[pty]",
134
- "hermes-agent[mcp]",
135
- "hermes-agent[honcho]",
136
- "hermes-agent[acp]",
131
+ "calvyn-code[cron]",
132
+ "calvyn-code[cli]",
133
+ "calvyn-code[pty]",
134
+ "calvyn-code[mcp]",
135
+ "calvyn-code[honcho]",
136
+ "calvyn-code[acp]",
137
137
  ]
138
138
  termux-all = [
139
139
  # Best-effort "install all" profile for Termux. Same policy as [all]:
140
140
  # only includes extras that aren't covered by `tools/lazy_deps.py`.
141
141
  # Backends like telegram/slack/dingtalk/feishu/honcho lazy-install at
142
142
  # first use, so they're no longer eager-installed here.
143
- "hermes-agent[termux]",
144
- "hermes-agent[google]",
145
- "hermes-agent[homeassistant]",
146
- "hermes-agent[sms]",
147
- "hermes-agent[web]",
143
+ "calvyn-code[termux]",
144
+ "calvyn-code[google]",
145
+ "calvyn-code[homeassistant]",
146
+ "calvyn-code[sms]",
147
+ "calvyn-code[web]",
148
148
  ]
149
149
  dingtalk = ["dingtalk-stream==0.24.3", "alibabacloud-dingtalk==2.2.42", "qrcode==7.4.2"]
150
150
  feishu = ["lark-oapi==1.5.3", "qrcode==7.4.2"]
@@ -188,25 +188,23 @@ all = [
188
188
  # [all], `uv sync --locked` on Windows tried to build it from sdist
189
189
  # and failed on `make`. Lazy-install routes that build to first use,
190
190
  # where the user is expected to have a toolchain available.
191
- "hermes-agent[cron]",
192
- "hermes-agent[cli]",
193
- "hermes-agent[dev]",
194
- "hermes-agent[pty]",
195
- "hermes-agent[mcp]",
196
- "hermes-agent[homeassistant]",
197
- "hermes-agent[sms]",
198
- "hermes-agent[acp]",
199
- "hermes-agent[google]",
200
- "hermes-agent[web]",
201
- "hermes-agent[youtube]",
191
+ "calvyn-code[cron]",
192
+ "calvyn-code[cli]",
193
+ "calvyn-code[dev]",
194
+ "calvyn-code[pty]",
195
+ "calvyn-code[mcp]",
196
+ "calvyn-code[homeassistant]",
197
+ "calvyn-code[sms]",
198
+ "calvyn-code[acp]",
199
+ "calvyn-code[google]",
200
+ "calvyn-code[web]",
201
+ "calvyn-code[youtube]",
202
202
  ]
203
203
 
204
204
  [project.scripts]
205
205
  calvyn = "hermes_cli.main:main"
206
206
  calvyn-agent = "run_agent:main"
207
207
  calvyn-acp = "acp_adapter.entry:main"
208
- hermes-agent = "run_agent:main"
209
- hermes-acp = "acp_adapter.entry:main"
210
208
 
211
209
  [tool.setuptools]
212
210
  py-modules = ["run_agent", "model_tools", "toolsets", "batch_runner", "trajectory_compressor", "toolset_distributions", "cli", "calvyn_bootstrap", "calvyn_constants", "calvyn_state", "calvyn_time", "calvyn_logging", "utils"]
@@ -95,6 +95,25 @@ function getVenvPaths() {
95
95
  }
96
96
  }
97
97
 
98
+ function ensureDefaultConfig() {
99
+ const homeDir = process.env.CALVYN_HOME
100
+ ? path.resolve(process.env.CALVYN_HOME)
101
+ : path.join(require("os").homedir(), ".calvyn")
102
+ const configDir = homeDir
103
+ const configPath = path.join(configDir, "config.yaml")
104
+ const bundledConfig = path.join(packageRoot, "cli-config.yaml")
105
+
106
+ if (!fs.existsSync(bundledConfig)) {
107
+ return
108
+ }
109
+
110
+ fs.mkdirSync(configDir, { recursive: true })
111
+ if (!fs.existsSync(configPath)) {
112
+ fs.copyFileSync(bundledConfig, configPath)
113
+ log(`Положил стартовый конфиг в ${configPath}`)
114
+ }
115
+ }
116
+
98
117
  function ensureVenv(python) {
99
118
  const venv = getVenvPaths()
100
119
  if (!fs.existsSync(venv.dir)) {
@@ -137,6 +156,7 @@ function main() {
137
156
  }
138
157
 
139
158
  ensureInstalled(venv.python)
159
+ ensureDefaultConfig()
140
160
 
141
161
  if (!fs.existsSync(venv.calvyn)) {
142
162
  fail("Установка прошла не до конца: команда calvyn внутри .venv не найдена")