chore: use more conventional XDG_CONFIG_HOME for config

This commit is contained in:
Joe Fleming
2026-03-13 19:22:37 -06:00
parent 398b98393a
commit 9ac92ed536
9 changed files with 28 additions and 28 deletions

View File

@@ -21,10 +21,10 @@ bun install # or use `mise install`
**1. Create a config file** **1. Create a config file**
```bash ```bash
mkdir -p ~/.nanobot mkdir -p ~/.config/nanobot
``` ```
`~/.nanobot/config.json`: `~/.config/nanobot/config.json`:
```json ```json
{ {
@@ -59,7 +59,7 @@ bun run nanobot agent [options]
| Option | Description | | Option | Description |
|--------|-------------| |--------|-------------|
| `-c, --config <path>` | Path to `config.json` (default: `~/.nanobot/config.json`) | | `-c, --config <path>` | Path to `config.json` (default: `~/.config/nanobot/config.json`) |
| `-m, --message <text>` | Send a single message and exit (non-interactive) | | `-m, --message <text>` | Send a single message and exit (non-interactive) |
| `-M, --model <model>` | Override the model for this session | | `-M, --model <model>` | Override the model for this session |
@@ -67,7 +67,7 @@ bun run nanobot agent [options]
```bash ```bash
bun run nanobot agent bun run nanobot agent
bun run nanobot agent -c ~/.nanobot-work/config.json bun run nanobot agent -c ~/.config/nanobot-work/config.json
bun run nanobot agent -w /tmp/scratch bun run nanobot agent -w /tmp/scratch
``` ```
@@ -90,18 +90,18 @@ bun run nanobot gateway [options]
| Option | Description | | Option | Description |
|--------|-------------| |--------|-------------|
| `-c, --config <path>` | Path to `config.json` (default: `~/.nanobot/config.json`) | | `-c, --config <path>` | Path to `config.json` (default: `~/.config/nanobot/config.json`) |
```bash ```bash
bun run nanobot gateway bun run nanobot gateway
bun run nanobot gateway -c ~/.nanobot-work/config.json bun run nanobot gateway -c ~/.config/nanobot-work/config.json
``` ```
Handles `SIGINT` / `SIGTERM` for graceful shutdown. Handles `SIGINT` / `SIGTERM` for graceful shutdown.
## Configuration ## Configuration
Config file: `~/.nanobot/config.json` (or pass `-c <path>` to any command). Config file: `~/.config/nanobot/config.json` (or pass `-c <path>` to any command).
Environment variable overrides: Environment variable overrides:
@@ -116,7 +116,7 @@ Environment variable overrides:
{ {
"agent": { "agent": {
"model": "openrouter/anthropic/claude-sonnet-4-5", "model": "openrouter/anthropic/claude-sonnet-4-5",
"workspacePath": "~/.nanobot", "workspacePath": "~/.config/nanobot",
"maxTokens": 4096, "maxTokens": 4096,
"contextWindowTokens": 65536, "contextWindowTokens": 65536,
"temperature": 0.7, "temperature": 0.7,
@@ -231,10 +231,10 @@ Run separate instances with different configs — useful for isolated workspaces
```bash ```bash
# Instance A # Instance A
bun run nanobot gateway -c ~/.nanobot-a/config.json bun run nanobot gateway -c ~/.config/nanobot-a/config.json
# Instance B # Instance B
bun run nanobot gateway -c ~/.nanobot-b/config.json bun run nanobot gateway -c ~/.config/nanobot-b/config.json
``` ```
Each instance needs its own config file. Set a different `agent.workspacePath` per instance to keep memory, sessions, and cron jobs isolated: Each instance needs its own config file. Set a different `agent.workspacePath` per instance to keep memory, sessions, and cron jobs isolated:
@@ -242,7 +242,7 @@ Each instance needs its own config file. Set a different `agent.workspacePath` p
```json ```json
{ {
"agent": { "agent": {
"workspacePath": "~/.nanobot-a" "workspacePath": "~/.config/nanobot-a"
} }
} }
``` ```
@@ -250,10 +250,10 @@ Each instance needs its own config file. Set a different `agent.workspacePath` p
To run a local CLI session against a specific instance: To run a local CLI session against a specific instance:
```bash ```bash
bun run nanobot agent -c ~/.nanobot-a/config.json -m "Hello" bun run nanobot agent -c ~/.config/nanobot-a/config.json -m "Hello"
# Temporarily override the workspace for a one-off run # Temporarily override the workspace for a one-off run
bun run nanobot agent -c ~/.nanobot-a/config.json -w /tmp/scratch bun run nanobot agent -c ~/.config/nanobot-a/config.json -w /tmp/scratch
``` ```
## Linux service (systemd) ## Linux service (systemd)

View File

@@ -123,7 +123,7 @@ Wraps Vercel AI SDK `generateText()` with:
- Normalized `LLMResponse` type - Normalized `LLMResponse` type
### SessionManager ### SessionManager
Persists conversation history to JSONL files in `~/.nanobot/sessions/`. Persists conversation history to JSONL files in `~/.config/nanobot/sessions/`.
- Key format: `{channel}:{chatId}` (e.g., `mattermost:abc123`) - Key format: `{channel}:{chatId}` (e.g., `mattermost:abc123`)
- Supports history truncation for context window limits - Supports history truncation for context window limits
@@ -136,7 +136,7 @@ When session history exceeds token limits, summarizes old messages and archives
## Configuration ## Configuration
- File: `~/.nanobot/config.json` - File: `~/.config/nanobot/config.json`
- Validation: Zod schemas in `src/config/types.ts` - Validation: Zod schemas in `src/config/types.ts`
- Env overrides: `NANOBOT_MODEL`, `NANOBOT_WORKSPACE`, `NANOBOT_CONFIG` - Env overrides: `NANOBOT_MODEL`, `NANOBOT_WORKSPACE`, `NANOBOT_CONFIG`

View File

@@ -129,7 +129,7 @@ const timeout = parseInt(strArg(args, 'timeout', '30'), 10);
## Session Persistence ## Session Persistence
- Format: JSONL (one JSON object per line) - Format: JSONL (one JSON object per line)
- Location: `~/.nanobot/sessions/{sessionKey}.jsonl` - Location: `~/.config/nanobot/sessions/{sessionKey}.jsonl`
- Tool results truncated at 16,000 characters - Tool results truncated at 16,000 characters
- Memory consolidation triggered when approaching context window limit - Memory consolidation triggered when approaching context window limit
@@ -147,5 +147,5 @@ Max 3 attempts with exponential backoff.
1. CLI flags (`-c`, `-m`, `-w`, `-M`) 1. CLI flags (`-c`, `-m`, `-w`, `-M`)
2. Environment variables (`NANOBOT_CONFIG`, `NANOBOT_MODEL`, `NANOBOT_WORKSPACE`) 2. Environment variables (`NANOBOT_CONFIG`, `NANOBOT_MODEL`, `NANOBOT_WORKSPACE`)
3. Config file (`~/.nanobot/config.json`) 3. Config file (`~/.config/nanobot/config.json`)
4. Zod schema defaults 4. Zod schema defaults

View File

@@ -12,7 +12,7 @@ A personal AI assistant that connects to Mattermost (via WebSocket) and runs an
## Key design principles (from Python codebase) ## Key design principles (from Python codebase)
- Ultra-lightweight: minimal dependencies, small codebase - Ultra-lightweight: minimal dependencies, small codebase
- Provider-agnostic: works with Anthropic, OpenAI, Google, Ollama, OpenRouter - Provider-agnostic: works with Anthropic, OpenAI, Google, Ollama, OpenRouter
- Workspace-centric: everything lives in a configurable workspace directory (`~/.nanobot/`) - Workspace-centric: everything lives in a configurable workspace directory (`~/.config/nanobot/`)
- SOUL/AGENTS/USER/TOOLS.md: workspace markdown files that define the bot's personality and rules - SOUL/AGENTS/USER/TOOLS.md: workspace markdown files that define the bot's personality and rules
- Memory is just markdown files (`MEMORY.md`, `HISTORY.md`) — no database - Memory is just markdown files (`MEMORY.md`, `HISTORY.md`) — no database

View File

@@ -34,7 +34,7 @@ Inbound and outbound messages are passed through a typed `AsyncQueue<T>`. The qu
- Returns a normalized `LLMResponse` type - Returns a normalized `LLMResponse` type
## Config Pattern ## Config Pattern
- Config file: `~/.nanobot/config.json` (camelCase JSON) - Config file: `~/.config/nanobot/config.json` (camelCase JSON)
- Loaded with `loadConfig()`, validated by Zod, returns inferred `Config` type - Loaded with `loadConfig()`, validated by Zod, returns inferred `Config` type
- `NANOBOT_` env vars can override fields (e.g. `NANOBOT_MODEL`) - `NANOBOT_` env vars can override fields (e.g. `NANOBOT_MODEL`)

View File

@@ -27,21 +27,21 @@ npx --yes clawhub@latest search "web scraping" --limit 5
## Install ## Install
```bash ```bash
npx --yes clawhub@latest install <slug> --workdir ~/.nanobot/workspace npx --yes clawhub@latest install <slug> --workdir ~/.config/nanobot/workspace
``` ```
Replace `<slug>` with the skill name from search results. This places the skill into `~/.nanobot/workspace/skills/`, where nanobot loads workspace skills from. Always include `--workdir`. Replace `<slug>` with the skill name from search results. This places the skill into `~/.config/nanobot/workspace/skills/`, where nanobot loads workspace skills from. Always include `--workdir`.
## Update ## Update
```bash ```bash
npx --yes clawhub@latest update --all --workdir ~/.nanobot/workspace npx --yes clawhub@latest update --all --workdir ~/.config/nanobot/workspace
``` ```
## List installed ## List installed
```bash ```bash
npx --yes clawhub@latest list --workdir ~/.nanobot/workspace npx --yes clawhub@latest list --workdir ~/.config/nanobot/workspace
``` ```
## Notes ## Notes
@@ -49,5 +49,5 @@ npx --yes clawhub@latest list --workdir ~/.nanobot/workspace
- Requires Node.js (`npx` comes with it). - Requires Node.js (`npx` comes with it).
- No API key needed for search and install. - No API key needed for search and install.
- Login (`npx --yes clawhub@latest login`) is only required for publishing. - Login (`npx --yes clawhub@latest login`) is only required for publishing.
- `--workdir ~/.nanobot/workspace` is critical — without it, skills install to the current directory instead of the nanobot workspace. - `--workdir ~/.config/nanobot/workspace` is critical — without it, skills install to the current directory instead of the nanobot workspace.
- After install, remind the user to start a new session to load the skill. - After install, remind the user to start a new session to load the skill.

View File

@@ -11,7 +11,7 @@ export function onboardCommand(program: Command): void {
.description('Initialize a new nanobot workspace with config and templates') .description('Initialize a new nanobot workspace with config and templates')
.action(async (rawPath?: string) => { .action(async (rawPath?: string) => {
try { try {
const targetPath = resolvePath(rawPath ?? '~/.nanobot'); const targetPath = resolvePath(rawPath ?? '~/.config/nanobot');
const configPath = join(targetPath, 'config.json'); const configPath = join(targetPath, 'config.json');
console.info(pc.blue('Initializing nanobot workspace...')); console.info(pc.blue('Initializing nanobot workspace...'));

View File

@@ -3,7 +3,7 @@ import { homedir } from 'node:os';
import { dirname, resolve } from 'node:path'; import { dirname, resolve } from 'node:path';
import { type Config, ConfigSchema } from './types.ts'; import { type Config, ConfigSchema } from './types.ts';
const DEFAULT_CONFIG_PATH = resolve(homedir(), '.nanobot', 'config.json'); const DEFAULT_CONFIG_PATH = resolve(homedir(), '.config', 'nanobot', 'config.json');
export function getConfigPath(override?: string): string { export function getConfigPath(override?: string): string {
return override ?? process.env['NANOBOT_CONFIG'] ?? DEFAULT_CONFIG_PATH; return override ?? process.env['NANOBOT_CONFIG'] ?? DEFAULT_CONFIG_PATH;

View File

@@ -41,7 +41,7 @@ export type ChannelsConfig = z.infer<typeof ChannelsConfigSchema>;
export const AgentConfigSchema = z.object({ export const AgentConfigSchema = z.object({
model: z.string().default('anthropic/claude-sonnet-4-5'), model: z.string().default('anthropic/claude-sonnet-4-5'),
workspacePath: z.string().default('~/.nanobot'), workspacePath: z.string().default('~/.config/nanobot'),
maxTokens: z.number().int().default(4096), maxTokens: z.number().int().default(4096),
contextWindowTokens: z.number().int().default(65536), contextWindowTokens: z.number().int().default(65536),
temperature: z.number().default(0.7), temperature: z.number().default(0.7),
@@ -114,7 +114,7 @@ export type HeartbeatConfig = z.infer<typeof HeartbeatConfigSchema>;
export const ConfigSchema = z.object({ export const ConfigSchema = z.object({
agent: AgentConfigSchema.default(() => ({ agent: AgentConfigSchema.default(() => ({
model: 'anthropic/claude-sonnet-4-5', model: 'anthropic/claude-sonnet-4-5',
workspacePath: '~/.nanobot', workspacePath: '~/.config/nanobot',
maxTokens: 4096, maxTokens: 4096,
contextWindowTokens: 65536, contextWindowTokens: 65536,
temperature: 0.7, temperature: 0.7,