{
  "openapi": "3.0.3",
  "info": {
    "title": "Claude Plan Viewer API",
    "description": "API for browsing and searching Claude Code plans",
    "version": "1.4.0",
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    }
  },
  "servers": [
    {
      "url": "http://localhost:3000",
      "description": "Local Claude Plan Viewer (run with: bunx claude-plan-viewer)"
    }
  ],
  "paths": {
    "/api/plans": {
      "get": {
        "summary": "List all plans",
        "description": "Returns metadata for all plans without content. Use /api/plans/{filename}/content to get content.",
        "operationId": "listPlans",
        "responses": {
          "200": {
            "description": "List of plans",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "plans": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PlanMetadata"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/plans/{filename}/content": {
      "get": {
        "summary": "Get plan content",
        "description": "Returns the markdown content for a specific plan",
        "operationId": "getPlanContent",
        "parameters": [
          {
            "name": "filename",
            "in": "path",
            "required": true,
            "description": "The plan filename (e.g., my-plan.md)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plan content",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "content": {
                      "type": "string",
                      "description": "Markdown content of the plan"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Plan not found"
          }
        }
      }
    },
    "/api/search": {
      "get": {
        "summary": "Search plan content",
        "description": "Returns filenames of plans whose markdown content contains the query (case-insensitive). Title, filename and project matching happens client-side against /api/plans.",
        "operationId": "searchPlans",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search text",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching plan filenames",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "filenames": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/memory": {
      "get": {
        "summary": "List auto memory",
        "description": "Memory directories and their entries, without content. Scans ~/.claude/projects/*/memory and autoMemoryDirectory settings; cached for 5 seconds.",
        "operationId": "listMemory",
        "responses": {
          "200": {
            "description": "Memory sources and entries",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sources": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MemorySource"
                      }
                    },
                    "entries": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MemoryEntry"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/memory/content": {
      "get": {
        "summary": "Get memory content",
        "description": "Raw markdown of one memory entry, including frontmatter",
        "operationId": "getMemoryContent",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "description": "Entry id from /api/memory",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Memory content",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "content": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Memory not found"
          }
        }
      }
    },
    "/api/memory/search": {
      "get": {
        "summary": "Search memory content",
        "description": "Ids of entries whose raw content contains the query (case-insensitive)",
        "operationId": "searchMemory",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search text",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching entry ids",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ids": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/projects": {
      "get": {
        "summary": "List all projects",
        "description": "Returns a list of unique project names associated with plans",
        "operationId": "listProjects",
        "responses": {
          "200": {
            "description": "List of project names",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "projects": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/refresh": {
      "post": {
        "summary": "Refresh cache",
        "description": "Invalidates the plan cache and reloads all plans from disk",
        "operationId": "refreshCache",
        "responses": {
          "200": {
            "description": "Cache refreshed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/open": {
      "post": {
        "summary": "Open plan in editor",
        "description": "Opens a plan or memory file in the system's default editor",
        "operationId": "openInEditor",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "filepath"
                ],
                "properties": {
                  "filepath": {
                    "type": "string",
                    "description": "filepath of a plan from /api/plans or a memory entry from /api/memory; any other path is rejected"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "File opened successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid path"
          },
          "500": {
            "description": "Failed to open file"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "PlanMetadata": {
        "type": "object",
        "properties": {
          "filename": {
            "type": "string",
            "description": "Plan filename (e.g., my-plan.md)"
          },
          "filepath": {
            "type": "string",
            "description": "Absolute path to the plan file"
          },
          "title": {
            "type": "string",
            "description": "Plan title extracted from markdown heading"
          },
          "size": {
            "type": "integer",
            "description": "File size in bytes"
          },
          "modified": {
            "type": "string",
            "format": "date-time",
            "description": "Last modification timestamp"
          },
          "created": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "lineCount": {
            "type": "integer",
            "description": "Number of lines in the plan"
          },
          "wordCount": {
            "type": "integer",
            "description": "Number of words in the plan"
          },
          "project": {
            "type": "string",
            "nullable": true,
            "description": "Associated Claude Code project name"
          },
          "sessionId": {
            "type": "string",
            "nullable": true,
            "description": "Associated Claude Code session ID"
          }
        }
      },
      "MemoryIndexStats": {
        "type": "object",
        "description": "MEMORY.md load budget. Claude Code loads the first lineLimit lines or byteLimit bytes, whichever comes first.",
        "properties": {
          "lines": {
            "type": "integer"
          },
          "bytes": {
            "type": "integer"
          },
          "lineLimit": {
            "type": "integer",
            "example": 200
          },
          "byteLimit": {
            "type": "integer",
            "example": 25000
          },
          "danglingLinks": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Index links to files that don't exist"
          }
        }
      },
      "MemorySource": {
        "type": "object",
        "description": "One auto memory directory",
        "properties": {
          "id": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "project",
              "custom"
            ],
            "description": "project: ~/.claude/projects/<project>/memory; custom: an autoMemoryDirectory setting"
          },
          "project": {
            "type": "string",
            "description": "Project name from the session cwd, or \"All projects\" for a user-level autoMemoryDirectory"
          },
          "cwd": {
            "type": "string",
            "nullable": true
          },
          "dir": {
            "type": "string",
            "description": "Absolute path of the memory directory"
          },
          "active": {
            "type": "boolean",
            "description": "False when an autoMemoryDirectory setting means Claude Code no longer uses this directory"
          },
          "index": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MemoryIndexStats"
              }
            ],
            "nullable": true
          },
          "orphans": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Topic files MEMORY.md doesn't link to"
          },
          "entryCount": {
            "type": "integer",
            "description": "Number of topic files (excludes MEMORY.md)"
          },
          "modified": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "MemoryEntry": {
        "type": "object",
        "description": "One memory file (MEMORY.md or a topic file)",
        "properties": {
          "id": {
            "type": "string",
            "description": "<sourceId>/<filename>"
          },
          "sourceId": {
            "type": "string"
          },
          "filename": {
            "type": "string"
          },
          "filepath": {
            "type": "string"
          },
          "isIndex": {
            "type": "boolean"
          },
          "name": {
            "type": "string",
            "description": "Frontmatter name, first heading, or filename"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "enum": [
              "user",
              "feedback",
              "project",
              "reference"
            ],
            "nullable": true
          },
          "sessionId": {
            "type": "string",
            "nullable": true,
            "description": "originSessionId from frontmatter"
          },
          "modified": {
            "type": "string",
            "format": "date-time",
            "description": "Frontmatter modified, or file mtime"
          },
          "size": {
            "type": "integer"
          },
          "lineCount": {
            "type": "integer"
          },
          "links": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Filenames this entry links to (markdown links and [[wikilinks]])"
          },
          "linkedFrom": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "inIndex": {
            "type": "boolean",
            "description": "Linked from MEMORY.md (always true for MEMORY.md)"
          }
        }
      }
    }
  }
}
