@brainfile/cli 0.13.2 → 0.13.3

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.
@@ -0,0 +1,369 @@
1
+ "use strict";
2
+ /**
3
+ * Schema command for Brainfile CLI
4
+ *
5
+ * View and manage brainfile schemas locally, eliminating network access for basic usage.
6
+ *
7
+ * Usage:
8
+ * brainfile schema # List available schemas
9
+ * brainfile schema <name> # Display specific schema
10
+ * brainfile schema update # Check for and download schema updates
11
+ * brainfile schema --json # Output in JSON format
12
+ *
13
+ * @packageDocumentation
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ var __importDefault = (this && this.__importDefault) || function (mod) {
49
+ return (mod && mod.__esModule) ? mod : { "default": mod };
50
+ };
51
+ Object.defineProperty(exports, "__esModule", { value: true });
52
+ exports.SCHEMA_COMMAND_HELP = void 0;
53
+ exports.schemaCommand = schemaCommand;
54
+ exports.schemaUpdateCommand = schemaUpdateCommand;
55
+ const fs = __importStar(require("fs"));
56
+ const path = __importStar(require("path"));
57
+ const chalk_1 = __importDefault(require("chalk"));
58
+ const logger_1 = require("../utils/logger");
59
+ const cli_error_1 = require("../utils/cli-error");
60
+ const errorHandler_1 = require("../utils/errorHandler");
61
+ const config_1 = require("../utils/config");
62
+ // ============================================================================
63
+ // Constants
64
+ // ============================================================================
65
+ const SCHEMA_BASE_URL = 'https://brainfile.md/v1';
66
+ const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
67
+ // Get bundled schemas directory (relative to this file after compilation)
68
+ function getBundledSchemasDir() {
69
+ // In development: cli/src/schemas
70
+ // In production: cli/dist/schemas
71
+ const distPath = path.join(__dirname, '..', 'schemas');
72
+ const srcPath = path.join(__dirname, '..', '..', 'src', 'schemas');
73
+ if (fs.existsSync(distPath)) {
74
+ return distPath;
75
+ }
76
+ if (fs.existsSync(srcPath)) {
77
+ return srcPath;
78
+ }
79
+ // Fallback for development
80
+ return path.join(__dirname, 'schemas');
81
+ }
82
+ // Schema metadata
83
+ const BUNDLED_SCHEMAS = [
84
+ {
85
+ id: 'board',
86
+ description: 'Board structure (columns, tasks, contracts)',
87
+ file: 'board.json',
88
+ },
89
+ {
90
+ id: 'base',
91
+ description: 'Base types (rules, agent instructions)',
92
+ file: 'base.json',
93
+ },
94
+ ];
95
+ // ============================================================================
96
+ // Help Text
97
+ // ============================================================================
98
+ exports.SCHEMA_COMMAND_HELP = `
99
+ Examples:
100
+ brainfile schema # List available schemas
101
+ brainfile schema board # View the board schema
102
+ brainfile schema base # View the base schema
103
+ brainfile schema update # Check for schema updates
104
+ brainfile schema board --json # Output board schema as JSON
105
+
106
+ Bundled schemas:
107
+ board - Board structure (columns, tasks, contracts)
108
+ base - Base types (rules, agent instructions)
109
+
110
+ Notes:
111
+ - Schemas are bundled with the CLI (no network required for basic usage)
112
+ - Use 'schema update' to check for newer versions from brainfile.md
113
+ - Auto-checks once per 24 hours (non-blocking notification)
114
+ `.trimEnd();
115
+ // ============================================================================
116
+ // Main Command
117
+ // ============================================================================
118
+ function schemaCommand(options, logger = logger_1.defaultLogger) {
119
+ const { name, json } = options;
120
+ // Handle update subcommand
121
+ if (name === 'update') {
122
+ return schemaUpdateCommand({ json }, logger);
123
+ }
124
+ // Handle show specific schema
125
+ if (name) {
126
+ return schemaShowCommand(name, { json }, logger);
127
+ }
128
+ // List all schemas
129
+ return schemaListCommand({ json }, logger);
130
+ }
131
+ // ============================================================================
132
+ // List Schemas
133
+ // ============================================================================
134
+ function schemaListCommand(options, logger) {
135
+ if (options.json) {
136
+ const output = {
137
+ schemas: BUNDLED_SCHEMAS.map((s) => ({
138
+ id: s.id,
139
+ description: s.description,
140
+ })),
141
+ };
142
+ logger.log(JSON.stringify(output, null, 2));
143
+ }
144
+ else {
145
+ logger.log('');
146
+ logger.log(chalk_1.default.bold('Available schemas:'));
147
+ logger.log('');
148
+ const maxIdLen = Math.max(...BUNDLED_SCHEMAS.map((s) => s.id.length));
149
+ for (const schema of BUNDLED_SCHEMAS) {
150
+ logger.log(` ${chalk_1.default.cyan(schema.id.padEnd(maxIdLen))} ${chalk_1.default.gray('-')} ${schema.description}`);
151
+ }
152
+ logger.log('');
153
+ logger.log(chalk_1.default.gray('Run: brainfile schema <name> to view schema'));
154
+ logger.log(chalk_1.default.gray('Run: brainfile schema update to check for updates'));
155
+ }
156
+ // Check for auto-update (non-blocking)
157
+ checkAutoUpdate(logger);
158
+ return {
159
+ success: true,
160
+ action: 'list',
161
+ schemas: BUNDLED_SCHEMAS.map((s) => s.id),
162
+ };
163
+ }
164
+ // ============================================================================
165
+ // Show Schema
166
+ // ============================================================================
167
+ function schemaShowCommand(name, options, logger) {
168
+ const schemaInfo = BUNDLED_SCHEMAS.find((s) => s.id === name);
169
+ if (!schemaInfo) {
170
+ const availableIds = BUNDLED_SCHEMAS.map((s) => s.id).join(', ');
171
+ throw new cli_error_1.CLIError(`Unknown schema: ${name}`, errorHandler_1.ExitCode.USER_ERROR, `Available schemas: ${availableIds}`);
172
+ }
173
+ const schemasDir = getBundledSchemasDir();
174
+ const schemaPath = path.join(schemasDir, schemaInfo.file);
175
+ if (!fs.existsSync(schemaPath)) {
176
+ throw new cli_error_1.CLIError(`Schema file not found: ${schemaInfo.file}`, errorHandler_1.ExitCode.USER_ERROR, `Expected at: ${schemaPath}`);
177
+ }
178
+ const content = fs.readFileSync(schemaPath, 'utf-8');
179
+ const schema = JSON.parse(content);
180
+ if (options.json) {
181
+ logger.log(JSON.stringify(schema, null, 2));
182
+ }
183
+ else {
184
+ logger.log('');
185
+ logger.log(chalk_1.default.bold(`Schema: ${name}`));
186
+ logger.log(chalk_1.default.gray(`Description: ${schemaInfo.description}`));
187
+ logger.log(chalk_1.default.gray(`Source: ${SCHEMA_BASE_URL}/${schemaInfo.file}`));
188
+ logger.log('');
189
+ logger.log(JSON.stringify(schema, null, 2));
190
+ }
191
+ return {
192
+ success: true,
193
+ action: 'show',
194
+ schema,
195
+ };
196
+ }
197
+ // ============================================================================
198
+ // Update Schemas
199
+ // ============================================================================
200
+ async function fetchWithTimeout(url, timeoutMs) {
201
+ const controller = new AbortController();
202
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
203
+ try {
204
+ const response = await fetch(url, { signal: controller.signal });
205
+ return response;
206
+ }
207
+ finally {
208
+ clearTimeout(timeout);
209
+ }
210
+ }
211
+ function schemaUpdateCommand(options, logger = logger_1.defaultLogger) {
212
+ // Run the async update and handle synchronously for CLI
213
+ schemaUpdateAsync(options, logger);
214
+ return {
215
+ success: true,
216
+ action: 'update',
217
+ updated: false, // Will be updated by async function
218
+ };
219
+ }
220
+ async function schemaUpdateAsync(options, logger) {
221
+ if (!options.json) {
222
+ logger.log('');
223
+ logger.log(chalk_1.default.bold('Checking for schema updates...'));
224
+ logger.log('');
225
+ }
226
+ const schemasDir = getBundledSchemasDir();
227
+ const results = [];
228
+ for (const schemaInfo of BUNDLED_SCHEMAS) {
229
+ const url = `${SCHEMA_BASE_URL}/${schemaInfo.file}`;
230
+ const localPath = path.join(schemasDir, schemaInfo.file);
231
+ try {
232
+ const response = await fetchWithTimeout(url, 10000);
233
+ if (!response.ok) {
234
+ results.push({
235
+ id: schemaInfo.id,
236
+ status: 'error',
237
+ error: `HTTP ${response.status}`,
238
+ });
239
+ continue;
240
+ }
241
+ const remoteContent = await response.text();
242
+ const remoteSchema = JSON.parse(remoteContent);
243
+ // Compare with local
244
+ let localSchema = null;
245
+ if (fs.existsSync(localPath)) {
246
+ const localContent = fs.readFileSync(localPath, 'utf-8');
247
+ localSchema = JSON.parse(localContent);
248
+ }
249
+ // Simple comparison using JSON stringification
250
+ const remoteStr = JSON.stringify(remoteSchema);
251
+ const localStr = localSchema ? JSON.stringify(localSchema) : '';
252
+ if (remoteStr !== localStr) {
253
+ // Update local schema
254
+ fs.writeFileSync(localPath, JSON.stringify(remoteSchema, null, 2));
255
+ results.push({ id: schemaInfo.id, status: 'updated' });
256
+ }
257
+ else {
258
+ results.push({ id: schemaInfo.id, status: 'current' });
259
+ }
260
+ }
261
+ catch (error) {
262
+ const errorMsg = error instanceof Error ? error.message : String(error);
263
+ results.push({ id: schemaInfo.id, status: 'error', error: errorMsg });
264
+ }
265
+ }
266
+ // Update last check time
267
+ updateLastCheckTime();
268
+ // Output results
269
+ if (options.json) {
270
+ logger.log(JSON.stringify({ schemas: results }, null, 2));
271
+ }
272
+ else {
273
+ for (const result of results) {
274
+ if (result.status === 'updated') {
275
+ logger.log(` ${chalk_1.default.green('+')} ${chalk_1.default.cyan(result.id)} - Updated`);
276
+ }
277
+ else if (result.status === 'current') {
278
+ logger.log(` ${chalk_1.default.gray('=')} ${chalk_1.default.cyan(result.id)} - Up to date`);
279
+ }
280
+ else {
281
+ logger.log(` ${chalk_1.default.red('!')} ${chalk_1.default.cyan(result.id)} - Error: ${result.error}`);
282
+ }
283
+ }
284
+ const updatedCount = results.filter((r) => r.status === 'updated').length;
285
+ logger.log('');
286
+ if (updatedCount > 0) {
287
+ logger.log(chalk_1.default.green(`Updated ${updatedCount} schema(s)`));
288
+ }
289
+ else {
290
+ logger.log(chalk_1.default.gray('All schemas are up to date'));
291
+ }
292
+ }
293
+ }
294
+ // ============================================================================
295
+ // Auto-Update Check
296
+ // ============================================================================
297
+ function getSchemaConfig() {
298
+ const config = (0, config_1.loadConfig)();
299
+ return config.schema || {};
300
+ }
301
+ function saveSchemaConfig(schemaConfig) {
302
+ const config = (0, config_1.loadConfig)();
303
+ config.schema = schemaConfig;
304
+ (0, config_1.saveConfig)(config);
305
+ }
306
+ function updateLastCheckTime() {
307
+ const schemaConfig = getSchemaConfig();
308
+ schemaConfig.lastCheck = new Date().toISOString();
309
+ saveSchemaConfig(schemaConfig);
310
+ }
311
+ function shouldAutoCheck() {
312
+ const schemaConfig = getSchemaConfig();
313
+ if (!schemaConfig.lastCheck) {
314
+ return true;
315
+ }
316
+ const lastCheck = new Date(schemaConfig.lastCheck).getTime();
317
+ const now = Date.now();
318
+ return now - lastCheck > CHECK_INTERVAL_MS;
319
+ }
320
+ function checkAutoUpdate(logger) {
321
+ if (!shouldAutoCheck()) {
322
+ return;
323
+ }
324
+ // Run async check in background (non-blocking)
325
+ checkForUpdatesAsync(logger).catch(() => {
326
+ // Silently ignore errors during auto-check
327
+ });
328
+ }
329
+ async function checkForUpdatesAsync(logger) {
330
+ const schemasDir = getBundledSchemasDir();
331
+ let hasUpdates = false;
332
+ for (const schemaInfo of BUNDLED_SCHEMAS) {
333
+ const url = `${SCHEMA_BASE_URL}/${schemaInfo.file}`;
334
+ const localPath = path.join(schemasDir, schemaInfo.file);
335
+ try {
336
+ const response = await fetchWithTimeout(url, 5000);
337
+ if (!response.ok) {
338
+ continue;
339
+ }
340
+ const remoteContent = await response.text();
341
+ const remoteSchema = JSON.parse(remoteContent);
342
+ // Compare with local
343
+ if (fs.existsSync(localPath)) {
344
+ const localContent = fs.readFileSync(localPath, 'utf-8');
345
+ const localSchema = JSON.parse(localContent);
346
+ const remoteStr = JSON.stringify(remoteSchema);
347
+ const localStr = JSON.stringify(localSchema);
348
+ if (remoteStr !== localStr) {
349
+ hasUpdates = true;
350
+ break;
351
+ }
352
+ }
353
+ }
354
+ catch {
355
+ // Silently ignore errors during auto-check
356
+ }
357
+ }
358
+ // Update last check time
359
+ updateLastCheckTime();
360
+ // Notify user if updates available
361
+ if (hasUpdates) {
362
+ logger.log('');
363
+ logger.log(chalk_1.default.yellow('Hint: ') +
364
+ 'Schema updates available. Run ' +
365
+ chalk_1.default.cyan('brainfile schema update') +
366
+ ' to update.');
367
+ }
368
+ }
369
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/commands/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,159 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://brainfile.md/v1/base.json",
4
+ "title": "Brainfile Base Schema",
5
+ "description": "Base schema that all brainfile types extend. Defines shared fields across all types. Community types can extend this schema with custom fields.",
6
+ "type": "object",
7
+ "required": ["title"],
8
+ "properties": {
9
+ "type": {
10
+ "type": "string",
11
+ "description": "Type identifier. Default: board.",
12
+ "minLength": 1,
13
+ "examples": ["board"]
14
+ },
15
+ "schema": {
16
+ "type": "string",
17
+ "description": "Schema URL for validation. Official types default to brainfile.md/v1/{type}.json. Community types MUST provide a schema URL for validation. Can be a remote URI (https://) or local file path.",
18
+ "examples": [
19
+ "https://brainfile.md/v1/board.json"
20
+ ]
21
+ },
22
+ "title": {
23
+ "type": "string",
24
+ "description": "Title of the brainfile",
25
+ "minLength": 1,
26
+ "examples": ["My Project", "Dev Log 2025", "Reading List"]
27
+ },
28
+ "protocolVersion": {
29
+ "type": "string",
30
+ "description": "Version of the Brainfile protocol this file uses",
31
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
32
+ "default": "1.0.0"
33
+ },
34
+ "agent": {
35
+ "type": "object",
36
+ "description": "Instructions for AI agents interacting with the brainfile",
37
+ "properties": {
38
+ "instructions": {
39
+ "type": "array",
40
+ "description": "List of instructions for AI agents",
41
+ "items": {
42
+ "type": "string",
43
+ "minLength": 1
44
+ },
45
+ "examples": [
46
+ ["Modify only the YAML frontmatter", "Preserve all IDs", "Use ISO dates for entries"]
47
+ ]
48
+ },
49
+ "llmNotes": {
50
+ "type": "string",
51
+ "description": "Free-form notes about how this project prefers AI work to be structured"
52
+ },
53
+ "tools": {
54
+ "type": "object",
55
+ "description": "CLI tools and commands available for agents to use. Reduces token usage vs manual file editing.",
56
+ "additionalProperties": {
57
+ "type": "object",
58
+ "description": "Tool configuration",
59
+ "properties": {
60
+ "description": {
61
+ "type": "string",
62
+ "description": "What this tool is for"
63
+ },
64
+ "alias": {
65
+ "type": "string",
66
+ "description": "Command alias if different from tool name"
67
+ },
68
+ "prefer": {
69
+ "type": ["boolean", "string"],
70
+ "description": "Whether to prefer this tool, or a note about when to prefer it"
71
+ },
72
+ "commands": {
73
+ "type": "array",
74
+ "description": "Available commands with their syntax",
75
+ "items": {
76
+ "type": "string"
77
+ }
78
+ }
79
+ },
80
+ "additionalProperties": true
81
+ },
82
+ "examples": [
83
+ {
84
+ "brainfile": {
85
+ "prefer": true,
86
+ "commands": ["move --task <id> --column <id>", "add --title \"...\" --column <id>", "list"]
87
+ },
88
+ "ripgrep": {
89
+ "alias": "rg",
90
+ "prefer": "use for all file content searches"
91
+ }
92
+ }
93
+ ]
94
+ }
95
+ },
96
+ "additionalProperties": true
97
+ },
98
+ "rules": {
99
+ "type": "object",
100
+ "description": "Project rules organized by category",
101
+ "properties": {
102
+ "always": {
103
+ "type": "array",
104
+ "description": "Rules that must always be followed",
105
+ "items": {
106
+ "$ref": "#/definitions/rule"
107
+ }
108
+ },
109
+ "never": {
110
+ "type": "array",
111
+ "description": "Rules that must never be violated",
112
+ "items": {
113
+ "$ref": "#/definitions/rule"
114
+ }
115
+ },
116
+ "prefer": {
117
+ "type": "array",
118
+ "description": "Preferred approaches or patterns",
119
+ "items": {
120
+ "$ref": "#/definitions/rule"
121
+ }
122
+ },
123
+ "context": {
124
+ "type": "array",
125
+ "description": "Contextual information and constraints",
126
+ "items": {
127
+ "$ref": "#/definitions/rule"
128
+ }
129
+ }
130
+ },
131
+ "additionalProperties": true
132
+ }
133
+ },
134
+ "additionalProperties": true,
135
+ "definitions": {
136
+ "rule": {
137
+ "type": "object",
138
+ "required": ["id", "rule"],
139
+ "properties": {
140
+ "id": {
141
+ "type": ["integer", "string"],
142
+ "description": "Unique identifier within the rule category"
143
+ },
144
+ "rule": {
145
+ "type": "string",
146
+ "description": "The rule text",
147
+ "minLength": 1
148
+ }
149
+ },
150
+ "additionalProperties": true
151
+ },
152
+ "timestamp": {
153
+ "type": "string",
154
+ "description": "ISO 8601 timestamp",
155
+ "format": "date-time",
156
+ "examples": ["2025-11-24T10:30:00Z", "2025-11-24T14:22:00-08:00"]
157
+ }
158
+ }
159
+ }