Skip to content

Commit a0c82d2

Browse files
authored
Merge pull request #22 from alanshurafa/contrib/alanshurafa/markdownlint-sweep-2
[docs] Markdownlint sweep for existing recipe/schema docs
2 parents ea7e1cb + 8f38840 commit a0c82d2

180 files changed

Lines changed: 22930 additions & 855 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,16 @@ Standalone capabilities that make your Open Brain smarter.
8383
| ------ | ------------ | ----------- |
8484
| [Auto-Capture Protocol](recipes/auto-capture/) | Stores ACT NOW items and session summaries in Open Brain at session close using the reusable Auto-Capture skill | [@jaredirish](https://github.com/jaredirish) |
8585
| [Panning for Gold](recipes/panning-for-gold/) | Mine brain dumps and voice transcripts for actionable ideas — battle-tested across 13+ sessions | [@jaredirish](https://github.com/jaredirish) |
86-
| [Claudeception](recipes/claudeception/) | Self-improving system that creates new skills from work sessions — skills that create other skills | [@jaredirish](https://github.com/jaredirish) |
86+
| [Aiception (formerly Claudeception)](recipes/claudeception/) | Self-improving system that creates new skills from work sessions — skills that create other skills | [@jaredirish](https://github.com/jaredirish) |
8787
| [Schema-Aware Routing](recipes/schema-aware-routing/) | LLM-powered routing that distributes unstructured text across multiple database tables | [@claydunker-yalc](https://github.com/claydunker-yalc) |
8888
| [Fingerprint Dedup Backfill](recipes/fingerprint-dedup-backfill/) | Backfill content fingerprints and safely remove duplicate thoughts | [@alanshurafa](https://github.com/alanshurafa) |
8989
| [Source Filtering](recipes/source-filtering/) | Filter thoughts by source and backfill missing metadata for early imports | [@matthallett1](https://github.com/matthallett1) |
9090
| [Life Engine](recipes/life-engine/) | Self-improving personal assistant — calendar, habits, health, proactive briefings via Telegram or Discord | [@justfinethanku](https://github.com/justfinethanku) |
9191
| [Life Engine Video](recipes/life-engine-video/) | Add-on that renders Life Engine briefings as short animated videos with voiceover | [@justfinethanku](https://github.com/justfinethanku) |
9292
| [Daily Digest](recipes/daily-digest/) | Automated daily summary of recent thoughts delivered via email or Slack | OB1 Team |
93+
| [Bring Your Own Context](recipes/bring-your-own-context/) | Portable context workflow that packages extraction prompts, profile generation, and remote MCP deployment into one entrypoint | [@jonathanedwards](https://github.com/jonathanedwards) |
94+
| [Work Operating Model Activation](recipes/work-operating-model-activation/) | Conversation-first workflow that turns tacit work patterns into structured Open Brain records and agent-ready operating files | [@jonathanedwards](https://github.com/jonathanedwards) |
95+
| [World Model Diagnostic Activation](recipes/world-model-diagnostic-activation/) | Ship-now activation path for a 20-minute world-model readiness diagnostic that compounds through core Open Brain capture | [@jonathanedwards](https://github.com/jonathanedwards) |
9396
| [Research-to-Decision Workflow](recipes/research-to-decision-workflow/) | Composition recipe that chains canonical skills into operator and investor research, synthesis, meeting, and memo workflows | [@NateBJones](https://github.com/NateBJones) |
9497

9598
### [`/skills`](skills/) — Agent Skills
@@ -105,7 +108,9 @@ Plain-text skill packs you can drop into Claude Code, Codex, or other AI clients
105108
| [Research Synthesis Skill Pack](skills/research-synthesis/) | Synthesizes source sets into findings, contradictions, confidence markers, and next questions | [@NateBJones](https://github.com/NateBJones) |
106109
| [Meeting Synthesis Skill Pack](skills/meeting-synthesis/) | Converts meeting notes or transcripts into decisions, action items, risks, and follow-up artifacts | [@NateBJones](https://github.com/NateBJones) |
107110
| [Panning for Gold Skill Pack](skills/panning-for-gold/) | Turns brain dumps and transcripts into evaluated idea inventories | [@jaredirish](https://github.com/jaredirish) |
108-
| [Claudeception Skill Pack](skills/claudeception/) | Extracts reusable lessons from work sessions into new skills | [@jaredirish](https://github.com/jaredirish) |
111+
| [Aiception Skill Pack (formerly Claudeception)](skills/claudeception/) | Extracts reusable lessons from work sessions into new skills | [@jaredirish](https://github.com/jaredirish) |
112+
| [Work Operating Model Skill Pack](skills/work-operating-model/) | Runs a five-layer elicitation interview and saves the approved operating model into Open Brain | [@jonathanedwards](https://github.com/jonathanedwards) |
113+
| [World Model Readiness Diagnostic](skills/world-model-diagnostic/) | Runs a 20-minute world-model diagnostic that maps paradigm fit, audits the boundary layer, and labels findings by confidence | [@jonathanedwards](https://github.com/jonathanedwards) |
109114

110115
### [`/dashboards`](dashboards/) — Frontend Templates
111116

dashboards/open-brain-dashboard-next/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ node_modules/
66
.env.local.example
77
next-env.d.ts
88
tsconfig.tsbuildinfo
9+
.vercel

dashboards/open-brain-dashboard-next/README.md

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ A full-featured web dashboard for your Open Brain second brain. Browse, search,
1414

1515
## What It Does
1616

17-
Provides 8 pages for managing your thoughts:
17+
Provides 9 pages for managing your thoughts:
1818

1919
| Page | Description |
2020
|------|-------------|
21-
| **Dashboard** | Stats overview (total thoughts, type distribution, top topics), recent activity, quick capture |
21+
| **Dashboard** | Stats overview (total thoughts, type distribution, top topics), recent activity, quick capture, workflow summary widget |
22+
| **Workflow** | Kanban board for tasks and ideas with drag-and-drop status management (New → Planning → Active → Review → Done → Archived) |
2223
| **Browse** | Paginated thought table with filters for type, source, and importance |
2324
| **Detail** | Full thought view with inline editing, delete, linked reflections, and related connections |
2425
| **Search** | Semantic (vector similarity) and full-text search with match scores and pagination |
@@ -103,6 +104,43 @@ When working correctly:
103104
- **Add to Brain** auto-routes short text (< 500 chars, single paragraph) to single capture, and long/structured text to extraction with dry-run preview
104105
- **Detail page** shows full thought content with metadata, inline edit for content/type/importance, and linked reflections
105106

107+
## Workflow Board
108+
109+
The Workflow page adds a visual kanban board for managing `task` and `idea` thoughts through status stages.
110+
111+
### Features
112+
113+
- **Drag-and-drop** between status columns using @dnd-kit (touch-friendly with 200ms hold delay)
114+
- **Collapsible columns** — click the arrow to collapse any column to a slim vertical bar (persisted in localStorage)
115+
- **Auto-adjusting widths** — expanded columns share available space equally, no horizontal scrollbar
116+
- **Inline editing** — tap a card to open the edit modal (status, priority, type, content)
117+
- **Priority dots** — click to change priority (Critical/High/Medium/Low mapped from importance 0-100)
118+
- **Dashboard widget** — summary of active workflow items on the main dashboard
119+
- **Mobile-first** — responsive layout, pinch-to-zoom enabled, full-screen edit modal on small screens
120+
121+
### Status Flow
122+
123+
```
124+
New → Planning → Active → Review → Done → (Archived)
125+
```
126+
127+
Cards auto-archive from Done after 30 days. Archived cards are hidden by default (toggle with "Show archived").
128+
129+
### Database Requirements
130+
131+
The Workflow board requires two additional columns on the `thoughts` table. See the [workflow-status schema](../../schemas/workflow-status/) for the migration SQL.
132+
133+
### MCP Integration
134+
135+
The `progress_task` tool in the Open Brain MCP server allows AI assistants to update task status and priority conversationally:
136+
137+
```
138+
"Move the API redesign task to active"
139+
"Set priority on thought 42 to high"
140+
```
141+
142+
When a new task or idea is captured, the MCP server auto-assigns `status: "new"`.
143+
106144
## REST API Endpoints Required
107145

108146
The dashboard calls these endpoints on your Open Brain REST API:
@@ -121,6 +159,8 @@ The dashboard calls these endpoints on your Open Brain REST API:
121159
| `/ingest` | POST | Smart ingest (extraction) |
122160
| `/ingestion-jobs` | GET | Ingest page (job history) |
123161
| `/duplicates` | GET | Duplicates page |
162+
| `/thoughts?type=task` | GET | Workflow board (filtered by type) |
163+
| `/thought/:id` | PUT | Workflow board (status/priority updates) |
124164

125165
> [!NOTE]
126166
> If your Open Brain instance doesn't have all these endpoints (e.g., no smart-ingest or duplicates), those pages will show errors but the core pages (dashboard, browse, search, detail) will still work.
@@ -154,6 +194,7 @@ No API key is stored in environment variables or exposed to the browser.
154194
- **React 19** with TypeScript
155195
- **Tailwind CSS 4** (dark theme)
156196
- **iron-session 8** (encrypted cookies)
197+
- **@dnd-kit** (drag-and-drop for workflow board)
157198
- Zero external runtime dependencies beyond these
158199

159200
## Troubleshooting
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { NextRequest, NextResponse } from "next/server";
2+
import { requireSession, AuthError } from "@/lib/auth";
3+
import { deleteThought } from "@/lib/api";
4+
5+
export async function POST(request: NextRequest) {
6+
let apiKey: string;
7+
try {
8+
({ apiKey } = await requireSession());
9+
} catch (err) {
10+
if (err instanceof AuthError)
11+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
12+
throw err;
13+
}
14+
15+
try {
16+
const body = await request.json();
17+
const { thoughtId } = body;
18+
19+
if (!thoughtId || typeof thoughtId !== "number") {
20+
return NextResponse.json(
21+
{ error: "thoughtId (number) is required" },
22+
{ status: 400 }
23+
);
24+
}
25+
26+
await deleteThought(apiKey, thoughtId);
27+
return NextResponse.json({ success: true });
28+
} catch (err) {
29+
return NextResponse.json(
30+
{ error: err instanceof Error ? err.message : "Delete failed" },
31+
{ status: 500 }
32+
);
33+
}
34+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { NextRequest, NextResponse } from "next/server";
2+
import { requireSession, AuthError } from "@/lib/auth";
3+
import { getSession } from "@/lib/auth";
4+
import { fetchKanbanThoughts } from "@/lib/api";
5+
6+
export async function GET(request: NextRequest) {
7+
let apiKey: string;
8+
try {
9+
({ apiKey } = await requireSession());
10+
} catch (err) {
11+
if (err instanceof AuthError)
12+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
13+
throw err;
14+
}
15+
16+
const session = await getSession();
17+
const excludeRestricted = session.restrictedUnlocked !== true;
18+
const includeArchived =
19+
request.nextUrl.searchParams.get("archived") === "true";
20+
21+
const statusFilter = includeArchived
22+
? "new,planning,active,review,done,archived"
23+
: "new,planning,active,review,done";
24+
25+
try {
26+
const thoughts = await fetchKanbanThoughts(apiKey, {
27+
status: statusFilter,
28+
exclude_restricted: excludeRestricted,
29+
});
30+
return NextResponse.json({ thoughts });
31+
} catch (err) {
32+
return NextResponse.json(
33+
{
34+
error:
35+
err instanceof Error ? err.message : "Failed to fetch kanban data",
36+
},
37+
{ status: 500 }
38+
);
39+
}
40+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { NextRequest, NextResponse } from "next/server";
2+
import { requireSession, AuthError } from "@/lib/auth";
3+
import { updateThought } from "@/lib/api";
4+
5+
const VALID_STATUSES = [
6+
"new",
7+
"planning",
8+
"active",
9+
"review",
10+
"done",
11+
"archived",
12+
];
13+
14+
export async function POST(request: NextRequest) {
15+
let apiKey: string;
16+
try {
17+
({ apiKey } = await requireSession());
18+
} catch (err) {
19+
if (err instanceof AuthError)
20+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
21+
throw err;
22+
}
23+
24+
try {
25+
const body = await request.json();
26+
const { thoughtId, status, importance, content, type } = body;
27+
28+
if (!thoughtId || typeof thoughtId !== "number") {
29+
return NextResponse.json(
30+
{ error: "thoughtId (number) is required" },
31+
{ status: 400 }
32+
);
33+
}
34+
35+
if (status !== undefined && status !== null && !VALID_STATUSES.includes(status)) {
36+
return NextResponse.json(
37+
{ error: `Invalid status. Must be one of: ${VALID_STATUSES.join(", ")}` },
38+
{ status: 400 }
39+
);
40+
}
41+
42+
const updates: Record<string, unknown> = {};
43+
if (status !== undefined) updates.status = status;
44+
if (importance !== undefined) updates.importance = importance;
45+
if (content !== undefined) updates.content = content;
46+
if (type !== undefined) updates.type = type;
47+
48+
if (Object.keys(updates).length === 0) {
49+
return NextResponse.json(
50+
{ error: "No fields to update" },
51+
{ status: 400 }
52+
);
53+
}
54+
55+
const result = await updateThought(apiKey, thoughtId, updates);
56+
return NextResponse.json(result);
57+
} catch (err) {
58+
return NextResponse.json(
59+
{ error: err instanceof Error ? err.message : "Update failed" },
60+
{ status: 500 }
61+
);
62+
}
63+
}

dashboards/open-brain-dashboard-next/app/globals.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,18 @@ body {
4949
background: var(--color-violet-glow);
5050
color: var(--color-text-primary);
5151
}
52+
53+
/* Phone landscape: hide desktop sidebar, keep mobile topbar, remove sidebar margin */
54+
@media (orientation: landscape) and (max-height: 600px) {
55+
aside {
56+
display: none !important;
57+
}
58+
main {
59+
margin-left: 0 !important;
60+
padding-top: 48px !important;
61+
}
62+
/* Force mobile topbar visible in landscape */
63+
.md\:hidden {
64+
display: flex !important;
65+
}
66+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { requireSessionOrRedirect } from "@/lib/auth";
2+
import { KanbanBoard } from "@/components/KanbanBoard";
3+
4+
export const dynamic = "force-dynamic";
5+
6+
7+
export default async function KanbanPage() {
8+
await requireSessionOrRedirect();
9+
10+
return (
11+
<div className="space-y-4">
12+
<div>
13+
<h1 className="text-2xl font-semibold mb-1">Workflow</h1>
14+
<p className="text-text-secondary text-sm">
15+
Track tasks and ideas through your workflow
16+
</p>
17+
</div>
18+
<KanbanBoard />
19+
</div>
20+
);
21+
}

dashboards/open-brain-dashboard-next/app/layout.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Metadata } from "next";
22
import { Geist, Geist_Mono } from "next/font/google";
33
import "./globals.css";
4-
import { Sidebar } from "@/components/Sidebar";
4+
import { SidebarShell } from "@/components/SidebarShell";
55

66
const geistSans = Geist({
77
variable: "--font-geist-sans",
@@ -27,11 +27,12 @@ export default function RootLayout({
2727
<html
2828
lang="en"
2929
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
30+
suppressHydrationWarning
3031
>
3132
<body className="min-h-screen flex bg-bg-primary text-text-primary">
32-
<Sidebar />
33-
<main className="flex-1 ml-56 min-h-screen">
34-
<div className="max-w-6xl mx-auto px-8 py-8">
33+
<SidebarShell />
34+
<main className="flex-1 md:ml-56 min-h-screen pt-12 md:pt-0">
35+
<div className="max-w-6xl mx-auto px-4 py-4 md:px-8 md:py-8">
3536
{children}
3637
</div>
3738
</main>

dashboards/open-brain-dashboard-next/app/page.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { fetchStats, fetchThoughts } from "@/lib/api";
22
import { requireSessionOrRedirect, getSession } from "@/lib/auth";
33
import { StatsWidget } from "@/components/StatsWidget";
4+
import { KanbanSummary } from "@/components/KanbanSummary";
45
import { ThoughtCard } from "@/components/ThoughtCard";
56
import { AddToBrain } from "@/components/AddToBrain";
67

@@ -43,6 +44,8 @@ export default async function DashboardPage() {
4344

4445
<StatsWidget stats={stats} />
4546

47+
<KanbanSummary />
48+
4649
{/* Add to Brain */}
4750
<div>
4851
<h2 className="text-lg font-medium mb-1">Add to Brain</h2>

0 commit comments

Comments
 (0)