# vaultgen

**vaultgen** is a CLI tool that uses an AI agent to generate and edit notes in an [Obsidian](https://obsidian.md/) vault. You describe what you want in natural language; the agent produces notes that follow a schema you define, then writes them as Markdown files into your vault.

## Features

- **Schema-driven notes**: Define your note structure (fields, types, optional fields) in a JSON schema inside `config.md`. The agent outputs notes that match this schema.
- **Vault-aware**: The agent sees your existing vault contents and can create new notes or update existing ones (by outputting a note with the same name).
- **Chat interface**: Have a conversation with the agent until you're happy with the result; confirm with `y` to export notes to the vault.
- **Flexible types**: Schema supports `str`, `int`, `float`, `bool`, `date`, `datetime`, `list`, `link` (Obsidian-style `[[Note Name]]`), and enums (e.g. `["Option1", "Option2"]`).

## Requirements

- **Python 3.12+**
- **API key**: The agent uses `google-gla:gemini-3-flash-preview`. Set your API key in the environment (e.g. as required by pydantic-ai for the Google model).

## Installation

From the project root:

```bash
# With uv
uv sync

# Or with pip
pip install -e .
```

The `vg` command will be available after installation.

## Usage

Run all commands from the **root of your Obsidian vault** (the folder that contains or will contain your `.md` files).

### 1. Initialize the vault

Create a `config.md` file with placeholder **Context** and **Schema** sections:

```bash
vg init
```

### 2. Configure the vault

Edit `config.md` in your vault. It has two parts:

- **Context** (inside a ` ```context ` code block): Describe the purpose of the vault and how notes should be written (style, conventions, domain). This is included in the agent’s instructions.
- **Schema** (inside a ` ```json ` code block): A JSON object that defines the fields of your notes. Each key is a field name; each value is an object with:
  - `"type"`: `"str"`, `"int"`, `"float"`, `"bool"`, `"date"`, `"datetime"`, `"list"`, `"link"`, or an array of strings for an enum (e.g. `["Backlog", "To do", "Done"]`).
  - `"description"`: Description of the field for the agent.
  - `"optional"`: `"True"` or `"False"` (optional; default is required).

The agent will always get two extra fields: `name` (file name and title) and `content` (body of the note).

**Example `config.md`** (task vault):

````markdown
## Context

```context
This vault is for project tasks. Each task has a status, a short description, start/end dates, and optional dependency on another task.
```

## Schema

```json
{
    "status": {
        "type": ["Backlog", "To do", "Doing", "Done"],
        "description": "The status of the task"
    },
    "start": {
        "type": "date",
        "description": "The start date of the task"
    },
    "end": {
        "type": "date",
        "description": "The end date of the task"
    },
    "depends on": {
        "type": "link",
        "description": "The task this one depends on ([[Task Name]])",
        "optional": "True"
    }
}
```
````

### 3. Chat and generate notes

Start the interactive chat from your vault directory:

```bash
vg chat
```

- The agent will ask what you want to generate.
- Type your request (e.g. “Add a task: Implement login, status To do, start tomorrow, end next Friday”).
- The agent may reply with clarifying questions (plain text) or with one or more structured notes (shown as previews).
- When you see a note preview, answer:
  - **`y`** — Export the note(s) to the vault as `.md` files (filename = `name` from the schema).
  - **Anything else** — Treat your message as feedback; the agent will adjust and propose again.

You can repeat until you’re satisfied, then confirm with `y` to write the files.

## How it works

- **Agent**: A [pydantic-ai](https://ai.pydantic.dev/) agent with your vault’s context and schema. It can return either a string (for dialogue) or structured note(s) matching your schema.
- **Schema**: Loaded from the ` ```json ` block in `config.md` and turned into a Pydantic model (with `name` and `content` added). The agent’s output type is this model (single note or list of notes).
- **Export**: On `y`, notes are serialized to Markdown (YAML frontmatter for fields other than `name`/`content`, then body). Files are written as `{name}.md` in the vault root.

## Project structure

```
vaultgen/
├── vaultgen/
│   ├── __init__.py
│   ├── main.py      # CLI entry (vg init, vg chat)
│   ├── cli.py       # Chat loop and export confirmation
│   ├── agent.py     # Agent setup, system prompts (vault state, timestamp)
│   ├── schema.py    # Load config.md JSON → Pydantic model
│   ├── instructions.py  # Build instructions from context + vault
│   ├── export.py    # Note → Markdown file writing
│   └── start.py     # vg init: create config.md
├── pyproject.toml
└── README.md
```

## License

MIT.
