@@ -22,6 +22,12 @@ Or with [uv](https://github.com/astral-sh/uv):
2222uv add brainfile
2323```
2424
25+ To enable file watching (optional):
26+
27+ ``` bash
28+ pip install brainfile[watch]
29+ ```
30+
2531## v2 Architecture
2632
2733Brainfile v2 uses a directory-based structure. Each task is its own markdown file.
@@ -39,55 +45,55 @@ Brainfile v2 uses a directory-based structure. Each task is its own markdown fil
3945## Quick Start
4046
4147``` python
42- from brainfile import ensureV2Dirs, addTaskFile, readTasksDir, completeTaskFile
48+ from brainfile import ensure_dirs, add_task_file, read_tasks_dir, complete_task_file
4349
4450# Initialize workspace
45- dirs = ensureV2Dirs (" .brainfile/brainfile.md" )
51+ dirs = ensure_dirs (" .brainfile/brainfile.md" )
4652
4753# Add a task
48- result = addTaskFile (
49- dirs.boardDir ,
54+ result = add_task_file (
55+ dirs.board_dir ,
5056 {" title" : " Implement auth" , " column" : " in-progress" , " priority" : " high" },
5157 body = " ## Description\n Add JWT authentication to the API.\n " ,
5258)
5359print (result[" task" ].id) # "task-1"
5460
5561# List all active tasks
56- for doc in readTasksDir (dirs.boardDir ):
62+ for doc in read_tasks_dir (dirs.board_dir ):
5763 t = doc.task
5864 print (f " { t.id} : { t.title} [ { t.column} ] " )
5965
6066# Complete a task (moves to logs/)
61- completeTaskFile (result[" filePath " ], dirs.logsDir )
67+ complete_task_file (result[" file_path " ], dirs.logs_dir )
6268```
6369
6470## Task File Operations
6571
6672Read and write individual task files.
6773
6874``` python
69- from brainfile import readTaskFile, writeTaskFile, findV2Task, getV2Dirs
75+ from brainfile import read_task_file, write_task_file, find_workspace_task, get_dirs
7076
7177# Read a single task
72- doc = readTaskFile (" .brainfile/board/task-1.md" )
78+ doc = read_task_file (" .brainfile/board/task-1.md" )
7379print (doc.task.title)
7480print (doc.body) # Markdown content below frontmatter
7581
7682# Find a task across board and logs
77- dirs = getV2Dirs (" .brainfile/brainfile.md" )
78- result = findV2Task (dirs, " task-1" , searchLogs = True )
83+ dirs = get_dirs (" .brainfile/brainfile.md" )
84+ result = find_workspace_task (dirs, " task-1" , search_logs = True )
7985if result:
80- print (result[" doc" ].task.title, " in" , " logs" if result[" isLog " ] else " board" )
86+ print (result[" doc" ].task.title, " in" , " logs" if result[" is_log " ] else " board" )
8187```
8288
8389## Contracts
8490
8591Tasks can carry formal contracts for AI agent coordination: deliverables, validation commands, constraints, and feedback for rework.
8692
8793``` python
88- from brainfile import readTaskFile, writeTaskFile , Contract, Deliverable
94+ from brainfile import read_task_file, write_task_file , Contract, Deliverable
8995
90- doc = readTaskFile (" .brainfile/board/task-1.md" )
96+ doc = read_task_file (" .brainfile/board/task-1.md" )
9197task = doc.task
9298
9399# Attach a contract
@@ -101,7 +107,7 @@ task.contract = Contract(
101107 constraints = [" Use PyJWT library" , " Token expiry must be configurable" ],
102108)
103109
104- writeTaskFile (" .brainfile/board/task-1.md" , task, doc.body)
110+ write_task_file (" .brainfile/board/task-1.md" , task, doc.body)
105111```
106112
107113### Contract Lifecycle
@@ -113,78 +119,10 @@ ready → in_progress → delivered → done
113119 (add feedback, reset to ready)
114120```
115121
116- ``` python
117- from brainfile import setTaskContractStatus
118-
119- # Agent picks up work
120- setTaskContractStatus(board, " task-1" , " in_progress" )
121-
122- # Agent delivers
123- setTaskContractStatus(board, " task-1" , " delivered" )
124-
125- # PM validates
126- setTaskContractStatus(board, " task-1" , " done" )
127- ```
128-
129- ## Board Operations (V1)
130-
131- Immutable operations on in-memory board objects. Useful for single-file workflows or building custom tools.
132-
133- ``` python
134- from brainfile import Brainfile, add_task, move_task, patch_task, TaskInput, TaskPatch
135-
136- # Parse a brainfile
137- result = Brainfile.parse(markdown_content)
138- board = result.board
139-
140- # Add a task
141- result = add_task(board, " todo" , TaskInput(title = " New task" , priority = " high" ))
142- board = result.board
143-
144- # Move between columns
145- result = move_task(board, " task-1" , " todo" , " in-progress" )
146-
147- # Patch fields
148- result = patch_task(board, " task-1" , TaskPatch(tags = [" urgent" ], assignee = " codex" ))
149-
150- # Serialize back
151- output = Brainfile.serialize(board)
152- ```
153-
154- ## Queries
155-
156- ``` python
157- from brainfile import (
158- find_task_by_id,
159- get_all_tasks,
160- get_tasks_by_tag,
161- get_tasks_by_assignee,
162- search_tasks,
163- )
164-
165- task_info = find_task_by_id(board, " task-1" )
166- urgent = get_tasks_by_tag(board, " urgent" )
167- results = search_tasks(board, " auth" )
168- ```
169-
170- ## Validation and Linting
171-
172- ``` python
173- from brainfile import BrainfileValidator, BrainfileLinter, LintOptions
174-
175- # Validate board structure
176- result = BrainfileValidator.validate(board)
177- for error in result.errors:
178- print (f " { error.path} : { error.message} " )
179-
180- # Lint with auto-fix
181- result = BrainfileLinter.lint(content, LintOptions(auto_fix = True ))
182- ```
183-
184122## File Discovery
185123
186124``` python
187- from brainfile import discover, find_nearest_brainfile, isV2
125+ from brainfile import discover, find_nearest_brainfile, is_workspace
188126
189127# Find brainfiles in a project
190128result = discover(" /path/to/project" )
@@ -194,8 +132,8 @@ for f in result.files:
194132# Walk up to find nearest brainfile
195133path = find_nearest_brainfile()
196134
197- # Check if a workspace is v2
198- if isV2 (" .brainfile/brainfile.md" ):
135+ # Check if a workspace has the v2 board/ directory
136+ if is_workspace (" .brainfile/brainfile.md" ):
199137 print (" V2 workspace detected" )
200138```
201139
0 commit comments