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**
```bash
mkdir -p ~/.nanobot
mkdir -p ~/.config/nanobot
```
`~/.nanobot/config.json`:
`~/.config/nanobot/config.json`:
```json
{
@@ -59,7 +59,7 @@ bun run nanobot agent [options]
| 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, --model <model>` | Override the model for this session |
@@ -67,7 +67,7 @@ bun run nanobot agent [options]
```bash
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
```
@@ -90,18 +90,18 @@ bun run nanobot gateway [options]
| 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
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.
## 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:
@@ -116,7 +116,7 @@ Environment variable overrides:
{
"agent": {
"model": "openrouter/anthropic/claude-sonnet-4-5",
"workspacePath": "~/.nanobot",
"workspacePath": "~/.config/nanobot",
"maxTokens": 4096,
"contextWindowTokens": 65536,
"temperature": 0.7,
@@ -231,10 +231,10 @@ Run separate instances with different configs — useful for isolated workspaces
```bash
# Instance A
bun run nanobot gateway -c ~/.nanobot-a/config.json
bun run nanobot gateway -c ~/.config/nanobot-a/config.json
# 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:
@@ -242,7 +242,7 @@ Each instance needs its own config file. Set a different `agent.workspacePath` p
```json
{
"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:
```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
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)

View File

@@ -123,7 +123,7 @@ Wraps Vercel AI SDK `generateText()` with:
- Normalized `LLMResponse` type
### 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`)
- Supports history truncation for context window limits
@@ -136,7 +136,7 @@ When session history exceeds token limits, summarizes old messages and archives
## Configuration
- File: `~/.nanobot/config.json`
- File: `~/.config/nanobot/config.json`
- Validation: Zod schemas in `src/config/types.ts`
- Env overrides: `NANOBOT_MODEL`, `NANOBOT_WORKSPACE`, `NANOBOT_CONFIG`

View File

@@ -129,7 +129,7 @@ const timeout = parseInt(strArg(args, 'timeout', '30'), 10);
## Session Persistence
- 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
- 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`)
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

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)
- Ultra-lightweight: minimal dependencies, small codebase
- 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
- 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
## 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
- `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
```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
```bash
npx --yes clawhub@latest update --all --workdir ~/.nanobot/workspace
npx --yes clawhub@latest update --all --workdir ~/.config/nanobot/workspace
```
## List installed
```bash
npx --yes clawhub@latest list --workdir ~/.nanobot/workspace
npx --yes clawhub@latest list --workdir ~/.config/nanobot/workspace
```
## Notes
@@ -49,5 +49,5 @@ npx --yes clawhub@latest list --workdir ~/.nanobot/workspace
- Requires Node.js (`npx` comes with it).
- No API key needed for search and install.
- 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.

View File

@@ -11,7 +11,7 @@ export function onboardCommand(program: Command): void {
.description('Initialize a new nanobot workspace with config and templates')
.action(async (rawPath?: string) => {
try {
const targetPath = resolvePath(rawPath ?? '~/.nanobot');
const targetPath = resolvePath(rawPath ?? '~/.config/nanobot');
const configPath = join(targetPath, 'config.json');
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 { 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 {
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({
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),
contextWindowTokens: z.number().int().default(65536),
temperature: z.number().default(0.7),
@@ -114,7 +114,7 @@ export type HeartbeatConfig = z.infer<typeof HeartbeatConfigSchema>;
export const ConfigSchema = z.object({
agent: AgentConfigSchema.default(() => ({
model: 'anthropic/claude-sonnet-4-5',
workspacePath: '~/.nanobot',
workspacePath: '~/.config/nanobot',
maxTokens: 4096,
contextWindowTokens: 65536,
temperature: 0.7,