Every project visible. Every morning. In one place.

Mission Control.

Five paste-prompts that turn Claude Code and Obsidian into a portfolio view that refreshes itself, a daily routine that asks the capacity question, and a per-project loop that keeps the next action current. About an hour to install. About six working weeks back across a year.

20-min setup 5 install prompts 6 steps No coding needed

The problem, and the promise.

You're running five projects. Maybe seven. Some half-living in Claude threads, some in Notion, some in your head. Every morning you spend twenty, thirty minutes per project rebuilding context. What you decided last, where you got to, what the next concrete step was. Across the portfolio, that's an hour gone before any real work happens. On a Monday, sometimes two.

The hour isn't on your calendar. It isn't on your to-do list. It just evaporates, every morning, into the gap between knowing the project exists and being able to work on it.

Mission Control fixes this in five steps.

Five prompts, pasted into Claude Code in sequence. One install pass. Then you live inside slash commands, with the dashboard open in Obsidian as your portfolio view. Claude opens every session with the context it needs already loaded. The minutes you used to lose handing it over drop to almost zero. Across a year, that's about six working weeks back.

The five prompts are right below. Each step tells you what the prompt builds and why it works the way it does. Hit Copy prompt, paste into Claude Code, follow the questions.

Let's jump in.

Here's how the install works:

Step 1

Vault scaffold, about-you, first project.

Paste Prompt 1. Claude Code asks you four short questions, then creates the folder tree, an _about-you.md operating filter, your first project hub, the CLAUDE.md helper, the Projects.base query, and the Mission Control.md dashboard page. Six building blocks, one paste.

Step 2

Session note template.

Paste Prompt 2. A small three-section template lands in 06-Templates/_session-template.md. Goal, current state, next. Single source of truth for every project. This is what /wrapup will fill in later.

Step 3

Install /new-project.

Paste Prompt 3. Installs the slash command that scaffolds new project hubs with consistent frontmatter and structure. From here, every new project gets the same shape automatically.

Step 4

Install /morning + daily file template.

Paste Prompt 4. Installs the morning routine that reads every project hub, asks the capacity question, archives yesterday's daily file, and writes today's.

Step 5

Install /pickup and /wrapup.

Paste Prompt 5. The inside-a-session pair. /pickup orients Claude before you sit down. /wrapup writes the session note and updates the hub at the close.

About fifteen minutes of setup.

The flow is Obsidian first, Claude Code second, then point Claude Code at the vault Obsidian created.

Step 1

Install Obsidian.

Free, from obsidian.md. Open it once after install.

Step 2

Create your vault in Obsidian.

First time you open Obsidian you hit the vault picker. Click "Create new vault", give it a name, click Browse to pick where it lives on your computer, then Create. Obsidian makes the folder for you. Call it Mission Control if you want to match this resource, or anything else that feels right (your own name, your initials, Vault). You can rename later. The name only matters to you. The install doesn't depend on it.

Step 3

Enable the Bases core plugin in Obsidian.

Settings, Core plugins, toggle Bases on. Bases ships with Obsidian 1.9+ (released 2025) but is not always enabled by default. This is the engine behind your Mission Control dashboard. Without it, Mission Control opens to an empty page. Nothing else from the community plugin store is needed. Everything else the system relies on (Properties panel for frontmatter, wikilinks, backlinks, outline view) is core Obsidian, on by default.

Step 4

Install Claude Code.

Two things called Claude Code exist. You want the local one that runs on your laptop and writes files into folders on it. Not the "Code" tab inside claude.ai in a browser, that is a different product (cloud-sandboxed, works against GitHub repos, not local folders) and is not what we are using here.

Download the local one from claude.ai/code. Sign in with a Claude account. The free tier is enough for the install. Pro or Max is the comfort level for daily use.

Any current Claude model runs all of this, so you do not need the most expensive one. A faster, lighter model is fine for everyday work; save a higher-end model for the genuinely hard sessions.

Step 5

Point Claude Code at your vault folder.

Two paths. Pick whichever you prefer.

Path A

Terminal

Open your terminal. On Mac, that's Terminal or iTerm2. On Windows, that's Windows Terminal or PowerShell. Get the path to your vault folder (Mac: drag the folder from Finder onto the terminal window. Windows: Shift + right-click the folder, then "Copy as path"). Type cd followed by a space, paste the path, press Enter. Run claude.

If you see "command not found: claude", close the terminal completely and reopen a fresh one. The install added the command but already-open terminals do not see it yet. If reopening does not fix it, use Path B instead, that route uses the VS Code extension which does not depend on the terminal command.

Path B

VS Code with the Claude Code extension

More visual, less terminal. Install VS Code from code.visualstudio.com. Open the Extensions panel and install Anthropic's official Claude Code extension. File menu, Open Folder, pick your vault folder. Open the integrated terminal (Ctrl plus backtick) and run claude. Or use the extension's chat panel directly.

Friendlier terminal alternatives exist, iTerm2, Warp, others, and there are alternative IDEs too. Not covered here. The two paths above are enough to run the install.

Two tools, one shared folder.

Claude Code does the writing. It scaffolds the folder structure, installs the skills, updates files when you run /morning, /pickup, /wrapup. Obsidian does the reading. It turns the markdown files Claude writes into a navigable workspace with Properties panels, dashboards, and links between files. The files themselves are plain markdown. Open them in anything. Nothing is locked in. Your work outlives any single tool.

A vault, in Obsidian's terms, is just the folder Obsidian opens. You already made one in step 2. Claude Code is about to fill it.

 

Want some help with it? → 30 mins · Google Meet · Free

Step 1. Set up the folders and tell Claude who you are.

Paste Prompt 1 (the box below). Claude Code asks four short questions first: your name, your role, what you're trying to do and why, the rules you want Claude to work by. Then two short questions about your first project (name, next step). Then it creates the building blocks:

One paste. Six building blocks. Two minutes.

Back in Obsidian, open Mission Control.md. You should see your first project in the table. If the table is empty, the Bases plugin isn't enabled yet (Settings, Core plugins, toggle Bases on).

Vault Scaffold, About You, First Project Paste into Claude Code
Prompt 1
You are helping me set up a vault for the projects I run with Claude Code. I am not a developer. Walk slowly. Ask one question at a time. Explain what you are about to do before doing it. Never use em-dashes in anything you write.

Follow these steps in order. Do not skip ahead.

1. Greet me, then tell me: "I'll ask you four short questions about yourself so I can be useful from day one, then two about your first project. Then I'll create the folder structure, the about-you file, your first project hub, a CLAUDE.md helper, and your Mission Control dashboard. Six building blocks in one pass." Wait for my acknowledgement.

2. Ask: "What's your name?" Wait for my answer.

3. Ask: "Your role, one line, how you'd say it to someone you just met." Wait for my answer.

4. Ask: "What are you trying to do right now, and why does it matter? This is the goal above any single project, the thing that would change something real if it happened." Wait for my answer. If I give only one half (the what, not the why, or vice versa), ask the other half before moving on.

5. Ask: "How should I communicate with you, and anything I should always or never do? 'Nothing yet' is a fine answer to the second part." Wait for my answer.

6. Ask: "What do you want to call your first project? Give it as you would say it out loud." Wait for my answer.

7. Ask: "What is the very next concrete step on that project? One line." Wait for my answer.

8. Check the current working directory. Look for a `.obsidian/` folder inside it (the marker that this folder is an Obsidian vault).

   - If `.obsidian/` exists, tell me: "I'm about to write the project structure into [show the current working directory]. Looks like an Obsidian vault. Ready?" Wait for my confirmation.
   - If `.obsidian/` does not exist, tell me: "I don't see a `.obsidian/` folder here, so this might not be the vault Obsidian created. The current folder is [show cwd]. Want me to proceed anyway, or do you want to point Claude Code at your vault folder first?" Wait for my answer. If I say to proceed, continue. If I say to point Claude Code at the vault first, stop and tell me to relaunch Claude Code inside the vault folder.

9. Inside the current working directory (the vault root), create the PARA subfolder structure. Slugify the project name for the project folder (lowercase, spaces to hyphens, no punctuation):

   01-Projects/{project-slug}/sessions/
   02-Areas/
   03-Resources/
   04-Archives/
   05-Daily-Files/archive/
   06-Templates/

10. In the vault root, create `_about-you.md` with this exact content, substituting my answers:

   # About you

   _Three sections. Edit any of them whenever something shifts. The more concrete you are, the better I can calibrate._

   ## About me

   - **Name:** {name}
   - **Role:** {role}

   ## About my work

   - **What I'm trying to do right now, and why it matters:** {what-and-why}

   ## My rules

   - **How I want you to communicate, and things to always or never do:** {comms-and-rules}

11. Inside the project folder, create a hub file named "{Project Name}.md" using the original project name with title case. Populate it with the content below, substituting my answers (priority defaults to medium, both are easy to edit later). If I did not give a target date, write `target_date:` with nothing after it, rather than the word "none": the field is read as a date, and a word in it would show as a broken countdown. The template is shown indented for readability, write the file with no leading whitespace on any line.

   YAML safety rule for the `next_action` and `title` values: if the value contains a colon, hash, ampersand, asterisk, question mark, pipe, greater-than, less-than, equals, exclamation mark, percent, at-sign, backtick, or starts with `[` or `{`, wrap the whole value in single quotes. If the value already contains a single quote, double it (`it's` becomes `it''s`). Otherwise write it unquoted.

   ---
   title: {project name}
   type: project
   status: in_progress
   priority: medium
   next_action: {next step}
   target_date:
   created: {today's date in YYYY-MM-DD}
   ---

   # {Project Name}

   ## Decisions Log

   _Append decisions here as you make them. Date, decision, reasoning. Three or four entries is enough for future-you to know why the project is shaped the way it is._

   ## Notes

   _Anything that doesn't fit elsewhere._

12. Create a file called "CLAUDE.md" in the vault root (not inside any subfolder). Populate it with this exact content:

   # Project vault

   You are helping me run my project vault. I am not a developer. Walk slowly. Ask one question at a time. Explain what you are about to do before doing it. Never use em-dashes in anything you write.

   ## About you

   At the start of every session, read `_about-you.md` in full before responding substantively. Apply it as the operating filter. The goal in "About my work" is what to push back with when sessions drift. The rules in "My rules" govern how you communicate. If `_about-you.md` is missing or empty, ask me to populate it before continuing.

   ## What lives where

   - Project hubs: `01-Projects/{slug}/{Project Name}.md`. One folder per project, one hub markdown file with frontmatter (status, priority, next_action, target_date) plus a Decisions Log body section.
   - Session notes: `01-Projects/{slug}/sessions/{YYYY-MM-DD}-{slug}.md`. Written by `/wrapup` at the close of a working block.
   - Daily files: `05-Daily-Files/today.md` is today's. `05-Daily-Files/archive/{DD-MM-YY}.md` holds previous days. Written by `/morning`.
   - Templates: `06-Templates/_session-template.md` and `06-Templates/_daily-template.md`. Single source of truth for the shape of session notes and daily files. Edit these and the change applies across every project, every day. `/wrapup` reads the session template, `/morning` reads the daily template.
   - Mission Control dashboard: `Mission Control.md` at the vault root, backed by `Projects.base` (also at vault root). The .base file queries every project hub in `01-Projects/`. The .md page is the human-readable wrapper. Open Mission Control in Obsidian to see the portfolio.
   - Skills: `.claude/skills/{name}/SKILL.md` inside this vault folder. `/new-project`, `/morning`, `/pickup`, `/wrapup` install there and only work when Claude Code is launched from this vault folder. Skills travel with the vault, back it up and they come along. These four skills install via Prompts 3, 4, and 5 in the install sequence. Until those prompts have been run, the slash commands do not exist yet.

   ## Where things go inside a project

   Inside a project folder, the convention is:

   - **Drafts:** anything you're writing for an output (posts, PRDs, emails). Lives in `01-Projects/{slug}/drafts/`.
   - **Research:** articles, notes, references you're gathering on the project's topic. Lives in `01-Projects/{slug}/research/`.
   - **References:** fixed assets you keep coming back to (specs, brand docs, terminology). Lives in `01-Projects/{slug}/references/`.

   These subfolders only need to exist when there's something to put in them. Create them on the fly. If you're unsure where something belongs, ask me.

   ## How the loop works

   - `/morning` runs once a day. Reads each project hub, asks the reader what they are committing to today, writes the daily file.
   - `/pickup` runs at the start of any working block on a project. Reads the project hub plus the latest session note. Orients you for the work.
   - `/wrapup` runs at the close of a working block. Drafts what you were trying to do, the state you got to, and the next action from the session itself, shows you the draft to confirm or fix, then writes the session note and updates the hub's next_action.
   - `/new-project` adds a new project hub to the vault when the reader is ready to track another project.

   ## Common problems

   - **`/morning` says it cannot find any project hubs.** Check that `01-Projects/` exists and contains at least one folder with a markdown file inside. Each project folder must hold one hub markdown file.
   - **A skill is installed but the slash command does not appear.** First check Claude Code is running from your vault folder, not from somewhere else, since skills are scoped to this vault. Then reload Claude Code. The skill file must be at `.claude/skills/{name}/SKILL.md` exactly inside the vault. Name, folder, and file path all matter.
   - **A hub's frontmatter is not being read.** Check the YAML at the top of the hub file closes with three dashes (`---`) on their own line. Missing close = whole file parsed as YAML and silently failing.
   - **The daily file is not being archived.** Check that the existing `05-Daily-Files/today.md` has a date header line (e.g. `# Sunday 10 May 2026`) at the very top. `/morning` reads that header to figure out which date to archive under.
   - **`/wrapup` cannot find the project to write a session note for.** It infers the project from the current working directory or from a project slug you pass. If neither is clear, it will ask. Tell it the project name as it appears in `01-Projects/`.
   - **Mission Control opens to an empty page in Obsidian.** The Bases core plugin is not enabled. In Obsidian: Settings, Core plugins, toggle Bases on. Bases ships with Obsidian 1.9+ but is not always enabled by default. Reload Mission Control after enabling.
   - **A skill says the vault is not set up here.** Every skill needs Claude Code to be running inside the vault folder. Run `pwd` (Mac) or `cd` with no arguments (Windows) to see the current folder. If it is not the vault, exit Claude Code, change directory into the vault folder, and run `claude` again. Re-run the skill.
   - **Mission Control has a row that is not a project.** `/morning` and `/pickup` only treat files with `type: project` in the frontmatter as project hubs. If a row appears with empty fields, check that the file at that path has `type: project` in its frontmatter and is the intended hub, not a scratch note.

   ## How to behave

   - Walk slowly. Explain what you are about to do before doing it.
   - Ask one question at a time.
   - If a file does not exist, tell me before creating one.
   - If something does not work, check the Common Problems section above before guessing.

13. Create a file at the vault root called `Projects.base`. This is the Obsidian Bases file that queries every project hub in the vault. The Bases plugin (core in Obsidian 1.9+) renders this as a live table. Write the file with the content below. No leading whitespace on any line. The content is shown indented here purely for readability.

   filters:
     and:
       - file.hasProperty("type")
       - type == "project"
       - file.folder.contains("01-Projects")
   properties:
     status:
       displayName: Status
     priority:
       displayName: Priority
     next_action:
       displayName: Next action
     target_date:
       displayName: Target date
   views:
     - type: table
       name: All projects
       order:
         - file.name
         - status
         - priority
         - next_action
         - target_date

14. Create a file at the vault root called `Mission Control.md`. This is the human-readable dashboard page. It embeds the Base view so the reader opens one file to see the whole portfolio. Write the file with this exact content. No leading whitespace on any line. Content shown indented here for readability.

   # Mission Control

   The portfolio dashboard. Every project hub appears below, surfaced through `Projects.base`. Status and next action stay live because `/wrapup` writes both back at the close of every working block. Priority and target date are yours to set in the hub, and stay where you put them.

   ![[Projects.base]]

   ## How to use this

   Open Mission Control first thing each morning. Scan the next-action column across the portfolio before running `/morning`. The dashboard tells you what is outstanding. `/morning` makes you commit to one chunk of it. If a project has not moved in a fortnight, that is a `/pickup` worth running to see whether it still belongs in the active set.

   This page reads the same hubs your skills already read. Same source, two readers.

15. Confirm what you created. Show me the folder tree, then the contents of `_about-you.md`, then the project hub, then `CLAUDE.md`, then `Projects.base`, then `Mission Control.md`.

16. Tell me: "Six building blocks in. Two next steps: (1) In Obsidian, open `_about-you.md` and read it through. Make sure it sounds like you. That file is the operating filter I'll read at every session. (2) In Obsidian, open `Mission Control.md`. You should see your first project in the table. (If the table is empty, the Bases core plugin isn't enabled yet, Settings, Core plugins, toggle Bases on.) Come back when you're ready for Prompt 2 (session note template)." Then stop. Do not create anything else.
Why this works

The reframe sits underneath everything else in this resource and it's worth naming early: context is the asset. Most AI setups treat context as input. You open a chat, paste the situation, explain what you've been working on, and start working. When the chat ends, the context goes with it. Tomorrow you do it all again.

That's the wrong shape. The context is the thing that took the longest to build. The decisions you've made on a project, the trade-offs you've considered, the things you've already ruled out, the people involved, the constraints you can't move. All of it accumulated. None of it disposable. If a junior PM joined the project tomorrow, the first two weeks would be them rebuilding what's already in your head.

Step 1 makes the context durable. The _about-you.md file holds the operating filter Claude reads every session, so its tone and recommendations fit your work from day one. The project hub holds the cumulative state of one project. The CLAUDE.md helper file makes the vault legible to Claude Code automatically. None of it lives inside a chat. All of it survives.

This also ages well. The better the models get, the more they make of a durable setup like this, files they can read, rather than a long chat to wade back through. A system you own keeps paying off as the tools move on.

Create the session note template.

Paste Prompt 2. Claude Code creates the session note template at 06-Templates/_session-template.md. Three sections: goal, current state, next action. Single source of truth, read by /wrapup for every project.

One paste. One file. Thirty seconds.

Session Note Template Paste into Claude Code
Prompt 2
You are helping me add a session note template to my project vault. The vault scaffold already exists from Prompt 1. Walk slowly.

Follow these steps in order.

1. Tell me: "I am about to create the session note template at `06-Templates/_session-template.md`. This is the single source of truth `/wrapup` will read every time it writes a session note, for every project. Edit it later and every future session note picks up the change. Ready?" Wait for my confirmation.

2. From the current working directory, check that `06-Templates/` exists. If it does not, tell me the vault does not appear to be set up here and stop.

3. Inside `06-Templates/`, create a file called `_session-template.md` with the content below. Leave `{Project Name}`, `{YYYY-MM-DD}`, and `{short session label}` as literal placeholders. `/wrapup` will substitute all three when it writes real session notes. The template below is shown indented for readability, write the file with no leading whitespace on any line.

   ---
   type: session
   date: {YYYY-MM-DD}
   related_to: '[[{Project Name}]]'
   ---

   # {Project Name}, {short session label}

   ## Goal

   What you were trying to do this session. One or two lines.

   ## Current state

   Where things stand right now. The state tomorrow-you walks into.

   ## Next

   The very next concrete action. One line. Specific enough that tomorrow-you can act without re-reading anything else.

4. Confirm the template was written. Show me the file path and the contents. Then stop. Do not create any session notes yet, those get written by `/wrapup` once the skills are installed in later prompts.
Why this works

The session note is where progress lives, per project. The daily file holds today's intent. The session note holds what actually moved. Separating the two stops the daily file from becoming a progress log nobody reads, and it stops the project hub from being the only place forty sessions of detail get crammed into.

When /pickup runs at the start of a working block (Step 5), it reads the most recent session note plus the hub. The session note holds the conversational thread, where you got to last time, what you were partway through. The hub holds the structural state, status, next action, decisions made so far. Two readers, two purposes, one consistent template.

The template is small on purpose. Three sections, no frontmatter beyond what /pickup and /wrapup will write automatically. Anything bigger gets ignored. Anything smaller fails to carry the working state across sessions. This shape sits at the floor of what works.

Install /new-project.

Paste Prompt 3. Claude Code writes a SKILL.md file to .claude/skills/new-project/. After install, you type /new-project whenever you're starting something new. The skill scaffolds a new project hub with consistent frontmatter, the right folder structure, and a starting decisions log.

One paste. One skill installed. After that, every new project gets the same shape automatically.

/new-project Skill Paste into Claude Code
Prompt 3
You are installing a Claude Code skill called `/new-project` for me. I am not a developer. Walk slowly. Explain what you are about to do before doing it.

Follow these steps in order.

1. Tell me: "I am about to create a folder at `.claude/skills/new-project/` and write a SKILL.md file inside it. This installs the `/new-project` slash command in Claude Code. After this runs, you can type `/new-project` in any Claude Code session to create a new project hub in your vault. Ready?" Wait for my confirmation.

2. Create the folder `.claude/skills/new-project/` if it does not exist.

3. Write the file `.claude/skills/new-project/SKILL.md` with this exact content:

   ---
   name: new-project
   description: Create a new project hub in the project vault. Use when the user says 'new project', 'add a project', or '/new-project'. Asks for project name, priority, next action, target date. Creates the project folder, sessions subfolder, and hub markdown file with frontmatter and decisions log section.
   ---

   # New project

   You are helping the user add a new project hub to their project vault. Walk slowly. Ask one question at a time.

   Follow these steps in order.

   1. Ask: "What is the name of the project? Give it as you would say it out loud." Wait for the answer.

   2. Ask: "Priority, high, medium, or low?" Wait for the answer.

   3. Ask: "What is the very next concrete step on this project? One line." Wait for the answer.

   4. Ask: "Target date you would like this project done by? Format YYYY-MM-DD, or say 'none'." Wait for the answer. If the user says none, leave the `target_date` field empty in step 8 rather than writing the word "none": the dashboard reads that field as a date, and a word in it renders a broken countdown.

   5. Slugify the project name (lowercase, spaces to hyphens, no punctuation).

   6. From the current working directory, check that `01-Projects/` exists. If it does not, tell the user the vault does not appear to be set up here and stop.

   7. Create the folder `01-Projects/{slug}/sessions/`. Leave it empty. The session note template lives at `06-Templates/_session-template.md` (created by Prompt 2) and is read by `/wrapup` for every project, so no per-project template file is needed.

   8. Write the hub file at `01-Projects/{slug}/{Project Name}.md` (use the original name with title case for the filename) with the content below, substituting the user's answers. The template is shown indented for readability, write the file with no leading whitespace on any line.

      YAML safety rule for `next_action` and `title`: if the value contains a colon, hash, ampersand, asterisk, question mark, pipe, greater-than, less-than, equals, exclamation mark, percent, at-sign, backtick, or starts with `[` or `{`, wrap the whole value in single quotes. If the value already contains a single quote, double it. Otherwise write it unquoted.

      ---
      title: {project name}
      type: project
      status: in_progress
      priority: {priority answer}
      next_action: {next step answer}
      target_date: {target date answer, or leave empty if the user said none}
      created: {today's date in YYYY-MM-DD}
      ---

      # {Project Name}

      ## Decisions Log

      _Append decisions here as you make them. Date, decision, reasoning._

      ## Notes

      _Anything that doesn't fit elsewhere._

   9. Confirm what was created. Show the user the hub file path and contents. Then stop.

4. Confirm the skill was installed. Show me the file path of the SKILL.md you just wrote. Tell me: "To test it, exit this Claude Code session and start a fresh one in the same vault folder, then type `/new-project`. New skills only show up after a Claude Code reload." Then stop.
Why this works

The vault has to be machine-readable as well as human-readable. The reason the dashboard you'll build later (Mission Control) works without anyone refreshing it is that every project hub has the same four frontmatter fields in the same format. If one hub has status: and another has Status: and a third has current_status:, the dashboard stops being a dashboard and starts being a guessing game.

/new-project removes that variance. The structure is set once, inside the skill, and every new project inherits it. The naming conventions, the frontmatter, the path layout. Consistent enough for a skill to navigate, light enough that you don't notice the discipline.

The architecture sitting underneath is PARA, extended. Tiago Forte's Projects-Areas-Resources-Archives is the scaffold. The extensions stay inside Projects (hubs, session note folders) and the daily-files folder. PARA on its own holds documents. The extensions hold the state a portfolio system needs: per-project hubs the dashboard reads, session note folders the pickup and wrapup skills write to, daily files the morning routine manages.

Install /morning and create the daily file template.

Paste Prompt 4. Claude Code writes the /morning skill to .claude/skills/morning/ and creates the daily file template. After install, you type /morning at the start of every day. The skill reads each project hub, surfaces what's outstanding across the portfolio, asks the capacity question, and writes today's daily file with your commitments plus the reasoning. Yesterday's daily file gets archived automatically.

One paste. One skill installed. One template created. From tomorrow morning, the routine runs.

/morning Skill Paste into Claude Code
Prompt 4
You are installing a Claude Code skill called `/morning` and creating the daily file template. I am not a developer. Walk slowly.

Follow these steps in order.

1. Tell me: "I am about to create the daily file template at `06-Templates/_daily-template.md` in your vault, then install a Claude Code skill at `.claude/skills/morning/SKILL.md`. After this runs, you can type `/morning` each morning to populate today's daily file. The template is the single source of truth `/morning` reads every time, edit it later and every future daily file picks up the change. Ready?" Wait for my confirmation.

2. From the current working directory, check that `05-Daily-Files/` and `06-Templates/` both exist. If either is missing, tell me the vault does not appear to be set up here and stop.

3. Write the file `06-Templates/_daily-template.md` with this exact content:

   # {Day} {DD} {Month} {YYYY}

   ## Today's commitment

   {The one chunk of work you are committing to today.}

   ## Reasoning

   {Why this and not the other things on your list.}

   ## Deferred

   {What you are saying no to today, and why.}

4. Create the folder `.claude/skills/morning/` if it does not exist.

5. Write the file `.claude/skills/morning/SKILL.md` with this exact content:

   ---
   name: morning
   description: Daily morning routine for the project vault. Use when the user says 'morning', 'good morning', or '/morning'. Reads the next_action from every project hub. Archives yesterday's daily file if one exists. Asks the user what they are committing to today, the reasoning, and what they are deferring. Writes today's daily file.
   ---

   # Morning routine

   You are helping the user run their morning routine. Walk slowly. Ask one question at a time.

   Follow these steps in order.

   1. From the current working directory, check that `01-Projects/`, `05-Daily-Files/`, and `06-Templates/_daily-template.md` all exist. If any is missing, tell the user the vault does not appear to be set up here and stop.

   2. Find every project hub. Read every markdown file matching `01-Projects/{*}/{*.md}`, and skip any whose frontmatter does not contain `type: project`. This filters out scratch notes the user may have dropped at a project folder root. From the remaining files, pull the `title` and `next_action` frontmatter fields. Show the user a numbered list:

      Today's project list:
      1. {Project title}: {next_action}
      2. ...

   3. Check whether `05-Daily-Files/today.md` exists.

      - If it does, read its first line (the date header, e.g. `# Sunday 10 May 2026`). Convert that date to `DD-MM-YY` format. Move the file to `05-Daily-Files/archive/{DD-MM-YY}.md`. If a file already exists at that archive path, overwrite it.
      - If it does not exist, skip this step.

   4. Ask: "Which one chunk of work are you committing to today? Give me the project name and what you are doing on it. One line." Wait for the answer.

   5. Ask: "What is the reasoning, why this and not the other things on the list?" Wait for the answer.

   6. Ask: "What are you deferring today, and why? One or two lines." Wait for the answer.

   7. Write `05-Daily-Files/today.md` using the template at `06-Templates/_daily-template.md`. Substitute today's date in the header (format: `# {Day} {DD} {Month} {YYYY}`), and the user's three answers in the three sections.

   8. Confirm the file was written. Show the user the file path and contents. Then stop.

6. Confirm the skill was installed and the template was written. Show me both file paths. Tell me: "To test it, exit this Claude Code session and start a fresh one in the same vault folder, then type `/morning`. New skills only show up after a Claude Code reload." Then stop.
Why this works

This is the step that gives you the hour back. The morning routine does three things you'd otherwise do yourself, badly, in twenty-minute chunks across the early morning.

First, it reads. Every project hub, and the next action sitting on each one. Across the portfolio. Before you've made a coffee.

Second, it asks the question the routine can't answer for you: out of everything that's outstanding, what's the one chunk of work you're committing to today? The capacity question forces you to pick. One chunk you can actually finish well, not seven half-attempts. The choice goes into the daily file with the reasoning attached, so future-you remembers what you decided and why the rest waited.

Third, it archives. Yesterday's daily file is closed and stored. Today's is fresh. The lifecycle is automatic, so the daily-files folder doesn't grow into a graveyard you'll never clean.

The daily file then sits open in Obsidian through the day. You read it more than you write it. Every time a meeting pulls you off track, you come back to it. Every time something new lands, you check it against the morning's commitment. By end of day the page is roughly the shape /morning created it in. The reading is what pays back. Writing once is the easy part. Claude writes the file. Obsidian renders it. You live alongside it.

Mission Control surfaces options. The morning routine challenges me on capacity. The daily file holds what I committed to. Three surfaces, three jobs. Each one knows what to read and what to write.

Install /pickup and /wrapup.

Paste Prompt 5. Claude Code writes /pickup to .claude/skills/pickup/ and /wrapup to .claude/skills/wrapup/. They install as a paired set. After install, you type /pickup at the start of every working block on a project, and /wrapup at the close.

One paste. Two skills installed. From your next working block, the inside-a-session loop runs.

/pickup + /wrapup Skills Paste into Claude Code
Prompt 5
You are installing two Claude Code skills called `/pickup` and `/wrapup`. I am not a developer. Walk slowly.

Follow these steps in order.

1. Tell me: "I am about to install two Claude Code skills, `/pickup` and `/wrapup`. `/pickup` runs at the start of any working block on a project. It reads the project hub and the latest session note, so Claude is oriented for the work. `/wrapup` runs at the close of a working block. It writes the session note, updates the project hub's next_action, and optionally appends to the decisions log. Ready?" Wait for my confirmation.

2. Create the folder `.claude/skills/pickup/` if it does not exist.

3. Write the file `.claude/skills/pickup/SKILL.md` with this exact content:

   ---
   name: pickup
   description: Resume work on a project in the project vault. Use when the user says 'pickup', 'pick up', 'resume', or '/pickup [project-name]'. Works out the project from the argument or the folder, then reads the hub and the latest session note and summarises last state and next action. Only asks the user whether to continue or take it somewhere different.
   ---

   # Pickup

   You are helping the user pick up work on one of their projects. Walk slowly.

   Follow these steps in order.

   1. Take the project name passed by the user as an argument, if any. If no argument was given, look at the folders in `01-Projects/`. If exactly one folder exists, use that project. Otherwise list the project folders and ask: "Which project are we picking up?" Wait for the answer.

   2. Slugify the project name (lowercase, spaces to hyphens, no punctuation). Verify `01-Projects/{slug}/` exists. If it does not, tell the user it cannot be found and stop.

   3. Find the hub file. Read every markdown file matching `01-Projects/{slug}/{*.md}` at the project folder root, and pick the one whose frontmatter contains `type: project`. That is the hub. Pull the frontmatter (status, priority, next_action, target_date). If no file matches, tell the user no hub was found in that project folder and stop.

   4. List the markdown files in `01-Projects/{slug}/sessions/`, ignoring any that start with an underscore (those are templates). Sort the rest by name ascending. Session notes are named `{YYYY-MM-DD}-{slug}.md` so this sorts by date. Take the last one in the list (most recent date).

   5. If a session note exists, read it. Show the user a short summary in this shape:

      Last session ({date from session note frontmatter or filename}):
      Where you got to: {Current state section}
      Next: {Next section}

      Hub next_action: {next_action from frontmatter}

   6. If no session note exists, tell the user this is the first session on this project. Show the hub's next_action and the Decisions Log.

   7. Ask: "Continue with that, or are you taking it somewhere different today?" Wait for the answer. Use the answer to set the working context for the rest of the conversation. If the answer turns on a past decision, for example the user asks why something was chosen, open the hub's Decisions Log and read the relevant entry. Do not write anything to disk in this step.

4. Create the folder `.claude/skills/wrapup/` if it does not exist.

5. Write the file `.claude/skills/wrapup/SKILL.md` with this exact content:

   ---
   name: wrapup
   description: Close a working block on a project. Use when the user says 'wrapup', 'wrap up', or '/wrapup'. Drafts the session note from what happened this session (reading the conversation, the latest session note, and the hub), then shows it to the user to confirm or correct. Only asks about what it cannot work out. Writes the session note. Updates the project hub's next_action. Optionally appends a decisions log entry.
   ---

   # Wrapup

   You are helping the user close a working block on one of their projects. Walk slowly.

   The point of this skill: you were in the session, so you already know most of what a session note needs. Work it out from the conversation first. Only ask the user about things you genuinely cannot tell, and never make the user retype something you already have.

   Follow these steps in order.

   1. Identify which project this session was on. If `/pickup` was run earlier in this conversation, use that project. Otherwise look at the folders in `01-Projects/`. If exactly one folder exists, use that project. Otherwise ask: "Which project are we wrapping up?" Wait for the answer.

   2. Slugify the project name. Verify `01-Projects/{project-slug}/sessions/` exists.

   3. Read the context you already have, in order: (a) this conversation, what the user worked on, decided, and got stuck on; (b) the most recent session note in `01-Projects/{project-slug}/sessions/` if one exists, for what the last "Next" was; (c) the hub's current next_action; (d) `05-Daily-Files/today.md` if it exists, for what the user committed to this morning.

   4. From that context, draft the session note yourself: the Goal (what this session set out to do), the Current state (where things actually stand now, in a sentence or two, since this is the part `/pickup` reads next time, so keep it short and concrete), the Next (the single most concrete next action for when the user sits back down, one line), plus any decisions or calls made during the session that future-you would need to know.

      Also work out where the project now stands, using exactly one of these five values:

      - `in_progress`: work is live and the user can pick it straight back up. This is the normal case, and the default when nothing in the session says otherwise.
      - `blocked`: something is stopping the work and it is not in the user's hands to unstick right now (a bug they cannot get past, a decision they are not the one to make).
      - `waiting`: the work is parked on someone else (a reply, a review, an approval, a delivery). The distinction from blocked is who holds it.
      - `paused`: the user has deliberately shelved the project for now. Nothing is stopping it, they have chosen to put it down. A paused project stops being flagged as gone quiet.
      - `done`: the project's goal has actually been met, not just this session's.

      Work this out from the session the same way you worked out the Next, and do not ask the user unless the session genuinely leaves it unclear (for example, they hit a wall and it is not obvious whether they are stuck or waiting on someone). If you are unsure, ask one plain question: "Is this one blocked, waiting on someone, paused, or just carrying on?" Never ask when the session already answers it.

   5. Show the user your draft, in this shape:

      "Here is what I captured from this session. Tell me what to fix, or say 'looks good'.
      Goal: {drafted goal}
      Current state: {drafted current state}
      Next: {drafted next}
      Status: {drafted status}
      Decisions: {decisions you spotted, or 'none spotted'}"

      Wait for the answer and apply any corrections. Only ask a direct question about a section if you genuinely could not work it out from the session, for example if almost no work happened this block. Do not re-ask sections you already drafted well.

   6. Write the session note at `01-Projects/{project-slug}/sessions/{YYYY-MM-DD}-{short-slug}.md`, using today's date and a 3-4 word slug from the Goal. Use the template at `06-Templates/_session-template.md` if it exists, otherwise this shape:

      ---
      type: session
      date: {YYYY-MM-DD}
      related_to: '[[{Project Name}]]'
      ---

      # {Project Name}, {short label from Goal}

      ## Goal

      {Goal answer}

      ## Current state

      {Current state answer}

      ## Next

      {Next answer}

   7. Update the project hub's frontmatter: set `next_action` to match the Next, and set `status` to the value confirmed in step 5 (one of `in_progress`, `blocked`, `waiting`, `paused`, `done`). Leave every other field alone: `priority`, `target_date` and `created` are the user's to set, not yours.

      YAML safety rule when writing the new value: if the Next answer contains a colon, hash, ampersand, asterisk, question mark, pipe, greater-than, less-than, equals, exclamation mark, percent, at-sign, backtick, or starts with `[` or `{`, wrap the whole value in single quotes. If the value already contains a single quote, double it (`it's` becomes `it''s`). Otherwise write it unquoted. Skipping this rule breaks the hub's frontmatter and the dashboard goes silently empty.

   8. If any decisions were captured (drafted in step 4, confirmed in step 5), append them to the project hub's Decisions Log body section in this shape, with today's date:

      - **{YYYY-MM-DD}:** {decision text}

      Placeholder handling: the initial Decisions Log written by Prompt 1 or `/new-project` contains a single italic placeholder line starting with an underscore (`_Append decisions here as you make them..._`). If that placeholder is still present and there are no real decision entries yet, replace the placeholder with the new decision entry. Otherwise insert the new entry above the most recent existing entry, so the log stays in reverse chronological order (newest first).

   9. Confirm what was written. Show the user the session note path, the updated hub `next_action`, and any decisions appended. Then stop.

6. Confirm both skills were installed. Show me both SKILL.md file paths. Tell me: "To test them, exit this Claude Code session and start a fresh one in the same vault folder. Type `/pickup` at the start of your next working block, and `/wrapup` at the close. New skills only show up after a Claude Code reload." Then stop.
Why this works

/pickup is the one that loads the context before you sit down. Type it at the start of a working block on a project. Claude reads the project hub and the most recent session note in under a minute: where you got to last time and the next concrete action. The decisions log and the older notes stay in the files, ready when the work calls for them. The first ten minutes you used to lose handing context over is gone. It comes from the files now, not from your memory. Claude opens with "do you want to continue with this?" rather than "what are we working on today?"

/wrapup is the one that keeps the next action current without anyone touching it. Type it at deliberate session ends. Switching projects. End of day. Hitting a natural stopping point. The skill writes a fuller record into the session note, and updates the project hub with the concrete next step you identified. It also works out where the project now stands, whether it's carrying on, blocked, waiting on someone, paused or done, from what actually happened in the session, and only asks you if the session genuinely leaves it unclear. That's what keeps "needs attention" honest without you maintaining it. If you made a call during the session, a new entry hits the decisions log in the hub body. Priority and target date stay where you set them.

That's how the loop closes. /wrapup writes the next action back to the hub. Tomorrow's /morning reads the hubs and surfaces the new next actions. Mission Control reads the same hubs every time you open it in Obsidian. The next-action column refreshes itself across the portfolio as a side effect of the workflow. The dashboard doesn't go stale because the field it depends on gets written every time you close a session.

Intent lives daily. Progress lives per-project. The daily file holds what you committed to. The session notes and the hubs hold what actually moved. Two readers, one consistent shape underneath.

Verify the install.

Reload Claude Code first. It only scans for new skills at startup. In the terminal, /exit then claude again from the vault folder. In the VS Code extension, Command Palette (Cmd+Shift+P on Mac, Ctrl+Shift+P on Windows), Reload Window.

Then check the four slash commands appear. Type / in the fresh session. The dropdown should show /new-project, /morning, /pickup, /wrapup. If none show, Claude Code isn't running from inside the vault folder. That's the only thing it needs.

A visual dashboard, inside Obsidian.

Here is the part people do not expect: Obsidian can render a full visual dashboard, right there in the app your notes already live in. No separate tool, no website, no export. The core install gives you a live table, which is all most people need. This optional upgrade turns that same Mission Control page into a proper board, drawn straight from your own markdown: status-coloured project cards, a portfolio stat strip, and small charts, all refreshing themselves from the hubs you already have. It is the one part that uses a community plugin, so it sits outside the core five prompts. Skip it and everything above still works exactly the same.

What you get: a header that flags any hub that has gone quiet, four stat tiles (active projects, what needs attention, open tasks, and decisions this week), a projects-by-status breakdown, an activity chart, today's commitment, and a card for every project. One page, opened in Obsidian, current every time.

The Mission Control visual dashboard: a header with an all-hubs-current badge, four stat tiles, a projects-by-status breakdown, an activity chart, today's commitment, and a card per project.
What Level 2 builds: the same hubs you already have, rendered as a live visual dashboard.

One rule it holds to: every number on it is current-state or this-week.

First, install Dataview.

One community plugin does the drawing. In Obsidian: open Settings, click Community plugins, click Turn on community plugins if it asks, click Browse, search for Dataview, click Install, then click Enable. That is the only plugin the whole system uses. Prompt 6 checks it is on before it does anything, and tells you exactly what to click if it is not, so you cannot end up with a half-built dashboard.

Then paste Prompt 6.

Claude Code adds the dashboard to Mission Control.md, gives new projects a Tasks checklist and a last_updated field, updates /wrapup to keep last_updated current, and writes a short troubleshooting list into your CLAUDE.md. That last part matters: because you are working inside Claude Code, if the dashboard ever looks wrong, you can just say so and Claude reads those notes and fixes it. One paste, then two small edits it walks you through for your existing projects.

Visual Dashboard Paste into Claude Code
Prompt 6
You are adding an optional visual dashboard to my Mission Control vault. It uses the Dataview community plugin. I am not a developer, I am running you inside Claude Code in my vault folder. Walk slowly. Explain what you are about to do before doing it. After each step, check your own work, and if something looks wrong, fix it before moving on. Never use em-dashes.

Follow these steps in order. Do not skip ahead.

1. Tell me what you are about to do and wait for my confirmation:
   "I will (1) check the Dataview plugin is on, (2) add a visual dashboard to Mission Control.md, (3) give new projects a Tasks checklist and a last_updated field, (4) update /wrapup to keep last_updated current, and (5) add a few troubleshooting notes to CLAUDE.md so any future session can fix the dashboard. The core install stays untouched. Ready?"

2. Check the Dataview plugin is enabled. Read `.obsidian/community-plugins.json` in the vault root.
   - If that file exists and its list contains "dataview", the plugin is on. Continue.
   - If the file is missing, or it does not contain "dataview", STOP and tell me, word for word: "The dashboard needs the Dataview plugin, which is not on yet. In Obsidian: open Settings, click Community plugins, click 'Turn on community plugins' if you see that button, click Browse, search Dataview, click Install, then click Enable. Tell me once it is enabled and I will carry on." Wait for me. When I reply, read `.obsidian/community-plugins.json` again to confirm before continuing. Do not proceed until "dataview" is in that file.

3. Check `Mission Control.md` exists at the vault root. If it does not, tell me the core install (Prompt 1) has not run yet, and stop.

4. Open `Mission Control.md`. Find the line `![[Projects.base]]`. Directly ABOVE it, insert the dataviewjs block below exactly as written, followed by a blank line. Do not change a character of the code. It is shown indented for readability, write it with no leading whitespace on any line. After writing, read the file back and confirm the block is present and the ```dataviewjs fence and closing ``` are both there.

   ```dataviewjs
   // Mission Control visual dashboard. Needs the Dataview plugin.
   const FOLDER = '"01-Projects"';
   const all = dv.pages(FOLDER).where(p => p.type === "project" && p.status !== "done");
   const projects = all.sort(p => { const o={in_progress:1,blocked:2,waiting:3,paused:4}; return o[p.status]||9; });

   const statusColour = { in_progress:"#06D6A0", blocked:"#EF476F", waiting:"#F4A261", paused:"#A8A8A8" };
   const today = dv.date("today");
   // Guard: a hub may hold a non-date value (e.g. target_date: none) or an unsubstituted
   // placeholder. dv.date() returns an invalid DateTime for those, which would render NaN.
   const asDate = (d) => { if (!d) return null; try { const dt = dv.date(d); return (dt && dt.isValid) ? dt : null; } catch { return null; } };
   const daysSince = (d) => { const dt = asDate(d); return dt ? Math.floor(today.diff(dt,"days").days) : null; };
   const daysUntil = (d) => { const dt = asDate(d); return dt ? Math.floor(dt.diff(today,"days").days) : null; };
   const el = (parent, tag, text, css) => { const e = parent.createEl(tag, text!==undefined?{text:String(text)}:{}); if(css) e.style.cssText=css; return e; };

   // ---------- HEADER STRIP ----------
   const header = dv.container.createEl("div");
   header.style.cssText = "display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;flex-wrap:wrap;gap:8px;";
   const hleft = header.createEl("div");
   el(hleft, "div", today.toFormat("cccc, d LLLL"), "font-size:15px;font-weight:600;");
   el(hleft, "div", "Your projects, from their hubs", "font-size:12px;color:#8a8578;");
   const stale = all.where(p => p.status!=="paused").where(p => { const d=daysSince(p.last_updated); return d===null || d>7; }).length;
   const badge = header.createEl("div");
   if (stale === 0) { badge.textContent = "✓ All hubs current"; badge.style.cssText="background:#e6f7ef;color:#06a37a;font-size:12px;font-weight:600;padding:6px 12px;border-radius:8px;"; }
   else { badge.textContent = `${stale} need a look`; badge.style.cssText="background:#fdeee6;color:#c86a2b;font-size:12px;font-weight:600;padding:6px 12px;border-radius:8px;"; }

   // ---------- STAT TILES (current-state / this-week only) ----------
   const countBy = (s) => all.where(p=>p.status===s).length;
   const active = all.where(p => ["in_progress","blocked","waiting"].includes(p.status)).length;
   const needsAttn = countBy("blocked") + countBy("waiting");
   const openTasks = dv.pages(FOLDER).where(p=>p.type==="project").file.tasks.where(t=>!t.completed).length;
   // Decisions THIS WEEK: dated bullets under a Decisions Log heading, date within 7 days.
   const decisionsWk = dv.pages(FOLDER).where(p=>p.type==="project").file.lists
     .where(l => (l.section?.subpath||"").toLowerCase().includes("decision"))
     .where(l => { const m = (l.text||"").match(/(\d{4}-\d{2}-\d{2})/); if(!m) return false; const d = daysSince(m[1]); return d!==null && d<=7; }).length;

   const stats = [
     {label:"Active projects",   value:active,        sub:"all live"},
     {label:"Needs attention",   value:needsAttn,     sub:"blocked / waiting"},
     {label:"Open tasks",        value:openTasks,     sub:"across hubs"},
     {label:"Decisions this week",value:decisionsWk,  sub:"logged"},
   ];
   const tiles = dv.container.createEl("div");
   tiles.style.cssText="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;margin-bottom:16px;";
   for (const s of stats){
     const t = el(tiles,"div",undefined,"background:#fff;border:1px solid #eae7df;border-radius:10px;padding:14px 16px;");
     el(t,"div",s.label,"font-size:11px;color:#8a8578;text-transform:uppercase;letter-spacing:0.5px;margin-bottom:6px;");
     el(t,"div",s.value,"font-size:30px;font-weight:700;line-height:1;color:#1a1a1a;font-family:Georgia,serif;");
     el(t,"div",s.sub,"font-size:11px;color:#06a37a;margin-top:6px;");
   }

   // ---------- 3-PANEL ROW ----------
   const row = dv.container.createEl("div");
   row.style.cssText="display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px;margin-bottom:16px;";
   const panel = (title) => { const p=el(row,"div",undefined,"background:#fff;border:1px solid #eae7df;border-radius:10px;padding:14px 16px;"); el(p,"div",title,"font-size:13px;font-weight:600;margin-bottom:10px;"); return p; };

   // Projects by status
   const pStatus = panel("Projects by status");
   const statuses = [["in_progress","In progress"],["blocked","Blocked"],["waiting","Waiting"],["paused","Paused"]];
   const maxC = Math.max(1, ...statuses.map(([s])=>countBy(s)));
   for (const [s,lbl] of statuses){
     const c = countBy(s);
     const r = el(pStatus,"div",undefined,"display:flex;align-items:center;gap:8px;margin-bottom:6px;font-size:12px;");
     el(r,"div",lbl,"width:80px;color:#555;");
     const barbg = el(r,"div",undefined,"flex:1;background:#f0eee7;height:10px;border-radius:3px;overflow:hidden;");
     el(barbg,"div",undefined,`background:${statusColour[s]};height:100%;width:${c/maxC*100}%;`);
     el(r,"div",c,"width:20px;text-align:right;color:#333;font-weight:600;");
   }

   // Activity this week (sessions per day, last 7 days)
   const sessions = dv.pages(FOLDER).where(p=>p.type==="session");
   const pAct = panel("Activity this week");
   const buckets = [];
   for (let i=6;i>=0;i--){
     const day = today.minus({days:i});
     const n = sessions.where(s => s.file.day && s.file.day.toFormat("yyyy-MM-dd")===day.toFormat("yyyy-MM-dd")).length;
     buckets.push({label:day.toFormat("ccc")[0], n});
   }
   const maxB = Math.max(1, ...buckets.map(b=>b.n));
   const chart = el(pAct,"div",undefined,"display:flex;align-items:flex-end;gap:6px;height:70px;");
   for (const b of buckets){
     const col = el(chart,"div",undefined,"flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;gap:4px;");
     el(col,"div",undefined,`width:100%;background:#06D6A0;border-radius:3px 3px 0 0;height:${Math.max(4,b.n/maxB*52)}px;`);
     el(col,"div",b.label,"font-size:10px;color:#999;");
   }
   el(pAct,"div","sessions per day","font-size:10px;color:#aaa;margin-top:6px;");

   // Today's commitment (reads the daily file /morning writes)
   // Reads the PROSE under "## Today's commitment" — /morning writes one line, not bullets.
   const pPri = panel("Today's commitment");
   let shown = false;
   try {
     const raw = await dv.io.load("05-Daily-Files/today.md");
     if (raw) {
       const m = raw.match(/##\s*Today's commitment\s*\n([\s\S]*?)(?=\n##\s|$)/i);
       const body = m ? m[1].split("\n").map(s=>s.trim()).filter(Boolean).join(" ") : "";
       if (body && !body.startsWith("{")) {
         const r = el(pPri,"div",undefined,"display:flex;gap:8px;margin-bottom:6px;font-size:12px;");
         el(r,"div","1","background:#c05a2b;color:white;width:18px;height:18px;border-radius:50%;text-align:center;font-size:11px;flex-shrink:0;line-height:18px;");
         el(r,"div",body,"color:#333;line-height:1.3;");
         shown = true;
       }
     }
   } catch (e) { /* falls through to the message below */ }
   if (!shown) el(pPri,"div","No commitment in today.md yet. Run /morning, or check the file has a \"## Today's commitment\" section.","font-size:12px;color:#999;");

   // ---------- PROJECT CARDS ----------
   const grid = dv.container.createEl("div");
   grid.style.cssText="display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:12px;";
   if (!projects.length) el(grid,"div","No active projects yet. Run /new-project to add one.","color:#888;font-size:13px;");
   for (const p of projects){
     const card = el(grid,"div",undefined,`border:1px solid #e5e5e5;border-left:4px solid ${statusColour[p.status]||'#ccc'};border-radius:8px;padding:12px;background:#fafafa;cursor:pointer;`);
     card.addEventListener("click", () => app.workspace.openLinkText(p.file.path,"",true));
     const hd = el(card,"div",undefined,"display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:6px;gap:8px;");
     el(hd,"div",p.file.name,"font-weight:600;font-size:14px;");
     const pills = el(hd,"div",undefined,"display:flex;gap:4px;flex-shrink:0;");
     const ds = daysSince(p.last_updated);
     if (ds!==null){ const c=ds<=3?"#06D6A0":ds<=7?"#F4A261":"#EF476F"; el(pills,"span",`${ds}d ago`,`background:${c};color:white;font-size:10px;padding:2px 6px;border-radius:3px;`); }
     const du = daysUntil(p.target_date);
     if (du!==null){ const c=du<0?"#EF476F":du<=14?"#F4A261":"#888"; el(pills,"span",du<0?`${Math.abs(du)}d overdue`:`${du}d to target`,`border:1px solid ${c};color:${c};font-size:10px;padding:2px 6px;border-radius:3px;`); }
     el(card,"div",`${p.status} · ${p.priority||'no priority'}`,"font-size:11px;color:#666;margin-bottom:8px;text-transform:uppercase;letter-spacing:0.5px;");
     const na = p.next_action||"no next action set";
     el(card,"div",na.length>200?na.slice(0,200)+"…":na,"font-size:12px;color:#222;line-height:1.4;");
   }
   ```

5. Open `.claude/skills/new-project/SKILL.md`. In the hub template it writes (the indented block starting with `---` and `type: project`), make two additions so future projects feed the dashboard, then save:
   - Add `last_updated: {today's date in YYYY-MM-DD}` to the frontmatter, directly under `type: project`, so a new hub is current from the moment it is created. Step 6 makes /wrapup keep it current from then on.
   - Add a `## Tasks` section to the body, above `## Notes`. Under the heading write only this italic placeholder line, and no checkboxes at all:

     _Add tasks here as checkboxes. The dashboard counts the unticked ones._

     Do not add an example task line. An example checkbox is not real work, and the dashboard would count it, so every new project would open showing one open task it does not have.

6. Open `.claude/skills/wrapup/SKILL.md`. Find the step that updates the hub's `next_action` field. In that same step, add one instruction: also set the hub's `last_updated` frontmatter field to today's date in `YYYY-MM-DD` format, creating the field if it is not already there. Save the file.

7. Open `CLAUDE.md` at the vault root. Find the `## Common problems` section (if there is no such heading, add one at the end). Add these five bullets so a future Claude Code session can fix the dashboard on its own:
   - The dashboard shows raw code instead of the cards. The note is in source mode. Switch it to reading mode (Cmd+E on Mac, Ctrl+E on Windows).
   - The dashboard area is blank, or shows "dv is not defined". The Dataview plugin is not enabled. In Obsidian: Settings, Community plugins, enable Dataview, then reload the note.
   - "Open tasks" reads zero but there is work outstanding. That tile counts `- [ ]` checkboxes under a `## Tasks` heading in each hub. Add them to the hubs you want counted.
   - Every project shows a red "days ago" pill, or the header says hubs need a look when they do not. The hubs have no `last_updated` field yet. Add a `last_updated: {today's date}` line to each hub's frontmatter; /wrapup keeps it current from then on. This field feeds the header badge and the per-card pill only, not the tiles.
   - A project is missing from the cards, or a card is blank. Check that hub has `type: project` in its frontmatter and a status other than `done`, and that its frontmatter closes with `---` on its own line.

8. Tell me, word for word: "Two small things to add to your EXISTING projects so the new tiles count them. For each project hub you want on the dashboard: (1) add a `## Tasks` heading with `- [ ]` checkboxes for its open tasks, and (2) add a `last_updated: <today's date>` line to its frontmatter. From now on /wrapup keeps last_updated current, and every new project gets both automatically."

9. Reload check. Tell me: "Reload Claude Code (exit and relaunch from the vault folder). Then open Mission Control.md in Obsidian and switch it to reading mode (Cmd+E on Mac, Ctrl+E on Windows). The visual dashboard appears above your table. If you see raw code, you are still in source mode, toggle to reading mode." Before you finish, read Mission Control.md one last time and confirm the dashboard block is still in place. If it is not, add it again. Then stop. Do not create anything else.
Why this works

This is the same path your own system takes as it grows. You start with the plain table, which is enough to get real value on day one. The visual layer is something you add when the portfolio is big enough that a picture beats a list. Keeping it optional means the core install stays what it is: five prompts, about an hour, no plugin and no code. The upgrade is yours to take or leave.

The numbers stay honest because each tile reads a different part of the loop and reports only what is live: active projects and what needs attention come from the hubs, open tasks from the checkboxes in them, decisions this week and the activity chart from your recent session notes, today's commitment from the morning daily file. A dashboard exists to help you decide what to do now, so a count that only ever rises is noise. Current-state or this-week, nothing else earns a tile.

And it holds up. Prompt 6 checks the plugin is on before it builds, verifies its own edits, and leaves a troubleshooting list in your CLAUDE.md, so the two or three things that usually trip people up (a note left in source mode, a plugin not yet enabled, a hub missing a field) are ones Claude Code can spot and fix for you. Underneath it is still plain markdown you can open in anything, so the work outlives the dashboard and any single tool.

Five paste-prompts. One install pass.

The install is done. The vault has the architecture, the skills, the templates, the dashboard. Four slash commands ready to use, plus the optional visual dashboard if you took Level 2.

A day in the life

Each working day starts with /morning. It reads each project hub, asks what you're committing to today, writes today's daily file. Day one on the loop.

Then /pickup loads the context for the project you committed to: the hub state, the last session, what's blocked, what's next. Work. Ask questions, draft content, gather research. Claude knows the project folder structure from CLAUDE.md, so files land in the right place without you having to think about it.

When you stop, even just for lunch, run /wrapup first. The session note gets written and the hub's next_action is set, so nothing's left in your head. When you come back, /pickup reads it and you carry on where you left off. Same at the end of the day, or any time the context is filling up. Tomorrow's /morning reads it all back.

Open Mission Control.md in Obsidian whenever you want the portfolio view. The same hubs /morning reads, rendered as a dashboard.

Where the input comes from

Two places. The work you do with Claude in each session, and any files you drop into the vault in Obsidian for Claude to pick up next time. That's the input.

This is the simple version, built to get you going. It doesn't reach into your email, Slack or your other tools yet, and it doesn't need to. When you want more, you add MCPs to connect your own tools and bring them in where you want.

The shape underneath

In your vault
  • _about-you.md, the operating filter Claude reads every session
  • Project hubs, cumulative state per project (status, priority, next action, decisions log)
  • Session notes, working record per project
  • Daily files, today's intent and reasoning
  • 06-Templates/, single source of truth for session and daily-file shape
  • Projects.base, the query that powers the dashboard
  • Mission Control.md, the dashboard you open in Obsidian
Slash commands
  • /new-project, scaffolds a new project hub
  • /morning, reads the hubs, writes today's daily file
  • /pickup, orients Claude at the start of a working block
  • /wrapup, closes a working block, updates the hub

Run the loop on one project for a fortnight. Context loads itself every session, because the session you finish writes the short brief the next one opens with. Intent and progress stay separate.

Once the loop is running, the question shifts. Less "how do I keep my work organised" and more "how do I build agents that act inside this architecture, the way /morning and /wrapup do." That's a different problem, and a different conversation.

What you've just built is one example of what Serpin does: AI brought properly into the work, in whatever shape fits the problem. Sometimes a workflow. Sometimes an agentic system. Sometimes the prompt and habit stack that lets a team actually use what they already have. We design and build the work, make sure it holds up in real conditions, and help your team make it part of how they actually work.