brainfile 0.20.0 → 0.21.0
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/dist/{chunk-UOCQBEEW.mjs → chunk-FOLBAGJS.mjs} +1232 -318
- package/dist/cli.mjs +2048 -1318
- package/dist/commands/brief.d.ts +1 -0
- package/dist/commands/brief.d.ts.map +1 -1
- package/dist/commands/brief.js +10 -0
- package/dist/commands/brief.js.map +1 -1
- package/dist/commands/init.d.ts +14 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +115 -15
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +44 -0
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/merge-driver.d.ts +26 -0
- package/dist/commands/merge-driver.d.ts.map +1 -0
- package/dist/commands/merge-driver.js +195 -0
- package/dist/commands/merge-driver.js.map +1 -0
- package/dist/commands/migrate-tracked.d.ts +8 -0
- package/dist/commands/migrate-tracked.d.ts.map +1 -0
- package/dist/commands/migrate-tracked.js +428 -0
- package/dist/commands/migrate-tracked.js.map +1 -0
- package/dist/commands/migrate.d.ts +6 -0
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +9 -0
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/sync.d.ts +16 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +152 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/where.d.ts +21 -0
- package/dist/commands/where.d.ts.map +1 -0
- package/dist/commands/where.js +135 -0
- package/dist/commands/where.js.map +1 -0
- package/dist/mcp/helpers.d.ts +8 -0
- package/dist/mcp/helpers.d.ts.map +1 -1
- package/dist/mcp/helpers.js +44 -0
- package/dist/mcp/helpers.js.map +1 -1
- package/dist/mcp/tools/brief_tool.d.ts.map +1 -1
- package/dist/mcp/tools/brief_tool.js +39 -1
- package/dist/mcp/tools/brief_tool.js.map +1 -1
- package/dist/mcp/tools/contract_tool.d.ts.map +1 -1
- package/dist/mcp/tools/contract_tool.js +6 -5
- package/dist/mcp/tools/contract_tool.js.map +1 -1
- package/dist/mcp/tools/subtask_tool.d.ts.map +1 -1
- package/dist/mcp/tools/subtask_tool.js +5 -4
- package/dist/mcp/tools/subtask_tool.js.map +1 -1
- package/dist/mcp/tools/task_add_tool.d.ts.map +1 -1
- package/dist/mcp/tools/task_add_tool.js +6 -5
- package/dist/mcp/tools/task_add_tool.js.map +1 -1
- package/dist/mcp/tools/task_complete_tool.d.ts.map +1 -1
- package/dist/mcp/tools/task_complete_tool.js +5 -4
- package/dist/mcp/tools/task_complete_tool.js.map +1 -1
- package/dist/mcp/tools/task_delete_tool.d.ts.map +1 -1
- package/dist/mcp/tools/task_delete_tool.js +5 -4
- package/dist/mcp/tools/task_delete_tool.js.map +1 -1
- package/dist/mcp/tools/task_move_tool.d.ts.map +1 -1
- package/dist/mcp/tools/task_move_tool.js +6 -5
- package/dist/mcp/tools/task_move_tool.js.map +1 -1
- package/dist/mcp/tools/task_patch_tool.d.ts.map +1 -1
- package/dist/mcp/tools/task_patch_tool.js +5 -4
- package/dist/mcp/tools/task_patch_tool.js.map +1 -1
- package/dist/{tui-H3RI22S4.mjs → tui-M2KWIG2E.mjs} +295 -253
- package/dist/utils/board-autosync.d.ts +22 -0
- package/dist/utils/board-autosync.d.ts.map +1 -0
- package/dist/utils/board-autosync.js +166 -0
- package/dist/utils/board-autosync.js.map +1 -0
- package/dist/utils/board-commit-hooks.d.ts +12 -0
- package/dist/utils/board-commit-hooks.d.ts.map +1 -0
- package/dist/utils/board-commit-hooks.js +51 -0
- package/dist/utils/board-commit-hooks.js.map +1 -0
- package/dist/utils/board-repo.d.ts +108 -0
- package/dist/utils/board-repo.d.ts.map +1 -0
- package/dist/utils/board-repo.js +501 -0
- package/dist/utils/board-repo.js.map +1 -0
- package/dist/utils/board-sync.d.ts +111 -0
- package/dist/utils/board-sync.d.ts.map +1 -0
- package/dist/utils/board-sync.js +469 -0
- package/dist/utils/board-sync.js.map +1 -0
- package/dist/utils/brainfile-path.d.ts +11 -1
- package/dist/utils/brainfile-path.d.ts.map +1 -1
- package/dist/utils/brainfile-path.js +39 -2
- package/dist/utils/brainfile-path.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type AutosyncMode, type SyncResult } from './board-sync';
|
|
2
|
+
export declare const AUTOSYNC_DELAY_MS = 5000;
|
|
3
|
+
export declare const FETCH_MAX_AGE_SECONDS = 60;
|
|
4
|
+
export declare function effectiveAutosync(dotDir: string): AutosyncMode;
|
|
5
|
+
/** The runnable CLI: the bundle we live in, or the built one next to the sources. */
|
|
6
|
+
export declare function autosyncCliPath(): string | null;
|
|
7
|
+
export declare function clearPushLock(dotDir: string): void;
|
|
8
|
+
/**
|
|
9
|
+
* Queue a background push for the board. Returns true when a child was
|
|
10
|
+
* started; false when autosync is off, no remote is set, a push is already
|
|
11
|
+
* pending (it will carry this commit too), or there is no CLI to run.
|
|
12
|
+
*/
|
|
13
|
+
export declare function schedulePush(dotDir: string, delayMs?: number): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* In `full` mode, bring the board up to date before a read when the last
|
|
16
|
+
* sync attempt is older than `maxAgeSeconds`. Returns the sync result, or
|
|
17
|
+
* null when nothing was fetched.
|
|
18
|
+
*/
|
|
19
|
+
export declare function fetchBeforeRead(dotDir: string, maxAgeSeconds?: number): SyncResult | null;
|
|
20
|
+
/** Push after every successful board commit made by this process. */
|
|
21
|
+
export declare function installAutosync(): void;
|
|
22
|
+
//# sourceMappingURL=board-autosync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-autosync.d.ts","sourceRoot":"","sources":["../../src/utils/board-autosync.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAA2D,MAAM,cAAc,CAAC;AAE3H,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAKxC,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAI9D;AAED,qFAAqF;AACrF,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAO/C;AAuBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAMlD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,SAAoB,GAAG,OAAO,CAuBjF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,SAAwB,GAAG,UAAU,GAAG,IAAI,CAMxG;AAGD,qEAAqE;AACrE,wBAAgB,eAAe,IAAI,IAAI,CAMtC"}
|
|
@@ -0,0 +1,166 @@
|
|
|
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.FETCH_MAX_AGE_SECONDS = exports.AUTOSYNC_DELAY_MS = void 0;
|
|
37
|
+
exports.effectiveAutosync = effectiveAutosync;
|
|
38
|
+
exports.autosyncCliPath = autosyncCliPath;
|
|
39
|
+
exports.clearPushLock = clearPushLock;
|
|
40
|
+
exports.schedulePush = schedulePush;
|
|
41
|
+
exports.fetchBeforeRead = fetchBeforeRead;
|
|
42
|
+
exports.installAutosync = installAutosync;
|
|
43
|
+
/**
|
|
44
|
+
* Autosync (spec-9 phase 3): keep a shared board flowing without anyone
|
|
45
|
+
* typing `sync`.
|
|
46
|
+
*
|
|
47
|
+
* push after every committed mutation, a detached `brainfile sync --push`
|
|
48
|
+
* runs a few seconds later so bursts collapse into one push and the
|
|
49
|
+
* mutation itself never waits on the network
|
|
50
|
+
* full additionally fetch before a read when the last sync is older than
|
|
51
|
+
* a minute
|
|
52
|
+
*
|
|
53
|
+
* `BRAINFILE_AUTOSYNC=off|push|full` overrides the board's config for one
|
|
54
|
+
* process (tests and CI set `off`).
|
|
55
|
+
*/
|
|
56
|
+
const fs = __importStar(require("fs"));
|
|
57
|
+
const path = __importStar(require("path"));
|
|
58
|
+
const child_process_1 = require("child_process");
|
|
59
|
+
const board_repo_1 = require("./board-repo");
|
|
60
|
+
const board_sync_1 = require("./board-sync");
|
|
61
|
+
exports.AUTOSYNC_DELAY_MS = 5000;
|
|
62
|
+
exports.FETCH_MAX_AGE_SECONDS = 60;
|
|
63
|
+
const LOCK_FILE = path.join('state', 'autosync.lock');
|
|
64
|
+
/** A pending push older than this is assumed dead (crashed child). */
|
|
65
|
+
const LOCK_STALE_MS = 60000;
|
|
66
|
+
function effectiveAutosync(dotDir) {
|
|
67
|
+
const override = process.env.BRAINFILE_AUTOSYNC;
|
|
68
|
+
if (override === 'off' || override === 'push' || override === 'full')
|
|
69
|
+
return override;
|
|
70
|
+
return (0, board_sync_1.boardAutosync)(dotDir);
|
|
71
|
+
}
|
|
72
|
+
/** The runnable CLI: the bundle we live in, or the built one next to the sources. */
|
|
73
|
+
function autosyncCliPath() {
|
|
74
|
+
const candidates = [
|
|
75
|
+
path.join(__dirname, 'cli.js'),
|
|
76
|
+
path.join(__dirname, '..', 'cli.js'),
|
|
77
|
+
path.join(__dirname, '..', '..', 'dist', 'cli.js'),
|
|
78
|
+
];
|
|
79
|
+
return candidates.find((p) => fs.existsSync(p)) ?? null;
|
|
80
|
+
}
|
|
81
|
+
function pidAlive(pid) {
|
|
82
|
+
try {
|
|
83
|
+
process.kill(pid, 0);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function pushPending(dotDir) {
|
|
91
|
+
const lock = path.join(dotDir, LOCK_FILE);
|
|
92
|
+
try {
|
|
93
|
+
const st = fs.statSync(lock);
|
|
94
|
+
if (Date.now() - st.mtimeMs > LOCK_STALE_MS)
|
|
95
|
+
return false;
|
|
96
|
+
const pid = Number.parseInt(fs.readFileSync(lock, 'utf-8'), 10);
|
|
97
|
+
return Number.isFinite(pid) && pidAlive(pid);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function clearPushLock(dotDir) {
|
|
104
|
+
try {
|
|
105
|
+
fs.rmSync(path.join(dotDir, LOCK_FILE), { force: true });
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
/* nothing to clear */
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Queue a background push for the board. Returns true when a child was
|
|
113
|
+
* started; false when autosync is off, no remote is set, a push is already
|
|
114
|
+
* pending (it will carry this commit too), or there is no CLI to run.
|
|
115
|
+
*/
|
|
116
|
+
function schedulePush(dotDir, delayMs = exports.AUTOSYNC_DELAY_MS) {
|
|
117
|
+
if (!(0, board_repo_1.isTrackedBoard)(dotDir))
|
|
118
|
+
return false;
|
|
119
|
+
const mode = effectiveAutosync(dotDir);
|
|
120
|
+
if (mode === 'off' || !(0, board_sync_1.boardRemote)(dotDir))
|
|
121
|
+
return false;
|
|
122
|
+
if (pushPending(dotDir))
|
|
123
|
+
return false;
|
|
124
|
+
const cli = autosyncCliPath();
|
|
125
|
+
if (!cli)
|
|
126
|
+
return false;
|
|
127
|
+
const delay = process.env.BRAINFILE_AUTOSYNC_DELAY_MS ? Number(process.env.BRAINFILE_AUTOSYNC_DELAY_MS) : delayMs;
|
|
128
|
+
try {
|
|
129
|
+
const child = (0, child_process_1.spawn)(process.execPath, [cli, 'sync', '--push', '--file', path.join(dotDir, 'brainfile.md'), '--wait', String(delay)], { cwd: dotDir, detached: true, stdio: 'ignore', env: { ...process.env, BRAINFILE_AUTOSYNC: 'off' } });
|
|
130
|
+
child.unref();
|
|
131
|
+
if (child.pid) {
|
|
132
|
+
fs.mkdirSync(path.join(dotDir, 'state'), { recursive: true });
|
|
133
|
+
fs.writeFileSync(path.join(dotDir, LOCK_FILE), String(child.pid), 'utf-8');
|
|
134
|
+
}
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* In `full` mode, bring the board up to date before a read when the last
|
|
143
|
+
* sync attempt is older than `maxAgeSeconds`. Returns the sync result, or
|
|
144
|
+
* null when nothing was fetched.
|
|
145
|
+
*/
|
|
146
|
+
function fetchBeforeRead(dotDir, maxAgeSeconds = exports.FETCH_MAX_AGE_SECONDS) {
|
|
147
|
+
if (!(0, board_repo_1.isTrackedBoard)(dotDir))
|
|
148
|
+
return null;
|
|
149
|
+
if (effectiveAutosync(dotDir) !== 'full')
|
|
150
|
+
return null;
|
|
151
|
+
const age = (0, board_sync_1.secondsSinceSync)(dotDir);
|
|
152
|
+
if (age !== null && age < maxAgeSeconds)
|
|
153
|
+
return null;
|
|
154
|
+
return (0, board_sync_1.syncBoard)(dotDir, { pull: true, push: false });
|
|
155
|
+
}
|
|
156
|
+
let installed = false;
|
|
157
|
+
/** Push after every successful board commit made by this process. */
|
|
158
|
+
function installAutosync() {
|
|
159
|
+
if (installed)
|
|
160
|
+
return;
|
|
161
|
+
installed = true;
|
|
162
|
+
(0, board_repo_1.onBoardCommitted)((dotDir) => {
|
|
163
|
+
schedulePush(dotDir);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=board-autosync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-autosync.js","sourceRoot":"","sources":["../../src/utils/board-autosync.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,8CAIC;AAGD,0CAOC;AAuBD,sCAMC;AAOD,oCAuBC;AAOD,0CAMC;AAID,0CAMC;AAzHD;;;;;;;;;;;;GAYG;AACH,uCAAyB;AACzB,2CAA6B;AAC7B,iDAAsC;AACtC,6CAAgE;AAChE,6CAA2H;AAE9G,QAAA,iBAAiB,GAAG,IAAI,CAAC;AACzB,QAAA,qBAAqB,GAAG,EAAE,CAAC;AACxC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;AACtD,sEAAsE;AACtE,MAAM,aAAa,GAAG,KAAM,CAAC;AAE7B,SAAgB,iBAAiB,CAAC,MAAc;IAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAChD,IAAI,QAAQ,KAAK,KAAK,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,QAAQ,CAAC;IACtF,OAAO,IAAA,0BAAa,EAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,qFAAqF;AACrF,SAAgB,eAAe;IAC7B,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC;KACnD,CAAC;IACF,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC1D,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC3B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,GAAG,aAAa;YAAE,OAAO,KAAK,CAAC;QAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAChE,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAgB,aAAa,CAAC,MAAc;IAC1C,IAAI,CAAC;QACH,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAAC,MAAc,EAAE,OAAO,GAAG,yBAAiB;IACtE,IAAI,CAAC,IAAA,2BAAc,EAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,IAAA,wBAAW,EAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACzD,IAAI,WAAW,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAClH,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAA,qBAAK,EACjB,OAAO,CAAC,QAAQ,EAChB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAC7F,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAAE,CACrG,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YACd,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9D,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAAC,MAAc,EAAE,aAAa,GAAG,6BAAqB;IACnF,IAAI,CAAC,IAAA,2BAAc,EAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,iBAAiB,CAAC,MAAM,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,GAAG,GAAG,IAAA,6BAAgB,EAAC,MAAM,CAAC,CAAC;IACrC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,GAAG,aAAa;QAAE,OAAO,IAAI,CAAC;IACrD,OAAO,IAAA,sBAAS,EAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,IAAI,SAAS,GAAG,KAAK,CAAC;AACtB,qEAAqE;AACrE,SAAgB,eAAe;IAC7B,IAAI,SAAS;QAAE,OAAO;IACtB,SAAS,GAAG,IAAI,CAAC;IACjB,IAAA,6BAAgB,EAAC,CAAC,MAAM,EAAE,EAAE;QAC1B,YAAY,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface CommandLike {
|
|
2
|
+
name(): string;
|
|
3
|
+
args: string[];
|
|
4
|
+
opts(): Record<string, unknown>;
|
|
5
|
+
parent?: CommandLike | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function topLevelCommandName(command: CommandLike): string;
|
|
8
|
+
export declare function boardDirForCommand(command: CommandLike): string | null;
|
|
9
|
+
export declare function beforeCommand(command: CommandLike): boolean;
|
|
10
|
+
export declare function afterCommand(command: CommandLike): boolean;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=board-commit-hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-commit-hooks.d.ts","sourceRoot":"","sources":["../../src/utils/board-commit-hooks.ts"],"names":[],"mappings":"AAWA,UAAU,WAAW;IACnB,IAAI,IAAI,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAC7B;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAQhE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAItE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAQ3D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAI1D"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.topLevelCommandName = topLevelCommandName;
|
|
4
|
+
exports.boardDirForCommand = boardDirForCommand;
|
|
5
|
+
exports.beforeCommand = beforeCommand;
|
|
6
|
+
exports.afterCommand = afterCommand;
|
|
7
|
+
/**
|
|
8
|
+
* Commander hooks that turn every CLI mutation into one commit on a tracked
|
|
9
|
+
* board (spec-9). `beforeCommand` commits hand edits on their own so they are
|
|
10
|
+
* never folded into the command's commit; `afterCommand` commits whatever the
|
|
11
|
+
* command changed, authored as the acting agent.
|
|
12
|
+
*/
|
|
13
|
+
const board_repo_1 = require("./board-repo");
|
|
14
|
+
const brainfile_path_1 = require("./brainfile-path");
|
|
15
|
+
const board_autosync_1 = require("./board-autosync");
|
|
16
|
+
const board_sync_1 = require("./board-sync");
|
|
17
|
+
/** Long-running or board-unrelated commands that manage their own commits, or none. */
|
|
18
|
+
const SKIP_COMMANDS = new Set(['mcp', 'tui', 'hooks', 'auth', 'sync', 'merge-driver', 'where']);
|
|
19
|
+
function topLevelCommandName(command) {
|
|
20
|
+
let cursor = command;
|
|
21
|
+
let name = command.name();
|
|
22
|
+
while (cursor.parent && cursor.parent.parent) {
|
|
23
|
+
cursor = cursor.parent;
|
|
24
|
+
name = cursor.name();
|
|
25
|
+
}
|
|
26
|
+
return name;
|
|
27
|
+
}
|
|
28
|
+
function boardDirForCommand(command) {
|
|
29
|
+
if (SKIP_COMMANDS.has(topLevelCommandName(command)))
|
|
30
|
+
return null;
|
|
31
|
+
const file = command.opts().file;
|
|
32
|
+
return (0, brainfile_path_1.tryResolveBoardDir)(typeof file === 'string' ? file : undefined);
|
|
33
|
+
}
|
|
34
|
+
function beforeCommand(command) {
|
|
35
|
+
const dotDir = boardDirForCommand(command);
|
|
36
|
+
if (!dotDir)
|
|
37
|
+
return false;
|
|
38
|
+
const committed = (0, board_repo_1.commitHandEdits)(dotDir);
|
|
39
|
+
// autosync=full: reads see other machines' work when the last sync is stale.
|
|
40
|
+
const fetched = (0, board_autosync_1.fetchBeforeRead)(dotDir);
|
|
41
|
+
if (fetched && !fetched.ok)
|
|
42
|
+
process.stderr.write(`${(0, board_sync_1.syncMessage)(fetched).text}\n`);
|
|
43
|
+
return committed;
|
|
44
|
+
}
|
|
45
|
+
function afterCommand(command) {
|
|
46
|
+
const dotDir = boardDirForCommand(command);
|
|
47
|
+
if (!dotDir)
|
|
48
|
+
return false;
|
|
49
|
+
return (0, board_repo_1.commitBoard)(dotDir, { message: (0, board_repo_1.describeCommandForCommit)(command), agent: (0, board_repo_1.resolveAgentName)() });
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=board-commit-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-commit-hooks.js","sourceRoot":"","sources":["../../src/utils/board-commit-hooks.ts"],"names":[],"mappings":";;AAqBA,kDAQC;AAED,gDAIC;AAED,sCAQC;AAED,oCAIC;AAnDD;;;;;GAKG;AACH,6CAAwG;AACxG,qDAAsD;AACtD,qDAAmD;AACnD,6CAA2C;AAS3C,uFAAuF;AACvF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;AAEhG,SAAgB,mBAAmB,CAAC,OAAoB;IACtD,IAAI,MAAM,GAAgB,OAAO,CAAC;IAClC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC1B,OAAO,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAC7C,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QACvB,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,kBAAkB,CAAC,OAAoB;IACrD,IAAI,aAAa,CAAC,GAAG,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACjE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC;IACjC,OAAO,IAAA,mCAAkB,EAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AACzE,CAAC;AAED,SAAgB,aAAa,CAAC,OAAoB;IAChD,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,MAAM,SAAS,GAAG,IAAA,4BAAe,EAAC,MAAM,CAAC,CAAC;IAC1C,6EAA6E;IAC7E,MAAM,OAAO,GAAG,IAAA,gCAAe,EAAC,MAAM,CAAC,CAAC;IACxC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAA,wBAAW,EAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;IACnF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,YAAY,CAAC,OAAoB;IAC/C,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,OAAO,IAAA,wBAAW,EAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAA,qCAAwB,EAAC,OAAO,CAAC,EAAE,KAAK,EAAE,IAAA,6BAAgB,GAAE,EAAE,CAAC,CAAC;AACxG,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export declare const DEFAULT_BOARD_BRANCH = "brainfile";
|
|
2
|
+
export declare const BOARD_BRANCH_CONFIG_KEY = "brainfile.branch";
|
|
3
|
+
export interface GitResult {
|
|
4
|
+
ok: boolean;
|
|
5
|
+
status: number | null;
|
|
6
|
+
stdout: string;
|
|
7
|
+
stderr: string;
|
|
8
|
+
}
|
|
9
|
+
/** Run git synchronously. Never throws; a missing git binary is `ok: false`. */
|
|
10
|
+
export declare function git(args: string[], cwd: string, env?: NodeJS.ProcessEnv): GitResult;
|
|
11
|
+
/** Toplevel of the working tree containing `cwd`, or null outside any repo. */
|
|
12
|
+
export declare function gitToplevel(cwd: string): string | null;
|
|
13
|
+
/** The git directory shared by every worktree of the repo containing `cwd`. */
|
|
14
|
+
export declare function gitCommonDir(cwd: string): string | null;
|
|
15
|
+
export interface WorktreeEntry {
|
|
16
|
+
path: string;
|
|
17
|
+
head?: string;
|
|
18
|
+
/** Full ref, e.g. `refs/heads/brainfile`; absent when detached or bare. */
|
|
19
|
+
branch?: string;
|
|
20
|
+
bare: boolean;
|
|
21
|
+
detached: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** `git worktree list --porcelain`, parsed. Empty outside a repo. */
|
|
24
|
+
export declare function listWorktrees(cwd: string): WorktreeEntry[];
|
|
25
|
+
/** Name of the board branch for the repo containing `cwd` (`brainfile.branch`, default `brainfile`). */
|
|
26
|
+
export declare function boardBranch(cwd: string): string;
|
|
27
|
+
export type BoardRepoKind = 'linked' | 'standalone';
|
|
28
|
+
/**
|
|
29
|
+
* How the board directory is tracked: a linked worktree (`.git` is a gitdir
|
|
30
|
+
* pointer file), a standalone repository (`.git` is a directory), or null for
|
|
31
|
+
* a plain directory.
|
|
32
|
+
*/
|
|
33
|
+
export declare function boardRepoKind(dotDir: string): BoardRepoKind | null;
|
|
34
|
+
export declare function isTrackedBoard(dotDir: string): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Resolution step 3: from anywhere inside a repo (including a linked code
|
|
37
|
+
* worktree that has no `.brainfile/` of its own), find the worktree checked
|
|
38
|
+
* out on the board branch.
|
|
39
|
+
*/
|
|
40
|
+
export declare function findTrackedBoardDir(cwd: string): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Resolution step 4: the board branch exists locally but no worktree has it
|
|
43
|
+
* checked out (a fresh clone, or the directory was removed). Create the
|
|
44
|
+
* worktree at `<main worktree>/.brainfile` — or inside the common git dir for
|
|
45
|
+
* bare layouts — and hide it from the code branch. Returns the new board
|
|
46
|
+
* directory, or null when there is nothing to materialize.
|
|
47
|
+
*/
|
|
48
|
+
export declare function materializeBoardWorktree(cwd: string): string | null;
|
|
49
|
+
/** Hide `.brainfile/` from the code branch without touching `.gitignore`. Returns true when an entry was added. */
|
|
50
|
+
export declare function ensureExcludeEntry(cwd: string): boolean;
|
|
51
|
+
/** Remove the exclude entry, but only the one we wrote (identified by its marker). */
|
|
52
|
+
export declare function removeExcludeEntry(cwd: string): boolean;
|
|
53
|
+
/** `git worktree add --orphan -b <branch> <dotDir>` (git >= 2.42). */
|
|
54
|
+
export declare function createOrphanBoardWorktree(repoCwd: string, dotDir: string, branch: string): void;
|
|
55
|
+
/** `git init` inside the board directory for boards outside any repo. */
|
|
56
|
+
export declare function initStandaloneBoardRepo(dotDir: string): void;
|
|
57
|
+
export declare function boardIsDirty(dotDir: string): boolean;
|
|
58
|
+
export declare function boardHasCommits(dotDir: string): boolean;
|
|
59
|
+
/** Files with uncommitted changes, relative to the board directory. */
|
|
60
|
+
/** Paths still carrying conflict markers from an unfinished merge. */
|
|
61
|
+
export declare function unmergedFiles(dotDir: string): string[];
|
|
62
|
+
export declare function boardDirtyFiles(dotDir: string): string[];
|
|
63
|
+
type CommitListener = (dotDir: string) => void;
|
|
64
|
+
/** Run `listener` after every successful board commit made by this process. */
|
|
65
|
+
export declare function onBoardCommitted(listener: CommitListener): void;
|
|
66
|
+
export interface CommitBoardOptions {
|
|
67
|
+
message: string;
|
|
68
|
+
/** Acting agent; becomes the commit author. The committer stays the git user. */
|
|
69
|
+
agent?: string | null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Stage everything in the board directory and commit it. Returns true when a
|
|
73
|
+
* commit was made, false when the board is plain or nothing changed. Never
|
|
74
|
+
* throws: a failed commit must not fail the mutation it records.
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* git does not store empty directories, and a board without `board/` reads
|
|
78
|
+
* as legacy on the other side. Keep both alive with a `.gitkeep`.
|
|
79
|
+
*/
|
|
80
|
+
export declare function ensureBoardDirs(dotDir: string): boolean;
|
|
81
|
+
export declare function commitBoard(dotDir: string, options: CommitBoardOptions): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Commit outstanding hand edits (files changed outside the CLI) before a
|
|
84
|
+
* command mutates, so they are never folded into that command's commit.
|
|
85
|
+
*/
|
|
86
|
+
export declare function commitHandEdits(dotDir: string): boolean;
|
|
87
|
+
/** The acting agent: `BRAINFILE_AGENT`, else `--agent <name>` on the command line. */
|
|
88
|
+
export declare function resolveAgentName(argv?: string[]): string | null;
|
|
89
|
+
/** The home board: `~/.brainfile`, addressed with `-g` / `--global` or `BRAINFILE_GLOBAL=1`. */
|
|
90
|
+
export declare function homeBoardDir(): string;
|
|
91
|
+
export declare function isGlobalBoardRequested(argv?: string[]): boolean;
|
|
92
|
+
interface CommandLike {
|
|
93
|
+
name(): string;
|
|
94
|
+
args: string[];
|
|
95
|
+
opts(): Record<string, unknown>;
|
|
96
|
+
parent?: CommandLike | null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Commit message for a CLI invocation: `<verb> <id>: <detail>`, e.g.
|
|
100
|
+
* `move task-3: in-progress`, `add: Fix login bug`, `contract pickup task-2`.
|
|
101
|
+
*/
|
|
102
|
+
export declare function describeCommandForCommit(command: CommandLike): string;
|
|
103
|
+
/** Queue a commit for a board; bursts of edits within `delayMs` become one commit. */
|
|
104
|
+
export declare function scheduleBoardCommit(brainfilePath: string, message: string, delayMs?: number): void;
|
|
105
|
+
/** Commit every queued board now. Safe to call from an `exit` handler (synchronous). */
|
|
106
|
+
export declare function flushBoardCommits(): void;
|
|
107
|
+
export {};
|
|
108
|
+
//# sourceMappingURL=board-repo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-repo.d.ts","sourceRoot":"","sources":["../../src/utils/board-repo.ts"],"names":[],"mappings":"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"}
|