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
|
@@ -10,20 +10,25 @@ import {
|
|
|
10
10
|
RULE,
|
|
11
11
|
createGitHubIssue,
|
|
12
12
|
createLinearIssue,
|
|
13
|
+
fetchBeforeRead,
|
|
13
14
|
getArchiveConfig,
|
|
14
15
|
getContractStateColor,
|
|
15
16
|
getEffectiveDestination,
|
|
16
17
|
getLinearTeams,
|
|
17
18
|
getTypeGlyph,
|
|
18
19
|
import_core,
|
|
20
|
+
installAutosync,
|
|
19
21
|
isGitHubAuthenticated,
|
|
20
22
|
isLinearAuthenticated,
|
|
21
23
|
markV2MigrationHintShown,
|
|
22
24
|
require_dist,
|
|
23
25
|
require_source,
|
|
24
26
|
resolveCliBrainfilePath,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
scheduleBoardCommit,
|
|
28
|
+
shouldSuggestV2Migration,
|
|
29
|
+
syncMessage,
|
|
30
|
+
syncStatusLabel
|
|
31
|
+
} from "./chunk-FOLBAGJS.mjs";
|
|
27
32
|
import {
|
|
28
33
|
__commonJS,
|
|
29
34
|
__export,
|
|
@@ -1994,8 +1999,8 @@ var require_react_reconciler_production = __commonJS({
|
|
|
1994
1999
|
currentEntangledActionThenable = {
|
|
1995
2000
|
status: "pending",
|
|
1996
2001
|
value: void 0,
|
|
1997
|
-
then: function(
|
|
1998
|
-
entangledListeners.push(
|
|
2002
|
+
then: function(resolve4) {
|
|
2003
|
+
entangledListeners.push(resolve4);
|
|
1999
2004
|
}
|
|
2000
2005
|
};
|
|
2001
2006
|
}
|
|
@@ -2018,8 +2023,8 @@ var require_react_reconciler_production = __commonJS({
|
|
|
2018
2023
|
status: "pending",
|
|
2019
2024
|
value: null,
|
|
2020
2025
|
reason: null,
|
|
2021
|
-
then: function(
|
|
2022
|
-
listeners.push(
|
|
2026
|
+
then: function(resolve4) {
|
|
2027
|
+
listeners.push(resolve4);
|
|
2023
2028
|
}
|
|
2024
2029
|
};
|
|
2025
2030
|
thenable.then(
|
|
@@ -9503,7 +9508,7 @@ var require_stack_utils = __commonJS({
|
|
|
9503
9508
|
});
|
|
9504
9509
|
|
|
9505
9510
|
// src/commands/tui.tsx
|
|
9506
|
-
var
|
|
9511
|
+
var import_react45 = __toESM(require_react());
|
|
9507
9512
|
|
|
9508
9513
|
// node_modules/ink/build/render.js
|
|
9509
9514
|
import { Stream } from "node:stream";
|
|
@@ -17097,8 +17102,8 @@ function Text({ color, backgroundColor, dimColor = false, bold = false, italic =
|
|
|
17097
17102
|
}
|
|
17098
17103
|
|
|
17099
17104
|
// node_modules/ink/build/components/ErrorOverview.js
|
|
17100
|
-
var cleanupPath = (
|
|
17101
|
-
return
|
|
17105
|
+
var cleanupPath = (path6) => {
|
|
17106
|
+
return path6?.replace(`file://${cwd()}/`, "");
|
|
17102
17107
|
};
|
|
17103
17108
|
var stackUtils = new import_stack_utils.default({
|
|
17104
17109
|
cwd: cwd(),
|
|
@@ -17771,8 +17776,8 @@ var kittyModifiers = {
|
|
|
17771
17776
|
var noop = () => {
|
|
17772
17777
|
};
|
|
17773
17778
|
var textEncoder = new TextEncoder();
|
|
17774
|
-
var yieldImmediate = async () => new Promise((
|
|
17775
|
-
setImmediate(
|
|
17779
|
+
var yieldImmediate = async () => new Promise((resolve4) => {
|
|
17780
|
+
setImmediate(resolve4);
|
|
17776
17781
|
});
|
|
17777
17782
|
var kittyQueryEscapeByte = 27;
|
|
17778
17783
|
var kittyQueryOpenBracketByte = 91;
|
|
@@ -17989,8 +17994,8 @@ var Ink = class {
|
|
|
17989
17994
|
};
|
|
17990
17995
|
}
|
|
17991
17996
|
this.initKittyKeyboard();
|
|
17992
|
-
this.exitPromise = new Promise((
|
|
17993
|
-
this.resolveExitPromise =
|
|
17997
|
+
this.exitPromise = new Promise((resolve4, reject) => {
|
|
17998
|
+
this.resolveExitPromise = resolve4;
|
|
17994
17999
|
this.rejectExitPromise = reject;
|
|
17995
18000
|
});
|
|
17996
18001
|
void this.exitPromise.catch(noop);
|
|
@@ -18301,9 +18306,9 @@ var Ink = class {
|
|
|
18301
18306
|
settleThrottle(this.throttledOnRender, canWriteToStdout);
|
|
18302
18307
|
settleThrottle(this.throttledLog, canWriteToStdout);
|
|
18303
18308
|
if (canWriteToStdout && hasWritableState) {
|
|
18304
|
-
await new Promise((
|
|
18309
|
+
await new Promise((resolve4) => {
|
|
18305
18310
|
this.options.stdout.write("", () => {
|
|
18306
|
-
|
|
18311
|
+
resolve4();
|
|
18307
18312
|
});
|
|
18308
18313
|
});
|
|
18309
18314
|
return;
|
|
@@ -18389,8 +18394,8 @@ var Ink = class {
|
|
|
18389
18394
|
async awaitNextRender() {
|
|
18390
18395
|
if (!this.nextRenderCommit) {
|
|
18391
18396
|
let resolveRender;
|
|
18392
|
-
const promise = new Promise((
|
|
18393
|
-
resolveRender =
|
|
18397
|
+
const promise = new Promise((resolve4) => {
|
|
18398
|
+
resolveRender = resolve4;
|
|
18394
18399
|
});
|
|
18395
18400
|
this.nextRenderCommit = { promise, resolve: resolveRender };
|
|
18396
18401
|
}
|
|
@@ -19192,7 +19197,7 @@ var import_chalk4 = __toESM(require_source());
|
|
|
19192
19197
|
import * as fs6 from "fs";
|
|
19193
19198
|
|
|
19194
19199
|
// src/tui/BrainfileTUI.tsx
|
|
19195
|
-
var
|
|
19200
|
+
var import_react44 = __toESM(require_react());
|
|
19196
19201
|
var import_core6 = __toESM(require_dist());
|
|
19197
19202
|
|
|
19198
19203
|
// src/tui/copy.ts
|
|
@@ -19488,7 +19493,7 @@ var ReaddirpStream = class extends Readable {
|
|
|
19488
19493
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
19489
19494
|
const statMethod = opts.lstat ? lstat : stat;
|
|
19490
19495
|
if (wantBigintFsStats) {
|
|
19491
|
-
this._stat = (
|
|
19496
|
+
this._stat = (path6) => statMethod(path6, { bigint: true });
|
|
19492
19497
|
} else {
|
|
19493
19498
|
this._stat = statMethod;
|
|
19494
19499
|
}
|
|
@@ -19513,8 +19518,8 @@ var ReaddirpStream = class extends Readable {
|
|
|
19513
19518
|
const par = this.parent;
|
|
19514
19519
|
const fil = par && par.files;
|
|
19515
19520
|
if (fil && fil.length > 0) {
|
|
19516
|
-
const { path:
|
|
19517
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
19521
|
+
const { path: path6, depth } = par;
|
|
19522
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path6));
|
|
19518
19523
|
const awaited = await Promise.all(slice);
|
|
19519
19524
|
for (const entry of awaited) {
|
|
19520
19525
|
if (!entry)
|
|
@@ -19554,20 +19559,20 @@ var ReaddirpStream = class extends Readable {
|
|
|
19554
19559
|
this.reading = false;
|
|
19555
19560
|
}
|
|
19556
19561
|
}
|
|
19557
|
-
async _exploreDir(
|
|
19562
|
+
async _exploreDir(path6, depth) {
|
|
19558
19563
|
let files;
|
|
19559
19564
|
try {
|
|
19560
|
-
files = await readdir(
|
|
19565
|
+
files = await readdir(path6, this._rdOptions);
|
|
19561
19566
|
} catch (error) {
|
|
19562
19567
|
this._onError(error);
|
|
19563
19568
|
}
|
|
19564
|
-
return { files, depth, path:
|
|
19569
|
+
return { files, depth, path: path6 };
|
|
19565
19570
|
}
|
|
19566
|
-
async _formatEntry(dirent,
|
|
19571
|
+
async _formatEntry(dirent, path6) {
|
|
19567
19572
|
let entry;
|
|
19568
19573
|
const basename4 = this._isDirent ? dirent.name : dirent;
|
|
19569
19574
|
try {
|
|
19570
|
-
const fullPath = presolve(pjoin(
|
|
19575
|
+
const fullPath = presolve(pjoin(path6, basename4));
|
|
19571
19576
|
entry = { path: prelative(this._root, fullPath), fullPath, basename: basename4 };
|
|
19572
19577
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
19573
19578
|
} catch (err) {
|
|
@@ -19967,16 +19972,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
19967
19972
|
};
|
|
19968
19973
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
19969
19974
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
19970
|
-
function createFsWatchInstance(
|
|
19975
|
+
function createFsWatchInstance(path6, options, listener, errHandler, emitRaw) {
|
|
19971
19976
|
const handleEvent = (rawEvent, evPath) => {
|
|
19972
|
-
listener(
|
|
19973
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
19974
|
-
if (evPath &&
|
|
19975
|
-
fsWatchBroadcast(sysPath.resolve(
|
|
19977
|
+
listener(path6);
|
|
19978
|
+
emitRaw(rawEvent, evPath, { watchedPath: path6 });
|
|
19979
|
+
if (evPath && path6 !== evPath) {
|
|
19980
|
+
fsWatchBroadcast(sysPath.resolve(path6, evPath), KEY_LISTENERS, sysPath.join(path6, evPath));
|
|
19976
19981
|
}
|
|
19977
19982
|
};
|
|
19978
19983
|
try {
|
|
19979
|
-
return fs_watch(
|
|
19984
|
+
return fs_watch(path6, {
|
|
19980
19985
|
persistent: options.persistent
|
|
19981
19986
|
}, handleEvent);
|
|
19982
19987
|
} catch (error) {
|
|
@@ -19992,12 +19997,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
19992
19997
|
listener(val1, val2, val3);
|
|
19993
19998
|
});
|
|
19994
19999
|
};
|
|
19995
|
-
var setFsWatchListener = (
|
|
20000
|
+
var setFsWatchListener = (path6, fullPath, options, handlers) => {
|
|
19996
20001
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
19997
20002
|
let cont = FsWatchInstances.get(fullPath);
|
|
19998
20003
|
let watcher;
|
|
19999
20004
|
if (!options.persistent) {
|
|
20000
|
-
watcher = createFsWatchInstance(
|
|
20005
|
+
watcher = createFsWatchInstance(path6, options, listener, errHandler, rawEmitter);
|
|
20001
20006
|
if (!watcher)
|
|
20002
20007
|
return;
|
|
20003
20008
|
return watcher.close.bind(watcher);
|
|
@@ -20008,7 +20013,7 @@ var setFsWatchListener = (path4, fullPath, options, handlers) => {
|
|
|
20008
20013
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
20009
20014
|
} else {
|
|
20010
20015
|
watcher = createFsWatchInstance(
|
|
20011
|
-
|
|
20016
|
+
path6,
|
|
20012
20017
|
options,
|
|
20013
20018
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
20014
20019
|
errHandler,
|
|
@@ -20023,7 +20028,7 @@ var setFsWatchListener = (path4, fullPath, options, handlers) => {
|
|
|
20023
20028
|
cont.watcherUnusable = true;
|
|
20024
20029
|
if (isWindows3 && error.code === "EPERM") {
|
|
20025
20030
|
try {
|
|
20026
|
-
const fd = await open(
|
|
20031
|
+
const fd = await open(path6, "r");
|
|
20027
20032
|
await fd.close();
|
|
20028
20033
|
broadcastErr(error);
|
|
20029
20034
|
} catch (err) {
|
|
@@ -20054,7 +20059,7 @@ var setFsWatchListener = (path4, fullPath, options, handlers) => {
|
|
|
20054
20059
|
};
|
|
20055
20060
|
};
|
|
20056
20061
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
20057
|
-
var setFsWatchFileListener = (
|
|
20062
|
+
var setFsWatchFileListener = (path6, fullPath, options, handlers) => {
|
|
20058
20063
|
const { listener, rawEmitter } = handlers;
|
|
20059
20064
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
20060
20065
|
const copts = cont && cont.options;
|
|
@@ -20076,7 +20081,7 @@ var setFsWatchFileListener = (path4, fullPath, options, handlers) => {
|
|
|
20076
20081
|
});
|
|
20077
20082
|
const currmtime = curr.mtimeMs;
|
|
20078
20083
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
20079
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
20084
|
+
foreach(cont.listeners, (listener2) => listener2(path6, curr));
|
|
20080
20085
|
}
|
|
20081
20086
|
})
|
|
20082
20087
|
};
|
|
@@ -20104,13 +20109,13 @@ var NodeFsHandler = class {
|
|
|
20104
20109
|
* @param listener on fs change
|
|
20105
20110
|
* @returns closer for the watcher instance
|
|
20106
20111
|
*/
|
|
20107
|
-
_watchWithNodeFs(
|
|
20112
|
+
_watchWithNodeFs(path6, listener) {
|
|
20108
20113
|
const opts = this.fsw.options;
|
|
20109
|
-
const directory = sysPath.dirname(
|
|
20110
|
-
const basename4 = sysPath.basename(
|
|
20114
|
+
const directory = sysPath.dirname(path6);
|
|
20115
|
+
const basename4 = sysPath.basename(path6);
|
|
20111
20116
|
const parent = this.fsw._getWatchedDir(directory);
|
|
20112
20117
|
parent.add(basename4);
|
|
20113
|
-
const absolutePath = sysPath.resolve(
|
|
20118
|
+
const absolutePath = sysPath.resolve(path6);
|
|
20114
20119
|
const options = {
|
|
20115
20120
|
persistent: opts.persistent
|
|
20116
20121
|
};
|
|
@@ -20120,12 +20125,12 @@ var NodeFsHandler = class {
|
|
|
20120
20125
|
if (opts.usePolling) {
|
|
20121
20126
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
20122
20127
|
options.interval = enableBin && isBinaryPath(basename4) ? opts.binaryInterval : opts.interval;
|
|
20123
|
-
closer = setFsWatchFileListener(
|
|
20128
|
+
closer = setFsWatchFileListener(path6, absolutePath, options, {
|
|
20124
20129
|
listener,
|
|
20125
20130
|
rawEmitter: this.fsw._emitRaw
|
|
20126
20131
|
});
|
|
20127
20132
|
} else {
|
|
20128
|
-
closer = setFsWatchListener(
|
|
20133
|
+
closer = setFsWatchListener(path6, absolutePath, options, {
|
|
20129
20134
|
listener,
|
|
20130
20135
|
errHandler: this._boundHandleError,
|
|
20131
20136
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -20141,13 +20146,13 @@ var NodeFsHandler = class {
|
|
|
20141
20146
|
if (this.fsw.closed) {
|
|
20142
20147
|
return;
|
|
20143
20148
|
}
|
|
20144
|
-
const
|
|
20149
|
+
const dirname6 = sysPath.dirname(file);
|
|
20145
20150
|
const basename4 = sysPath.basename(file);
|
|
20146
|
-
const parent = this.fsw._getWatchedDir(
|
|
20151
|
+
const parent = this.fsw._getWatchedDir(dirname6);
|
|
20147
20152
|
let prevStats = stats;
|
|
20148
20153
|
if (parent.has(basename4))
|
|
20149
20154
|
return;
|
|
20150
|
-
const listener = async (
|
|
20155
|
+
const listener = async (path6, newStats) => {
|
|
20151
20156
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
20152
20157
|
return;
|
|
20153
20158
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -20161,16 +20166,16 @@ var NodeFsHandler = class {
|
|
|
20161
20166
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
20162
20167
|
}
|
|
20163
20168
|
if ((isMacos || isLinux2 || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
20164
|
-
this.fsw._closeFile(
|
|
20169
|
+
this.fsw._closeFile(path6);
|
|
20165
20170
|
prevStats = newStats2;
|
|
20166
20171
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
20167
20172
|
if (closer2)
|
|
20168
|
-
this.fsw._addPathCloser(
|
|
20173
|
+
this.fsw._addPathCloser(path6, closer2);
|
|
20169
20174
|
} else {
|
|
20170
20175
|
prevStats = newStats2;
|
|
20171
20176
|
}
|
|
20172
20177
|
} catch (error) {
|
|
20173
|
-
this.fsw._remove(
|
|
20178
|
+
this.fsw._remove(dirname6, basename4);
|
|
20174
20179
|
}
|
|
20175
20180
|
} else if (parent.has(basename4)) {
|
|
20176
20181
|
const at = newStats.atimeMs;
|
|
@@ -20197,7 +20202,7 @@ var NodeFsHandler = class {
|
|
|
20197
20202
|
* @param item basename of this item
|
|
20198
20203
|
* @returns true if no more processing is needed for this entry.
|
|
20199
20204
|
*/
|
|
20200
|
-
async _handleSymlink(entry, directory,
|
|
20205
|
+
async _handleSymlink(entry, directory, path6, item) {
|
|
20201
20206
|
if (this.fsw.closed) {
|
|
20202
20207
|
return;
|
|
20203
20208
|
}
|
|
@@ -20207,7 +20212,7 @@ var NodeFsHandler = class {
|
|
|
20207
20212
|
this.fsw._incrReadyCount();
|
|
20208
20213
|
let linkPath;
|
|
20209
20214
|
try {
|
|
20210
|
-
linkPath = await fsrealpath(
|
|
20215
|
+
linkPath = await fsrealpath(path6);
|
|
20211
20216
|
} catch (e) {
|
|
20212
20217
|
this.fsw._emitReady();
|
|
20213
20218
|
return true;
|
|
@@ -20217,12 +20222,12 @@ var NodeFsHandler = class {
|
|
|
20217
20222
|
if (dir.has(item)) {
|
|
20218
20223
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
20219
20224
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
20220
|
-
this.fsw._emit(EV.CHANGE,
|
|
20225
|
+
this.fsw._emit(EV.CHANGE, path6, entry.stats);
|
|
20221
20226
|
}
|
|
20222
20227
|
} else {
|
|
20223
20228
|
dir.add(item);
|
|
20224
20229
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
20225
|
-
this.fsw._emit(EV.ADD,
|
|
20230
|
+
this.fsw._emit(EV.ADD, path6, entry.stats);
|
|
20226
20231
|
}
|
|
20227
20232
|
this.fsw._emitReady();
|
|
20228
20233
|
return true;
|
|
@@ -20251,9 +20256,9 @@ var NodeFsHandler = class {
|
|
|
20251
20256
|
return;
|
|
20252
20257
|
}
|
|
20253
20258
|
const item = entry.path;
|
|
20254
|
-
let
|
|
20259
|
+
let path6 = sysPath.join(directory, item);
|
|
20255
20260
|
current.add(item);
|
|
20256
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
20261
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path6, item)) {
|
|
20257
20262
|
return;
|
|
20258
20263
|
}
|
|
20259
20264
|
if (this.fsw.closed) {
|
|
@@ -20262,11 +20267,11 @@ var NodeFsHandler = class {
|
|
|
20262
20267
|
}
|
|
20263
20268
|
if (item === target || !target && !previous.has(item)) {
|
|
20264
20269
|
this.fsw._incrReadyCount();
|
|
20265
|
-
|
|
20266
|
-
this._addToNodeFs(
|
|
20270
|
+
path6 = sysPath.join(dir, sysPath.relative(dir, path6));
|
|
20271
|
+
this._addToNodeFs(path6, initialAdd, wh, depth + 1);
|
|
20267
20272
|
}
|
|
20268
20273
|
}).on(EV.ERROR, this._boundHandleError);
|
|
20269
|
-
return new Promise((
|
|
20274
|
+
return new Promise((resolve4, reject) => {
|
|
20270
20275
|
if (!stream)
|
|
20271
20276
|
return reject();
|
|
20272
20277
|
stream.once(STR_END, () => {
|
|
@@ -20275,7 +20280,7 @@ var NodeFsHandler = class {
|
|
|
20275
20280
|
return;
|
|
20276
20281
|
}
|
|
20277
20282
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
20278
|
-
|
|
20283
|
+
resolve4(void 0);
|
|
20279
20284
|
previous.getChildren().filter((item) => {
|
|
20280
20285
|
return item !== directory && !current.has(item);
|
|
20281
20286
|
}).forEach((item) => {
|
|
@@ -20332,13 +20337,13 @@ var NodeFsHandler = class {
|
|
|
20332
20337
|
* @param depth Child path actually targeted for watch
|
|
20333
20338
|
* @param target Child path actually targeted for watch
|
|
20334
20339
|
*/
|
|
20335
|
-
async _addToNodeFs(
|
|
20340
|
+
async _addToNodeFs(path6, initialAdd, priorWh, depth, target) {
|
|
20336
20341
|
const ready = this.fsw._emitReady;
|
|
20337
|
-
if (this.fsw._isIgnored(
|
|
20342
|
+
if (this.fsw._isIgnored(path6) || this.fsw.closed) {
|
|
20338
20343
|
ready();
|
|
20339
20344
|
return false;
|
|
20340
20345
|
}
|
|
20341
|
-
const wh = this.fsw._getWatchHelpers(
|
|
20346
|
+
const wh = this.fsw._getWatchHelpers(path6);
|
|
20342
20347
|
if (priorWh) {
|
|
20343
20348
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
20344
20349
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -20354,8 +20359,8 @@ var NodeFsHandler = class {
|
|
|
20354
20359
|
const follow = this.fsw.options.followSymlinks;
|
|
20355
20360
|
let closer;
|
|
20356
20361
|
if (stats.isDirectory()) {
|
|
20357
|
-
const absPath = sysPath.resolve(
|
|
20358
|
-
const targetPath = follow ? await fsrealpath(
|
|
20362
|
+
const absPath = sysPath.resolve(path6);
|
|
20363
|
+
const targetPath = follow ? await fsrealpath(path6) : path6;
|
|
20359
20364
|
if (this.fsw.closed)
|
|
20360
20365
|
return;
|
|
20361
20366
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -20365,29 +20370,29 @@ var NodeFsHandler = class {
|
|
|
20365
20370
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
20366
20371
|
}
|
|
20367
20372
|
} else if (stats.isSymbolicLink()) {
|
|
20368
|
-
const targetPath = follow ? await fsrealpath(
|
|
20373
|
+
const targetPath = follow ? await fsrealpath(path6) : path6;
|
|
20369
20374
|
if (this.fsw.closed)
|
|
20370
20375
|
return;
|
|
20371
20376
|
const parent = sysPath.dirname(wh.watchPath);
|
|
20372
20377
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
20373
20378
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
20374
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
20379
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path6, wh, targetPath);
|
|
20375
20380
|
if (this.fsw.closed)
|
|
20376
20381
|
return;
|
|
20377
20382
|
if (targetPath !== void 0) {
|
|
20378
|
-
this.fsw._symlinkPaths.set(sysPath.resolve(
|
|
20383
|
+
this.fsw._symlinkPaths.set(sysPath.resolve(path6), targetPath);
|
|
20379
20384
|
}
|
|
20380
20385
|
} else {
|
|
20381
20386
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
20382
20387
|
}
|
|
20383
20388
|
ready();
|
|
20384
20389
|
if (closer)
|
|
20385
|
-
this.fsw._addPathCloser(
|
|
20390
|
+
this.fsw._addPathCloser(path6, closer);
|
|
20386
20391
|
return false;
|
|
20387
20392
|
} catch (error) {
|
|
20388
20393
|
if (this.fsw._handleError(error)) {
|
|
20389
20394
|
ready();
|
|
20390
|
-
return
|
|
20395
|
+
return path6;
|
|
20391
20396
|
}
|
|
20392
20397
|
}
|
|
20393
20398
|
}
|
|
@@ -20430,26 +20435,26 @@ function createPattern(matcher) {
|
|
|
20430
20435
|
}
|
|
20431
20436
|
return () => false;
|
|
20432
20437
|
}
|
|
20433
|
-
function normalizePath(
|
|
20434
|
-
if (typeof
|
|
20438
|
+
function normalizePath(path6) {
|
|
20439
|
+
if (typeof path6 !== "string")
|
|
20435
20440
|
throw new Error("string expected");
|
|
20436
|
-
|
|
20437
|
-
|
|
20441
|
+
path6 = sysPath2.normalize(path6);
|
|
20442
|
+
path6 = path6.replace(/\\/g, "/");
|
|
20438
20443
|
let prepend = false;
|
|
20439
|
-
if (
|
|
20444
|
+
if (path6.startsWith("//"))
|
|
20440
20445
|
prepend = true;
|
|
20441
20446
|
const DOUBLE_SLASH_RE2 = /\/\//;
|
|
20442
|
-
while (
|
|
20443
|
-
|
|
20447
|
+
while (path6.match(DOUBLE_SLASH_RE2))
|
|
20448
|
+
path6 = path6.replace(DOUBLE_SLASH_RE2, "/");
|
|
20444
20449
|
if (prepend)
|
|
20445
|
-
|
|
20446
|
-
return
|
|
20450
|
+
path6 = "/" + path6;
|
|
20451
|
+
return path6;
|
|
20447
20452
|
}
|
|
20448
20453
|
function matchPatterns(patterns, testString, stats) {
|
|
20449
|
-
const
|
|
20454
|
+
const path6 = normalizePath(testString);
|
|
20450
20455
|
for (let index = 0; index < patterns.length; index++) {
|
|
20451
20456
|
const pattern = patterns[index];
|
|
20452
|
-
if (pattern(
|
|
20457
|
+
if (pattern(path6, stats)) {
|
|
20453
20458
|
return true;
|
|
20454
20459
|
}
|
|
20455
20460
|
}
|
|
@@ -20489,19 +20494,19 @@ var toUnix = (string) => {
|
|
|
20489
20494
|
}
|
|
20490
20495
|
return str;
|
|
20491
20496
|
};
|
|
20492
|
-
var normalizePathToUnix = (
|
|
20493
|
-
var normalizeIgnored = (cwd2 = "") => (
|
|
20494
|
-
if (typeof
|
|
20495
|
-
return normalizePathToUnix(sysPath2.isAbsolute(
|
|
20497
|
+
var normalizePathToUnix = (path6) => toUnix(sysPath2.normalize(toUnix(path6)));
|
|
20498
|
+
var normalizeIgnored = (cwd2 = "") => (path6) => {
|
|
20499
|
+
if (typeof path6 === "string") {
|
|
20500
|
+
return normalizePathToUnix(sysPath2.isAbsolute(path6) ? path6 : sysPath2.join(cwd2, path6));
|
|
20496
20501
|
} else {
|
|
20497
|
-
return
|
|
20502
|
+
return path6;
|
|
20498
20503
|
}
|
|
20499
20504
|
};
|
|
20500
|
-
var getAbsolutePath = (
|
|
20501
|
-
if (sysPath2.isAbsolute(
|
|
20502
|
-
return
|
|
20505
|
+
var getAbsolutePath = (path6, cwd2) => {
|
|
20506
|
+
if (sysPath2.isAbsolute(path6)) {
|
|
20507
|
+
return path6;
|
|
20503
20508
|
}
|
|
20504
|
-
return sysPath2.join(cwd2,
|
|
20509
|
+
return sysPath2.join(cwd2, path6);
|
|
20505
20510
|
};
|
|
20506
20511
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
20507
20512
|
var DirEntry = class {
|
|
@@ -20556,10 +20561,10 @@ var DirEntry = class {
|
|
|
20556
20561
|
var STAT_METHOD_F = "stat";
|
|
20557
20562
|
var STAT_METHOD_L = "lstat";
|
|
20558
20563
|
var WatchHelper = class {
|
|
20559
|
-
constructor(
|
|
20564
|
+
constructor(path6, follow, fsw) {
|
|
20560
20565
|
this.fsw = fsw;
|
|
20561
|
-
const watchPath =
|
|
20562
|
-
this.path =
|
|
20566
|
+
const watchPath = path6;
|
|
20567
|
+
this.path = path6 = path6.replace(REPLACER_RE, "");
|
|
20563
20568
|
this.watchPath = watchPath;
|
|
20564
20569
|
this.fullWatchPath = sysPath2.resolve(watchPath);
|
|
20565
20570
|
this.dirParts = [];
|
|
@@ -20681,20 +20686,20 @@ var FSWatcher = class extends EventEmitter3 {
|
|
|
20681
20686
|
this._closePromise = void 0;
|
|
20682
20687
|
let paths = unifyPaths(paths_);
|
|
20683
20688
|
if (cwd2) {
|
|
20684
|
-
paths = paths.map((
|
|
20685
|
-
const absPath = getAbsolutePath(
|
|
20689
|
+
paths = paths.map((path6) => {
|
|
20690
|
+
const absPath = getAbsolutePath(path6, cwd2);
|
|
20686
20691
|
return absPath;
|
|
20687
20692
|
});
|
|
20688
20693
|
}
|
|
20689
|
-
paths.forEach((
|
|
20690
|
-
this._removeIgnoredPath(
|
|
20694
|
+
paths.forEach((path6) => {
|
|
20695
|
+
this._removeIgnoredPath(path6);
|
|
20691
20696
|
});
|
|
20692
20697
|
this._userIgnored = void 0;
|
|
20693
20698
|
if (!this._readyCount)
|
|
20694
20699
|
this._readyCount = 0;
|
|
20695
20700
|
this._readyCount += paths.length;
|
|
20696
|
-
Promise.all(paths.map(async (
|
|
20697
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
20701
|
+
Promise.all(paths.map(async (path6) => {
|
|
20702
|
+
const res = await this._nodeFsHandler._addToNodeFs(path6, !_internal, void 0, 0, _origAdd);
|
|
20698
20703
|
if (res)
|
|
20699
20704
|
this._emitReady();
|
|
20700
20705
|
return res;
|
|
@@ -20716,17 +20721,17 @@ var FSWatcher = class extends EventEmitter3 {
|
|
|
20716
20721
|
return this;
|
|
20717
20722
|
const paths = unifyPaths(paths_);
|
|
20718
20723
|
const { cwd: cwd2 } = this.options;
|
|
20719
|
-
paths.forEach((
|
|
20720
|
-
if (!sysPath2.isAbsolute(
|
|
20724
|
+
paths.forEach((path6) => {
|
|
20725
|
+
if (!sysPath2.isAbsolute(path6) && !this._closers.has(path6)) {
|
|
20721
20726
|
if (cwd2)
|
|
20722
|
-
|
|
20723
|
-
|
|
20727
|
+
path6 = sysPath2.join(cwd2, path6);
|
|
20728
|
+
path6 = sysPath2.resolve(path6);
|
|
20724
20729
|
}
|
|
20725
|
-
this._closePath(
|
|
20726
|
-
this._addIgnoredPath(
|
|
20727
|
-
if (this._watched.has(
|
|
20730
|
+
this._closePath(path6);
|
|
20731
|
+
this._addIgnoredPath(path6);
|
|
20732
|
+
if (this._watched.has(path6)) {
|
|
20728
20733
|
this._addIgnoredPath({
|
|
20729
|
-
path:
|
|
20734
|
+
path: path6,
|
|
20730
20735
|
recursive: true
|
|
20731
20736
|
});
|
|
20732
20737
|
}
|
|
@@ -20790,38 +20795,38 @@ var FSWatcher = class extends EventEmitter3 {
|
|
|
20790
20795
|
* @param stats arguments to be passed with event
|
|
20791
20796
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
20792
20797
|
*/
|
|
20793
|
-
async _emit(event,
|
|
20798
|
+
async _emit(event, path6, stats) {
|
|
20794
20799
|
if (this.closed)
|
|
20795
20800
|
return;
|
|
20796
20801
|
const opts = this.options;
|
|
20797
20802
|
if (isWindows3)
|
|
20798
|
-
|
|
20803
|
+
path6 = sysPath2.normalize(path6);
|
|
20799
20804
|
if (opts.cwd)
|
|
20800
|
-
|
|
20801
|
-
const args = [
|
|
20805
|
+
path6 = sysPath2.relative(opts.cwd, path6);
|
|
20806
|
+
const args = [path6];
|
|
20802
20807
|
if (stats != null)
|
|
20803
20808
|
args.push(stats);
|
|
20804
20809
|
const awf = opts.awaitWriteFinish;
|
|
20805
20810
|
let pw;
|
|
20806
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
20811
|
+
if (awf && (pw = this._pendingWrites.get(path6))) {
|
|
20807
20812
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
20808
20813
|
return this;
|
|
20809
20814
|
}
|
|
20810
20815
|
if (opts.atomic) {
|
|
20811
20816
|
if (event === EVENTS.UNLINK) {
|
|
20812
|
-
this._pendingUnlinks.set(
|
|
20817
|
+
this._pendingUnlinks.set(path6, [event, ...args]);
|
|
20813
20818
|
setTimeout(() => {
|
|
20814
|
-
this._pendingUnlinks.forEach((entry,
|
|
20819
|
+
this._pendingUnlinks.forEach((entry, path7) => {
|
|
20815
20820
|
this.emit(...entry);
|
|
20816
20821
|
this.emit(EVENTS.ALL, ...entry);
|
|
20817
|
-
this._pendingUnlinks.delete(
|
|
20822
|
+
this._pendingUnlinks.delete(path7);
|
|
20818
20823
|
});
|
|
20819
20824
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
20820
20825
|
return this;
|
|
20821
20826
|
}
|
|
20822
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
20827
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path6)) {
|
|
20823
20828
|
event = EVENTS.CHANGE;
|
|
20824
|
-
this._pendingUnlinks.delete(
|
|
20829
|
+
this._pendingUnlinks.delete(path6);
|
|
20825
20830
|
}
|
|
20826
20831
|
}
|
|
20827
20832
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -20839,16 +20844,16 @@ var FSWatcher = class extends EventEmitter3 {
|
|
|
20839
20844
|
this.emitWithAll(event, args);
|
|
20840
20845
|
}
|
|
20841
20846
|
};
|
|
20842
|
-
this._awaitWriteFinish(
|
|
20847
|
+
this._awaitWriteFinish(path6, awf.stabilityThreshold, event, awfEmit);
|
|
20843
20848
|
return this;
|
|
20844
20849
|
}
|
|
20845
20850
|
if (event === EVENTS.CHANGE) {
|
|
20846
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
20851
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path6, 50);
|
|
20847
20852
|
if (isThrottled)
|
|
20848
20853
|
return this;
|
|
20849
20854
|
}
|
|
20850
20855
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
20851
|
-
const fullPath = opts.cwd ? sysPath2.join(opts.cwd,
|
|
20856
|
+
const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path6) : path6;
|
|
20852
20857
|
let stats2;
|
|
20853
20858
|
try {
|
|
20854
20859
|
stats2 = await stat3(fullPath);
|
|
@@ -20879,23 +20884,23 @@ var FSWatcher = class extends EventEmitter3 {
|
|
|
20879
20884
|
* @param timeout duration of time to suppress duplicate actions
|
|
20880
20885
|
* @returns tracking object or false if action should be suppressed
|
|
20881
20886
|
*/
|
|
20882
|
-
_throttle(actionType,
|
|
20887
|
+
_throttle(actionType, path6, timeout) {
|
|
20883
20888
|
if (!this._throttled.has(actionType)) {
|
|
20884
20889
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
20885
20890
|
}
|
|
20886
20891
|
const action = this._throttled.get(actionType);
|
|
20887
20892
|
if (!action)
|
|
20888
20893
|
throw new Error("invalid throttle");
|
|
20889
|
-
const actionPath = action.get(
|
|
20894
|
+
const actionPath = action.get(path6);
|
|
20890
20895
|
if (actionPath) {
|
|
20891
20896
|
actionPath.count++;
|
|
20892
20897
|
return false;
|
|
20893
20898
|
}
|
|
20894
20899
|
let timeoutObject;
|
|
20895
20900
|
const clear = () => {
|
|
20896
|
-
const item = action.get(
|
|
20901
|
+
const item = action.get(path6);
|
|
20897
20902
|
const count = item ? item.count : 0;
|
|
20898
|
-
action.delete(
|
|
20903
|
+
action.delete(path6);
|
|
20899
20904
|
clearTimeout(timeoutObject);
|
|
20900
20905
|
if (item)
|
|
20901
20906
|
clearTimeout(item.timeoutObject);
|
|
@@ -20903,7 +20908,7 @@ var FSWatcher = class extends EventEmitter3 {
|
|
|
20903
20908
|
};
|
|
20904
20909
|
timeoutObject = setTimeout(clear, timeout);
|
|
20905
20910
|
const thr = { timeoutObject, clear, count: 0 };
|
|
20906
|
-
action.set(
|
|
20911
|
+
action.set(path6, thr);
|
|
20907
20912
|
return thr;
|
|
20908
20913
|
}
|
|
20909
20914
|
_incrReadyCount() {
|
|
@@ -20917,44 +20922,44 @@ var FSWatcher = class extends EventEmitter3 {
|
|
|
20917
20922
|
* @param event
|
|
20918
20923
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
20919
20924
|
*/
|
|
20920
|
-
_awaitWriteFinish(
|
|
20925
|
+
_awaitWriteFinish(path6, threshold, event, awfEmit) {
|
|
20921
20926
|
const awf = this.options.awaitWriteFinish;
|
|
20922
20927
|
if (typeof awf !== "object")
|
|
20923
20928
|
return;
|
|
20924
20929
|
const pollInterval = awf.pollInterval;
|
|
20925
20930
|
let timeoutHandler;
|
|
20926
|
-
let fullPath =
|
|
20927
|
-
if (this.options.cwd && !sysPath2.isAbsolute(
|
|
20928
|
-
fullPath = sysPath2.join(this.options.cwd,
|
|
20931
|
+
let fullPath = path6;
|
|
20932
|
+
if (this.options.cwd && !sysPath2.isAbsolute(path6)) {
|
|
20933
|
+
fullPath = sysPath2.join(this.options.cwd, path6);
|
|
20929
20934
|
}
|
|
20930
20935
|
const now = /* @__PURE__ */ new Date();
|
|
20931
20936
|
const writes = this._pendingWrites;
|
|
20932
20937
|
function awaitWriteFinishFn(prevStat) {
|
|
20933
20938
|
statcb(fullPath, (err, curStat) => {
|
|
20934
|
-
if (err || !writes.has(
|
|
20939
|
+
if (err || !writes.has(path6)) {
|
|
20935
20940
|
if (err && err.code !== "ENOENT")
|
|
20936
20941
|
awfEmit(err);
|
|
20937
20942
|
return;
|
|
20938
20943
|
}
|
|
20939
20944
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
20940
20945
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
20941
|
-
writes.get(
|
|
20946
|
+
writes.get(path6).lastChange = now2;
|
|
20942
20947
|
}
|
|
20943
|
-
const pw = writes.get(
|
|
20948
|
+
const pw = writes.get(path6);
|
|
20944
20949
|
const df = now2 - pw.lastChange;
|
|
20945
20950
|
if (df >= threshold) {
|
|
20946
|
-
writes.delete(
|
|
20951
|
+
writes.delete(path6);
|
|
20947
20952
|
awfEmit(void 0, curStat);
|
|
20948
20953
|
} else {
|
|
20949
20954
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
20950
20955
|
}
|
|
20951
20956
|
});
|
|
20952
20957
|
}
|
|
20953
|
-
if (!writes.has(
|
|
20954
|
-
writes.set(
|
|
20958
|
+
if (!writes.has(path6)) {
|
|
20959
|
+
writes.set(path6, {
|
|
20955
20960
|
lastChange: now,
|
|
20956
20961
|
cancelWait: () => {
|
|
20957
|
-
writes.delete(
|
|
20962
|
+
writes.delete(path6);
|
|
20958
20963
|
clearTimeout(timeoutHandler);
|
|
20959
20964
|
return event;
|
|
20960
20965
|
}
|
|
@@ -20965,8 +20970,8 @@ var FSWatcher = class extends EventEmitter3 {
|
|
|
20965
20970
|
/**
|
|
20966
20971
|
* Determines whether user has asked to ignore this path.
|
|
20967
20972
|
*/
|
|
20968
|
-
_isIgnored(
|
|
20969
|
-
if (this.options.atomic && DOT_RE.test(
|
|
20973
|
+
_isIgnored(path6, stats) {
|
|
20974
|
+
if (this.options.atomic && DOT_RE.test(path6))
|
|
20970
20975
|
return true;
|
|
20971
20976
|
if (!this._userIgnored) {
|
|
20972
20977
|
const { cwd: cwd2 } = this.options;
|
|
@@ -20976,17 +20981,17 @@ var FSWatcher = class extends EventEmitter3 {
|
|
|
20976
20981
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd2)), ...ignored];
|
|
20977
20982
|
this._userIgnored = anymatch(list, void 0);
|
|
20978
20983
|
}
|
|
20979
|
-
return this._userIgnored(
|
|
20984
|
+
return this._userIgnored(path6, stats);
|
|
20980
20985
|
}
|
|
20981
|
-
_isntIgnored(
|
|
20982
|
-
return !this._isIgnored(
|
|
20986
|
+
_isntIgnored(path6, stat4) {
|
|
20987
|
+
return !this._isIgnored(path6, stat4);
|
|
20983
20988
|
}
|
|
20984
20989
|
/**
|
|
20985
20990
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
20986
20991
|
* @param path file or directory pattern being watched
|
|
20987
20992
|
*/
|
|
20988
|
-
_getWatchHelpers(
|
|
20989
|
-
return new WatchHelper(
|
|
20993
|
+
_getWatchHelpers(path6) {
|
|
20994
|
+
return new WatchHelper(path6, this.options.followSymlinks, this);
|
|
20990
20995
|
}
|
|
20991
20996
|
// Directory helpers
|
|
20992
20997
|
// -----------------
|
|
@@ -21018,63 +21023,63 @@ var FSWatcher = class extends EventEmitter3 {
|
|
|
21018
21023
|
* @param item base path of item/directory
|
|
21019
21024
|
*/
|
|
21020
21025
|
_remove(directory, item, isDirectory) {
|
|
21021
|
-
const
|
|
21022
|
-
const fullPath = sysPath2.resolve(
|
|
21023
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
21024
|
-
if (!this._throttle("remove",
|
|
21026
|
+
const path6 = sysPath2.join(directory, item);
|
|
21027
|
+
const fullPath = sysPath2.resolve(path6);
|
|
21028
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path6) || this._watched.has(fullPath);
|
|
21029
|
+
if (!this._throttle("remove", path6, 100))
|
|
21025
21030
|
return;
|
|
21026
21031
|
if (!isDirectory && this._watched.size === 1) {
|
|
21027
21032
|
this.add(directory, item, true);
|
|
21028
21033
|
}
|
|
21029
|
-
const wp = this._getWatchedDir(
|
|
21034
|
+
const wp = this._getWatchedDir(path6);
|
|
21030
21035
|
const nestedDirectoryChildren = wp.getChildren();
|
|
21031
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
21036
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path6, nested));
|
|
21032
21037
|
const parent = this._getWatchedDir(directory);
|
|
21033
21038
|
const wasTracked = parent.has(item);
|
|
21034
21039
|
parent.remove(item);
|
|
21035
21040
|
if (this._symlinkPaths.has(fullPath)) {
|
|
21036
21041
|
this._symlinkPaths.delete(fullPath);
|
|
21037
21042
|
}
|
|
21038
|
-
let relPath =
|
|
21043
|
+
let relPath = path6;
|
|
21039
21044
|
if (this.options.cwd)
|
|
21040
|
-
relPath = sysPath2.relative(this.options.cwd,
|
|
21045
|
+
relPath = sysPath2.relative(this.options.cwd, path6);
|
|
21041
21046
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
21042
21047
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
21043
21048
|
if (event === EVENTS.ADD)
|
|
21044
21049
|
return;
|
|
21045
21050
|
}
|
|
21046
|
-
this._watched.delete(
|
|
21051
|
+
this._watched.delete(path6);
|
|
21047
21052
|
this._watched.delete(fullPath);
|
|
21048
21053
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
21049
|
-
if (wasTracked && !this._isIgnored(
|
|
21050
|
-
this._emit(eventName,
|
|
21051
|
-
this._closePath(
|
|
21054
|
+
if (wasTracked && !this._isIgnored(path6))
|
|
21055
|
+
this._emit(eventName, path6);
|
|
21056
|
+
this._closePath(path6);
|
|
21052
21057
|
}
|
|
21053
21058
|
/**
|
|
21054
21059
|
* Closes all watchers for a path
|
|
21055
21060
|
*/
|
|
21056
|
-
_closePath(
|
|
21057
|
-
this._closeFile(
|
|
21058
|
-
const dir = sysPath2.dirname(
|
|
21059
|
-
this._getWatchedDir(dir).remove(sysPath2.basename(
|
|
21061
|
+
_closePath(path6) {
|
|
21062
|
+
this._closeFile(path6);
|
|
21063
|
+
const dir = sysPath2.dirname(path6);
|
|
21064
|
+
this._getWatchedDir(dir).remove(sysPath2.basename(path6));
|
|
21060
21065
|
}
|
|
21061
21066
|
/**
|
|
21062
21067
|
* Closes only file-specific watchers
|
|
21063
21068
|
*/
|
|
21064
|
-
_closeFile(
|
|
21065
|
-
const closers = this._closers.get(
|
|
21069
|
+
_closeFile(path6) {
|
|
21070
|
+
const closers = this._closers.get(path6);
|
|
21066
21071
|
if (!closers)
|
|
21067
21072
|
return;
|
|
21068
21073
|
closers.forEach((closer) => closer());
|
|
21069
|
-
this._closers.delete(
|
|
21074
|
+
this._closers.delete(path6);
|
|
21070
21075
|
}
|
|
21071
|
-
_addPathCloser(
|
|
21076
|
+
_addPathCloser(path6, closer) {
|
|
21072
21077
|
if (!closer)
|
|
21073
21078
|
return;
|
|
21074
|
-
let list = this._closers.get(
|
|
21079
|
+
let list = this._closers.get(path6);
|
|
21075
21080
|
if (!list) {
|
|
21076
21081
|
list = [];
|
|
21077
|
-
this._closers.set(
|
|
21082
|
+
this._closers.set(path6, list);
|
|
21078
21083
|
}
|
|
21079
21084
|
list.push(closer);
|
|
21080
21085
|
}
|
|
@@ -21106,10 +21111,10 @@ function watch(paths, options = {}) {
|
|
|
21106
21111
|
var import_core4 = __toESM(require_dist());
|
|
21107
21112
|
|
|
21108
21113
|
// src/tui/actions.ts
|
|
21109
|
-
var import_core3 = __toESM(require_dist());
|
|
21110
21114
|
import * as fs3 from "fs";
|
|
21111
21115
|
import * as path from "path";
|
|
21112
21116
|
import { spawnSync } from "child_process";
|
|
21117
|
+
var import_core3 = __toESM(require_dist());
|
|
21113
21118
|
function readBrainfile(filePath) {
|
|
21114
21119
|
try {
|
|
21115
21120
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
@@ -21169,6 +21174,7 @@ function moveTaskAction(filePath, taskId, targetColumnId) {
|
|
|
21169
21174
|
targetColumn.id
|
|
21170
21175
|
);
|
|
21171
21176
|
if (!moveResult.success) return { success: false, error: moveResult.error };
|
|
21177
|
+
scheduleBoardCommit(filePath, `move ${taskId}: ${targetColumn.id}`);
|
|
21172
21178
|
return {
|
|
21173
21179
|
success: true,
|
|
21174
21180
|
message: moveResult.autoCompleted ? `Completed via ${targetColumn.title}` : `Moved to ${targetColumn.title}`
|
|
@@ -21178,6 +21184,7 @@ function moveTaskAction(filePath, taskId, targetColumnId) {
|
|
|
21178
21184
|
if (!result.success) return { success: false, error: result.error };
|
|
21179
21185
|
const writeResult = writeBrainfile(filePath, result.board);
|
|
21180
21186
|
if (!writeResult.success) return writeResult;
|
|
21187
|
+
scheduleBoardCommit(filePath, `move ${taskId}: ${targetColumn.id}`);
|
|
21181
21188
|
return { success: true, message: `Moved to ${targetColumn.title}` };
|
|
21182
21189
|
}
|
|
21183
21190
|
function deleteTaskAction(filePath, taskId) {
|
|
@@ -21190,12 +21197,14 @@ function deleteTaskAction(filePath, taskId) {
|
|
|
21190
21197
|
if (!located) return { success: false, error: `Task ${taskId} not found` };
|
|
21191
21198
|
const result2 = (0, import_core3.deleteTaskFile)(located.taskPath);
|
|
21192
21199
|
if (!result2.success) return { success: false, error: result2.error };
|
|
21200
|
+
scheduleBoardCommit(filePath, `delete ${taskId}`);
|
|
21193
21201
|
return { success: true, message: `Deleted ${taskId}` };
|
|
21194
21202
|
}
|
|
21195
21203
|
const result = (0, import_core3.deleteTask)(board, taskInfo.column.id, taskId);
|
|
21196
21204
|
if (!result.success) return { success: false, error: result.error };
|
|
21197
21205
|
const writeResult = writeBrainfile(filePath, result.board);
|
|
21198
21206
|
if (!writeResult.success) return writeResult;
|
|
21207
|
+
scheduleBoardCommit(filePath, `delete ${taskId}`);
|
|
21199
21208
|
return { success: true, message: `Deleted ${taskId}` };
|
|
21200
21209
|
}
|
|
21201
21210
|
function getArchivePath(filePath) {
|
|
@@ -21224,6 +21233,7 @@ function archiveTaskAction(filePath, taskId, options) {
|
|
|
21224
21233
|
incompleteChildren: result2.incompleteChildren
|
|
21225
21234
|
};
|
|
21226
21235
|
}
|
|
21236
|
+
scheduleBoardCommit(filePath, `complete ${taskId}`);
|
|
21227
21237
|
return { success: true, message: `Moved ${taskId} to logs` };
|
|
21228
21238
|
}
|
|
21229
21239
|
const { board, error } = readBrainfile(filePath);
|
|
@@ -21266,6 +21276,7 @@ function archiveTaskAction(filePath, taskId, options) {
|
|
|
21266
21276
|
error: `Task removed from board but failed to write logs: ${err instanceof Error ? err.message : String(err)}`
|
|
21267
21277
|
};
|
|
21268
21278
|
}
|
|
21279
|
+
scheduleBoardCommit(filePath, `complete ${taskId}`);
|
|
21269
21280
|
return { success: true, message: `Moved ${taskId} to logs` };
|
|
21270
21281
|
}
|
|
21271
21282
|
async function archiveTaskActionAsync(filePath, taskId, options) {
|
|
@@ -21397,6 +21408,7 @@ function cyclePriorityAction(filePath, taskId) {
|
|
|
21397
21408
|
const nextPriority2 = priorities[nextIndex2];
|
|
21398
21409
|
const result2 = (0, import_core3.patchTaskFile)(located.taskPath, { priority: nextPriority2 ?? null });
|
|
21399
21410
|
if (!result2.success) return { success: false, error: result2.error };
|
|
21411
|
+
scheduleBoardCommit(filePath, `patch ${taskId}: priority ${nextPriority2 || "none"}`);
|
|
21400
21412
|
return { success: true, message: `Priority: ${nextPriority2 || "none"}` };
|
|
21401
21413
|
}
|
|
21402
21414
|
const { board, error } = readBrainfile(filePath);
|
|
@@ -21411,6 +21423,7 @@ function cyclePriorityAction(filePath, taskId) {
|
|
|
21411
21423
|
if (!result.success) return { success: false, error: result.error };
|
|
21412
21424
|
const writeResult = writeBrainfile(filePath, result.board);
|
|
21413
21425
|
if (!writeResult.success) return writeResult;
|
|
21426
|
+
scheduleBoardCommit(filePath, `patch ${taskId}: priority ${nextPriority || "none"}`);
|
|
21414
21427
|
return { success: true, message: `Priority: ${nextPriority || "none"}` };
|
|
21415
21428
|
}
|
|
21416
21429
|
function toggleSubtaskAction(filePath, taskId, subtaskId) {
|
|
@@ -21424,6 +21437,7 @@ function toggleSubtaskAction(filePath, taskId, subtaskId) {
|
|
|
21424
21437
|
error: result2.missing?.length ? `Subtask ${subtaskId} not found` : result2.error
|
|
21425
21438
|
};
|
|
21426
21439
|
}
|
|
21440
|
+
scheduleBoardCommit(filePath, `subtask toggle ${subtaskId}`);
|
|
21427
21441
|
return { success: true, message: `Toggled ${subtaskId}` };
|
|
21428
21442
|
}
|
|
21429
21443
|
const { board, error } = readBrainfile(filePath);
|
|
@@ -21432,6 +21446,7 @@ function toggleSubtaskAction(filePath, taskId, subtaskId) {
|
|
|
21432
21446
|
if (!result.success) return { success: false, error: result.error };
|
|
21433
21447
|
const writeResult = writeBrainfile(filePath, result.board);
|
|
21434
21448
|
if (!writeResult.success) return writeResult;
|
|
21449
|
+
scheduleBoardCommit(filePath, `subtask toggle ${subtaskId}`);
|
|
21435
21450
|
return { success: true, message: `Toggled ${subtaskId}` };
|
|
21436
21451
|
}
|
|
21437
21452
|
function addTaskAction(filePath, columnId, taskInput) {
|
|
@@ -21459,6 +21474,7 @@ ${taskInput.description.trim()}
|
|
|
21459
21474
|
dirs.logsDir
|
|
21460
21475
|
);
|
|
21461
21476
|
if (!result2.success) return { success: false, error: result2.error };
|
|
21477
|
+
scheduleBoardCommit(filePath, `add ${result2.task?.id || "task"}`);
|
|
21462
21478
|
return { success: true, message: `Added ${result2.task?.id || "task"}` };
|
|
21463
21479
|
}
|
|
21464
21480
|
const result = (0, import_core3.addTask)(board, column.id, taskInput);
|
|
@@ -21467,6 +21483,7 @@ ${taskInput.description.trim()}
|
|
|
21467
21483
|
if (!writeResult.success) return writeResult;
|
|
21468
21484
|
const newColumn = result.board.columns.find((c) => c.id === column.id);
|
|
21469
21485
|
const newTask = newColumn?.tasks[newColumn.tasks.length - 1];
|
|
21486
|
+
scheduleBoardCommit(filePath, `add ${newTask?.id || "task"}`);
|
|
21470
21487
|
return { success: true, message: `Added ${newTask?.id || "task"}` };
|
|
21471
21488
|
}
|
|
21472
21489
|
function resolveTaskFilePath(filePath, taskId) {
|
|
@@ -21747,8 +21764,25 @@ ${getV2ChangeSignature(filePath)}`) : (0, import_core4.hashBoardContent)(content
|
|
|
21747
21764
|
return { loadBrainfile };
|
|
21748
21765
|
}
|
|
21749
21766
|
|
|
21767
|
+
// src/tui/hooks/useSyncStatus.ts
|
|
21768
|
+
var import_react35 = __toESM(require_react());
|
|
21769
|
+
import * as path3 from "path";
|
|
21770
|
+
var POLL_MS = 5e3;
|
|
21771
|
+
function useSyncStatus(filePath, lastUpdated) {
|
|
21772
|
+
const dotDir = path3.dirname(path3.resolve(filePath));
|
|
21773
|
+
const [label, setLabel] = (0, import_react35.useState)(() => syncStatusLabel(dotDir) ?? void 0);
|
|
21774
|
+
(0, import_react35.useEffect)(() => {
|
|
21775
|
+
const refresh = () => setLabel(syncStatusLabel(dotDir) ?? void 0);
|
|
21776
|
+
refresh();
|
|
21777
|
+
const timer = setInterval(refresh, POLL_MS);
|
|
21778
|
+
timer.unref?.();
|
|
21779
|
+
return () => clearInterval(timer);
|
|
21780
|
+
}, [dotDir, lastUpdated]);
|
|
21781
|
+
return label;
|
|
21782
|
+
}
|
|
21783
|
+
|
|
21750
21784
|
// src/tui/hooks/useKeyboardNavigation.ts
|
|
21751
|
-
var
|
|
21785
|
+
var import_react37 = __toESM(require_react());
|
|
21752
21786
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
21753
21787
|
|
|
21754
21788
|
// src/tui/detailStops.ts
|
|
@@ -21765,7 +21799,7 @@ function clampDetailCursor(cursor, stopCount) {
|
|
|
21765
21799
|
}
|
|
21766
21800
|
|
|
21767
21801
|
// src/tui/components/DetailView.tsx
|
|
21768
|
-
var
|
|
21802
|
+
var import_react36 = __toESM(require_react());
|
|
21769
21803
|
var MAX_DELIVERABLES = 3;
|
|
21770
21804
|
var MAX_VALIDATION_COMMANDS = 2;
|
|
21771
21805
|
function computeDetailLayout(task, width, height, children, activity) {
|
|
@@ -21827,7 +21861,7 @@ function DetailView({
|
|
|
21827
21861
|
const breadcrumbStr = truncateStart(breadcrumb.join(" \u25B8 ") || task.id, breadcrumbBudget);
|
|
21828
21862
|
const headWidth = Math.max(1, contentWidth - stateText.length - 2);
|
|
21829
21863
|
const head = truncate(`${breadcrumbStr} ${task.title}`, headWidth);
|
|
21830
|
-
return /* @__PURE__ */
|
|
21864
|
+
return /* @__PURE__ */ import_react36.default.createElement(Box_default, { flexDirection: "column", width, flexShrink: 0 }, /* @__PURE__ */ import_react36.default.createElement(Box_default, { paddingLeft: 1, width }, /* @__PURE__ */ import_react36.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.text, bold: true }, head), /* @__PURE__ */ import_react36.default.createElement(Text, null, pad(Math.max(1, contentWidth - head.length - stateText.length))), /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textSecondary }, columnLabel), priority ? /* @__PURE__ */ import_react36.default.createElement(Text, null, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textDim }, " \xB7 "), /* @__PURE__ */ import_react36.default.createElement(Text, { color: getPriorityColor(priority) }, priority)) : null)), /* @__PURE__ */ import_react36.default.createElement(Box_default, { paddingLeft: 1, width }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textDim }, RULE.repeat(contentWidth))), /* @__PURE__ */ import_react36.default.createElement(MetadataBlock, { task, parent, stacked, width }), bodyLines.length > 0 ? /* @__PURE__ */ import_react36.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 1, marginTop: 1 }, /* @__PURE__ */ import_react36.default.createElement(
|
|
21831
21865
|
DescriptionHeading,
|
|
21832
21866
|
{
|
|
21833
21867
|
bodyOverflows,
|
|
@@ -21835,7 +21869,7 @@ function DetailView({
|
|
|
21835
21869
|
total: bodyLines.length,
|
|
21836
21870
|
contentWidth
|
|
21837
21871
|
}
|
|
21838
|
-
), visibleBody.map((line, index) => /* @__PURE__ */
|
|
21872
|
+
), visibleBody.map((line, index) => /* @__PURE__ */ import_react36.default.createElement(
|
|
21839
21873
|
Text,
|
|
21840
21874
|
{
|
|
21841
21875
|
key: `body-${index}`,
|
|
@@ -21844,7 +21878,7 @@ function DetailView({
|
|
|
21844
21878
|
color: line.kind === "code" ? PALETTE.textMuted : line.kind === "heading" ? PALETTE.text : PALETTE.textSecondary
|
|
21845
21879
|
},
|
|
21846
21880
|
line.text || " "
|
|
21847
|
-
))) : null, children.length > 0 ? /* @__PURE__ */
|
|
21881
|
+
))) : null, children.length > 0 ? /* @__PURE__ */ import_react36.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 1, marginTop: 1 }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textMuted }, `children (${children.length})`), children.map((child, index) => /* @__PURE__ */ import_react36.default.createElement(
|
|
21848
21882
|
StopRow,
|
|
21849
21883
|
{
|
|
21850
21884
|
key: child.id,
|
|
@@ -21854,10 +21888,10 @@ function DetailView({
|
|
|
21854
21888
|
rightColor: PALETTE.textSecondary,
|
|
21855
21889
|
contentWidth
|
|
21856
21890
|
}
|
|
21857
|
-
))) : null, subtasks.length > 0 ? /* @__PURE__ */
|
|
21891
|
+
))) : null, subtasks.length > 0 ? /* @__PURE__ */ import_react36.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 1, marginTop: 1 }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textMuted }, `subtasks (${subtasks.filter((s) => s.completed).length}/${subtasks.length})`), subtasks.map((subtask, index) => {
|
|
21858
21892
|
const stopIndex = children.length + index;
|
|
21859
21893
|
const glyph = subtask.completed ? GLYPHS.subtaskDone : GLYPHS.subtaskOpen;
|
|
21860
|
-
return /* @__PURE__ */
|
|
21894
|
+
return /* @__PURE__ */ import_react36.default.createElement(
|
|
21861
21895
|
StopRow,
|
|
21862
21896
|
{
|
|
21863
21897
|
key: subtask.id,
|
|
@@ -21867,7 +21901,7 @@ function DetailView({
|
|
|
21867
21901
|
contentWidth
|
|
21868
21902
|
}
|
|
21869
21903
|
);
|
|
21870
|
-
})) : null, contract ? /* @__PURE__ */
|
|
21904
|
+
})) : null, contract ? /* @__PURE__ */ import_react36.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 1, marginTop: 1 }, /* @__PURE__ */ import_react36.default.createElement(Text, null, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textMuted }, "contract "), /* @__PURE__ */ import_react36.default.createElement(Text, { color: getContractStateColor(contract.status) }, contract.status)), contract.deliverables?.length ? /* @__PURE__ */ import_react36.default.createElement(
|
|
21871
21905
|
LabeledList,
|
|
21872
21906
|
{
|
|
21873
21907
|
label: "deliverables",
|
|
@@ -21875,7 +21909,7 @@ function DetailView({
|
|
|
21875
21909
|
contentWidth,
|
|
21876
21910
|
color: PALETTE.textSecondary
|
|
21877
21911
|
}
|
|
21878
|
-
) : null, contract.validation?.commands?.length ? /* @__PURE__ */
|
|
21912
|
+
) : null, contract.validation?.commands?.length ? /* @__PURE__ */ import_react36.default.createElement(
|
|
21879
21913
|
LabeledList,
|
|
21880
21914
|
{
|
|
21881
21915
|
label: "validation",
|
|
@@ -21883,11 +21917,11 @@ function DetailView({
|
|
|
21883
21917
|
contentWidth,
|
|
21884
21918
|
color: PALETTE.textMuted
|
|
21885
21919
|
}
|
|
21886
|
-
) : null, contract.feedback ? /* @__PURE__ */
|
|
21920
|
+
) : null, contract.feedback ? /* @__PURE__ */ import_react36.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textMuted }, " feedback "), /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.error }, truncate(contract.feedback, Math.max(1, contentWidth - 12)))) : null) : null, activity.length > 0 ? /* @__PURE__ */ import_react36.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 1, marginTop: 1 }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textMuted }, "activity"), activity.map((entry, index) => {
|
|
21887
21921
|
const stamp = entry.at ? entry.at.slice(5, 10) : " ";
|
|
21888
21922
|
const prefix = ` ${stamp} `;
|
|
21889
|
-
return /* @__PURE__ */
|
|
21890
|
-
})) : null, files.length > 0 ? /* @__PURE__ */
|
|
21923
|
+
return /* @__PURE__ */ import_react36.default.createElement(Text, { key: `activity-${index}`, wrap: "truncate" }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textDim }, prefix), /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textSecondary }, truncate(entry.text, Math.max(1, contentWidth - prefix.length))));
|
|
21924
|
+
})) : null, files.length > 0 ? /* @__PURE__ */ import_react36.default.createElement(Box_default, { paddingLeft: 1, marginTop: 1, width }, /* @__PURE__ */ import_react36.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textMuted }, "files "), /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textSecondary }, truncate(files.join(" \xB7 "), Math.max(1, contentWidth - 7))))) : null);
|
|
21891
21925
|
}
|
|
21892
21926
|
function DescriptionHeading({
|
|
21893
21927
|
bodyOverflows,
|
|
@@ -21897,7 +21931,7 @@ function DescriptionHeading({
|
|
|
21897
21931
|
}) {
|
|
21898
21932
|
const indicator = bodyOverflows ? `${GLYPHS.scroll} ${scrollStart}/${total}` : "";
|
|
21899
21933
|
const gap = Math.max(1, contentWidth - "description".length - indicator.length);
|
|
21900
|
-
return /* @__PURE__ */
|
|
21934
|
+
return /* @__PURE__ */ import_react36.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textMuted }, "description"), indicator ? /* @__PURE__ */ import_react36.default.createElement(Text, null, pad(gap)) : null, indicator ? /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textDim }, indicator) : null);
|
|
21901
21935
|
}
|
|
21902
21936
|
function StopRow({
|
|
21903
21937
|
selected,
|
|
@@ -21910,7 +21944,7 @@ function StopRow({
|
|
|
21910
21944
|
const rightText = right ?? "";
|
|
21911
21945
|
const leftTruncated = truncate(left, Math.max(1, contentWidth - rightText.length - 2));
|
|
21912
21946
|
const gap = Math.max(1, contentWidth - leftTruncated.length - rightText.length);
|
|
21913
|
-
return /* @__PURE__ */
|
|
21947
|
+
return /* @__PURE__ */ import_react36.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: selected ? void 0 : leftColor, inverse: selected }, leftTruncated), /* @__PURE__ */ import_react36.default.createElement(Text, null, pad(gap)), rightText ? /* @__PURE__ */ import_react36.default.createElement(Text, { color: rightColor }, rightText) : null);
|
|
21914
21948
|
}
|
|
21915
21949
|
function LabeledList({
|
|
21916
21950
|
label,
|
|
@@ -21919,7 +21953,7 @@ function LabeledList({
|
|
|
21919
21953
|
color
|
|
21920
21954
|
}) {
|
|
21921
21955
|
const labelWidth = 16;
|
|
21922
|
-
return /* @__PURE__ */
|
|
21956
|
+
return /* @__PURE__ */ import_react36.default.createElement(import_react36.default.Fragment, null, items.map((item, index) => /* @__PURE__ */ import_react36.default.createElement(Text, { key: `${label}-${index}`, wrap: "truncate" }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textMuted }, ` ${index === 0 ? label.padEnd(labelWidth - 2) : " ".repeat(labelWidth - 2)}`), /* @__PURE__ */ import_react36.default.createElement(Text, { color }, truncate(item, Math.max(1, contentWidth - labelWidth))))));
|
|
21923
21957
|
}
|
|
21924
21958
|
function MetadataBlock({
|
|
21925
21959
|
task,
|
|
@@ -21938,9 +21972,9 @@ function MetadataBlock({
|
|
|
21938
21972
|
["parent", parentLabel]
|
|
21939
21973
|
];
|
|
21940
21974
|
if (stacked) {
|
|
21941
|
-
return /* @__PURE__ */
|
|
21975
|
+
return /* @__PURE__ */ import_react36.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 1, width }, fields.map(([label, value]) => /* @__PURE__ */ import_react36.default.createElement(Text, { key: label, wrap: "truncate" }, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textMuted }, `${label} `), /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textSecondary }, value))));
|
|
21942
21976
|
}
|
|
21943
|
-
return /* @__PURE__ */
|
|
21977
|
+
return /* @__PURE__ */ import_react36.default.createElement(Box_default, { paddingLeft: 1, width }, /* @__PURE__ */ import_react36.default.createElement(Text, { wrap: "truncate" }, fields.map(([label, value], index) => /* @__PURE__ */ import_react36.default.createElement(Text, { key: label }, index > 0 ? /* @__PURE__ */ import_react36.default.createElement(Text, null, pad(4)) : null, /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textMuted }, `${label} `), /* @__PURE__ */ import_react36.default.createElement(Text, { color: PALETTE.textSecondary }, value)))));
|
|
21944
21978
|
}
|
|
21945
21979
|
function parentLabelFor(task, parent) {
|
|
21946
21980
|
if (!task.parentId) return "\u2014";
|
|
@@ -21987,9 +22021,9 @@ function buildBodyLines(description, width) {
|
|
|
21987
22021
|
// src/tui/tuiState.ts
|
|
21988
22022
|
var import_core5 = __toESM(require_dist());
|
|
21989
22023
|
import * as fs5 from "fs";
|
|
21990
|
-
import * as
|
|
22024
|
+
import * as path4 from "path";
|
|
21991
22025
|
function getTuiStatePath(brainfilePath) {
|
|
21992
|
-
return
|
|
22026
|
+
return path4.join((0, import_core5.getBrainfileStateDir)(brainfilePath), import_core5.DOT_BRAINFILE_STATE_DIRNAME, "tui.json");
|
|
21993
22027
|
}
|
|
21994
22028
|
function readTuiState(brainfilePath) {
|
|
21995
22029
|
const statePath = getTuiStatePath(brainfilePath);
|
|
@@ -22039,15 +22073,15 @@ function useKeyboardNavigation({
|
|
|
22039
22073
|
}) {
|
|
22040
22074
|
const { exit, suspendTerminal } = use_app_default();
|
|
22041
22075
|
const { isRawModeSupported } = use_stdin_default();
|
|
22042
|
-
const statusTimers = (0,
|
|
22043
|
-
(0,
|
|
22076
|
+
const statusTimers = (0, import_react37.useRef)(/* @__PURE__ */ new Set());
|
|
22077
|
+
(0, import_react37.useEffect)(
|
|
22044
22078
|
() => () => {
|
|
22045
22079
|
for (const timer of statusTimers.current) clearTimeout(timer);
|
|
22046
22080
|
statusTimers.current.clear();
|
|
22047
22081
|
},
|
|
22048
22082
|
[]
|
|
22049
22083
|
);
|
|
22050
|
-
const showStatus = (0,
|
|
22084
|
+
const showStatus = (0, import_react37.useCallback)(
|
|
22051
22085
|
(text, type) => {
|
|
22052
22086
|
const timestamp = Date.now();
|
|
22053
22087
|
setState((prev) => ({ ...prev, statusMessage: { text, type, timestamp } }));
|
|
@@ -22061,7 +22095,7 @@ function useKeyboardNavigation({
|
|
|
22061
22095
|
},
|
|
22062
22096
|
[setState]
|
|
22063
22097
|
);
|
|
22064
|
-
const openInEditor = (0,
|
|
22098
|
+
const openInEditor = (0, import_react37.useCallback)(
|
|
22065
22099
|
(taskId) => {
|
|
22066
22100
|
const located = resolveTaskFilePath(filePath, taskId);
|
|
22067
22101
|
if (!located.success) {
|
|
@@ -22086,7 +22120,7 @@ function useKeyboardNavigation({
|
|
|
22086
22120
|
},
|
|
22087
22121
|
[filePath, showStatus, suspendTerminal, loadBrainfile, isRawModeSupported]
|
|
22088
22122
|
);
|
|
22089
|
-
const rememberColumn = (0,
|
|
22123
|
+
const rememberColumn = (0, import_react37.useCallback)(
|
|
22090
22124
|
(columnIndex) => {
|
|
22091
22125
|
const id = allColumns[columnIndex]?.id;
|
|
22092
22126
|
if (id) patchTuiState(filePath, { lastColumn: id });
|
|
@@ -22646,7 +22680,7 @@ function getTypeCycleOptions(board) {
|
|
|
22646
22680
|
}
|
|
22647
22681
|
|
|
22648
22682
|
// src/tui/components/HeaderBar.tsx
|
|
22649
|
-
var
|
|
22683
|
+
var import_react38 = __toESM(require_react());
|
|
22650
22684
|
function HeaderBar({
|
|
22651
22685
|
title,
|
|
22652
22686
|
columns,
|
|
@@ -22657,7 +22691,8 @@ function HeaderBar({
|
|
|
22657
22691
|
matchCount,
|
|
22658
22692
|
totalCount,
|
|
22659
22693
|
panelLabel,
|
|
22660
|
-
activeType
|
|
22694
|
+
activeType,
|
|
22695
|
+
statusLabel
|
|
22661
22696
|
}) {
|
|
22662
22697
|
const affordances = CHROME.filterAffordance;
|
|
22663
22698
|
const boardTitle = truncate(title, 24);
|
|
@@ -22667,18 +22702,19 @@ function HeaderBar({
|
|
|
22667
22702
|
const active = index === activeColumnIndex;
|
|
22668
22703
|
return sum + (index > 0 ? 3 : 0) + `${column.title} ${column.tasks?.length ?? 0}`.length + (active ? 1 : 0);
|
|
22669
22704
|
}, 0)) + typeLabel.length;
|
|
22705
|
+
const status = statusLabel ? `${statusLabel} ` : "";
|
|
22670
22706
|
const used = boardTitle.length + separator.length + tabsWidth;
|
|
22671
|
-
const gap = Math.max(1, width - 1 - used - affordances.length - 1);
|
|
22707
|
+
const gap = Math.max(1, width - 1 - used - status.length - affordances.length - 1);
|
|
22672
22708
|
return (
|
|
22673
22709
|
// flexShrink={0}: a detail v2 pane can legitimately render taller than the
|
|
22674
22710
|
// nominal viewport (§B1's many optional sections). Without this, yoga
|
|
22675
22711
|
// shrinks *this* sibling instead of letting the column overflow, and the
|
|
22676
22712
|
// header silently loses rows rather than the frame simply growing.
|
|
22677
|
-
/* @__PURE__ */
|
|
22713
|
+
/* @__PURE__ */ import_react38.default.createElement(Box_default, { flexDirection: "column", flexShrink: 0 }, /* @__PURE__ */ import_react38.default.createElement(Box_default, { paddingLeft: 1, width }, /* @__PURE__ */ import_react38.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react38.default.createElement(Text, { color: PALETTE.text, bold: true }, boardTitle), /* @__PURE__ */ import_react38.default.createElement(Text, { color: PALETTE.textDim }, separator), panelLabel ? /* @__PURE__ */ import_react38.default.createElement(Text, { color: PALETTE.text }, panelLabel) : columns.map((column, index) => {
|
|
22678
22714
|
const active = index === activeColumnIndex;
|
|
22679
22715
|
const count = column.tasks?.length ?? 0;
|
|
22680
|
-
return /* @__PURE__ */
|
|
22681
|
-
}), typeLabel ? /* @__PURE__ */
|
|
22716
|
+
return /* @__PURE__ */ import_react38.default.createElement(Text, { key: column.id }, index > 0 ? /* @__PURE__ */ import_react38.default.createElement(Text, { color: PALETTE.textDim }, " \u2502 ") : null, /* @__PURE__ */ import_react38.default.createElement(Text, { color: active ? PALETTE.text : PALETTE.textMuted, bold: active }, `${column.title} ${count}`), active ? /* @__PURE__ */ import_react38.default.createElement(Text, { color: PALETTE.text, bold: true }, "*") : null);
|
|
22717
|
+
}), typeLabel ? /* @__PURE__ */ import_react38.default.createElement(Text, { color: PALETTE.textDim }, typeLabel) : null, /* @__PURE__ */ import_react38.default.createElement(Text, null, pad(gap)), status ? /* @__PURE__ */ import_react38.default.createElement(Text, { color: statusLabel?.startsWith("not synced \xB7") ? PALETTE.warning : PALETTE.textDim }, status) : null, /* @__PURE__ */ import_react38.default.createElement(Text, { color: PALETTE.textMuted }, affordances))), filterActive ? /* @__PURE__ */ import_react38.default.createElement(
|
|
22682
22718
|
FilterLine,
|
|
22683
22719
|
{
|
|
22684
22720
|
query: filterQuery,
|
|
@@ -22686,7 +22722,7 @@ function HeaderBar({
|
|
|
22686
22722
|
matchCount,
|
|
22687
22723
|
totalCount
|
|
22688
22724
|
}
|
|
22689
|
-
) : /* @__PURE__ */
|
|
22725
|
+
) : /* @__PURE__ */ import_react38.default.createElement(Box_default, { paddingLeft: 1, width }, /* @__PURE__ */ import_react38.default.createElement(Text, { color: PALETTE.textDim }, RULE.repeat(Math.max(1, width - 2)))))
|
|
22690
22726
|
);
|
|
22691
22727
|
}
|
|
22692
22728
|
function FilterLine({
|
|
@@ -22698,11 +22734,11 @@ function FilterLine({
|
|
|
22698
22734
|
const count = matchCount === void 0 || totalCount === void 0 ? "" : matchCountLabel(matchCount, totalCount, query);
|
|
22699
22735
|
const input = `/${query}`;
|
|
22700
22736
|
const gap = Math.max(1, width - 2 - input.length - 1 - count.length);
|
|
22701
|
-
return /* @__PURE__ */
|
|
22737
|
+
return /* @__PURE__ */ import_react38.default.createElement(Box_default, { paddingLeft: 1, width }, /* @__PURE__ */ import_react38.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react38.default.createElement(Text, { color: PALETTE.accent }, input), /* @__PURE__ */ import_react38.default.createElement(Text, { color: PALETTE.accent }, GLYPHS.cursor), /* @__PURE__ */ import_react38.default.createElement(Text, null, pad(gap)), /* @__PURE__ */ import_react38.default.createElement(Text, { color: PALETTE.textMuted }, count || " ")));
|
|
22702
22738
|
}
|
|
22703
22739
|
|
|
22704
22740
|
// src/tui/components/FooterBar.tsx
|
|
22705
|
-
var
|
|
22741
|
+
var import_react39 = __toESM(require_react());
|
|
22706
22742
|
function browseActions(selected, archived = false) {
|
|
22707
22743
|
if (archived) return ["\u21B5 detail", "e edit", "t type", "L board", "q quit"];
|
|
22708
22744
|
const actions = ["\u21B5 detail", "m move"];
|
|
@@ -22742,12 +22778,12 @@ function FooterBar({
|
|
|
22742
22778
|
return (
|
|
22743
22779
|
// flexShrink={0}: see HeaderBar's matching comment — the footer must not
|
|
22744
22780
|
// be the thing that silently loses rows when detail v2 overflows.
|
|
22745
|
-
/* @__PURE__ */
|
|
22781
|
+
/* @__PURE__ */ import_react39.default.createElement(Box_default, { flexDirection: "column", flexShrink: 0 }, showRule ? /* @__PURE__ */ import_react39.default.createElement(Box_default, { paddingLeft: 1, width }, /* @__PURE__ */ import_react39.default.createElement(Text, { color: PALETTE.textDim }, RULE.repeat(Math.max(1, width - 2)))) : null, /* @__PURE__ */ import_react39.default.createElement(Box_default, { paddingLeft: 1, width }, /* @__PURE__ */ import_react39.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react39.default.createElement(Text, { color: PALETTE.textMuted }, text), /* @__PURE__ */ import_react39.default.createElement(Text, null, pad(gap)), quit ? /* @__PURE__ */ import_react39.default.createElement(Text, { color: PALETTE.textMuted }, quit) : null, quit && chip ? /* @__PURE__ */ import_react39.default.createElement(Text, null, pad(2)) : null, /* @__PURE__ */ import_react39.default.createElement(Text, { color: PALETTE.textSecondary }, chip || " "))))
|
|
22746
22782
|
);
|
|
22747
22783
|
}
|
|
22748
22784
|
|
|
22749
22785
|
// src/tui/components/DocumentRow.tsx
|
|
22750
|
-
var
|
|
22786
|
+
var import_react40 = __toESM(require_react());
|
|
22751
22787
|
var MAX_CHIPS = 3;
|
|
22752
22788
|
function buildChips(row) {
|
|
22753
22789
|
const chips = [];
|
|
@@ -22794,11 +22830,11 @@ function DocumentRow({ row, selected, width, idWidth, archived = false }) {
|
|
|
22794
22830
|
const title = truncate(task.title, titleWidth);
|
|
22795
22831
|
const gap = Math.max(1, width - leftWidth - title.length - rightWidth - 1);
|
|
22796
22832
|
const dim = selected ? void 0 : PALETTE.textMuted;
|
|
22797
|
-
return /* @__PURE__ */
|
|
22833
|
+
return /* @__PURE__ */ import_react40.default.createElement(Text, { wrap: "truncate", inverse: selected }, /* @__PURE__ */ import_react40.default.createElement(Text, null, indent), /* @__PURE__ */ import_react40.default.createElement(Text, { color: selected ? void 0 : PALETTE.textSecondary }, glyphCell), /* @__PURE__ */ import_react40.default.createElement(Text, { color: dim }, idCell), /* @__PURE__ */ import_react40.default.createElement(Text, { color: selected ? void 0 : archived ? PALETTE.textMuted : PALETTE.text }, title), /* @__PURE__ */ import_react40.default.createElement(Text, null, pad(gap)), rightSegments.map((seg, index) => /* @__PURE__ */ import_react40.default.createElement(Text, { key: `${seg.text}-${index}` }, index > 0 ? /* @__PURE__ */ import_react40.default.createElement(Text, null, pad(2)) : null, /* @__PURE__ */ import_react40.default.createElement(Text, { color: selected ? void 0 : seg.color }, seg.text))), /* @__PURE__ */ import_react40.default.createElement(Text, null, pad(1)));
|
|
22798
22834
|
}
|
|
22799
22835
|
|
|
22800
22836
|
// src/tui/components/DocumentList.tsx
|
|
22801
|
-
var
|
|
22837
|
+
var import_react41 = __toESM(require_react());
|
|
22802
22838
|
function DocumentList({
|
|
22803
22839
|
rows,
|
|
22804
22840
|
selectedIndex,
|
|
@@ -22808,11 +22844,11 @@ function DocumentList({
|
|
|
22808
22844
|
emptyMessage = EMPTY.noDocuments
|
|
22809
22845
|
}) {
|
|
22810
22846
|
if (rows.length === 0) {
|
|
22811
|
-
return /* @__PURE__ */
|
|
22847
|
+
return /* @__PURE__ */ import_react41.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1, paddingLeft: 1 }, /* @__PURE__ */ import_react41.default.createElement(Text, { color: PALETTE.textMuted }, emptyMessage));
|
|
22812
22848
|
}
|
|
22813
22849
|
const { visible, start } = windowRows(rows, selectedIndex, viewportHeight);
|
|
22814
22850
|
const idWidth = Math.max(6, ...visible.map((row) => row.task.id.length));
|
|
22815
|
-
return /* @__PURE__ */
|
|
22851
|
+
return /* @__PURE__ */ import_react41.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1 }, visible.map((row, index) => /* @__PURE__ */ import_react41.default.createElement(
|
|
22816
22852
|
DocumentRow,
|
|
22817
22853
|
{
|
|
22818
22854
|
key: row.task.id,
|
|
@@ -22826,7 +22862,7 @@ function DocumentList({
|
|
|
22826
22862
|
}
|
|
22827
22863
|
|
|
22828
22864
|
// src/tui/components/HelpOverlay.tsx
|
|
22829
|
-
var
|
|
22865
|
+
var import_react42 = __toESM(require_react());
|
|
22830
22866
|
var LIST = {
|
|
22831
22867
|
heading: "list",
|
|
22832
22868
|
rows: [
|
|
@@ -22885,25 +22921,25 @@ var KEYS_WIDTH = 14;
|
|
|
22885
22921
|
function HelpOverlay({ termWidth, termHeight }) {
|
|
22886
22922
|
const columnWidth = Math.max(24, Math.floor((termWidth - 4) / COLUMNS.length));
|
|
22887
22923
|
const descriptionWidth = Math.max(6, columnWidth - KEYS_WIDTH - 2);
|
|
22888
|
-
return /* @__PURE__ */
|
|
22924
|
+
return /* @__PURE__ */ import_react42.default.createElement(Box_default, { flexDirection: "column", width: termWidth, height: termHeight, paddingLeft: 1 }, /* @__PURE__ */ import_react42.default.createElement(Text, { color: PALETTE.text, bold: true }, CHROME.helpTitle), /* @__PURE__ */ import_react42.default.createElement(Text, { color: PALETTE.textDim }, RULE.repeat(Math.max(1, termWidth - 2))), /* @__PURE__ */ import_react42.default.createElement(Box_default, { marginTop: 1 }, COLUMNS.map((column, columnIndex) => /* @__PURE__ */ import_react42.default.createElement(Box_default, { key: columnIndex, flexDirection: "column", width: columnWidth }, column.map((group, groupIndex) => /* @__PURE__ */ import_react42.default.createElement(
|
|
22889
22925
|
Box_default,
|
|
22890
22926
|
{
|
|
22891
22927
|
key: group.heading,
|
|
22892
22928
|
flexDirection: "column",
|
|
22893
22929
|
marginTop: groupIndex === 0 ? 0 : 1
|
|
22894
22930
|
},
|
|
22895
|
-
/* @__PURE__ */
|
|
22896
|
-
group.rows.map(([keys, description]) => /* @__PURE__ */
|
|
22897
|
-
))))), /* @__PURE__ */
|
|
22931
|
+
/* @__PURE__ */ import_react42.default.createElement(Text, { color: PALETTE.textSecondary, bold: true }, group.heading),
|
|
22932
|
+
group.rows.map(([keys, description]) => /* @__PURE__ */ import_react42.default.createElement(Text, { key: keys, wrap: "truncate" }, /* @__PURE__ */ import_react42.default.createElement(Text, { color: PALETTE.text }, keys.padEnd(KEYS_WIDTH)), /* @__PURE__ */ import_react42.default.createElement(Text, { color: PALETTE.textMuted }, truncate(description, descriptionWidth))))
|
|
22933
|
+
))))), /* @__PURE__ */ import_react42.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react42.default.createElement(Text, { color: PALETTE.textDim }, CHROME.helpDismiss)));
|
|
22898
22934
|
}
|
|
22899
22935
|
|
|
22900
22936
|
// src/tui/components/Overlays.tsx
|
|
22901
|
-
var
|
|
22937
|
+
var import_react43 = __toESM(require_react());
|
|
22902
22938
|
function StatusMessageDisplay({ message }) {
|
|
22903
22939
|
if (!message) return null;
|
|
22904
22940
|
const color = message.type === "success" ? PALETTE.success : message.type === "error" ? PALETTE.error : PALETTE.textSecondary;
|
|
22905
22941
|
const glyph = message.type === "success" ? GLYPHS.success : message.type === "error" ? GLYPHS.error : GLYPHS.live;
|
|
22906
|
-
return /* @__PURE__ */
|
|
22942
|
+
return /* @__PURE__ */ import_react43.default.createElement(Box_default, { paddingLeft: 1 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color, wrap: "truncate" }, `${glyph} ${message.text}`));
|
|
22907
22943
|
}
|
|
22908
22944
|
function MoveOverlay({
|
|
22909
22945
|
columns,
|
|
@@ -22912,16 +22948,16 @@ function MoveOverlay({
|
|
|
22912
22948
|
taskTitle,
|
|
22913
22949
|
width
|
|
22914
22950
|
}) {
|
|
22915
|
-
return /* @__PURE__ */
|
|
22951
|
+
return /* @__PURE__ */ import_react43.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1, paddingLeft: 1 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, "move"), /* @__PURE__ */ import_react43.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, ` ${taskId} `), /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.text }, truncate(taskTitle, Math.max(1, width - taskId.length - 6)))), /* @__PURE__ */ import_react43.default.createElement(Box_default, { flexDirection: "column", marginTop: 1, paddingLeft: 2 }, columns.map((column, index) => /* @__PURE__ */ import_react43.default.createElement(Text, { key: column.id, inverse: index === selectedIndex, wrap: "truncate" }, `${index + 1} ${column.title}`))), /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1, paddingLeft: 2 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, "\u2191\u2193 select \xB7 1-", columns.length, " jump \xB7 \u21B5 confirm \xB7 esc cancel")));
|
|
22916
22952
|
}
|
|
22917
22953
|
function DeleteConfirmOverlay({ taskId, taskTitle, width }) {
|
|
22918
|
-
return /* @__PURE__ */
|
|
22954
|
+
return /* @__PURE__ */ import_react43.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1, paddingLeft: 1 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.error }, "delete"), /* @__PURE__ */ import_react43.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, ` ${taskId} `), /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.text }, truncate(taskTitle, Math.max(1, width - taskId.length - 6)))), /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1, paddingLeft: 2 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, "Deletes the file. This cannot be undone.")), /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1, paddingLeft: 2 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, "y delete \xB7 n cancel")));
|
|
22919
22955
|
}
|
|
22920
22956
|
function CompleteConfirmOverlay({ target, width }) {
|
|
22921
|
-
return /* @__PURE__ */
|
|
22957
|
+
return /* @__PURE__ */ import_react43.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1, paddingLeft: 1 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.warning }, "complete"), /* @__PURE__ */ import_react43.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, ` ${target.id} `), /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.text }, truncate(target.title, Math.max(1, width - target.id.length - 6)))), /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1, paddingLeft: 2 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, incompleteChildrenLabel(target.incompleteChildren.length))), /* @__PURE__ */ import_react43.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 4 }, target.incompleteChildren.map((child) => /* @__PURE__ */ import_react43.default.createElement(Text, { key: child.id, wrap: "truncate" }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, `${child.id} `), /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textSecondary }, truncate(child.title, Math.max(1, width - child.id.length - 8)))))), /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1, paddingLeft: 2 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, "y complete anyway \xB7 n cancel")));
|
|
22922
22958
|
}
|
|
22923
22959
|
function AddOverlay({ title, columnName, thenEdit = false }) {
|
|
22924
|
-
return /* @__PURE__ */
|
|
22960
|
+
return /* @__PURE__ */ import_react43.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1, paddingLeft: 1 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, thenEdit ? `add to ${columnName}, then edit` : `add to ${columnName}`), /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1, paddingLeft: 2 }, /* @__PURE__ */ import_react43.default.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: title ? PALETTE.text : PALETTE.textMuted }, title || "title\u2026"), /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.accent }, GLYPHS.cursor))), /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1, paddingLeft: 2 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: PALETTE.textMuted }, thenEdit ? "\u21B5 create and edit \xB7 esc cancel" : "\u21B5 create \xB7 esc cancel")));
|
|
22925
22961
|
}
|
|
22926
22962
|
|
|
22927
22963
|
// src/tui/BrainfileTUI.tsx
|
|
@@ -22950,11 +22986,11 @@ var baseInitialState = {
|
|
|
22950
22986
|
};
|
|
22951
22987
|
function BrainfileTUI({ filePath, width, height }) {
|
|
22952
22988
|
const { stdout } = use_stdout_default();
|
|
22953
|
-
const [dimensions, setDimensions] = (0,
|
|
22989
|
+
const [dimensions, setDimensions] = (0, import_react44.useState)({
|
|
22954
22990
|
width: width ?? stdout?.columns ?? process.stdout.columns ?? 80,
|
|
22955
22991
|
height: height ?? stdout?.rows ?? process.stdout.rows ?? 24
|
|
22956
22992
|
});
|
|
22957
|
-
(0,
|
|
22993
|
+
(0, import_react44.useEffect)(() => {
|
|
22958
22994
|
if (width !== void 0 && height !== void 0) return void 0;
|
|
22959
22995
|
const handleResize = () => {
|
|
22960
22996
|
setDimensions({
|
|
@@ -22971,8 +23007,8 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
22971
23007
|
const termHeight = height ?? dimensions.height;
|
|
22972
23008
|
const isTooSmall = termWidth < LAYOUT.MIN_WIDTH || termHeight < LAYOUT.MIN_HEIGHT;
|
|
22973
23009
|
const layoutMode = termWidth >= LAYOUT.DETAIL_PANE_MIN_WIDTH ? "wide" : "narrow";
|
|
22974
|
-
const resumeColumn = (0,
|
|
22975
|
-
const [state, setState] = (0,
|
|
23010
|
+
const resumeColumn = (0, import_react44.useRef)(void 0);
|
|
23011
|
+
const [state, setState] = (0, import_react44.useState)(() => {
|
|
22976
23012
|
const persisted = readTuiState(filePath);
|
|
22977
23013
|
resumeColumn.current = persisted.lastColumn;
|
|
22978
23014
|
return {
|
|
@@ -22984,7 +23020,8 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
22984
23020
|
});
|
|
22985
23021
|
const viewportHeight = Math.max(termHeight - HEADER_ROWS - FOOTER_ROWS, 3);
|
|
22986
23022
|
const { loadBrainfile } = useBrainfileLoader(filePath, state, setState);
|
|
22987
|
-
const
|
|
23023
|
+
const syncStatus = useSyncStatus(filePath, state.lastUpdated);
|
|
23024
|
+
const orderedColumns = (0, import_react44.useMemo)(() => {
|
|
22988
23025
|
if (!state.board) return [];
|
|
22989
23026
|
return [...state.board.columns].sort((a, b) => {
|
|
22990
23027
|
const orderA = a.order ?? Number.MAX_SAFE_INTEGER;
|
|
@@ -22992,24 +23029,24 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
22992
23029
|
return orderA - orderB;
|
|
22993
23030
|
});
|
|
22994
23031
|
}, [state.board]);
|
|
22995
|
-
const typeCycleOptions = (0,
|
|
23032
|
+
const typeCycleOptions = (0, import_react44.useMemo)(() => getTypeCycleOptions(state.board), [state.board]);
|
|
22996
23033
|
const activeTypeFilter = typeCycleOptions.includes(state.activeTypeFilter) ? state.activeTypeFilter : "all";
|
|
22997
23034
|
const typeFilterActive = activeTypeFilter !== "all";
|
|
22998
23035
|
const doneView = state.doneView;
|
|
22999
|
-
const typeFilteredColumns = (0,
|
|
23036
|
+
const typeFilteredColumns = (0, import_react44.useMemo)(() => {
|
|
23000
23037
|
if (!typeFilterActive) return orderedColumns;
|
|
23001
23038
|
return orderedColumns.map((column) => ({
|
|
23002
23039
|
...column,
|
|
23003
23040
|
tasks: (column.tasks ?? []).filter((task) => getDocType(task) === activeTypeFilter)
|
|
23004
23041
|
}));
|
|
23005
23042
|
}, [orderedColumns, typeFilterActive, doneView, activeTypeFilter]);
|
|
23006
|
-
const totalCount = (0,
|
|
23043
|
+
const totalCount = (0, import_react44.useMemo)(
|
|
23007
23044
|
() => doneView ? typeFilterActive ? state.logs.filter((task) => getDocType(task) === activeTypeFilter).length : state.logs.length : typeFilteredColumns.reduce((sum, column) => sum + (column.tasks?.length ?? 0), 0),
|
|
23008
23045
|
[typeFilteredColumns, doneView, state.logs]
|
|
23009
23046
|
);
|
|
23010
23047
|
const filterQuery = state.filterQuery.trim();
|
|
23011
23048
|
const hasFilter = filterQuery.length > 0;
|
|
23012
|
-
const filteredColumns = (0,
|
|
23049
|
+
const filteredColumns = (0, import_react44.useMemo)(() => {
|
|
23013
23050
|
if (!hasFilter) return typeFilteredColumns;
|
|
23014
23051
|
return typeFilteredColumns.map((column) => {
|
|
23015
23052
|
const docs = (column.tasks ?? []).map((task) => ({ task, body: task.description ?? "" }));
|
|
@@ -23017,14 +23054,14 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
23017
23054
|
return { ...column, tasks: matches.map((match) => match.doc.task) };
|
|
23018
23055
|
});
|
|
23019
23056
|
}, [typeFilteredColumns, hasFilter, filterQuery]);
|
|
23020
|
-
const filteredLogs = (0,
|
|
23057
|
+
const filteredLogs = (0, import_react44.useMemo)(() => {
|
|
23021
23058
|
if (!doneView) return [];
|
|
23022
23059
|
const typed = typeFilterActive ? state.logs.filter((task) => getDocType(task) === activeTypeFilter) : state.logs;
|
|
23023
23060
|
if (!hasFilter) return typed;
|
|
23024
23061
|
const docs = typed.map((task) => ({ task, body: task.description ?? "" }));
|
|
23025
23062
|
return (0, import_core6.searchTasksRanked)(docs, filterQuery).map((match) => match.doc.task);
|
|
23026
23063
|
}, [doneView, state.logs, typeFilterActive, activeTypeFilter, hasFilter, filterQuery]);
|
|
23027
|
-
const matchCount = (0,
|
|
23064
|
+
const matchCount = (0, import_react44.useMemo)(
|
|
23028
23065
|
() => doneView ? filteredLogs.length : filteredColumns.reduce((sum, column) => sum + (column.tasks?.length ?? 0), 0),
|
|
23029
23066
|
[filteredColumns, doneView, filteredLogs]
|
|
23030
23067
|
);
|
|
@@ -23033,30 +23070,30 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
23033
23070
|
Math.max(0, filteredColumns.length - 1)
|
|
23034
23071
|
);
|
|
23035
23072
|
const currentColumn = filteredColumns[activeColumnIndex];
|
|
23036
|
-
const rows = (0,
|
|
23073
|
+
const rows = (0, import_react44.useMemo)(
|
|
23037
23074
|
() => doneView ? buildFlatRows(filteredLogs) : typeFilterActive ? buildFlatRows(currentColumn?.tasks ?? []) : buildRows(currentColumn?.tasks ?? [], state.collapsedIds),
|
|
23038
23075
|
[currentColumn, doneView, filteredLogs, typeFilterActive, state.collapsedIds]
|
|
23039
23076
|
);
|
|
23040
23077
|
const maxRowIndex = Math.max(0, rows.length - 1);
|
|
23041
23078
|
const selectedIndex = Math.min(state.selectedTaskIndex, maxRowIndex);
|
|
23042
23079
|
const selectedTask = rows[selectedIndex]?.task;
|
|
23043
|
-
const allBoardTasks = (0,
|
|
23080
|
+
const allBoardTasks = (0, import_react44.useMemo)(
|
|
23044
23081
|
() => orderedColumns.flatMap((column) => column.tasks ?? []),
|
|
23045
23082
|
[orderedColumns]
|
|
23046
23083
|
);
|
|
23047
|
-
const allDocs = (0,
|
|
23084
|
+
const allDocs = (0, import_react44.useMemo)(
|
|
23048
23085
|
() => [...allBoardTasks, ...state.logs],
|
|
23049
23086
|
[allBoardTasks, state.logs]
|
|
23050
23087
|
);
|
|
23051
|
-
const archivedIds = (0,
|
|
23088
|
+
const archivedIds = (0, import_react44.useMemo)(() => new Set(state.logs.map((t) => t.id)), [state.logs]);
|
|
23052
23089
|
const detailTaskId = state.detailPath[state.detailPath.length - 1];
|
|
23053
23090
|
const detailTask = state.detailPath.length > 0 ? allDocs.find((t) => t.id === detailTaskId) : void 0;
|
|
23054
|
-
const detailChildren = (0,
|
|
23091
|
+
const detailChildren = (0, import_react44.useMemo)(
|
|
23055
23092
|
() => detailTask ? allDocs.filter((t) => t.parentId === detailTask.id) : [],
|
|
23056
23093
|
[allDocs, detailTask]
|
|
23057
23094
|
);
|
|
23058
23095
|
const detailParent = detailTask?.parentId ? allDocs.find((t) => t.id === detailTask.parentId) : void 0;
|
|
23059
|
-
const detailColumnLabel = (0,
|
|
23096
|
+
const detailColumnLabel = (0, import_react44.useMemo)(() => {
|
|
23060
23097
|
if (!detailTask) return "";
|
|
23061
23098
|
if (archivedIds.has(detailTask.id)) {
|
|
23062
23099
|
const at = detailTask.completedAt;
|
|
@@ -23064,7 +23101,7 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
23064
23101
|
}
|
|
23065
23102
|
return orderedColumns.find((c) => c.tasks?.some((t) => t.id === detailTask.id))?.id ?? "";
|
|
23066
23103
|
}, [orderedColumns, detailTask, archivedIds]);
|
|
23067
|
-
const detailActivity = (0,
|
|
23104
|
+
const detailActivity = (0, import_react44.useMemo)(
|
|
23068
23105
|
() => detailTask ? getTaskActivity(filePath, detailTask.id) : [],
|
|
23069
23106
|
[detailTask, filePath, state.lastUpdated]
|
|
23070
23107
|
);
|
|
@@ -23074,14 +23111,14 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
23074
23111
|
const detailViewWidth = fullscreenDetailMode ? termWidth : detailPaneWidth;
|
|
23075
23112
|
const detailViewHeight = fullscreenDetailMode ? termHeight - FOOTER_ROWS : viewportHeight;
|
|
23076
23113
|
const detailLayout = detailTask ? computeDetailLayout(detailTask, detailViewWidth, detailViewHeight, detailChildren, detailActivity) : null;
|
|
23077
|
-
(0,
|
|
23114
|
+
(0, import_react44.useEffect)(() => {
|
|
23078
23115
|
const wanted = resumeColumn.current;
|
|
23079
23116
|
if (!wanted || orderedColumns.length === 0) return;
|
|
23080
23117
|
resumeColumn.current = void 0;
|
|
23081
23118
|
const idx = orderedColumns.findIndex((c) => c.id === wanted);
|
|
23082
23119
|
if (idx > 0) setState((prev) => ({ ...prev, activeColumnIndex: idx }));
|
|
23083
23120
|
}, [orderedColumns]);
|
|
23084
|
-
(0,
|
|
23121
|
+
(0, import_react44.useEffect)(() => {
|
|
23085
23122
|
setState((prev) => ({
|
|
23086
23123
|
...prev,
|
|
23087
23124
|
activeColumnIndex: Math.min(prev.activeColumnIndex, Math.max(0, filteredColumns.length - 1)),
|
|
@@ -23108,16 +23145,16 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
23108
23145
|
detailArchived: Boolean(detailTask && archivedIds.has(detailTask.id))
|
|
23109
23146
|
});
|
|
23110
23147
|
if (isTooSmall) {
|
|
23111
|
-
return /* @__PURE__ */
|
|
23148
|
+
return /* @__PURE__ */ import_react44.default.createElement(Box_default, { flexDirection: "column", width: termWidth, height: termHeight, paddingLeft: 1 }, /* @__PURE__ */ import_react44.default.createElement(Text, { color: PALETTE.error }, CHROME.tooSmall), /* @__PURE__ */ import_react44.default.createElement(Text, { color: PALETTE.textMuted }, "Minimum ", LAYOUT.MIN_WIDTH, "\xD7", LAYOUT.MIN_HEIGHT, " \xB7 current ", termWidth, "\xD7", termHeight));
|
|
23112
23149
|
}
|
|
23113
23150
|
if (state.error) {
|
|
23114
|
-
return /* @__PURE__ */
|
|
23151
|
+
return /* @__PURE__ */ import_react44.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 1 }, /* @__PURE__ */ import_react44.default.createElement(Text, { color: PALETTE.error }, CHROME.errorTitle), /* @__PURE__ */ import_react44.default.createElement(Text, { color: PALETTE.textSecondary }, state.error), /* @__PURE__ */ import_react44.default.createElement(Text, { color: PALETTE.textMuted }, CHROME.errorHint));
|
|
23115
23152
|
}
|
|
23116
23153
|
if (!state.board) {
|
|
23117
|
-
return /* @__PURE__ */
|
|
23154
|
+
return /* @__PURE__ */ import_react44.default.createElement(Box_default, { paddingLeft: 1 }, /* @__PURE__ */ import_react44.default.createElement(Text, { color: PALETTE.textMuted }, CHROME.loading));
|
|
23118
23155
|
}
|
|
23119
23156
|
if (state.mode === "help") {
|
|
23120
|
-
return /* @__PURE__ */
|
|
23157
|
+
return /* @__PURE__ */ import_react44.default.createElement(HelpOverlay, { termWidth, termHeight });
|
|
23121
23158
|
}
|
|
23122
23159
|
const boardTitle = state.board.title || "brainfile";
|
|
23123
23160
|
const columnLabel = doneView ? "done" : currentColumn?.id ?? "";
|
|
@@ -23133,7 +23170,7 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
23133
23170
|
archived: detailArchived
|
|
23134
23171
|
};
|
|
23135
23172
|
if (fullscreenDetail && detailTask) {
|
|
23136
|
-
return /* @__PURE__ */
|
|
23173
|
+
return /* @__PURE__ */ import_react44.default.createElement(Box_default, { flexDirection: "column", width: termWidth, height: termHeight }, /* @__PURE__ */ import_react44.default.createElement(
|
|
23137
23174
|
DetailView,
|
|
23138
23175
|
{
|
|
23139
23176
|
task: detailTask,
|
|
@@ -23147,7 +23184,7 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
23147
23184
|
cursor: state.detailCursor,
|
|
23148
23185
|
scrollOffset: state.detailScroll
|
|
23149
23186
|
}
|
|
23150
|
-
), /* @__PURE__ */
|
|
23187
|
+
), /* @__PURE__ */ import_react44.default.createElement(Box_default, { flexGrow: 1 }), /* @__PURE__ */ import_react44.default.createElement(Box_default, { height: 1, flexShrink: 0 }, /* @__PURE__ */ import_react44.default.createElement(StatusMessageDisplay, { message: state.statusMessage })), /* @__PURE__ */ import_react44.default.createElement(
|
|
23151
23188
|
FooterBar,
|
|
23152
23189
|
{
|
|
23153
23190
|
width: termWidth,
|
|
@@ -23158,7 +23195,7 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
23158
23195
|
}
|
|
23159
23196
|
const listWidth = detailOpen ? termWidth - detailPaneWidth : termWidth;
|
|
23160
23197
|
const footerActions = detailOpen ? detailActions(detailFooterCtx) : browseActions(selectedTask, doneView);
|
|
23161
|
-
return /* @__PURE__ */
|
|
23198
|
+
return /* @__PURE__ */ import_react44.default.createElement(Box_default, { flexDirection: "column", width: termWidth, height: termHeight }, /* @__PURE__ */ import_react44.default.createElement(
|
|
23162
23199
|
HeaderBar,
|
|
23163
23200
|
{
|
|
23164
23201
|
title: boardTitle,
|
|
@@ -23170,9 +23207,10 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
23170
23207
|
matchCount,
|
|
23171
23208
|
totalCount,
|
|
23172
23209
|
panelLabel: doneView ? "done" : void 0,
|
|
23173
|
-
activeType: typeFilterActive ? activeTypeFilter : "all"
|
|
23210
|
+
activeType: typeFilterActive ? activeTypeFilter : "all",
|
|
23211
|
+
statusLabel: syncStatus
|
|
23174
23212
|
}
|
|
23175
|
-
), /* @__PURE__ */
|
|
23213
|
+
), /* @__PURE__ */ import_react44.default.createElement(Box_default, { flexGrow: 1, flexShrink: 0, flexDirection: "column" }, /* @__PURE__ */ import_react44.default.createElement(
|
|
23176
23214
|
BoardContent,
|
|
23177
23215
|
{
|
|
23178
23216
|
state,
|
|
@@ -23196,7 +23234,7 @@ function BrainfileTUI({ filePath, width, height }) {
|
|
|
23196
23234
|
typeFilter: typeFilterActive ? activeTypeFilter : void 0,
|
|
23197
23235
|
thenEdit: state.addThenEdit
|
|
23198
23236
|
}
|
|
23199
|
-
)), /* @__PURE__ */
|
|
23237
|
+
)), /* @__PURE__ */ import_react44.default.createElement(Box_default, { height: 1, flexShrink: 0 }, /* @__PURE__ */ import_react44.default.createElement(StatusMessageDisplay, { message: state.statusMessage })), /* @__PURE__ */ import_react44.default.createElement(
|
|
23200
23238
|
FooterBar,
|
|
23201
23239
|
{
|
|
23202
23240
|
width: termWidth,
|
|
@@ -23230,7 +23268,7 @@ function BoardContent({
|
|
|
23230
23268
|
}) {
|
|
23231
23269
|
const overlayTarget = state.detailPath.length > 0 ? detailTask : selectedTask;
|
|
23232
23270
|
if (state.mode === "move" && overlayTarget) {
|
|
23233
|
-
return /* @__PURE__ */
|
|
23271
|
+
return /* @__PURE__ */ import_react44.default.createElement(
|
|
23234
23272
|
MoveOverlay,
|
|
23235
23273
|
{
|
|
23236
23274
|
columns,
|
|
@@ -23242,7 +23280,7 @@ function BoardContent({
|
|
|
23242
23280
|
);
|
|
23243
23281
|
}
|
|
23244
23282
|
if (state.mode === "delete-confirm" && overlayTarget) {
|
|
23245
|
-
return /* @__PURE__ */
|
|
23283
|
+
return /* @__PURE__ */ import_react44.default.createElement(
|
|
23246
23284
|
DeleteConfirmOverlay,
|
|
23247
23285
|
{
|
|
23248
23286
|
taskId: overlayTarget.id,
|
|
@@ -23252,12 +23290,12 @@ function BoardContent({
|
|
|
23252
23290
|
);
|
|
23253
23291
|
}
|
|
23254
23292
|
if (state.mode === "complete-confirm" && state.completeConfirm) {
|
|
23255
|
-
return /* @__PURE__ */
|
|
23293
|
+
return /* @__PURE__ */ import_react44.default.createElement(CompleteConfirmOverlay, { target: state.completeConfirm, width: termWidth });
|
|
23256
23294
|
}
|
|
23257
23295
|
if (state.mode === "add") {
|
|
23258
|
-
return /* @__PURE__ */
|
|
23296
|
+
return /* @__PURE__ */ import_react44.default.createElement(AddOverlay, { title: state.newTaskTitle, columnName, thenEdit });
|
|
23259
23297
|
}
|
|
23260
|
-
const list = /* @__PURE__ */
|
|
23298
|
+
const list = /* @__PURE__ */ import_react44.default.createElement(
|
|
23261
23299
|
DocumentList,
|
|
23262
23300
|
{
|
|
23263
23301
|
rows,
|
|
@@ -23276,7 +23314,7 @@ function BoardContent({
|
|
|
23276
23314
|
// shrink to fit corrupts the layout — rows silently lose height and their
|
|
23277
23315
|
// text vanishes — rather than the frame simply growing taller, which ink
|
|
23278
23316
|
// and real terminals handle fine.
|
|
23279
|
-
/* @__PURE__ */
|
|
23317
|
+
/* @__PURE__ */ import_react44.default.createElement(Box_default, { flexDirection: "row", flexGrow: 1, flexShrink: 0 }, /* @__PURE__ */ import_react44.default.createElement(Box_default, { width: listWidth, flexDirection: "column", flexShrink: 0 }, list), /* @__PURE__ */ import_react44.default.createElement(Box_default, { width: detailPaneWidth, flexDirection: "column", flexShrink: 0 }, /* @__PURE__ */ import_react44.default.createElement(
|
|
23280
23318
|
DetailView,
|
|
23281
23319
|
{
|
|
23282
23320
|
task: detailTask,
|
|
@@ -23295,6 +23333,7 @@ function BoardContent({
|
|
|
23295
23333
|
}
|
|
23296
23334
|
|
|
23297
23335
|
// src/commands/tui.tsx
|
|
23336
|
+
import * as path5 from "path";
|
|
23298
23337
|
async function tuiCommand(options) {
|
|
23299
23338
|
const filePath = resolveCliBrainfilePath(options.file);
|
|
23300
23339
|
if (!fs6.existsSync(filePath)) {
|
|
@@ -23314,7 +23353,10 @@ async function tuiCommand(options) {
|
|
|
23314
23353
|
console.log("");
|
|
23315
23354
|
markV2MigrationHintShown(filePath);
|
|
23316
23355
|
}
|
|
23317
|
-
|
|
23356
|
+
installAutosync();
|
|
23357
|
+
const fetched = fetchBeforeRead(path5.dirname(filePath));
|
|
23358
|
+
if (fetched && !fetched.ok) console.error(import_chalk4.default.yellow(syncMessage(fetched).text));
|
|
23359
|
+
const { waitUntilExit } = render_default(/* @__PURE__ */ import_react45.default.createElement(BrainfileTUI, { filePath }));
|
|
23318
23360
|
await waitUntilExit();
|
|
23319
23361
|
process.stdout.write("\x1B[2J");
|
|
23320
23362
|
process.stdout.write("\x1B[H");
|