@brainfile/cli 0.13.3 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/README.md +129 -354
- package/dist/cli.js +91 -5
- package/dist/cli.js.map +1 -1
- package/dist/commands/add.d.ts +3 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +163 -3
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/adr.d.ts +22 -0
- package/dist/commands/adr.d.ts.map +1 -0
- package/dist/commands/adr.js +182 -0
- package/dist/commands/adr.js.map +1 -0
- package/dist/commands/archive.d.ts.map +1 -1
- package/dist/commands/archive.js +147 -0
- package/dist/commands/archive.js.map +1 -1
- package/dist/commands/complete.d.ts +30 -0
- package/dist/commands/complete.d.ts.map +1 -0
- package/dist/commands/complete.js +254 -0
- package/dist/commands/complete.js.map +1 -0
- package/dist/commands/contract.d.ts.map +1 -1
- package/dist/commands/contract.js +2 -0
- package/dist/commands/contract.js.map +1 -1
- package/dist/commands/delete.d.ts.map +1 -1
- package/dist/commands/delete.js +29 -1
- package/dist/commands/delete.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +38 -19
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.d.ts +1 -0
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +35 -12
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/log.d.ts +52 -0
- package/dist/commands/log.d.ts.map +1 -0
- package/dist/commands/log.js +246 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +864 -44
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/migrate.d.ts +4 -3
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +225 -33
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/move.d.ts.map +1 -1
- package/dist/commands/move.js +90 -0
- package/dist/commands/move.js.map +1 -1
- package/dist/commands/patch.d.ts.map +1 -1
- package/dist/commands/patch.js +85 -13
- package/dist/commands/patch.js.map +1 -1
- package/dist/commands/search.d.ts +33 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +209 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +75 -1
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/subtask.d.ts.map +1 -1
- package/dist/commands/subtask.js +72 -5
- package/dist/commands/subtask.js.map +1 -1
- package/dist/commands/tui.d.ts.map +1 -1
- package/dist/commands/tui.js +10 -0
- package/dist/commands/tui.js.map +1 -1
- package/dist/commands/types.d.ts +40 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +242 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/contractRunner.d.ts.map +1 -1
- package/dist/lib/contractRunner.js +177 -12
- package/dist/lib/contractRunner.js.map +1 -1
- package/dist/schemas/board.json +105 -18
- package/dist/tui/BrainfileTUI.d.ts.map +1 -1
- package/dist/tui/BrainfileTUI.js +23 -20
- package/dist/tui/BrainfileTUI.js.map +1 -1
- package/dist/tui/actions.d.ts +5 -5
- package/dist/tui/actions.d.ts.map +1 -1
- package/dist/tui/actions.js +335 -47
- package/dist/tui/actions.js.map +1 -1
- package/dist/tui/components/ArchivePanel.js +1 -1
- package/dist/tui/components/ArchivePanel.js.map +1 -1
- package/dist/tui/components/ColumnTabs.d.ts.map +1 -1
- package/dist/tui/components/ColumnTabs.js +6 -2
- package/dist/tui/components/ColumnTabs.js.map +1 -1
- package/dist/tui/components/HelpOverlay.js +3 -3
- package/dist/tui/components/HelpOverlay.js.map +1 -1
- package/dist/tui/components/LogsPanel.d.ts +16 -0
- package/dist/tui/components/LogsPanel.d.ts.map +1 -0
- package/dist/tui/components/LogsPanel.js +115 -0
- package/dist/tui/components/LogsPanel.js.map +1 -0
- package/dist/tui/components/MainPanelTabs.d.ts +2 -2
- package/dist/tui/components/MainPanelTabs.d.ts.map +1 -1
- package/dist/tui/components/MainPanelTabs.js +3 -3
- package/dist/tui/components/MainPanelTabs.js.map +1 -1
- package/dist/tui/components/StackedTaskList.d.ts +2 -1
- package/dist/tui/components/StackedTaskList.d.ts.map +1 -1
- package/dist/tui/components/StackedTaskList.js +9 -9
- package/dist/tui/components/StackedTaskList.js.map +1 -1
- package/dist/tui/components/TaskCard.d.ts +2 -1
- package/dist/tui/components/TaskCard.d.ts.map +1 -1
- package/dist/tui/components/TaskCard.js +41 -5
- package/dist/tui/components/TaskCard.js.map +1 -1
- package/dist/tui/components/TaskCardMeasure.d.ts +2 -16
- package/dist/tui/components/TaskCardMeasure.d.ts.map +1 -1
- package/dist/tui/components/TaskCardMeasure.js +30 -25
- package/dist/tui/components/TaskCardMeasure.js.map +1 -1
- package/dist/tui/components/TaskDetail.d.ts +2 -3
- package/dist/tui/components/TaskDetail.d.ts.map +1 -1
- package/dist/tui/components/TaskDetail.js +35 -12
- package/dist/tui/components/TaskDetail.js.map +1 -1
- package/dist/tui/components/TaskList.d.ts +2 -1
- package/dist/tui/components/TaskList.d.ts.map +1 -1
- package/dist/tui/components/TaskList.js +5 -5
- package/dist/tui/components/TaskList.js.map +1 -1
- package/dist/tui/components/index.d.ts +2 -2
- package/dist/tui/components/index.d.ts.map +1 -1
- package/dist/tui/components/index.js +3 -3
- package/dist/tui/components/index.js.map +1 -1
- package/dist/tui/hooks/useBrainfileLoader.d.ts.map +1 -1
- package/dist/tui/hooks/useBrainfileLoader.js +97 -31
- package/dist/tui/hooks/useBrainfileLoader.js.map +1 -1
- package/dist/tui/hooks/useKeyboardNavigation.d.ts.map +1 -1
- package/dist/tui/hooks/useKeyboardNavigation.js +47 -47
- package/dist/tui/hooks/useKeyboardNavigation.js.map +1 -1
- package/dist/tui/types.d.ts +7 -7
- package/dist/tui/types.d.ts.map +1 -1
- package/dist/utils/board-types.d.ts +13 -0
- package/dist/utils/board-types.d.ts.map +1 -0
- package/dist/utils/board-types.js +7 -0
- package/dist/utils/board-types.js.map +1 -0
- package/dist/utils/dot-brainfile.d.ts +9 -0
- package/dist/utils/dot-brainfile.d.ts.map +1 -0
- package/dist/utils/dot-brainfile.js +74 -0
- package/dist/utils/dot-brainfile.js.map +1 -0
- package/dist/utils/strict-validation.d.ts +8 -0
- package/dist/utils/strict-validation.d.ts.map +1 -0
- package/dist/utils/strict-validation.js +41 -0
- package/dist/utils/strict-validation.js.map +1 -0
- package/dist/utils/v2-detect.d.ts +28 -0
- package/dist/utils/v2-detect.d.ts.map +1 -0
- package/dist/utils/v2-detect.js +112 -0
- package/dist/utils/v2-detect.js.map +1 -0
- package/dist/utils/v2-tasks.d.ts +121 -0
- package/dist/utils/v2-tasks.d.ts.map +1 -0
- package/dist/utils/v2-tasks.js +384 -0
- package/dist/utils/v2-tasks.js.map +1 -0
- package/dist/utils/workspace-format.d.ts +25 -0
- package/dist/utils/workspace-format.d.ts.map +1 -0
- package/dist/utils/workspace-format.js +106 -0
- package/dist/utils/workspace-format.js.map +1 -0
- package/package.json +3 -3
- package/state.json +3 -0
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* V2 per-task file architecture utilities.
|
|
4
|
+
*
|
|
5
|
+
* In v2, tasks live as individual .md files in .brainfile/tasks/ (active)
|
|
6
|
+
* and .brainfile/logs/ (completed). The brainfile.md is config-only.
|
|
7
|
+
*
|
|
8
|
+
* Task file format:
|
|
9
|
+
* ---
|
|
10
|
+
* id: task-1
|
|
11
|
+
* title: My Task
|
|
12
|
+
* column: todo
|
|
13
|
+
* position: 0
|
|
14
|
+
* priority: high
|
|
15
|
+
* tags: [bug, urgent]
|
|
16
|
+
* assignee: alice
|
|
17
|
+
* contract:
|
|
18
|
+
* status: ready
|
|
19
|
+
* ...
|
|
20
|
+
* ---
|
|
21
|
+
*
|
|
22
|
+
* ## Description
|
|
23
|
+
* Task description here...
|
|
24
|
+
*
|
|
25
|
+
* ## Log
|
|
26
|
+
* - 2026-02-18T10:00:00Z: Created task
|
|
27
|
+
*
|
|
28
|
+
* @packageDocumentation
|
|
29
|
+
*/
|
|
30
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
31
|
+
if (k2 === undefined) k2 = k;
|
|
32
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
33
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
34
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
35
|
+
}
|
|
36
|
+
Object.defineProperty(o, k2, desc);
|
|
37
|
+
}) : (function(o, m, k, k2) {
|
|
38
|
+
if (k2 === undefined) k2 = k;
|
|
39
|
+
o[k2] = m[k];
|
|
40
|
+
}));
|
|
41
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
42
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
43
|
+
}) : function(o, v) {
|
|
44
|
+
o["default"] = v;
|
|
45
|
+
});
|
|
46
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
47
|
+
var ownKeys = function(o) {
|
|
48
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
49
|
+
var ar = [];
|
|
50
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
51
|
+
return ar;
|
|
52
|
+
};
|
|
53
|
+
return ownKeys(o);
|
|
54
|
+
};
|
|
55
|
+
return function (mod) {
|
|
56
|
+
if (mod && mod.__esModule) return mod;
|
|
57
|
+
var result = {};
|
|
58
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
59
|
+
__setModuleDefault(result, mod);
|
|
60
|
+
return result;
|
|
61
|
+
};
|
|
62
|
+
})();
|
|
63
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
64
|
+
exports.getV2Dirs = getV2Dirs;
|
|
65
|
+
exports.isV2 = isV2;
|
|
66
|
+
exports.getTaskFilePath = getTaskFilePath;
|
|
67
|
+
exports.getLogFilePath = getLogFilePath;
|
|
68
|
+
exports.ensureV2Dirs = ensureV2Dirs;
|
|
69
|
+
exports.parseTaskFile = parseTaskFile;
|
|
70
|
+
exports.serializeTaskFile = serializeTaskFile;
|
|
71
|
+
exports.readTaskFile = readTaskFile;
|
|
72
|
+
exports.readAllTasks = readAllTasks;
|
|
73
|
+
exports.readAllLogs = readAllLogs;
|
|
74
|
+
exports.findV2Task = findV2Task;
|
|
75
|
+
exports.writeTaskFile = writeTaskFile;
|
|
76
|
+
exports.taskToV2 = taskToV2;
|
|
77
|
+
exports.v2ToTask = v2ToTask;
|
|
78
|
+
exports.readV2BoardConfig = readV2BoardConfig;
|
|
79
|
+
exports.buildBoardFromV2 = buildBoardFromV2;
|
|
80
|
+
exports.generateNextV2TaskId = generateNextV2TaskId;
|
|
81
|
+
const fs = __importStar(require("fs"));
|
|
82
|
+
const path = __importStar(require("path"));
|
|
83
|
+
const yaml = __importStar(require("js-yaml"));
|
|
84
|
+
// ============================================================================
|
|
85
|
+
// Path Helpers
|
|
86
|
+
// ============================================================================
|
|
87
|
+
/**
|
|
88
|
+
* Get the v2 directory structure paths from a brainfile path.
|
|
89
|
+
*/
|
|
90
|
+
function getV2Dirs(brainfilePath) {
|
|
91
|
+
const dotDir = path.dirname(path.resolve(brainfilePath));
|
|
92
|
+
return {
|
|
93
|
+
dotDir,
|
|
94
|
+
tasksDir: path.join(dotDir, 'tasks'),
|
|
95
|
+
logsDir: path.join(dotDir, 'logs'),
|
|
96
|
+
brainfilePath: path.resolve(brainfilePath),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Check if a brainfile is using v2 per-task file architecture.
|
|
101
|
+
* V2 is detected by the presence of a tasks/ directory in .brainfile/.
|
|
102
|
+
*/
|
|
103
|
+
function isV2(brainfilePath) {
|
|
104
|
+
const { tasksDir } = getV2Dirs(brainfilePath);
|
|
105
|
+
return fs.existsSync(tasksDir);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get the file path for a task.
|
|
109
|
+
*/
|
|
110
|
+
function getTaskFilePath(tasksDir, taskId) {
|
|
111
|
+
return path.join(tasksDir, `${taskId}.md`);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get the file path for a completed task (log).
|
|
115
|
+
*/
|
|
116
|
+
function getLogFilePath(logsDir, taskId) {
|
|
117
|
+
return path.join(logsDir, `${taskId}.md`);
|
|
118
|
+
}
|
|
119
|
+
// ============================================================================
|
|
120
|
+
// Ensure Directories
|
|
121
|
+
// ============================================================================
|
|
122
|
+
/**
|
|
123
|
+
* Ensure the v2 directory structure exists.
|
|
124
|
+
*/
|
|
125
|
+
function ensureV2Dirs(brainfilePath) {
|
|
126
|
+
const dirs = getV2Dirs(brainfilePath);
|
|
127
|
+
fs.mkdirSync(dirs.tasksDir, { recursive: true });
|
|
128
|
+
fs.mkdirSync(dirs.logsDir, { recursive: true });
|
|
129
|
+
return dirs;
|
|
130
|
+
}
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// Task File I/O
|
|
133
|
+
// ============================================================================
|
|
134
|
+
/**
|
|
135
|
+
* Parse a task .md file into frontmatter and markdown sections.
|
|
136
|
+
*/
|
|
137
|
+
function parseTaskFile(content) {
|
|
138
|
+
const match = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
139
|
+
if (!match) {
|
|
140
|
+
throw new Error('Invalid task file: missing YAML frontmatter');
|
|
141
|
+
}
|
|
142
|
+
const frontmatter = yaml.load(match[1]);
|
|
143
|
+
const body = match[2] || '';
|
|
144
|
+
// Extract description and log from markdown body
|
|
145
|
+
let description;
|
|
146
|
+
let log;
|
|
147
|
+
const descMatch = body.match(/## Description\n([\s\S]*?)(?=\n## |\n*$)/);
|
|
148
|
+
if (descMatch) {
|
|
149
|
+
description = descMatch[1].trim();
|
|
150
|
+
}
|
|
151
|
+
const logMatch = body.match(/## Log\n([\s\S]*?)(?=\n## |\n*$)/);
|
|
152
|
+
if (logMatch) {
|
|
153
|
+
log = logMatch[1].trim();
|
|
154
|
+
}
|
|
155
|
+
return { frontmatter, description, log, rawMarkdown: body };
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Serialize a task to .md file format.
|
|
159
|
+
*/
|
|
160
|
+
function serializeTaskFile(task, description, log) {
|
|
161
|
+
// Build frontmatter object - exclude description (goes in markdown body)
|
|
162
|
+
const fm = {
|
|
163
|
+
id: task.id,
|
|
164
|
+
title: task.title,
|
|
165
|
+
};
|
|
166
|
+
// Only include column/position for active tasks
|
|
167
|
+
if (task.column)
|
|
168
|
+
fm.column = task.column;
|
|
169
|
+
if (task.position !== undefined)
|
|
170
|
+
fm.position = task.position;
|
|
171
|
+
if (task.completedAt)
|
|
172
|
+
fm.completedAt = task.completedAt;
|
|
173
|
+
if (task.priority)
|
|
174
|
+
fm.priority = task.priority;
|
|
175
|
+
if (task.tags && task.tags.length > 0)
|
|
176
|
+
fm.tags = task.tags;
|
|
177
|
+
if (task.assignee)
|
|
178
|
+
fm.assignee = task.assignee;
|
|
179
|
+
if (task.dueDate)
|
|
180
|
+
fm.dueDate = task.dueDate;
|
|
181
|
+
if (task.relatedFiles && task.relatedFiles.length > 0)
|
|
182
|
+
fm.relatedFiles = task.relatedFiles;
|
|
183
|
+
if (task.subtasks && task.subtasks.length > 0)
|
|
184
|
+
fm.subtasks = task.subtasks;
|
|
185
|
+
if (task.template)
|
|
186
|
+
fm.template = task.template;
|
|
187
|
+
if (task.contract)
|
|
188
|
+
fm.contract = task.contract;
|
|
189
|
+
if (task.createdAt)
|
|
190
|
+
fm.createdAt = task.createdAt;
|
|
191
|
+
if (task.updatedAt)
|
|
192
|
+
fm.updatedAt = task.updatedAt;
|
|
193
|
+
const yamlStr = yaml.dump(fm, {
|
|
194
|
+
lineWidth: -1,
|
|
195
|
+
noRefs: true,
|
|
196
|
+
quotingType: '"',
|
|
197
|
+
forceQuotes: false,
|
|
198
|
+
}).trimEnd();
|
|
199
|
+
const sections = [];
|
|
200
|
+
sections.push(`---\n${yamlStr}\n---`);
|
|
201
|
+
// Use task.description if no explicit description passed
|
|
202
|
+
const desc = description ?? task.description;
|
|
203
|
+
if (desc && desc.trim()) {
|
|
204
|
+
sections.push(`\n## Description\n${desc.trim()}`);
|
|
205
|
+
}
|
|
206
|
+
if (log && log.trim()) {
|
|
207
|
+
sections.push(`\n## Log\n${log.trim()}`);
|
|
208
|
+
}
|
|
209
|
+
return sections.join('\n') + '\n';
|
|
210
|
+
}
|
|
211
|
+
// ============================================================================
|
|
212
|
+
// Read Operations
|
|
213
|
+
// ============================================================================
|
|
214
|
+
/**
|
|
215
|
+
* Read a single task file.
|
|
216
|
+
*/
|
|
217
|
+
function readTaskFile(filePath) {
|
|
218
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
219
|
+
return parseTaskFile(content);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Read all active tasks from the tasks/ directory.
|
|
223
|
+
*/
|
|
224
|
+
function readAllTasks(tasksDir) {
|
|
225
|
+
if (!fs.existsSync(tasksDir))
|
|
226
|
+
return [];
|
|
227
|
+
const files = fs.readdirSync(tasksDir).filter(f => f.endsWith('.md'));
|
|
228
|
+
const tasks = [];
|
|
229
|
+
for (const file of files) {
|
|
230
|
+
try {
|
|
231
|
+
const taskFile = readTaskFile(path.join(tasksDir, file));
|
|
232
|
+
tasks.push(taskFile);
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
// Skip invalid task files
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return tasks;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Read all completed tasks from the logs/ directory.
|
|
242
|
+
*/
|
|
243
|
+
function readAllLogs(logsDir) {
|
|
244
|
+
if (!fs.existsSync(logsDir))
|
|
245
|
+
return [];
|
|
246
|
+
const files = fs.readdirSync(logsDir).filter(f => f.endsWith('.md'));
|
|
247
|
+
const logs = [];
|
|
248
|
+
for (const file of files) {
|
|
249
|
+
try {
|
|
250
|
+
const taskFile = readTaskFile(path.join(logsDir, file));
|
|
251
|
+
logs.push(taskFile);
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
// Skip invalid log files
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return logs;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Find a task by ID across active tasks and optionally logs.
|
|
261
|
+
*/
|
|
262
|
+
function findV2Task(dirs, taskId, searchLogs = false) {
|
|
263
|
+
const taskPath = getTaskFilePath(dirs.tasksDir, taskId);
|
|
264
|
+
if (fs.existsSync(taskPath)) {
|
|
265
|
+
return { taskFile: readTaskFile(taskPath), filePath: taskPath, isLog: false };
|
|
266
|
+
}
|
|
267
|
+
if (searchLogs) {
|
|
268
|
+
const logPath = getLogFilePath(dirs.logsDir, taskId);
|
|
269
|
+
if (fs.existsSync(logPath)) {
|
|
270
|
+
return { taskFile: readTaskFile(logPath), filePath: logPath, isLog: true };
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
// ============================================================================
|
|
276
|
+
// Write Operations
|
|
277
|
+
// ============================================================================
|
|
278
|
+
/**
|
|
279
|
+
* Write a task file.
|
|
280
|
+
*/
|
|
281
|
+
function writeTaskFile(filePath, task, description, log) {
|
|
282
|
+
const content = serializeTaskFile(task, description, log);
|
|
283
|
+
fs.writeFileSync(filePath, content, 'utf-8');
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Convert a v1 Task to a V2Task with column and position.
|
|
287
|
+
*/
|
|
288
|
+
function taskToV2(task, column, position) {
|
|
289
|
+
return {
|
|
290
|
+
...task,
|
|
291
|
+
column,
|
|
292
|
+
position,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Convert a V2Task back to a v1 Task (stripping column/position).
|
|
297
|
+
*/
|
|
298
|
+
function v2ToTask(v2task) {
|
|
299
|
+
const { column, position, completedAt, ...task } = v2task;
|
|
300
|
+
return task;
|
|
301
|
+
}
|
|
302
|
+
// ============================================================================
|
|
303
|
+
// Board Config Reading (v2 board has no tasks in YAML)
|
|
304
|
+
// ============================================================================
|
|
305
|
+
/**
|
|
306
|
+
* Read the v2 board config (columns, rules, etc. without embedded tasks).
|
|
307
|
+
*/
|
|
308
|
+
function readV2BoardConfig(brainfilePath) {
|
|
309
|
+
const content = fs.readFileSync(brainfilePath, 'utf-8');
|
|
310
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
311
|
+
if (!match) {
|
|
312
|
+
throw new Error('Invalid brainfile: missing YAML frontmatter');
|
|
313
|
+
}
|
|
314
|
+
const config = yaml.load(match[1]);
|
|
315
|
+
// Ensure columns exist and have empty task arrays
|
|
316
|
+
if (config.columns) {
|
|
317
|
+
for (const col of config.columns) {
|
|
318
|
+
if (!col.tasks)
|
|
319
|
+
col.tasks = [];
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
config.columns = [];
|
|
324
|
+
}
|
|
325
|
+
return config;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Build a full v1-compatible Board from v2 per-task files.
|
|
329
|
+
* Reads the board config and populates column tasks from the tasks/ directory.
|
|
330
|
+
*/
|
|
331
|
+
function buildBoardFromV2(brainfilePath) {
|
|
332
|
+
const dirs = getV2Dirs(brainfilePath);
|
|
333
|
+
const board = readV2BoardConfig(brainfilePath);
|
|
334
|
+
const taskFiles = readAllTasks(dirs.tasksDir);
|
|
335
|
+
// Group tasks by column
|
|
336
|
+
const tasksByColumn = new Map();
|
|
337
|
+
for (const tf of taskFiles) {
|
|
338
|
+
const col = tf.frontmatter.column || 'todo';
|
|
339
|
+
if (!tasksByColumn.has(col)) {
|
|
340
|
+
tasksByColumn.set(col, []);
|
|
341
|
+
}
|
|
342
|
+
tasksByColumn.get(col).push(tf);
|
|
343
|
+
}
|
|
344
|
+
// Populate board columns with tasks sorted by position
|
|
345
|
+
for (const col of board.columns) {
|
|
346
|
+
const colTasks = tasksByColumn.get(col.id) || [];
|
|
347
|
+
colTasks.sort((a, b) => (a.frontmatter.position || 0) - (b.frontmatter.position || 0));
|
|
348
|
+
col.tasks = colTasks.map(tf => {
|
|
349
|
+
const task = v2ToTask(tf.frontmatter);
|
|
350
|
+
// Restore description from markdown body if not in frontmatter
|
|
351
|
+
if (tf.description && !task.description) {
|
|
352
|
+
task.description = tf.description;
|
|
353
|
+
}
|
|
354
|
+
return task;
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
return board;
|
|
358
|
+
}
|
|
359
|
+
// ============================================================================
|
|
360
|
+
// ID Generation for v2
|
|
361
|
+
// ============================================================================
|
|
362
|
+
/**
|
|
363
|
+
* Generate the next task ID by scanning existing task files.
|
|
364
|
+
*/
|
|
365
|
+
function generateNextV2TaskId(dirs) {
|
|
366
|
+
const taskFiles = fs.existsSync(dirs.tasksDir)
|
|
367
|
+
? fs.readdirSync(dirs.tasksDir).filter(f => f.endsWith('.md'))
|
|
368
|
+
: [];
|
|
369
|
+
const logFiles = fs.existsSync(dirs.logsDir)
|
|
370
|
+
? fs.readdirSync(dirs.logsDir).filter(f => f.endsWith('.md'))
|
|
371
|
+
: [];
|
|
372
|
+
const allFiles = [...taskFiles, ...logFiles];
|
|
373
|
+
let maxNum = 0;
|
|
374
|
+
for (const file of allFiles) {
|
|
375
|
+
const match = file.match(/^task-(\d+)\.md$/);
|
|
376
|
+
if (match) {
|
|
377
|
+
const num = parseInt(match[1], 10);
|
|
378
|
+
if (num > maxNum)
|
|
379
|
+
maxNum = num;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return `task-${maxNum + 1}`;
|
|
383
|
+
}
|
|
384
|
+
//# sourceMappingURL=v2-tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2-tasks.js","sourceRoot":"","sources":["../../src/utils/v2-tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type WorkspaceFormat = 'v2' | 'legacy-root' | 'legacy-dotbrainfile' | 'mixed' | 'empty';
|
|
2
|
+
export interface WorkspacePaths {
|
|
3
|
+
rootDir: string;
|
|
4
|
+
rootBrainfilePath: string;
|
|
5
|
+
dotDir: string;
|
|
6
|
+
dotBrainfilePath: string;
|
|
7
|
+
boardDir: string;
|
|
8
|
+
logsDir: string;
|
|
9
|
+
}
|
|
10
|
+
export interface WorkspacePresence {
|
|
11
|
+
rootBrainfile: boolean;
|
|
12
|
+
dotBrainfile: boolean;
|
|
13
|
+
boardDir: boolean;
|
|
14
|
+
logsDir: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface WorkspaceProbe {
|
|
17
|
+
format: WorkspaceFormat;
|
|
18
|
+
paths: WorkspacePaths;
|
|
19
|
+
presence: WorkspacePresence;
|
|
20
|
+
}
|
|
21
|
+
export declare function workspaceRootFromBrainfilePath(brainfilePath: string): string;
|
|
22
|
+
export declare function probeWorkspaceFormat(rootDir?: string): WorkspaceProbe;
|
|
23
|
+
export declare function probeWorkspaceForBrainfile(brainfilePath: string): WorkspaceProbe;
|
|
24
|
+
export declare function shouldSuggestMigration(probe: WorkspaceProbe): boolean;
|
|
25
|
+
//# sourceMappingURL=workspace-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-format.d.ts","sourceRoot":"","sources":["../../src/utils/workspace-format.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,eAAe,GACvB,IAAI,GACJ,aAAa,GACb,qBAAqB,GACrB,OAAO,GACP,OAAO,CAAC;AAEZ,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,cAAc,CAAC;IACtB,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAkBD,wBAAgB,8BAA8B,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAI5E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,MAAsB,GAAG,cAAc,CAqCpF;AAED,wBAAgB,0BAA0B,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,CAEhF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAErE"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.workspaceRootFromBrainfilePath = workspaceRootFromBrainfilePath;
|
|
37
|
+
exports.probeWorkspaceFormat = probeWorkspaceFormat;
|
|
38
|
+
exports.probeWorkspaceForBrainfile = probeWorkspaceForBrainfile;
|
|
39
|
+
exports.shouldSuggestMigration = shouldSuggestMigration;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
function existsFile(filePath) {
|
|
43
|
+
try {
|
|
44
|
+
return fs.statSync(filePath).isFile();
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function existsDir(dirPath) {
|
|
51
|
+
try {
|
|
52
|
+
return fs.statSync(dirPath).isDirectory();
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function workspaceRootFromBrainfilePath(brainfilePath) {
|
|
59
|
+
const absolute = path.resolve(brainfilePath);
|
|
60
|
+
const dir = path.dirname(absolute);
|
|
61
|
+
return path.basename(dir) === '.brainfile' ? path.dirname(dir) : dir;
|
|
62
|
+
}
|
|
63
|
+
function probeWorkspaceFormat(rootDir = process.cwd()) {
|
|
64
|
+
const resolvedRoot = path.resolve(rootDir);
|
|
65
|
+
const dotDir = path.join(resolvedRoot, '.brainfile');
|
|
66
|
+
const paths = {
|
|
67
|
+
rootDir: resolvedRoot,
|
|
68
|
+
rootBrainfilePath: path.join(resolvedRoot, 'brainfile.md'),
|
|
69
|
+
dotDir,
|
|
70
|
+
dotBrainfilePath: path.join(dotDir, 'brainfile.md'),
|
|
71
|
+
boardDir: path.join(dotDir, 'board'),
|
|
72
|
+
logsDir: path.join(dotDir, 'logs'),
|
|
73
|
+
};
|
|
74
|
+
const presence = {
|
|
75
|
+
rootBrainfile: existsFile(paths.rootBrainfilePath),
|
|
76
|
+
dotBrainfile: existsFile(paths.dotBrainfilePath),
|
|
77
|
+
boardDir: existsDir(paths.boardDir),
|
|
78
|
+
logsDir: existsDir(paths.logsDir),
|
|
79
|
+
};
|
|
80
|
+
const hasAnyV2Artifacts = presence.boardDir || presence.logsDir;
|
|
81
|
+
const hasFullV2 = presence.dotBrainfile && presence.boardDir && presence.logsDir;
|
|
82
|
+
let format;
|
|
83
|
+
if (!presence.rootBrainfile && !presence.dotBrainfile && !hasAnyV2Artifacts) {
|
|
84
|
+
format = 'empty';
|
|
85
|
+
}
|
|
86
|
+
else if (hasFullV2 && !presence.rootBrainfile) {
|
|
87
|
+
format = 'v2';
|
|
88
|
+
}
|
|
89
|
+
else if (presence.rootBrainfile && !presence.dotBrainfile && !hasAnyV2Artifacts) {
|
|
90
|
+
format = 'legacy-root';
|
|
91
|
+
}
|
|
92
|
+
else if (!presence.rootBrainfile && presence.dotBrainfile && !hasAnyV2Artifacts) {
|
|
93
|
+
format = 'legacy-dotbrainfile';
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
format = 'mixed';
|
|
97
|
+
}
|
|
98
|
+
return { format, paths, presence };
|
|
99
|
+
}
|
|
100
|
+
function probeWorkspaceForBrainfile(brainfilePath) {
|
|
101
|
+
return probeWorkspaceFormat(workspaceRootFromBrainfilePath(brainfilePath));
|
|
102
|
+
}
|
|
103
|
+
function shouldSuggestMigration(probe) {
|
|
104
|
+
return probe.format === 'legacy-root' || probe.format === 'legacy-dotbrainfile' || probe.format === 'mixed';
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=workspace-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-format.js","sourceRoot":"","sources":["../../src/utils/workspace-format.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainfile/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "Command-line interface for Brainfile task management",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@brainfile/core": "^0.
|
|
37
|
+
"@brainfile/core": "^0.12.0",
|
|
38
38
|
"@modelcontextprotocol/sdk": "^1.22.0",
|
|
39
39
|
"chalk": "^4.1.2",
|
|
40
40
|
"chokidar": "^4.0.3",
|
|
41
41
|
"commander": "^12.1.0",
|
|
42
42
|
"ink": "^3.2.0",
|
|
43
|
-
"open": "^10.1.0",
|
|
44
43
|
"js-yaml": "^4.1.0",
|
|
44
|
+
"open": "^10.1.0",
|
|
45
45
|
"react": "^17.0.2",
|
|
46
46
|
"zod": "^3.25.76"
|
|
47
47
|
},
|
package/state.json
ADDED