#!/usr/bin/env bash

set -euo pipefail

TARGET_DIR=""
ENABLE_GITHUB=0
GITHUB_OWNER=""
GITHUB_REPO="llm-wiki-vault"
GITHUB_VISIBILITY="private"

usage() {
  cat <<'EOF'
Usage:
  ./bootstrap_obsidian_cowork_llm_wiki.sh --target-dir PATH [options]

Required:
  --target-dir PATH         Where to create the new vault

Optional:
  --config FILE             Source a shell-style config file before parsing flags
  --enable-github           Create a GitHub repo after local git init
  --github-owner OWNER      GitHub owner or org for repo creation
  --github-repo REPO        GitHub repo name (default: llm-wiki-vault)
  --github-visibility VIS   private or public (default: private)
  --help                    Show this message

Examples:
  ./bootstrap_obsidian_cowork_llm_wiki.sh \
    --target-dir ~/dev/llm_wiki_vault

  ./bootstrap_obsidian_cowork_llm_wiki.sh \
    --target-dir ~/dev/llm_wiki_vault \
    --enable-github \
    --github-owner YOUR_GITHUB_OWNER \
    --github-repo llm-wiki-vault
EOF
}

require_cmd() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "Missing required command: $1" >&2
    exit 1
  fi
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --config)
      source "$2"
      shift 2
      ;;
    --target-dir)
      TARGET_DIR="$2"
      shift 2
      ;;
    --enable-github)
      ENABLE_GITHUB=1
      shift
      ;;
    --github-owner)
      GITHUB_OWNER="$2"
      shift 2
      ;;
    --github-repo)
      GITHUB_REPO="$2"
      shift 2
      ;;
    --github-visibility)
      GITHUB_VISIBILITY="$2"
      shift 2
      ;;
    --help|-h)
      usage
      exit 0
      ;;
    *)
      echo "Unknown argument: $1" >&2
      usage
      exit 1
      ;;
  esac
done

require_cmd git

if [[ -z "$TARGET_DIR" ]]; then
  echo "Missing required argument: --target-dir" >&2
  usage
  exit 1
fi

if [[ "$ENABLE_GITHUB" -eq 1 ]]; then
  require_cmd gh
  if [[ -z "$GITHUB_OWNER" ]]; then
    echo "GitHub setup requested, but --github-owner is missing." >&2
    exit 1
  fi
fi

TARGET_DIR="${TARGET_DIR/#\~/$HOME}"

if [[ -e "$TARGET_DIR" && -n "$(find "$TARGET_DIR" -mindepth 1 -maxdepth 1 2>/dev/null)" ]]; then
  echo "Target directory is not empty: $TARGET_DIR" >&2
  exit 1
fi

today="$(date '+%Y-%m-%d')"
week="$(date '+%G-W%V')"

mkdir -p \
  "$TARGET_DIR/.obsidian" \
  "$TARGET_DIR/01 Daily" \
  "$TARGET_DIR/02 Sources" \
  "$TARGET_DIR/03 Meetings" \
  "$TARGET_DIR/04 People" \
  "$TARGET_DIR/05 Decisions" \
  "$TARGET_DIR/06 Workstreams" \
  "$TARGET_DIR/07 Risks" \
  "$TARGET_DIR/08 Open Questions" \
  "$TARGET_DIR/09 Weekly Syntheses" \
  "$TARGET_DIR/10 Executive Briefs" \
  "$TARGET_DIR/99 Templates"

cat > "$TARGET_DIR/.gitignore" <<'EOF'
.DS_Store
.obsidian/workspace.json
EOF

cat > "$TARGET_DIR/.obsidian/core-plugins.json" <<'EOF'
{
  "file-explorer": true,
  "global-search": true,
  "switcher": true,
  "graph": true,
  "backlink": true,
  "canvas": true,
  "outgoing-link": true,
  "tag-pane": true,
  "properties": true,
  "page-preview": true,
  "daily-notes": true,
  "templates": true,
  "note-composer": true,
  "command-palette": true,
  "editor-status": true,
  "bookmarks": true,
  "outline": true,
  "word-count": true,
  "file-recovery": true
}
EOF

cat > "$TARGET_DIR/.obsidian/app.json" <<'EOF'
{}
EOF

cat > "$TARGET_DIR/.obsidian/appearance.json" <<'EOF'
{}
EOF

cat > "$TARGET_DIR/README.md" <<'EOF'
# LLM Wiki Vault

This vault is a local-first, Karpathy-style LLM wiki.

The durable layer lives in plain Markdown on disk. Raw notes can still come from meetings, docs, email, screenshots, or direct daily writing, but the canonical knowledge base is this vault.

## What this vault is for

- Keep project knowledge durable and portable.
- Give Cowork or Claude a clean filesystem-native knowledge base to update.
- Separate raw capture from synthesized project truth.
- Produce weekly syntheses and executive briefs without hunting through scattered notes.

## Quick Start

1. Open this folder as an Obsidian vault.
2. In `Settings` -> `Core plugins`, enable `Templates` and `Daily notes`.
3. In `Settings` -> `Templates`, set `Template folder location` to `99 Templates`.
4. In `Settings` -> `Daily notes`, set `New file location` to `01 Daily` and `Template file location` to `99 Templates/Daily Note Template.md`.
5. In `Settings` -> `Community plugins`, install and enable `Calendar`, then expand the right sidebar.
6. Click today in `Calendar` to open or create the current daily note in `01 Daily`.
7. Ask the agent to promote durable facts into meetings, sources, decisions, workstreams, risks, people pages, and open questions.
EOF

cat > "$TARGET_DIR/Naming Conventions.md" <<'EOF'
# Naming Conventions

Use stable, boring names. The goal is for both humans and agents to find the canonical page fast.

## File Naming Rules

| Note Type | Folder | File Name Pattern |
| --- | --- | --- |
| Daily note | `01 Daily` | `YYYY-MM-DD` |
| Source | `02 Sources` | `SRC-#### - Short Title` |
| Meeting | `03 Meetings` | `YYYY-MM-DD - Counterparty - Topic` |
| Person | `04 People` | `Preferred Name` or `Preferred Name Role` when disambiguation matters |
| Decision | `05 Decisions` | `DEC-#### - Verb Phrase` |
| Workstream | `06 Workstreams` | `WS-### - Noun Phrase` |
| Risk | `07 Risks` | `RISK-### - Short Description` |
| Open question | `08 Open Questions` | `Q-### - Question` |
| Weekly synthesis | `09 Weekly Syntheses` | `YYYY-Www` |
| Executive brief | `10 Executive Briefs` | `YYYY-MM-DD - Executive Brief - Topic` |

## Backlink Safety Rules

- Simple wikilinks should resolve to the canonical page for a concept.
- Reuse existing canonical page names instead of creating near-duplicate pages.
EOF

cat > "$TARGET_DIR/CLAUDE.md" <<'EOF'
# LLM Wiki Agent Instructions

This vault is a Karpathy-style LLM wiki.

Your job is not to make the raw notes prettier. Your job is to maintain a durable, interlinked project wiki that stays grounded in raw evidence.

## Mission

- Keep the vault accurate, compressed, and up to date.
- Separate raw capture from synthesized truth.
- Prefer updating existing canonical pages over creating duplicates.
- Turn scattered notes into durable project memory.

## Vault Model

### Raw capture layer

- `01 Daily` as the default place for live note capture
- `02 Sources` and `03 Meetings` when raw daily material is later promoted into cleaner evidence notes

### Durable knowledge layer

- `04 People`
- `05 Decisions`
- `06 Workstreams`
- `07 Risks`
- `08 Open Questions`

### Output layer

- `09 Weekly Syntheses`
- `10 Executive Briefs`

## Evidence Rules

- Link durable claims back to raw notes or source notes.
- Preserve chronology in daily notes and meetings.
- Do not delete raw capture unless explicitly asked.
- Prefer simple links to existing canonical pages.
EOF

cat > "$TARGET_DIR/Obsidian and Cowork LLM Wiki Setup Guide.md" <<'EOF'
---
type: guide
status: active
---

# Obsidian and Cowork LLM Wiki Setup Guide

This guide explains how to set up a local-first LLM wiki using Obsidian for the durable knowledge base and Cowork for task execution.

Assume this is a totally fresh setup. No import is required.

## Goal

Use Obsidian as the durable local knowledge base and point Cowork at the same vault so tasks can read project context before doing work and can promote daily notes into the durable layer.

After setup, use `[[LLM Wiki Day-to-Day Guide]]` as the human operating guide for working in the vault each day.

## What You Need

- Obsidian installed
- Cowork access
- A fresh folder for the vault
- Optional: GitHub CLI (`gh`) if you want the bootstrap script to create a private GitHub repo for backup

## Fresh Setup

Start by creating the vault scaffold.

Use Claude Code or a terminal session to run the bootstrap script first. Do not use Cowork for the bootstrap step. Cowork should point at the vault after the folder already exists.

Run:

```bash
cd /path/to/template-files
./bootstrap_obsidian_cowork_llm_wiki.sh --target-dir /path/to/llm_wiki_vault
```

Optional GitHub setup:

```bash
cd /path/to/template-files
./bootstrap_obsidian_cowork_llm_wiki.sh \
  --target-dir /path/to/llm_wiki_vault \
  --enable-github \
  --github-owner YOUR_GITHUB_OWNER \
  --github-repo llm-wiki-vault
```

## Install And Open Obsidian

1. Install Obsidian.
2. Open Obsidian.
3. Choose `Open folder as vault`.
4. Select the freshly created vault folder, for example `/path/to/llm_wiki_vault`.

## Obsidian Setup

1. Open the vault folder as an Obsidian vault.
2. Go to `Settings` -> `Core plugins`.
3. Enable `Templates`.
4. Enable `Daily notes`.
5. Go to `Settings` -> `Templates`.
6. Set `Template folder location` to `99 Templates`.
7. Go to `Settings` -> `Daily notes`.
8. Set `New file location` to `01 Daily`.
9. Set `Template file location` to `99 Templates/Daily Note Template.md`.
10. Go to `Settings` -> `Community plugins`.
11. Turn off `Restricted mode` if needed.
12. Click `Browse`, install `Calendar`, and enable it.
13. Expand the right sidebar so the calendar pane is visible.
14. To start any day, click the day in the calendar. Obsidian will open that day's note and create it if it does not already exist.

## Point Cowork At The Vault

1. In Cowork, choose `Use an existing folder`.
2. Pick the same vault folder path you opened in Obsidian.
3. Name the project.
4. Paste the instructions text from the `Cowork Instructions Box Text` section below into the instructions box.
5. Create the project.

## Cowork Instructions Box Text

```md
This folder is an Obsidian vault that serves as the durable knowledge base for this project.

Read these first at the start of a session:
- Home.md
- CLAUDE.md
- Naming Conventions.md
- 04 People/People Index.md
- 06 Workstreams/Workstreams Index.md
- 09 Weekly Syntheses/Weekly Syntheses Index.md
- the most recent note in 01 Daily

Working model:
- 01 Daily is the default raw capture note during the day.
- 02 Sources and 03 Meetings are usually created during the promotion pass when raw daily notes are turned into cleaner evidence notes.
- 04 People, 05 Decisions, 06 Workstreams, 07 Risks, and 08 Open Questions are the canonical durable layer.
- 09 Weekly Syntheses and 10 Executive Briefs are synthesized outputs.

How I want to use this project:
- When I ask you to work on a task, first check the relevant notes in this vault for context before responding or doing work.
- Assume this vault is the main project memory and use it to ground recommendations, analysis, and drafts.
- During the day, I will usually capture everything in the daily note, including live meeting notes.
- At the end of the day, assume the daily note is already part of the project context. I may add extra docs, emails, articles, screenshots, or other source material that was not captured in the note.
- When I do that, update the daily note first, then promote the durable signal into the right canonical pages.
- That promotion pass should usually include any relevant updates to Meetings, Sources, People, Decisions, Workstreams, Risks, Open Questions, Weekly Syntheses, and Executive Briefs.
- If something important appears repeatedly and does not yet have a canonical page, create one in the appropriate folder.

Rules:
- Prefer updating existing canonical pages over creating duplicates.
- Promote durable insights out of daily notes into the canonical pages.
- Use simple links for canonical pages.
- Keep the wiki concise, accurate, and link-rich.
- When asked for status, read the durable layer first and use raw notes only to verify recent changes.
- If context is missing, inspect the vault first, then ask me only for the minimum missing information needed.
- Be proactive about suggesting what should be promoted, clarified, or turned into a durable note.
```

## Daily Operating Loop

1. Start the day by clicking today in the `Calendar` sidebar so Obsidian opens or creates today's note in `01 Daily`.
2. Capture everything in the current daily note by default, including live meeting notes.
3. Use Cowork tasks against that same vault so the agent checks the notes before doing work.
4. At the end of the day, add any extra docs, emails, articles, screenshots, or other source material that is not already captured in the daily note.
5. Run the end-of-day promotion prompt in the Cowork knowledge-base project.

## End-Of-Day Promotion Prompt

```md
Process today’s daily note and promote the durable signal into meetings, sources, people, decisions, workstreams, risks, open questions, weekly syntheses, and executive briefs as needed.
```

## Notes

- Obsidian is the durable local-first source of truth.
- Cowork should be pointed at the same vault so tasks use accumulated project context.
- GitHub backup is optional.
- Default capture should be daily-note-first. Meetings and other durable notes are usually created during the end-of-day promotion pass, not during live note-taking.
EOF

cat > "$TARGET_DIR/Home.md" <<EOF
---
type: home
project: LLM Wiki
status: active
---

# LLM Wiki

This is the canonical, durable knowledge base for the project.

## Start Here

- [[Obsidian and Cowork LLM Wiki Setup Guide]]
- [[LLM Wiki Day-to-Day Guide]]
- [[01 Daily/${today}]]
- [[02 Sources/Sources Index]]
- [[03 Meetings/Meetings Index]]
- [[04 People/People Index]]
- [[05 Decisions/Decisions Index]]
- [[06 Workstreams/Workstreams Index]]
- [[07 Risks/Risks Index]]
- [[08 Open Questions/Open Questions Index]]
- [[09 Weekly Syntheses/Weekly Syntheses Index]]
- [[10 Executive Briefs/Executive Briefs Index]]
EOF

cat > "$TARGET_DIR/LLM Wiki Day-to-Day Guide.md" <<'EOF'
# LLM Wiki Day-to-Day Guide

This is the simple human workflow for using the vault during the day.

## Start The Day

1. Open Obsidian.
2. Expand the right sidebar if the `Calendar` pane is hidden.
3. Click today's date in `Calendar`.
4. Obsidian will open or create today's note in `01 Daily`.

## Capture Notes

- Capture everything in today's daily note by default.
- Put live meeting notes in the daily note too.
- If you know the canonical page already, add a wiki link while you type.
- If you do not know the right page yet, do not stop to organize it. Just keep capturing in the daily note.

## Link Notes

- Use `[[Page Name]]` to create a wiki link to another note.
- Obsidian automatically shows backlinks when notes link to each other, so you do not need a separate backlink step.
- Link to canonical pages like people, workstreams, decisions, risks, and open questions when you know them.
- If you are unsure of the exact page name, leave plain text and let Cowork fix the links during the promotion pass.

## Paste Material And Attachments

- Paste emails, meeting summaries, or text snippets directly into the daily note when they are part of the day's working context.
- Drag files or images into the note when the original artifact matters as evidence.
- Use attachments as supporting evidence, not as the durable summary.
- If a document deserves its own source note, ask Cowork to turn it into a note in `02 Sources` during the promotion pass.

## End Of Day

1. Stay in the Cowork knowledge-base project that already points at this vault.
2. Add any extra emails, docs, articles, screenshots, or other source material from the day that is not already captured in the daily note.
3. Run this prompt:

```md
Process today’s daily note and promote the durable signal into meetings, sources, people, decisions, workstreams, risks, open questions, weekly syntheses, and executive briefs as needed.
```

## Default Principle

Capture fast in the daily note. Organize later through the promotion pass.
EOF

cat > "$TARGET_DIR/02 Sources/Sources Index.md" <<'EOF'
---
type: index
area: sources
---

# Sources Index
EOF

cat > "$TARGET_DIR/03 Meetings/Meetings Index.md" <<'EOF'
---
type: index
area: meetings
---

# Meetings Index
EOF

cat > "$TARGET_DIR/04 People/People Index.md" <<'EOF'
---
type: index
area: people
---

# People Index
EOF

cat > "$TARGET_DIR/05 Decisions/Decisions Index.md" <<'EOF'
---
type: index
area: decisions
---

# Decisions Index
EOF

cat > "$TARGET_DIR/06 Workstreams/Workstreams Index.md" <<'EOF'
---
type: index
area: workstreams
---

# Workstreams Index
EOF

cat > "$TARGET_DIR/07 Risks/Risks Index.md" <<'EOF'
---
type: index
area: risks
---

# Risks Index
EOF

cat > "$TARGET_DIR/08 Open Questions/Open Questions Index.md" <<'EOF'
---
type: index
area: open_questions
---

# Open Questions Index
EOF

cat > "$TARGET_DIR/09 Weekly Syntheses/Weekly Syntheses Index.md" <<'EOF'
---
type: index
area: weekly_syntheses
---

# Weekly Syntheses Index
EOF

cat > "$TARGET_DIR/10 Executive Briefs/Executive Briefs Index.md" <<'EOF'
---
type: index
area: executive_briefs
---

# Executive Briefs Index
EOF

cat > "$TARGET_DIR/01 Daily/${today}.md" <<EOF
---
type: daily
date: "${today}"
week: "${week}"
project: LLM Wiki
tags:
  - daily
---

# ${today}

## Today's Focus

- Bootstrap the LLM wiki.

## Notes

- Set up a local-first Obsidian vault for durable project memory.

## Promotions

- Decisions:
- Workstreams:
- Risks:
- Open questions:

## Next Actions

- Configure Obsidian Templates to use \`99 Templates\`.
- Configure Daily Notes to write into \`01 Daily\`.
EOF

cat > "$TARGET_DIR/99 Templates/Daily Note Template.md" <<'EOF'
---
type: daily
date: "{{date:YYYY-MM-DD}}"
week: "{{date:GGGG-[W]WW}}"
project: LLM Wiki
tags:
  - daily
---

# {{date:YYYY-MM-DD}}

## Today's Focus

- 

## Notes

- 

## Promotions

- Decisions:
- Workstreams:
- Risks:
- Open questions:

## Next Actions

- 
EOF

cat > "$TARGET_DIR/99 Templates/Decision Template.md" <<'EOF'
---
type: decision
id: DEC-XXXX
status: proposed
decision_date: "{{date:YYYY-MM-DD}}"
---

# DEC-XXXX - Decision Title

## Decision

- 

## Context

- 

## Consequences

- 

## Evidence

- 
EOF

cat > "$TARGET_DIR/99 Templates/Executive Brief Template.md" <<'EOF'
---
type: executive_brief
date: "{{date:YYYY-MM-DD}}"
status: draft
audience:
---

# Executive Brief - Topic

## Bottom Line Up Front

- 

## What Changed

- 

## Why It Matters

- 

## Recommended Next Step

- 
EOF

cat > "$TARGET_DIR/99 Templates/Meeting Template.md" <<'EOF'
---
type: meeting
date: "{{date:YYYY-MM-DD}}"
counterparty:
topic:
tags:
  - meeting
---

# Meeting Note

## Attendees

- 

## Agenda

- 

## Notes

- 

## Decisions Made

- 

## Follow-Ups

- 

## Signals to Promote

- Risks:
- Questions:
- Workstream changes:
EOF

cat > "$TARGET_DIR/99 Templates/Open Question Template.md" <<'EOF'
---
type: open_question
id: Q-XXX
status: open
opened: "{{date:YYYY-MM-DD}}"
---

# Q-XXX - Question

## Question

- 

## Why This Matters

- 

## What We Know So Far

- 

## Next Action

- 

## Related Notes

- 
EOF

cat > "$TARGET_DIR/99 Templates/Person Template.md" <<'EOF'
---
type: person
role:
organization:
status: active
---

# Full Name

## Role

- 

## Why This Person Matters

- 

## Current Topics

- 

## Preferences and Signals

- 

## Related Notes

- 
EOF

cat > "$TARGET_DIR/99 Templates/Risk Template.md" <<'EOF'
---
type: risk
id: RISK-XXX
status: open
probability:
impact:
owner:
---

# RISK-XXX - Risk Title

## Risk

- 

## Why It Matters

- 

## Mitigation

- 

## Trigger Signals

- 

## Related Notes

- 
EOF

cat > "$TARGET_DIR/99 Templates/Source Template.md" <<'EOF'
---
type: source
id: SRC-XXXX
captured_on: "{{date:YYYY-MM-DD}}"
status: raw
source:
---

# SRC-XXXX - Title

## Summary

- 

## Key Facts

- 

## Why It Matters

- 

## Related Notes

- 
EOF

cat > "$TARGET_DIR/99 Templates/Weekly Synthesis Template.md" <<'EOF'
---
type: weekly_synthesis
week: "{{date:GGGG-[W]WW}}"
status: draft
---

# {{date:GGGG-[W]WW}}

## Bottom Line

- 

## What Changed

- 

## Current Truth

- 

## Decisions This Week

- 

## Risks and Open Questions

- 
EOF

cat > "$TARGET_DIR/99 Templates/Workstream Template.md" <<'EOF'
---
type: workstream
id: WS-XXX
status: active
owner:
started: "{{date:YYYY-MM-DD}}"
---

# WS-XXX - Workstream Title

## Objective

- 

## Current Status

- 

## Milestones

- [ ] 

## Risks

- 

## Related Notes

- 
EOF

(
  cd "$TARGET_DIR"
  git init -b main >/dev/null
)

if [[ "$ENABLE_GITHUB" -eq 1 ]]; then
  (
    cd "$TARGET_DIR"
    git add . >/dev/null
    git commit -m "Bootstrap LLM wiki vault" >/dev/null
    gh repo create "${GITHUB_OWNER}/${GITHUB_REPO}" \
      "--${GITHUB_VISIBILITY}" \
      --source=. \
      --remote=origin \
      --push
  )
fi

cat <<EOF
Bootstrap complete.

Vault path:
  $TARGET_DIR

Next steps:
  1. Open the folder as an Obsidian vault.
  2. In Obsidian Settings, enable 'Templates' and 'Daily notes' under Core plugins.
  3. In Obsidian Settings, set Templates -> Template folder location to '99 Templates'.
  4. In Obsidian Settings, set Daily notes -> New file location to '01 Daily' and Template file location to '99 Templates/Daily Note Template.md'.
  5. Install the 'Calendar' community plugin and expand the right sidebar.
  6. In Cowork, create a project from the same folder path.
  7. Paste the instructions from the 'Cowork Instructions Box Text' section in 'Obsidian and Cowork LLM Wiki Setup Guide.md' into the Cowork instructions box.
EOF
