brainfile 0.20.0 → 0.21.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/dist/{chunk-UOCQBEEW.mjs → chunk-MUV7XTFA.mjs} +1345 -316
- package/dist/cli.mjs +2196 -1349
- 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/log.d.ts.map +1 -1
- package/dist/commands/log.js +4 -1
- package/dist/commands/log.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 +18 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +161 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/where.d.ts +24 -0
- package/dist/commands/where.d.ts.map +1 -0
- package/dist/commands/where.js +141 -0
- package/dist/commands/where.js.map +1 -0
- package/dist/mcp/helpers.d.ts +9 -0
- package/dist/mcp/helpers.d.ts.map +1 -1
- package/dist/mcp/helpers.js +43 -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-5TFQR53I.mjs} +295 -253
- package/dist/utils/actor.d.ts +22 -0
- package/dist/utils/actor.d.ts.map +1 -0
- package/dist/utils/actor.js +200 -0
- package/dist/utils/actor.js.map +1 -0
- 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 +52 -0
- package/dist/utils/board-commit-hooks.js.map +1 -0
- package/dist/utils/board-repo.d.ts +132 -0
- package/dist/utils/board-repo.d.ts.map +1 -0
- package/dist/utils/board-repo.js +602 -0
- package/dist/utils/board-repo.js.map +1 -0
- package/dist/utils/board-sync.d.ts +126 -0
- package/dist/utils/board-sync.d.ts.map +1 -0
- package/dist/utils/board-sync.js +554 -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
|
+
export type ActorSource = 'flag' | 'env' | 'process' | 'fingerprint' | 'git';
|
|
2
|
+
export interface Actor {
|
|
3
|
+
name: string;
|
|
4
|
+
source: ActorSource;
|
|
5
|
+
}
|
|
6
|
+
/** The nearest agent CLI among this process's ancestors, or null. */
|
|
7
|
+
export declare function agentFromProcessTree(startPid?: number): string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Environment variables agents set for the commands they run. Specific
|
|
10
|
+
* markers only: a Claude session can carry `CODEX_COMPANION_*` from a plugin,
|
|
11
|
+
* so a loose `CODEX_` prefix would misattribute it. Codex comes first because
|
|
12
|
+
* its sandbox hides the process tree while inheriting a parent Claude's
|
|
13
|
+
* variables when it was started from one.
|
|
14
|
+
*/
|
|
15
|
+
export declare function agentFromEnvironment(env?: NodeJS.ProcessEnv): string | null;
|
|
16
|
+
/** The agent running this process, when one can be told; never the git user. */
|
|
17
|
+
export declare function detectAgent(argv?: string[], env?: NodeJS.ProcessEnv): Actor | null;
|
|
18
|
+
/** The agent, else the git user (`user.name`) for `cwd`, else null. */
|
|
19
|
+
export declare function resolveActor(cwd?: string, argv?: string[]): Actor | null;
|
|
20
|
+
/** For tests: forget the cached process-tree answer. */
|
|
21
|
+
export declare function resetActorCache(): void;
|
|
22
|
+
//# sourceMappingURL=actor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../../src/utils/actor.ts"],"names":[],"mappings":"AAqBA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,aAAa,GAAG,KAAK,CAAC;AAE7E,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;CACrB;AA+DD,qEAAqE;AACrE,wBAAgB,oBAAoB,CAAC,QAAQ,GAAE,MAAqB,GAAG,MAAM,GAAG,IAAI,CAanF;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,IAAI,CAQxF;AAWD,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAM,EAAiB,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,KAAK,GAAG,IAAI,CAoB7G;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAsB,EAAE,IAAI,GAAE,MAAM,EAAiB,GAAG,KAAK,GAAG,IAAI,CAKrG;AAED,wDAAwD;AACxD,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
|
|
@@ -0,0 +1,200 @@
|
|
|
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.agentFromProcessTree = agentFromProcessTree;
|
|
37
|
+
exports.agentFromEnvironment = agentFromEnvironment;
|
|
38
|
+
exports.detectAgent = detectAgent;
|
|
39
|
+
exports.resolveActor = resolveActor;
|
|
40
|
+
exports.resetActorCache = resetActorCache;
|
|
41
|
+
/**
|
|
42
|
+
* Who is acting on the board. Board commits are always authored by the git
|
|
43
|
+
* user; the actor is what the board itself records: the `[name]` on a note
|
|
44
|
+
* and the `[name]` suffix on a board commit message.
|
|
45
|
+
*
|
|
46
|
+
* 1. `--agent <name>` or `BRAINFILE_AGENT`, when the agent says who it is
|
|
47
|
+
* 2. the nearest agent CLI among this process's ancestors (claude, codex, …)
|
|
48
|
+
* 3. an agent's environment fingerprint (for sandboxes that hide the
|
|
49
|
+
* process tree, like Codex's)
|
|
50
|
+
* 4. the git user
|
|
51
|
+
*
|
|
52
|
+
* `BRAINFILE_DETECT_AGENT=off` turns off 2 and 3.
|
|
53
|
+
*
|
|
54
|
+
* Only agent command-line tools count. Desktop apps and editors (the Claude
|
|
55
|
+
* app, Cursor, VS Code) also host the person's own terminals, so a command
|
|
56
|
+
* under them is the person's.
|
|
57
|
+
*/
|
|
58
|
+
const fs = __importStar(require("fs"));
|
|
59
|
+
const child_process_1 = require("child_process");
|
|
60
|
+
const board_repo_1 = require("./board-repo");
|
|
61
|
+
/** Executable name → the name recorded on the board. */
|
|
62
|
+
const AGENT_BINARIES = {
|
|
63
|
+
claude: 'claude',
|
|
64
|
+
codex: 'codex',
|
|
65
|
+
'cursor-agent': 'cursor',
|
|
66
|
+
gemini: 'gemini',
|
|
67
|
+
opencode: 'opencode',
|
|
68
|
+
goose: 'goose',
|
|
69
|
+
droid: 'droid',
|
|
70
|
+
crush: 'crush',
|
|
71
|
+
aider: 'aider',
|
|
72
|
+
cline: 'cline',
|
|
73
|
+
amp: 'amp',
|
|
74
|
+
qwen: 'qwen',
|
|
75
|
+
copilot: 'copilot',
|
|
76
|
+
};
|
|
77
|
+
const MAX_DEPTH = 32;
|
|
78
|
+
function sanitize(name) {
|
|
79
|
+
return name.replace(/[[\]<>\r\n]/g, '').trim();
|
|
80
|
+
}
|
|
81
|
+
function agentFromCommand(words) {
|
|
82
|
+
// A native binary shows as argv[0]; a node/python-wrapped CLI as argv[1].
|
|
83
|
+
for (const word of words.slice(0, 2)) {
|
|
84
|
+
const base = word.split('/').pop()?.replace(/\.(c|m)?js$/, '') ?? '';
|
|
85
|
+
if (AGENT_BINARIES[base])
|
|
86
|
+
return AGENT_BINARIES[base];
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
function linuxProc(pid) {
|
|
91
|
+
try {
|
|
92
|
+
const stat = fs.readFileSync(`/proc/${pid}/stat`, 'utf-8');
|
|
93
|
+
// The command name is in parentheses and may contain spaces.
|
|
94
|
+
const ppid = Number.parseInt(stat.slice(stat.lastIndexOf(')') + 2).split(' ')[1], 10);
|
|
95
|
+
const comm = stat.slice(stat.indexOf('(') + 1, stat.lastIndexOf(')'));
|
|
96
|
+
const cmdline = fs.readFileSync(`/proc/${pid}/cmdline`, 'utf-8').split('\0').filter(Boolean);
|
|
97
|
+
return { ppid, words: [comm, ...cmdline] };
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function psTable() {
|
|
104
|
+
const r = (0, child_process_1.spawnSync)('ps', ['-A', '-o', 'pid=,ppid=,args='], { encoding: 'utf-8', timeout: 2000 });
|
|
105
|
+
if (r.status !== 0 || !r.stdout)
|
|
106
|
+
return null;
|
|
107
|
+
const table = new Map();
|
|
108
|
+
for (const line of r.stdout.split('\n')) {
|
|
109
|
+
const m = /^\s*(\d+)\s+(\d+)\s+(.*)$/.exec(line);
|
|
110
|
+
if (m)
|
|
111
|
+
table.set(Number(m[1]), { ppid: Number(m[2]), words: m[3].split(/\s+/) });
|
|
112
|
+
}
|
|
113
|
+
return table;
|
|
114
|
+
}
|
|
115
|
+
/** The nearest agent CLI among this process's ancestors, or null. */
|
|
116
|
+
function agentFromProcessTree(startPid = process.ppid) {
|
|
117
|
+
const useProc = process.platform === 'linux' && fs.existsSync('/proc/self/stat');
|
|
118
|
+
const table = useProc ? null : process.platform === 'win32' ? null : psTable();
|
|
119
|
+
if (!useProc && !table)
|
|
120
|
+
return null;
|
|
121
|
+
let pid = startPid;
|
|
122
|
+
for (let depth = 0; depth < MAX_DEPTH && pid > 1; depth++) {
|
|
123
|
+
const info = useProc ? linuxProc(pid) : table?.get(pid) ?? null;
|
|
124
|
+
if (!info)
|
|
125
|
+
return null;
|
|
126
|
+
const agent = agentFromCommand(info.words);
|
|
127
|
+
if (agent)
|
|
128
|
+
return agent;
|
|
129
|
+
pid = info.ppid;
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Environment variables agents set for the commands they run. Specific
|
|
135
|
+
* markers only: a Claude session can carry `CODEX_COMPANION_*` from a plugin,
|
|
136
|
+
* so a loose `CODEX_` prefix would misattribute it. Codex comes first because
|
|
137
|
+
* its sandbox hides the process tree while inheriting a parent Claude's
|
|
138
|
+
* variables when it was started from one.
|
|
139
|
+
*/
|
|
140
|
+
function agentFromEnvironment(env = process.env) {
|
|
141
|
+
if (env.CODEX_THREAD_ID || env.CODEX_SESSION_ID)
|
|
142
|
+
return 'codex';
|
|
143
|
+
if (env.GEMINI_CLI === '1')
|
|
144
|
+
return 'gemini';
|
|
145
|
+
if (env.CLAUDECODE === '1')
|
|
146
|
+
return 'claude';
|
|
147
|
+
// A shared convention some agents follow, e.g. `claude-code_2-1-280_agent`.
|
|
148
|
+
const generic = env.AI_AGENT?.split('_')[0];
|
|
149
|
+
if (generic)
|
|
150
|
+
return generic === 'claude-code' ? 'claude' : sanitize(generic) || null;
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
function flagValue(argv) {
|
|
154
|
+
const at = argv.indexOf('--agent');
|
|
155
|
+
if (at >= 0 && argv[at + 1] && !argv[at + 1].startsWith('-'))
|
|
156
|
+
return argv[at + 1];
|
|
157
|
+
const inline = argv.find((a) => a.startsWith('--agent='));
|
|
158
|
+
return inline ? inline.slice('--agent='.length) : null;
|
|
159
|
+
}
|
|
160
|
+
let detected = null;
|
|
161
|
+
/** The agent running this process, when one can be told; never the git user. */
|
|
162
|
+
function detectAgent(argv = process.argv, env = process.env) {
|
|
163
|
+
const flag = sanitize(flagValue(argv) ?? '');
|
|
164
|
+
if (flag)
|
|
165
|
+
return { name: flag, source: 'flag' };
|
|
166
|
+
const named = sanitize(env.BRAINFILE_AGENT ?? '');
|
|
167
|
+
if (named)
|
|
168
|
+
return { name: named, source: 'env' };
|
|
169
|
+
// `BRAINFILE_DETECT_AGENT=off` keeps only explicit names (the test runner
|
|
170
|
+
// sets it, so running the suite inside an agent does not change results).
|
|
171
|
+
if (env.BRAINFILE_DETECT_AGENT === 'off')
|
|
172
|
+
return null;
|
|
173
|
+
if (!detected) {
|
|
174
|
+
let value = null;
|
|
175
|
+
try {
|
|
176
|
+
value = agentFromProcessTree();
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
value = null;
|
|
180
|
+
}
|
|
181
|
+
detected = { value };
|
|
182
|
+
}
|
|
183
|
+
if (detected.value)
|
|
184
|
+
return { name: detected.value, source: 'process' };
|
|
185
|
+
const fingerprint = agentFromEnvironment(env);
|
|
186
|
+
return fingerprint ? { name: fingerprint, source: 'fingerprint' } : null;
|
|
187
|
+
}
|
|
188
|
+
/** The agent, else the git user (`user.name`) for `cwd`, else null. */
|
|
189
|
+
function resolveActor(cwd = process.cwd(), argv = process.argv) {
|
|
190
|
+
const agent = detectAgent(argv);
|
|
191
|
+
if (agent)
|
|
192
|
+
return agent;
|
|
193
|
+
const user = sanitize((0, board_repo_1.git)(['config', '--get', 'user.name'], cwd).stdout);
|
|
194
|
+
return user ? { name: user, source: 'git' } : null;
|
|
195
|
+
}
|
|
196
|
+
/** For tests: forget the cached process-tree answer. */
|
|
197
|
+
function resetActorCache() {
|
|
198
|
+
detected = null;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=actor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor.js","sourceRoot":"","sources":["../../src/utils/actor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0FA,oDAaC;AASD,oDAQC;AAYD,kCAoBC;AAGD,oCAKC;AAGD,0CAEC;AArKD;;;;;;;;;;;;;;;;GAgBG;AACH,uCAAyB;AACzB,iDAA0C;AAC1C,6CAAmC;AASnC,wDAAwD;AACxD,MAAM,cAAc,GAA2B;IAC7C,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,cAAc,EAAE,QAAQ;IACxB,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;CACnB,CAAC;AAEF,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACjD,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAe;IACvC,0EAA0E;IAC1E,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;QACrE,IAAI,cAAc,CAAC,IAAI,CAAC;YAAE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAOD,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,GAAG,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3D,6DAA6D;QAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACtF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,GAAG,UAAU,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7F,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,OAAO;IACd,MAAM,CAAC,GAAG,IAAA,yBAAS,EAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,kBAAkB,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAClG,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,qEAAqE;AACrE,SAAgB,oBAAoB,CAAC,WAAmB,OAAO,CAAC,IAAI;IAClE,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;IACjF,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/E,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,IAAI,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QAChE,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,oBAAoB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACvE,IAAI,GAAG,CAAC,eAAe,IAAI,GAAG,CAAC,gBAAgB;QAAE,OAAO,OAAO,CAAC;IAChE,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG;QAAE,OAAO,QAAQ,CAAC;IAC5C,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG;QAAE,OAAO,QAAQ,CAAC;IAC5C,4EAA4E;IAC5E,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,IAAI,OAAO;QAAE,OAAO,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IACrF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACnC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAClF,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1D,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACzD,CAAC;AAED,IAAI,QAAQ,GAAoC,IAAI,CAAC;AAErD,gFAAgF;AAChF,SAAgB,WAAW,CAAC,OAAiB,OAAO,CAAC,IAAI,EAAE,MAAyB,OAAO,CAAC,GAAG;IAC7F,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7C,IAAI,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAChD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;IAClD,IAAI,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACjD,0EAA0E;IAC1E,0EAA0E;IAC1E,IAAI,GAAG,CAAC,sBAAsB,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,IAAI,KAAK,GAAkB,IAAI,CAAC;QAChC,IAAI,CAAC;YACH,KAAK,GAAG,oBAAoB,EAAE,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;QACD,QAAQ,GAAG,EAAE,KAAK,EAAE,CAAC;IACvB,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACvE,MAAM,WAAW,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC9C,OAAO,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3E,CAAC;AAED,uEAAuE;AACvE,SAAgB,YAAY,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE,EAAE,OAAiB,OAAO,CAAC,IAAI;IACrF,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAA,gBAAG,EAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IACzE,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC;AAED,wDAAwD;AACxD,SAAgB,eAAe;IAC7B,QAAQ,GAAG,IAAI,CAAC;AAClB,CAAC"}
|
|
@@ -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":"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"}
|
|
@@ -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":"AAYA,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,52 @@
|
|
|
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 by the git user and tagged with the agent, if any.
|
|
12
|
+
*/
|
|
13
|
+
const board_repo_1 = require("./board-repo");
|
|
14
|
+
const actor_1 = require("./actor");
|
|
15
|
+
const brainfile_path_1 = require("./brainfile-path");
|
|
16
|
+
const board_autosync_1 = require("./board-autosync");
|
|
17
|
+
const board_sync_1 = require("./board-sync");
|
|
18
|
+
/** Long-running or board-unrelated commands that manage their own commits, or none. */
|
|
19
|
+
const SKIP_COMMANDS = new Set(['mcp', 'tui', 'hooks', 'auth', 'sync', 'merge-driver', 'where']);
|
|
20
|
+
function topLevelCommandName(command) {
|
|
21
|
+
let cursor = command;
|
|
22
|
+
let name = command.name();
|
|
23
|
+
while (cursor.parent && cursor.parent.parent) {
|
|
24
|
+
cursor = cursor.parent;
|
|
25
|
+
name = cursor.name();
|
|
26
|
+
}
|
|
27
|
+
return name;
|
|
28
|
+
}
|
|
29
|
+
function boardDirForCommand(command) {
|
|
30
|
+
if (SKIP_COMMANDS.has(topLevelCommandName(command)))
|
|
31
|
+
return null;
|
|
32
|
+
const file = command.opts().file;
|
|
33
|
+
return (0, brainfile_path_1.tryResolveBoardDir)(typeof file === 'string' ? file : undefined);
|
|
34
|
+
}
|
|
35
|
+
function beforeCommand(command) {
|
|
36
|
+
const dotDir = boardDirForCommand(command);
|
|
37
|
+
if (!dotDir)
|
|
38
|
+
return false;
|
|
39
|
+
const committed = (0, board_repo_1.commitHandEdits)(dotDir);
|
|
40
|
+
// autosync=full: reads see other machines' work when the last sync is stale.
|
|
41
|
+
const fetched = (0, board_autosync_1.fetchBeforeRead)(dotDir);
|
|
42
|
+
if (fetched && !fetched.ok)
|
|
43
|
+
process.stderr.write(`${(0, board_sync_1.syncMessage)(fetched).text}\n`);
|
|
44
|
+
return committed;
|
|
45
|
+
}
|
|
46
|
+
function afterCommand(command) {
|
|
47
|
+
const dotDir = boardDirForCommand(command);
|
|
48
|
+
if (!dotDir)
|
|
49
|
+
return false;
|
|
50
|
+
return (0, board_repo_1.commitBoard)(dotDir, { message: (0, board_repo_1.describeCommandForCommit)(command), agent: (0, actor_1.detectAgent)()?.name });
|
|
51
|
+
}
|
|
52
|
+
//# 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":";;AAsBA,kDAQC;AAED,gDAIC;AAED,sCAQC;AAED,oCAIC;AApDD;;;;;GAKG;AACH,6CAAsF;AACtF,mCAAsC;AACtC,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,mBAAW,GAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AACzG,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export declare const DEFAULT_BOARD_BRANCH = "brainfile";
|
|
2
|
+
export declare const BOARD_BRANCH_CONFIG_KEY = "brainfile.branch";
|
|
3
|
+
/**
|
|
4
|
+
* On a remote, a board is stored under `refs/brainfile/<name>` rather than as
|
|
5
|
+
* a branch: hosts list, badge and offer pull requests for branches only, so
|
|
6
|
+
* the board stays out of the project's branch list while still being pushed,
|
|
7
|
+
* fetched and kept like any other ref. Locally the last-known remote position
|
|
8
|
+
* lives under `refs/brainfile/remotes/<remote>/<name>`, outside `refs/remotes/`
|
|
9
|
+
* so a user's `git fetch --prune` never deletes it.
|
|
10
|
+
*/
|
|
11
|
+
export declare const BOARD_REF_NAMESPACE = "refs/brainfile";
|
|
12
|
+
export declare const BOARD_NAME_CONFIG_KEY = "brainfile.boardName";
|
|
13
|
+
/** 0.21.0 key: the branch the board was pushed to. Still read as the name. */
|
|
14
|
+
export declare const LEGACY_REMOTE_BRANCH_CONFIG_KEY = "brainfile.remoteBranch";
|
|
15
|
+
/** Default name for a board that lives in a code repository. */
|
|
16
|
+
export declare const DEFAULT_BOARD_NAME = "board";
|
|
17
|
+
export declare function remoteBoardRef(name: string): string;
|
|
18
|
+
export declare function boardTrackingRef(remote: string, name: string): string;
|
|
19
|
+
export declare function gitNetwork(args: string[], cwd: string): GitResult;
|
|
20
|
+
export interface GitResult {
|
|
21
|
+
ok: boolean;
|
|
22
|
+
status: number | null;
|
|
23
|
+
stdout: string;
|
|
24
|
+
stderr: string;
|
|
25
|
+
}
|
|
26
|
+
/** Run git synchronously. Never throws; a missing git binary is `ok: false`. */
|
|
27
|
+
export declare function git(args: string[], cwd: string, env?: NodeJS.ProcessEnv, timeoutMs?: number): GitResult;
|
|
28
|
+
/** Toplevel of the working tree containing `cwd`, or null outside any repo. */
|
|
29
|
+
export declare function gitToplevel(cwd: string): string | null;
|
|
30
|
+
/** The git directory shared by every worktree of the repo containing `cwd`. */
|
|
31
|
+
export declare function gitCommonDir(cwd: string): string | null;
|
|
32
|
+
export interface WorktreeEntry {
|
|
33
|
+
path: string;
|
|
34
|
+
head?: string;
|
|
35
|
+
/** Full ref, e.g. `refs/heads/brainfile`; absent when detached or bare. */
|
|
36
|
+
branch?: string;
|
|
37
|
+
bare: boolean;
|
|
38
|
+
detached: boolean;
|
|
39
|
+
}
|
|
40
|
+
/** `git worktree list --porcelain`, parsed. Empty outside a repo. */
|
|
41
|
+
export declare function listWorktrees(cwd: string): WorktreeEntry[];
|
|
42
|
+
/** Name of the board branch for the repo containing `cwd` (`brainfile.branch`, default `brainfile`). */
|
|
43
|
+
export declare function boardBranch(cwd: string): string;
|
|
44
|
+
export type BoardRepoKind = 'linked' | 'standalone';
|
|
45
|
+
/**
|
|
46
|
+
* How the board directory is tracked: a linked worktree (`.git` is a gitdir
|
|
47
|
+
* pointer file), a standalone repository (`.git` is a directory), or null for
|
|
48
|
+
* a plain directory.
|
|
49
|
+
*/
|
|
50
|
+
export declare function boardRepoKind(dotDir: string): BoardRepoKind | null;
|
|
51
|
+
export declare function isTrackedBoard(dotDir: string): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Resolution step 3: from anywhere inside a repo (including a linked code
|
|
54
|
+
* worktree that has no `.brainfile/` of its own), find the worktree checked
|
|
55
|
+
* out on the board branch.
|
|
56
|
+
*/
|
|
57
|
+
export declare function findTrackedBoardDir(cwd: string): string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Board names published on `remote` (`refs/brainfile/<name>`), or null when
|
|
60
|
+
* the remote could not be asked. One network round trip.
|
|
61
|
+
*/
|
|
62
|
+
export declare function listRemoteBoards(cwd: string, remote: string): string[] | null;
|
|
63
|
+
export interface MaterializeOptions {
|
|
64
|
+
/** Ask the remote even if a recent lookup found nothing (after `--set-remote`). */
|
|
65
|
+
fresh?: boolean;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Resolution step 4: the board is not checked out anywhere (a fresh clone,
|
|
69
|
+
* or the directory was removed). Create the worktree at
|
|
70
|
+
* `<main worktree>/.brainfile` — or inside the common git dir for bare
|
|
71
|
+
* layouts — and hide it from the code branch. Returns the new board
|
|
72
|
+
* directory, or null when there is nothing to materialize.
|
|
73
|
+
*/
|
|
74
|
+
export declare function materializeBoardWorktree(cwd: string, options?: MaterializeOptions): string | null;
|
|
75
|
+
/** Hide `.brainfile/` from the code branch without touching `.gitignore`. Returns true when an entry was added. */
|
|
76
|
+
export declare function ensureExcludeEntry(cwd: string): boolean;
|
|
77
|
+
/** Remove the exclude entry, but only the one we wrote (identified by its marker). */
|
|
78
|
+
export declare function removeExcludeEntry(cwd: string): boolean;
|
|
79
|
+
/** `git worktree add --orphan -b <branch> <dotDir>` (git >= 2.42). */
|
|
80
|
+
export declare function createOrphanBoardWorktree(repoCwd: string, dotDir: string, branch: string): void;
|
|
81
|
+
/** `git init` inside the board directory for boards outside any repo. */
|
|
82
|
+
export declare function initStandaloneBoardRepo(dotDir: string): void;
|
|
83
|
+
export declare function boardIsDirty(dotDir: string): boolean;
|
|
84
|
+
export declare function boardHasCommits(dotDir: string): boolean;
|
|
85
|
+
/** Files with uncommitted changes, relative to the board directory. */
|
|
86
|
+
/** Paths still carrying conflict markers from an unfinished merge. */
|
|
87
|
+
export declare function unmergedFiles(dotDir: string): string[];
|
|
88
|
+
export declare function boardDirtyFiles(dotDir: string): string[];
|
|
89
|
+
type CommitListener = (dotDir: string) => void;
|
|
90
|
+
/** Run `listener` after every successful board commit made by this process. */
|
|
91
|
+
export declare function onBoardCommitted(listener: CommitListener): void;
|
|
92
|
+
export interface CommitBoardOptions {
|
|
93
|
+
message: string;
|
|
94
|
+
/** The agent acting, recorded as a `[name]` suffix; the author stays the git user. */
|
|
95
|
+
agent?: string | null;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Stage everything in the board directory and commit it. Returns true when a
|
|
99
|
+
* commit was made, false when the board is plain or nothing changed. Never
|
|
100
|
+
* throws: a failed commit must not fail the mutation it records.
|
|
101
|
+
*/
|
|
102
|
+
/**
|
|
103
|
+
* git does not store empty directories, and a board without `board/` reads
|
|
104
|
+
* as legacy on the other side. Keep both alive with a `.gitkeep`.
|
|
105
|
+
*/
|
|
106
|
+
export declare function ensureBoardDirs(dotDir: string): boolean;
|
|
107
|
+
export declare function commitBoard(dotDir: string, options: CommitBoardOptions): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Commit outstanding hand edits (files changed outside the CLI) before a
|
|
110
|
+
* command mutates, so they are never folded into that command's commit.
|
|
111
|
+
*/
|
|
112
|
+
export declare function commitHandEdits(dotDir: string): boolean;
|
|
113
|
+
/** The home board: `~/.brainfile`, addressed with `-g` / `--global` or `BRAINFILE_GLOBAL=1`. */
|
|
114
|
+
export declare function homeBoardDir(): string;
|
|
115
|
+
export declare function isGlobalBoardRequested(argv?: string[]): boolean;
|
|
116
|
+
interface CommandLike {
|
|
117
|
+
name(): string;
|
|
118
|
+
args: string[];
|
|
119
|
+
opts(): Record<string, unknown>;
|
|
120
|
+
parent?: CommandLike | null;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Commit message for a CLI invocation: `<verb> <id>: <detail>`, e.g.
|
|
124
|
+
* `move task-3: in-progress`, `add: Fix login bug`, `contract pickup task-2`.
|
|
125
|
+
*/
|
|
126
|
+
export declare function describeCommandForCommit(command: CommandLike): string;
|
|
127
|
+
/** Queue a commit for a board; bursts of edits within `delayMs` become one commit. */
|
|
128
|
+
export declare function scheduleBoardCommit(brainfilePath: string, message: string, delayMs?: number): void;
|
|
129
|
+
/** Commit every queued board now. Safe to call from an `exit` handler (synchronous). */
|
|
130
|
+
export declare function flushBoardCommits(): void;
|
|
131
|
+
export {};
|
|
132
|
+
//# 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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"}
|