#!/usr/bin/env bash set -Eeuo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)" VAULT_NAME="${VAULT_NAME:-content-forge}" VAULT_PATH="${VAULT_PATH:-${PROJECT_ROOT}/content-forge}" readonly SCRIPT_DIR readonly PROJECT_ROOT readonly VAULT_NAME readonly VAULT_PATH log() { printf '[init-vault] %s\n' "$*" } die() { printf '[init-vault] ERROR: %s\n' "$*" >&2 exit 1 } trap 'die "Command failed at line ${LINENO}: ${BASH_COMMAND}"' ERR require_obsidian() { if ! command -v obsidian >/dev/null 2>&1; then die "Missing required command: obsidian. Run the obsidian-setup skill first." fi } register_vault() { # Vault registration writes directly to ~/.config/obsidian/obsidian.json. # The obsidian CLI has no vault-add subcommand; registration is done by # editing the config file (same approach as obsidian-setup/scripts/register_vault.py). local config_path="$HOME/.config/obsidian/obsidian.json" python3 -c " import json, os, hashlib, time vault_path = '${VAULT_PATH}' vault_id = hashlib.md5(vault_path.encode()).hexdigest()[:16] config_path = os.path.expanduser('${config_path}') os.makedirs(os.path.join(vault_path, '.obsidian'), exist_ok=True) if os.path.exists(config_path): with open(config_path) as f: config = json.load(f) else: os.makedirs(os.path.dirname(config_path), exist_ok=True) config = {} config['cli'] = True config.setdefault('vaults', {}) # Check if already registered for vid, vdata in config['vaults'].items(): if vdata.get('path') == vault_path: print(f'Vault already registered: {vault_path} (id: {vid})') exit(0) config['vaults'][vault_id] = {'path': vault_path, 'ts': int(time.time() * 1000)} with open(config_path, 'w') as f: json.dump(config, f, indent=2) print(f'Registered vault: {vault_path} (id: {vault_id})') " } create_directories() { local dirs=( "00-inbox" "01-topics" "02-drafts" "03-review" "04-published" "05-assets" "templates" ) local dir for dir in "${dirs[@]}"; do mkdir -p "${VAULT_PATH}/${dir}" done log "Ensured vault directories exist." } create_templates() { local t="${VAULT_PATH}/templates" mkdir -p "${t}" # article template — matches writing-styles.md:tech_blog structure if [[ ! -f "${t}/article.md" ]]; then cat >"${t}/article.md" <<'EOF' --- id: "" title: "" slug: "" status: "topic" content_type: "article" channels: [] language: "zh-CN" source_urls: [] assets: [] cover_image: "" template: "article" owner: "content-forge" created_at: "" updated_at: "" published_at: null --- # 问题背景 # 核心方案 # 实现细节 # 验证结果 # 总结与扩展 EOF log "Created template: article" else log "Template already exists, skip: article" fi # tech-blog template — same frontmatter, tech_blog structure if [[ ! -f "${t}/tech-blog.md" ]]; then cat >"${t}/tech-blog.md" <<'EOF' --- id: "" title: "" slug: "" status: "topic" content_type: "article" channels: [] language: "zh-CN" source_urls: [] assets: [] cover_image: "" template: "tech-blog" owner: "content-forge" created_at: "" updated_at: "" published_at: null --- # 问题背景 # 核心方案 # 实现细节 # 验证结果 # 总结与扩展 EOF log "Created template: tech-blog" else log "Template already exists, skip: tech-blog" fi # social-post template — matches writing-styles.md:social_short structure if [[ ! -f "${t}/social-post.md" ]]; then cat >"${t}/social-post.md" <<'EOF' --- id: "" title: "" slug: "" status: "topic" content_type: "x-post" channels: ["x"] language: "zh-CN" source_urls: [] assets: [] cover_image: "" template: "social-post" owner: "content-forge" created_at: "" updated_at: "" published_at: null --- EOF log "Created template: social-post" else log "Template already exists, skip: social-post" fi } main() { require_obsidian mkdir -p "${VAULT_PATH}" register_vault create_directories create_templates log "Vault initialization complete: ${VAULT_PATH}" } main "$@"