# 需求文档

## 技术栈

- Rust
  - 相关库(crate):
    - Cli 参数解析: [clap-rs/clap: A full featured, fast Command Line Argument Parser for Rust](https://github.com/clap-rs/clap) (使用 builder 模式, derive模式编译慢而且提示差)
    - Cli 交互处理: [mikaelmello/inquire: A Rust library for building interactive prompts](https://github.com/mikaelmello/inquire)
    - 跨平台配置目录: [dirs/directories-rs: a mid-level library that provides config/cache/data paths, following the respective conventions on Linux, macOS and Windows - Codeberg.org](https://codeberg.org/dirs/directories-rs)
    - 简化Error处理
      - 定义错误 [dtolnay/thiserror: derive(Error) for struct and enum error types](https://github.com/dtolnay/thiserror)
      - 处理错误 [dtolnay/anyhow: Flexible concrete Error type built on std::error::Error](https://github.com/dtolnay/anyhow)
    - i18n: [longbridge/rust-i18n: A better and simply I18n crate for Rust.](https://github.com/longbridge/rust-i18n)

## 背景说明

> 简要: 管理通用cursorrule时比较麻烦和原始, 设计一个Cli应用, 其子功能可以解决这个问题

我们在使用cursor一类的ai编辑器时可能需要设定一些rules, 大多数时候这些rules是通用模板可以在各个模式中共用一部分, 再根据项目做一些个别调整, 因此如果能有一个可以在全局管理这些规则文件(CRUD), 并且可以提供方便且智慧的在此项目中生成/注入规则文件就好了, 这样可以简化管理规则的方式(从之前随意找项目中的规则复制粘贴到统一位置管理)

## 目标

- 初始化版本, 不需要有太多额外的功能和考虑, 以避免过早优化和过度思考
- 仅 Linux 可用, 但需要抽象 Linux 操作系统特有的API方便之后适配其他系统
- 提供 inquire 交互逻辑, 避免用户记忆过多的cli选项, 导致难以上手
- 开箱即用, 清晰明确的命令(CLI)设计, 要符合使用直觉
- 支持配置管理目录, 比如 在 `~/.config/llman/` 中作为配置目录, 用子目录 `prompt/editor_rules/cursor` 等管理相关规则, 用子目录 `prompt/editor_rules/template/` 管理通用规则


## 一些需要讨论和解决的问题

TODO:
- [x] 子命令是用 `prompt` 还是 `rule`
  - 用 `prompt` 然后看能不能把 `rule` 实现为 alias
- [x] 上一个单数还是复数
  - 用单数, 能少打一个字少打一个, 不会影响用意
- [x] 需要选择一个cli使用的配置格式
  - 第一个版本暂时不需要这个, 暂时不考虑

## 实现前调研

### 细节: Cli 命令设计

#### 主命令

cli名为 `llman`, 意为 `(LLM Man)agement`

##### 全局选项

##### 日志选项 `--log-level [DEBUG|ERROR|INFO|WARING|...]`

或者通过如 -v 或 --verbose, 实现详细输出选项，允许用户在需要时获取更详细的执行信息。 确保使用 inquire 进行的交互式提示清晰明了，并尽可能提供合理的默认选项。

#### 子命令 `prompt` (`rule`)

- 生成提示规则文件(交互方式执行)
```
$ llman prompt gen -i # --interactive
```
功能描述: 此命令用于在当前工作目录下为指定的 LLM 应用生成上下文规则文件, 但是使用 inquire的库提供的方便易用的交互方式
--interactive 或者 -i: 使用 inquire 交互, 生成选项, 同"生成提示规则文件"

- 生成提示规则文件
```
$ llman prompt gen --app <app_name> --template <template_name> [--force]
```
功能描述: 此命令用于在当前工作目录下为指定的 LLM 应用生成上下文规则文件。
--app <app_name>: 指定目标 LLM 应用的名称，例如 cursor。llman 将根据此参数确定生成的规则文件的格式和目标路径。
--template <template_name>: 指定用于生成规则的模板名称，例如 project-python-common。模板定义了针对特定项目类型或场景的规则内容和结构。
仓库检测: 默认情况下，llman 会检测当前目录是否为一个版本控制系统（VCS）仓库（例如，通过检查是否存在 .git 目录）。如果不是仓库，命令将提示用户或中止操作，除非使用了 --force 标志。
--force: 此可选标志将覆盖仓库检测机制，强制在当前位置生成规则文件。
规则注入: 生成的规则文件将自动放置到目标 LLM 应用期望的位置。例如，对于 Cursor，规则文件可能是项目根目录下的 .cursor/mcp.json。

- 列出规则文件
```
$ llman prompt list [--app <app_name>]
```
功能描述: 列出 llman 管理的或已知的规则。
--app <app_name> (可选): 如果提供，则仅列出与特定 LLM 应用相关的规则。
输出应清晰展示规则的名称、关联的应用、模板来源（如果适用）以及其状态或位置。

- 编辑/增加规则文件
```
llman prompt upsert --app <app_name> --name <rule_name> (--content <text> | --file <path_to_file>)
```
  功能描述: 更新或插入（如果不存在）一个指定的规则。此命令允许用户手动管理或自定义规则。
  --app <app_name>: 指定规则所属的 LLM 应用。
  --name <rule_name>: 为规则指定一个唯一的名称，用于后续管理。
  --content <text>: 直接通过命令行提供规则的内容（例如一些文本）。
  --file <path_to_rule_file>: 指定一个包含规则内容的文件路径。llman 将读取此文件内容作为规则。
  此命令需要处理规则的序列化（如果从结构化输入创建）和存储。

- 移除规则文件
```
$ llman prompt rm --app <app_name> --name <rule_name>
```
功能描述: 删除一个指定的规则。
--app <app_name>: 指定规则所属的 LLM 应用。
--name <rule_name>: 指定要删除的规则的名称。
删除操作应谨慎，可能需要用户确认。

##### 选项注释

###### `--app`

值为以下时, 有额外规则

- `cursor`

> `cursor` 的生成目录为 `当前命令运行目录/.cursor/rules/` , 目标文件结尾为 mdc, 如 `当前命令运行目录/.cursor/rules/project-python-common.mdc`

NOTE:
- 限制生成的文件前要判断运行当前命令的工作目录不能是 `~` (home目录), 避免以外生成


### 细节: 配置目录

在 Linux 系统上，应遵循 XDG Base Directory Specification，例如将配置存储在 `$XDG_CONFIG_HOME/llman` 或 `~/.config/llman`


#### 子命令 `prompt` 的目录

暂时定为 `prompt` , 即(`~/.config/llman/prompt/`)

每个app为一个子目录, 如 `prompt/cursor` , 即(`~/.config/llman/prompt/cursor/`)


### 细节: 用户友好的错误处理
健壮的错误处理和清晰的用户反馈是优质 CLI 工具的标志

- 使用 `thiserror` 包定义 llman 特有的错误类型, 其可以方便地创建包含丰富上下文的自定义错误枚举，从而向用户提供更具体、更有帮助的错误信息。
- 严格区分标准输出 (stdout) 和标准错误 (stderr)。成功的命令结果输出到 stdout，而错误信息、警告和调试信息输出到 stderr。

# 使用的库(crate)仓库示例
- clap (builder) : https://github.com/clap-rs/clap/tree/master/examples/tutorial_builder
- inquire: https://github.com/mikaelmello/inquire/tree/main/inquire/examples

