@dualityinstitute/blink 0.0.3 → 0.0.4
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/README.md +16 -11
- package/dist/cli.js +15 -6
- package/dist/electron/main.js +865 -529
- package/dist/electron/preload.cjs +31 -0
- package/dist/electron/renderer/popup.css +125 -15
- package/dist/electron/renderer/popup.html +17 -3
- package/dist/electron/renderer/popup.js +121 -42
- package/dist/electron/renderer/settings.css +439 -0
- package/dist/electron/renderer/settings.html +93 -0
- package/dist/electron/renderer/settings.js +4067 -0
- package/package.json +2 -2
- package/vendor/Blink.app/Contents/Helpers/BlinkAudio +0 -0
- package/vendor/Blink.app/Contents/MacOS/Blink +0 -0
- package/vendor/Blink.app/Contents/_CodeSignature/CodeResources +2 -2
package/dist/electron/main.js
CHANGED
|
@@ -14,7 +14,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
14
14
|
|
|
15
15
|
// node_modules/picomatch/lib/constants.js
|
|
16
16
|
var require_constants = __commonJS((exports, module) => {
|
|
17
|
-
var
|
|
17
|
+
var path7 = __require("path");
|
|
18
18
|
var WIN_SLASH = "\\\\/";
|
|
19
19
|
var WIN_NO_SLASH = `[^${WIN_SLASH}]`;
|
|
20
20
|
var DEFAULT_MAX_EXTGLOB_RECURSION = 0;
|
|
@@ -140,7 +140,7 @@ var require_constants = __commonJS((exports, module) => {
|
|
|
140
140
|
CHAR_UNDERSCORE: 95,
|
|
141
141
|
CHAR_VERTICAL_LINE: 124,
|
|
142
142
|
CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279,
|
|
143
|
-
SEP:
|
|
143
|
+
SEP: path7.sep,
|
|
144
144
|
extglobChars(chars) {
|
|
145
145
|
return {
|
|
146
146
|
"!": { type: "negate", open: "(?:(?!(?:", close: `))${chars.STAR})` },
|
|
@@ -158,7 +158,7 @@ var require_constants = __commonJS((exports, module) => {
|
|
|
158
158
|
|
|
159
159
|
// node_modules/picomatch/lib/utils.js
|
|
160
160
|
var require_utils = __commonJS((exports) => {
|
|
161
|
-
var
|
|
161
|
+
var path7 = __require("path");
|
|
162
162
|
var win32 = process.platform === "win32";
|
|
163
163
|
var {
|
|
164
164
|
REGEX_BACKSLASH,
|
|
@@ -187,7 +187,7 @@ var require_utils = __commonJS((exports) => {
|
|
|
187
187
|
if (options && typeof options.windows === "boolean") {
|
|
188
188
|
return options.windows;
|
|
189
189
|
}
|
|
190
|
-
return win32 === true ||
|
|
190
|
+
return win32 === true || path7.sep === "\\";
|
|
191
191
|
};
|
|
192
192
|
exports.escapeLast = (input2, char, lastIdx) => {
|
|
193
193
|
const idx = input2.lastIndexOf(char, lastIdx);
|
|
@@ -1540,7 +1540,7 @@ var require_parse = __commonJS((exports, module) => {
|
|
|
1540
1540
|
|
|
1541
1541
|
// node_modules/picomatch/lib/picomatch.js
|
|
1542
1542
|
var require_picomatch = __commonJS((exports, module) => {
|
|
1543
|
-
var
|
|
1543
|
+
var path7 = __require("path");
|
|
1544
1544
|
var scan = require_scan();
|
|
1545
1545
|
var parse5 = require_parse();
|
|
1546
1546
|
var utils = require_utils();
|
|
@@ -1626,7 +1626,7 @@ var require_picomatch = __commonJS((exports, module) => {
|
|
|
1626
1626
|
};
|
|
1627
1627
|
picomatch.matchBase = (input2, glob, options, posix = utils.isWindows(options)) => {
|
|
1628
1628
|
const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
|
|
1629
|
-
return regex.test(
|
|
1629
|
+
return regex.test(path7.basename(input2));
|
|
1630
1630
|
};
|
|
1631
1631
|
picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
|
|
1632
1632
|
picomatch.parse = (pattern, options) => {
|
|
@@ -1681,15 +1681,15 @@ var require_picomatch = __commonJS((exports, module) => {
|
|
|
1681
1681
|
|
|
1682
1682
|
// node_modules/readdirp/index.js
|
|
1683
1683
|
var require_readdirp = __commonJS((exports, module) => {
|
|
1684
|
-
var
|
|
1684
|
+
var fs6 = __require("fs");
|
|
1685
1685
|
var { Readable } = __require("stream");
|
|
1686
1686
|
var sysPath = __require("path");
|
|
1687
1687
|
var { promisify } = __require("util");
|
|
1688
1688
|
var picomatch = require_picomatch();
|
|
1689
|
-
var readdir = promisify(
|
|
1690
|
-
var stat = promisify(
|
|
1691
|
-
var lstat = promisify(
|
|
1692
|
-
var realpath = promisify(
|
|
1689
|
+
var readdir = promisify(fs6.readdir);
|
|
1690
|
+
var stat = promisify(fs6.stat);
|
|
1691
|
+
var lstat = promisify(fs6.lstat);
|
|
1692
|
+
var realpath = promisify(fs6.realpath);
|
|
1693
1693
|
var BANG = "!";
|
|
1694
1694
|
var RECURSIVE_ERROR_CODE = "READDIRP_RECURSIVE_ERROR";
|
|
1695
1695
|
var NORMAL_FLOW_ERRORS = new Set(["ENOENT", "EPERM", "EACCES", "ELOOP", RECURSIVE_ERROR_CODE]);
|
|
@@ -1735,8 +1735,8 @@ var require_readdirp = __commonJS((exports, module) => {
|
|
|
1735
1735
|
static get defaultOptions() {
|
|
1736
1736
|
return {
|
|
1737
1737
|
root: ".",
|
|
1738
|
-
fileFilter: (
|
|
1739
|
-
directoryFilter: (
|
|
1738
|
+
fileFilter: (path7) => true,
|
|
1739
|
+
directoryFilter: (path7) => true,
|
|
1740
1740
|
type: FILE_TYPE,
|
|
1741
1741
|
lstat: false,
|
|
1742
1742
|
depth: 2147483648,
|
|
@@ -1755,7 +1755,7 @@ var require_readdirp = __commonJS((exports, module) => {
|
|
|
1755
1755
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
1756
1756
|
const statMethod = opts.lstat ? lstat : stat;
|
|
1757
1757
|
if (wantBigintFsStats) {
|
|
1758
|
-
this._stat = (
|
|
1758
|
+
this._stat = (path7) => statMethod(path7, { bigint: true });
|
|
1759
1759
|
} else {
|
|
1760
1760
|
this._stat = statMethod;
|
|
1761
1761
|
}
|
|
@@ -1764,7 +1764,7 @@ var require_readdirp = __commonJS((exports, module) => {
|
|
|
1764
1764
|
this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type);
|
|
1765
1765
|
this._wantsEverything = type === EVERYTHING_TYPE;
|
|
1766
1766
|
this._root = sysPath.resolve(root);
|
|
1767
|
-
this._isDirent = "Dirent" in
|
|
1767
|
+
this._isDirent = "Dirent" in fs6 && !opts.alwaysStat;
|
|
1768
1768
|
this._statsProp = this._isDirent ? "dirent" : "stats";
|
|
1769
1769
|
this._rdOptions = { encoding: "utf8", withFileTypes: this._isDirent };
|
|
1770
1770
|
this.parents = [this._exploreDir(root, 1)];
|
|
@@ -1777,9 +1777,9 @@ var require_readdirp = __commonJS((exports, module) => {
|
|
|
1777
1777
|
this.reading = true;
|
|
1778
1778
|
try {
|
|
1779
1779
|
while (!this.destroyed && batch > 0) {
|
|
1780
|
-
const { path:
|
|
1780
|
+
const { path: path7, depth, files = [] } = this.parent || {};
|
|
1781
1781
|
if (files.length > 0) {
|
|
1782
|
-
const slice = files.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
1782
|
+
const slice = files.splice(0, batch).map((dirent) => this._formatEntry(dirent, path7));
|
|
1783
1783
|
for (const entry of await Promise.all(slice)) {
|
|
1784
1784
|
if (this.destroyed)
|
|
1785
1785
|
return;
|
|
@@ -1816,20 +1816,20 @@ var require_readdirp = __commonJS((exports, module) => {
|
|
|
1816
1816
|
this.reading = false;
|
|
1817
1817
|
}
|
|
1818
1818
|
}
|
|
1819
|
-
async _exploreDir(
|
|
1819
|
+
async _exploreDir(path7, depth) {
|
|
1820
1820
|
let files;
|
|
1821
1821
|
try {
|
|
1822
|
-
files = await readdir(
|
|
1822
|
+
files = await readdir(path7, this._rdOptions);
|
|
1823
1823
|
} catch (error61) {
|
|
1824
1824
|
this._onError(error61);
|
|
1825
1825
|
}
|
|
1826
|
-
return { files, depth, path:
|
|
1826
|
+
return { files, depth, path: path7 };
|
|
1827
1827
|
}
|
|
1828
|
-
async _formatEntry(dirent,
|
|
1828
|
+
async _formatEntry(dirent, path7) {
|
|
1829
1829
|
let entry;
|
|
1830
1830
|
try {
|
|
1831
1831
|
const basename2 = this._isDirent ? dirent.name : dirent;
|
|
1832
|
-
const fullPath = sysPath.resolve(sysPath.join(
|
|
1832
|
+
const fullPath = sysPath.resolve(sysPath.join(path7, basename2));
|
|
1833
1833
|
entry = { path: sysPath.relative(this._root, fullPath), fullPath, basename: basename2 };
|
|
1834
1834
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
1835
1835
|
} catch (err) {
|
|
@@ -1918,24 +1918,24 @@ var require_normalize_path = __commonJS((exports, module) => {
|
|
|
1918
1918
|
* Copyright (c) 2014-2018, Jon Schlinkert.
|
|
1919
1919
|
* Released under the MIT License.
|
|
1920
1920
|
*/
|
|
1921
|
-
module.exports = function(
|
|
1922
|
-
if (typeof
|
|
1921
|
+
module.exports = function(path7, stripTrailing) {
|
|
1922
|
+
if (typeof path7 !== "string") {
|
|
1923
1923
|
throw new TypeError("expected path to be a string");
|
|
1924
1924
|
}
|
|
1925
|
-
if (
|
|
1925
|
+
if (path7 === "\\" || path7 === "/")
|
|
1926
1926
|
return "/";
|
|
1927
|
-
var len =
|
|
1927
|
+
var len = path7.length;
|
|
1928
1928
|
if (len <= 1)
|
|
1929
|
-
return
|
|
1929
|
+
return path7;
|
|
1930
1930
|
var prefix = "";
|
|
1931
|
-
if (len > 4 &&
|
|
1932
|
-
var ch =
|
|
1933
|
-
if ((ch === "?" || ch === ".") &&
|
|
1934
|
-
|
|
1931
|
+
if (len > 4 && path7[3] === "\\") {
|
|
1932
|
+
var ch = path7[2];
|
|
1933
|
+
if ((ch === "?" || ch === ".") && path7.slice(0, 2) === "\\\\") {
|
|
1934
|
+
path7 = path7.slice(2);
|
|
1935
1935
|
prefix = "//";
|
|
1936
1936
|
}
|
|
1937
1937
|
}
|
|
1938
|
-
var segs =
|
|
1938
|
+
var segs = path7.split(/[/\\]+/);
|
|
1939
1939
|
if (stripTrailing !== false && segs[segs.length - 1] === "") {
|
|
1940
1940
|
segs.pop();
|
|
1941
1941
|
}
|
|
@@ -1970,17 +1970,17 @@ var require_anymatch = __commonJS((exports, module) => {
|
|
|
1970
1970
|
if (!isList && typeof _path !== "string") {
|
|
1971
1971
|
throw new TypeError("anymatch: second argument must be a string: got " + Object.prototype.toString.call(_path));
|
|
1972
1972
|
}
|
|
1973
|
-
const
|
|
1973
|
+
const path7 = normalizePath(_path, false);
|
|
1974
1974
|
for (let index = 0;index < negPatterns.length; index++) {
|
|
1975
1975
|
const nglob = negPatterns[index];
|
|
1976
|
-
if (nglob(
|
|
1976
|
+
if (nglob(path7)) {
|
|
1977
1977
|
return returnIndex ? -1 : false;
|
|
1978
1978
|
}
|
|
1979
1979
|
}
|
|
1980
|
-
const applied = isList && [
|
|
1980
|
+
const applied = isList && [path7].concat(args.slice(1));
|
|
1981
1981
|
for (let index = 0;index < patterns.length; index++) {
|
|
1982
1982
|
const pattern = patterns[index];
|
|
1983
|
-
if (isList ? pattern(...applied) : pattern(
|
|
1983
|
+
if (isList ? pattern(...applied) : pattern(path7)) {
|
|
1984
1984
|
return returnIndex ? index : true;
|
|
1985
1985
|
}
|
|
1986
1986
|
}
|
|
@@ -2574,7 +2574,7 @@ var require_fill_range = __commonJS((exports, module) => {
|
|
|
2574
2574
|
}
|
|
2575
2575
|
return options.stringify === true;
|
|
2576
2576
|
};
|
|
2577
|
-
var
|
|
2577
|
+
var pad4 = (input2, maxLength, toNumber) => {
|
|
2578
2578
|
if (maxLength > 0) {
|
|
2579
2579
|
let dash = input2[0] === "-" ? "-" : "";
|
|
2580
2580
|
if (dash)
|
|
@@ -2683,7 +2683,7 @@ var require_fill_range = __commonJS((exports, module) => {
|
|
|
2683
2683
|
if (options.toRegex === true && step > 1) {
|
|
2684
2684
|
push(a);
|
|
2685
2685
|
} else {
|
|
2686
|
-
range.push(
|
|
2686
|
+
range.push(pad4(format(a, index), maxLen, toNumber));
|
|
2687
2687
|
}
|
|
2688
2688
|
a = descending ? a - step : a + step;
|
|
2689
2689
|
index++;
|
|
@@ -3499,10 +3499,10 @@ var require_binary_extensions = __commonJS((exports, module) => {
|
|
|
3499
3499
|
|
|
3500
3500
|
// node_modules/is-binary-path/index.js
|
|
3501
3501
|
var require_is_binary_path = __commonJS((exports, module) => {
|
|
3502
|
-
var
|
|
3502
|
+
var path7 = __require("path");
|
|
3503
3503
|
var binaryExtensions = require_binary_extensions();
|
|
3504
3504
|
var extensions = new Set(binaryExtensions);
|
|
3505
|
-
module.exports = (filePath) => extensions.has(
|
|
3505
|
+
module.exports = (filePath) => extensions.has(path7.extname(filePath).slice(1).toLowerCase());
|
|
3506
3506
|
});
|
|
3507
3507
|
|
|
3508
3508
|
// node_modules/chokidar/lib/constants.js
|
|
@@ -3567,7 +3567,7 @@ var require_constants3 = __commonJS((exports) => {
|
|
|
3567
3567
|
|
|
3568
3568
|
// node_modules/chokidar/lib/nodefs-handler.js
|
|
3569
3569
|
var require_nodefs_handler = __commonJS((exports, module) => {
|
|
3570
|
-
var
|
|
3570
|
+
var fs6 = __require("fs");
|
|
3571
3571
|
var sysPath = __require("path");
|
|
3572
3572
|
var { promisify } = __require("util");
|
|
3573
3573
|
var isBinaryPath = require_is_binary_path();
|
|
@@ -3590,11 +3590,11 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3590
3590
|
STAR
|
|
3591
3591
|
} = require_constants3();
|
|
3592
3592
|
var THROTTLE_MODE_WATCH = "watch";
|
|
3593
|
-
var open2 = promisify(
|
|
3594
|
-
var stat = promisify(
|
|
3595
|
-
var lstat = promisify(
|
|
3596
|
-
var close = promisify(
|
|
3597
|
-
var fsrealpath = promisify(
|
|
3593
|
+
var open2 = promisify(fs6.open);
|
|
3594
|
+
var stat = promisify(fs6.stat);
|
|
3595
|
+
var lstat = promisify(fs6.lstat);
|
|
3596
|
+
var close = promisify(fs6.close);
|
|
3597
|
+
var fsrealpath = promisify(fs6.realpath);
|
|
3598
3598
|
var statMethods = { lstat, stat };
|
|
3599
3599
|
var foreach = (val, fn) => {
|
|
3600
3600
|
if (val instanceof Set) {
|
|
@@ -3628,16 +3628,16 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3628
3628
|
};
|
|
3629
3629
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
3630
3630
|
var FsWatchInstances = new Map;
|
|
3631
|
-
function createFsWatchInstance(
|
|
3631
|
+
function createFsWatchInstance(path7, options, listener, errHandler, emitRaw) {
|
|
3632
3632
|
const handleEvent = (rawEvent, evPath) => {
|
|
3633
|
-
listener(
|
|
3634
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
3635
|
-
if (evPath &&
|
|
3636
|
-
fsWatchBroadcast(sysPath.resolve(
|
|
3633
|
+
listener(path7);
|
|
3634
|
+
emitRaw(rawEvent, evPath, { watchedPath: path7 });
|
|
3635
|
+
if (evPath && path7 !== evPath) {
|
|
3636
|
+
fsWatchBroadcast(sysPath.resolve(path7, evPath), KEY_LISTENERS, sysPath.join(path7, evPath));
|
|
3637
3637
|
}
|
|
3638
3638
|
};
|
|
3639
3639
|
try {
|
|
3640
|
-
return
|
|
3640
|
+
return fs6.watch(path7, options, handleEvent);
|
|
3641
3641
|
} catch (error61) {
|
|
3642
3642
|
errHandler(error61);
|
|
3643
3643
|
}
|
|
@@ -3650,12 +3650,12 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3650
3650
|
listener(val1, val2, val3);
|
|
3651
3651
|
});
|
|
3652
3652
|
};
|
|
3653
|
-
var setFsWatchListener = (
|
|
3653
|
+
var setFsWatchListener = (path7, fullPath, options, handlers) => {
|
|
3654
3654
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
3655
3655
|
let cont = FsWatchInstances.get(fullPath);
|
|
3656
3656
|
let watcher;
|
|
3657
3657
|
if (!options.persistent) {
|
|
3658
|
-
watcher = createFsWatchInstance(
|
|
3658
|
+
watcher = createFsWatchInstance(path7, options, listener, errHandler, rawEmitter);
|
|
3659
3659
|
return watcher.close.bind(watcher);
|
|
3660
3660
|
}
|
|
3661
3661
|
if (cont) {
|
|
@@ -3663,7 +3663,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3663
3663
|
addAndConvert(cont, KEY_ERR, errHandler);
|
|
3664
3664
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
3665
3665
|
} else {
|
|
3666
|
-
watcher = createFsWatchInstance(
|
|
3666
|
+
watcher = createFsWatchInstance(path7, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
|
|
3667
3667
|
if (!watcher)
|
|
3668
3668
|
return;
|
|
3669
3669
|
watcher.on(EV_ERROR, async (error61) => {
|
|
@@ -3671,7 +3671,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3671
3671
|
cont.watcherUnusable = true;
|
|
3672
3672
|
if (isWindows && error61.code === "EPERM") {
|
|
3673
3673
|
try {
|
|
3674
|
-
const fd = await open2(
|
|
3674
|
+
const fd = await open2(path7, "r");
|
|
3675
3675
|
await close(fd);
|
|
3676
3676
|
broadcastErr(error61);
|
|
3677
3677
|
} catch (err) {}
|
|
@@ -3701,7 +3701,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3701
3701
|
};
|
|
3702
3702
|
};
|
|
3703
3703
|
var FsWatchFileInstances = new Map;
|
|
3704
|
-
var setFsWatchFileListener = (
|
|
3704
|
+
var setFsWatchFileListener = (path7, fullPath, options, handlers) => {
|
|
3705
3705
|
const { listener, rawEmitter } = handlers;
|
|
3706
3706
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
3707
3707
|
let listeners = new Set;
|
|
@@ -3710,7 +3710,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3710
3710
|
if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
|
|
3711
3711
|
listeners = cont.listeners;
|
|
3712
3712
|
rawEmitters = cont.rawEmitters;
|
|
3713
|
-
|
|
3713
|
+
fs6.unwatchFile(fullPath);
|
|
3714
3714
|
cont = undefined;
|
|
3715
3715
|
}
|
|
3716
3716
|
if (cont) {
|
|
@@ -3721,13 +3721,13 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3721
3721
|
listeners: listener,
|
|
3722
3722
|
rawEmitters: rawEmitter,
|
|
3723
3723
|
options,
|
|
3724
|
-
watcher:
|
|
3724
|
+
watcher: fs6.watchFile(fullPath, options, (curr, prev) => {
|
|
3725
3725
|
foreach(cont.rawEmitters, (rawEmitter2) => {
|
|
3726
3726
|
rawEmitter2(EV_CHANGE, fullPath, { curr, prev });
|
|
3727
3727
|
});
|
|
3728
3728
|
const currmtime = curr.mtimeMs;
|
|
3729
3729
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
3730
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
3730
|
+
foreach(cont.listeners, (listener2) => listener2(path7, curr));
|
|
3731
3731
|
}
|
|
3732
3732
|
})
|
|
3733
3733
|
};
|
|
@@ -3738,7 +3738,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3738
3738
|
delFromSet(cont, KEY_RAW, rawEmitter);
|
|
3739
3739
|
if (isEmptySet(cont.listeners)) {
|
|
3740
3740
|
FsWatchFileInstances.delete(fullPath);
|
|
3741
|
-
|
|
3741
|
+
fs6.unwatchFile(fullPath);
|
|
3742
3742
|
cont.options = cont.watcher = undefined;
|
|
3743
3743
|
Object.freeze(cont);
|
|
3744
3744
|
}
|
|
@@ -3750,25 +3750,25 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3750
3750
|
this.fsw = fsW;
|
|
3751
3751
|
this._boundHandleError = (error61) => fsW._handleError(error61);
|
|
3752
3752
|
}
|
|
3753
|
-
_watchWithNodeFs(
|
|
3753
|
+
_watchWithNodeFs(path7, listener) {
|
|
3754
3754
|
const opts = this.fsw.options;
|
|
3755
|
-
const directory = sysPath.dirname(
|
|
3756
|
-
const basename2 = sysPath.basename(
|
|
3755
|
+
const directory = sysPath.dirname(path7);
|
|
3756
|
+
const basename2 = sysPath.basename(path7);
|
|
3757
3757
|
const parent = this.fsw._getWatchedDir(directory);
|
|
3758
3758
|
parent.add(basename2);
|
|
3759
|
-
const absolutePath = sysPath.resolve(
|
|
3759
|
+
const absolutePath = sysPath.resolve(path7);
|
|
3760
3760
|
const options = { persistent: opts.persistent };
|
|
3761
3761
|
if (!listener)
|
|
3762
3762
|
listener = EMPTY_FN;
|
|
3763
3763
|
let closer;
|
|
3764
3764
|
if (opts.usePolling) {
|
|
3765
3765
|
options.interval = opts.enableBinaryInterval && isBinaryPath(basename2) ? opts.binaryInterval : opts.interval;
|
|
3766
|
-
closer = setFsWatchFileListener(
|
|
3766
|
+
closer = setFsWatchFileListener(path7, absolutePath, options, {
|
|
3767
3767
|
listener,
|
|
3768
3768
|
rawEmitter: this.fsw._emitRaw
|
|
3769
3769
|
});
|
|
3770
3770
|
} else {
|
|
3771
|
-
closer = setFsWatchListener(
|
|
3771
|
+
closer = setFsWatchListener(path7, absolutePath, options, {
|
|
3772
3772
|
listener,
|
|
3773
3773
|
errHandler: this._boundHandleError,
|
|
3774
3774
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -3786,7 +3786,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3786
3786
|
let prevStats = stats;
|
|
3787
3787
|
if (parent.has(basename2))
|
|
3788
3788
|
return;
|
|
3789
|
-
const listener = async (
|
|
3789
|
+
const listener = async (path7, newStats) => {
|
|
3790
3790
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file2, 5))
|
|
3791
3791
|
return;
|
|
3792
3792
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -3800,9 +3800,9 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3800
3800
|
this.fsw._emit(EV_CHANGE, file2, newStats2);
|
|
3801
3801
|
}
|
|
3802
3802
|
if (isLinux && prevStats.ino !== newStats2.ino) {
|
|
3803
|
-
this.fsw._closeFile(
|
|
3803
|
+
this.fsw._closeFile(path7);
|
|
3804
3804
|
prevStats = newStats2;
|
|
3805
|
-
this.fsw._addPathCloser(
|
|
3805
|
+
this.fsw._addPathCloser(path7, this._watchWithNodeFs(file2, listener));
|
|
3806
3806
|
} else {
|
|
3807
3807
|
prevStats = newStats2;
|
|
3808
3808
|
}
|
|
@@ -3826,7 +3826,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3826
3826
|
}
|
|
3827
3827
|
return closer;
|
|
3828
3828
|
}
|
|
3829
|
-
async _handleSymlink(entry, directory,
|
|
3829
|
+
async _handleSymlink(entry, directory, path7, item) {
|
|
3830
3830
|
if (this.fsw.closed) {
|
|
3831
3831
|
return;
|
|
3832
3832
|
}
|
|
@@ -3836,7 +3836,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3836
3836
|
this.fsw._incrReadyCount();
|
|
3837
3837
|
let linkPath;
|
|
3838
3838
|
try {
|
|
3839
|
-
linkPath = await fsrealpath(
|
|
3839
|
+
linkPath = await fsrealpath(path7);
|
|
3840
3840
|
} catch (e) {
|
|
3841
3841
|
this.fsw._emitReady();
|
|
3842
3842
|
return true;
|
|
@@ -3846,12 +3846,12 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3846
3846
|
if (dir.has(item)) {
|
|
3847
3847
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
3848
3848
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
3849
|
-
this.fsw._emit(EV_CHANGE,
|
|
3849
|
+
this.fsw._emit(EV_CHANGE, path7, entry.stats);
|
|
3850
3850
|
}
|
|
3851
3851
|
} else {
|
|
3852
3852
|
dir.add(item);
|
|
3853
3853
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
3854
|
-
this.fsw._emit(EV_ADD,
|
|
3854
|
+
this.fsw._emit(EV_ADD, path7, entry.stats);
|
|
3855
3855
|
}
|
|
3856
3856
|
this.fsw._emitReady();
|
|
3857
3857
|
return true;
|
|
@@ -3880,9 +3880,9 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3880
3880
|
return;
|
|
3881
3881
|
}
|
|
3882
3882
|
const item = entry.path;
|
|
3883
|
-
let
|
|
3883
|
+
let path7 = sysPath.join(directory, item);
|
|
3884
3884
|
current.add(item);
|
|
3885
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
3885
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path7, item)) {
|
|
3886
3886
|
return;
|
|
3887
3887
|
}
|
|
3888
3888
|
if (this.fsw.closed) {
|
|
@@ -3891,8 +3891,8 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3891
3891
|
}
|
|
3892
3892
|
if (item === target || !target && !previous.has(item)) {
|
|
3893
3893
|
this.fsw._incrReadyCount();
|
|
3894
|
-
|
|
3895
|
-
this._addToNodeFs(
|
|
3894
|
+
path7 = sysPath.join(dir, sysPath.relative(dir, path7));
|
|
3895
|
+
this._addToNodeFs(path7, initialAdd, wh, depth + 1);
|
|
3896
3896
|
}
|
|
3897
3897
|
}).on(EV_ERROR, this._boundHandleError);
|
|
3898
3898
|
return new Promise((resolve) => stream.once(STR_END, () => {
|
|
@@ -3940,13 +3940,13 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3940
3940
|
}
|
|
3941
3941
|
return closer;
|
|
3942
3942
|
}
|
|
3943
|
-
async _addToNodeFs(
|
|
3943
|
+
async _addToNodeFs(path7, initialAdd, priorWh, depth, target) {
|
|
3944
3944
|
const ready = this.fsw._emitReady;
|
|
3945
|
-
if (this.fsw._isIgnored(
|
|
3945
|
+
if (this.fsw._isIgnored(path7) || this.fsw.closed) {
|
|
3946
3946
|
ready();
|
|
3947
3947
|
return false;
|
|
3948
3948
|
}
|
|
3949
|
-
const wh = this.fsw._getWatchHelpers(
|
|
3949
|
+
const wh = this.fsw._getWatchHelpers(path7, depth);
|
|
3950
3950
|
if (!wh.hasGlob && priorWh) {
|
|
3951
3951
|
wh.hasGlob = priorWh.hasGlob;
|
|
3952
3952
|
wh.globFilter = priorWh.globFilter;
|
|
@@ -3961,11 +3961,11 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3961
3961
|
ready();
|
|
3962
3962
|
return false;
|
|
3963
3963
|
}
|
|
3964
|
-
const follow = this.fsw.options.followSymlinks && !
|
|
3964
|
+
const follow = this.fsw.options.followSymlinks && !path7.includes(STAR) && !path7.includes(BRACE_START);
|
|
3965
3965
|
let closer;
|
|
3966
3966
|
if (stats.isDirectory()) {
|
|
3967
|
-
const absPath = sysPath.resolve(
|
|
3968
|
-
const targetPath = follow ? await fsrealpath(
|
|
3967
|
+
const absPath = sysPath.resolve(path7);
|
|
3968
|
+
const targetPath = follow ? await fsrealpath(path7) : path7;
|
|
3969
3969
|
if (this.fsw.closed)
|
|
3970
3970
|
return;
|
|
3971
3971
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -3975,28 +3975,28 @@ var require_nodefs_handler = __commonJS((exports, module) => {
|
|
|
3975
3975
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
3976
3976
|
}
|
|
3977
3977
|
} else if (stats.isSymbolicLink()) {
|
|
3978
|
-
const targetPath = follow ? await fsrealpath(
|
|
3978
|
+
const targetPath = follow ? await fsrealpath(path7) : path7;
|
|
3979
3979
|
if (this.fsw.closed)
|
|
3980
3980
|
return;
|
|
3981
3981
|
const parent = sysPath.dirname(wh.watchPath);
|
|
3982
3982
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
3983
3983
|
this.fsw._emit(EV_ADD, wh.watchPath, stats);
|
|
3984
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
3984
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path7, wh, targetPath);
|
|
3985
3985
|
if (this.fsw.closed)
|
|
3986
3986
|
return;
|
|
3987
3987
|
if (targetPath !== undefined) {
|
|
3988
|
-
this.fsw._symlinkPaths.set(sysPath.resolve(
|
|
3988
|
+
this.fsw._symlinkPaths.set(sysPath.resolve(path7), targetPath);
|
|
3989
3989
|
}
|
|
3990
3990
|
} else {
|
|
3991
3991
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
3992
3992
|
}
|
|
3993
3993
|
ready();
|
|
3994
|
-
this.fsw._addPathCloser(
|
|
3994
|
+
this.fsw._addPathCloser(path7, closer);
|
|
3995
3995
|
return false;
|
|
3996
3996
|
} catch (error61) {
|
|
3997
3997
|
if (this.fsw._handleError(error61)) {
|
|
3998
3998
|
ready();
|
|
3999
|
-
return
|
|
3999
|
+
return path7;
|
|
4000
4000
|
}
|
|
4001
4001
|
}
|
|
4002
4002
|
}
|
|
@@ -4016,9 +4016,9 @@ var require_fsevents2 = __commonJS((exports) => {
|
|
|
4016
4016
|
}
|
|
4017
4017
|
var Native = require_fsevents();
|
|
4018
4018
|
var events = Native.constants;
|
|
4019
|
-
function watch(
|
|
4020
|
-
if (typeof
|
|
4021
|
-
throw new TypeError(`fsevents argument 1 must be a string and not a ${typeof
|
|
4019
|
+
function watch(path7, since, handler) {
|
|
4020
|
+
if (typeof path7 !== "string") {
|
|
4021
|
+
throw new TypeError(`fsevents argument 1 must be a string and not a ${typeof path7}`);
|
|
4022
4022
|
}
|
|
4023
4023
|
if (typeof since === "function" && typeof handler === "undefined") {
|
|
4024
4024
|
handler = since;
|
|
@@ -4030,18 +4030,18 @@ var require_fsevents2 = __commonJS((exports) => {
|
|
|
4030
4030
|
if (typeof handler !== "function") {
|
|
4031
4031
|
throw new TypeError(`fsevents argument 3 must be a function and not a ${typeof handler}`);
|
|
4032
4032
|
}
|
|
4033
|
-
let instance = Native.start(Native.global,
|
|
4033
|
+
let instance = Native.start(Native.global, path7, since, handler);
|
|
4034
4034
|
if (!instance)
|
|
4035
|
-
throw new Error(`could not watch: ${
|
|
4035
|
+
throw new Error(`could not watch: ${path7}`);
|
|
4036
4036
|
return () => {
|
|
4037
4037
|
const result = instance ? Promise.resolve(instance).then(Native.stop) : Promise.resolve(undefined);
|
|
4038
4038
|
instance = undefined;
|
|
4039
4039
|
return result;
|
|
4040
4040
|
};
|
|
4041
4041
|
}
|
|
4042
|
-
function getInfo(
|
|
4042
|
+
function getInfo(path7, flags) {
|
|
4043
4043
|
return {
|
|
4044
|
-
path:
|
|
4044
|
+
path: path7,
|
|
4045
4045
|
flags,
|
|
4046
4046
|
event: getEventType(flags),
|
|
4047
4047
|
type: getFileType(flags),
|
|
@@ -4095,7 +4095,7 @@ var require_fsevents2 = __commonJS((exports) => {
|
|
|
4095
4095
|
|
|
4096
4096
|
// node_modules/chokidar/lib/fsevents-handler.js
|
|
4097
4097
|
var require_fsevents_handler = __commonJS((exports, module) => {
|
|
4098
|
-
var
|
|
4098
|
+
var fs6 = __require("fs");
|
|
4099
4099
|
var sysPath = __require("path");
|
|
4100
4100
|
var { promisify } = __require("util");
|
|
4101
4101
|
var fsevents;
|
|
@@ -4140,9 +4140,9 @@ var require_fsevents_handler = __commonJS((exports, module) => {
|
|
|
4140
4140
|
IDENTITY_FN
|
|
4141
4141
|
} = require_constants3();
|
|
4142
4142
|
var Depth = (value) => isNaN(value) ? {} : { depth: value };
|
|
4143
|
-
var stat = promisify(
|
|
4144
|
-
var lstat = promisify(
|
|
4145
|
-
var realpath = promisify(
|
|
4143
|
+
var stat = promisify(fs6.stat);
|
|
4144
|
+
var lstat = promisify(fs6.lstat);
|
|
4145
|
+
var realpath = promisify(fs6.realpath);
|
|
4146
4146
|
var statMethods = { stat, lstat };
|
|
4147
4147
|
var FSEventsWatchers = new Map;
|
|
4148
4148
|
var consolidateThreshhold = 10;
|
|
@@ -4156,18 +4156,18 @@ var require_fsevents_handler = __commonJS((exports, module) => {
|
|
|
4156
4156
|
131840,
|
|
4157
4157
|
262912
|
|
4158
4158
|
]);
|
|
4159
|
-
var createFSEventsInstance = (
|
|
4160
|
-
const stop2 = fsevents.watch(
|
|
4159
|
+
var createFSEventsInstance = (path7, callback) => {
|
|
4160
|
+
const stop2 = fsevents.watch(path7, callback);
|
|
4161
4161
|
return { stop: stop2 };
|
|
4162
4162
|
};
|
|
4163
|
-
function setFSEventsListener(
|
|
4163
|
+
function setFSEventsListener(path7, realPath, listener, rawEmitter) {
|
|
4164
4164
|
let watchPath = sysPath.extname(realPath) ? sysPath.dirname(realPath) : realPath;
|
|
4165
4165
|
const parentPath = sysPath.dirname(watchPath);
|
|
4166
4166
|
let cont = FSEventsWatchers.get(watchPath);
|
|
4167
4167
|
if (couldConsolidate(parentPath)) {
|
|
4168
4168
|
watchPath = parentPath;
|
|
4169
4169
|
}
|
|
4170
|
-
const resolvedPath = sysPath.resolve(
|
|
4170
|
+
const resolvedPath = sysPath.resolve(path7);
|
|
4171
4171
|
const hasSymlink = resolvedPath !== realPath;
|
|
4172
4172
|
const filteredListener = (fullPath, flags, info) => {
|
|
4173
4173
|
if (hasSymlink)
|
|
@@ -4217,10 +4217,10 @@ var require_fsevents_handler = __commonJS((exports, module) => {
|
|
|
4217
4217
|
}
|
|
4218
4218
|
};
|
|
4219
4219
|
}
|
|
4220
|
-
var couldConsolidate = (
|
|
4220
|
+
var couldConsolidate = (path7) => {
|
|
4221
4221
|
let count = 0;
|
|
4222
4222
|
for (const watchPath of FSEventsWatchers.keys()) {
|
|
4223
|
-
if (watchPath.indexOf(
|
|
4223
|
+
if (watchPath.indexOf(path7) === 0) {
|
|
4224
4224
|
count++;
|
|
4225
4225
|
if (count >= consolidateThreshhold) {
|
|
4226
4226
|
return true;
|
|
@@ -4230,9 +4230,9 @@ var require_fsevents_handler = __commonJS((exports, module) => {
|
|
|
4230
4230
|
return false;
|
|
4231
4231
|
};
|
|
4232
4232
|
var canUse = () => fsevents && FSEventsWatchers.size < 128;
|
|
4233
|
-
var calcDepth = (
|
|
4233
|
+
var calcDepth = (path7, root) => {
|
|
4234
4234
|
let i = 0;
|
|
4235
|
-
while (!
|
|
4235
|
+
while (!path7.indexOf(root) && (path7 = sysPath.dirname(path7)) !== root)
|
|
4236
4236
|
i++;
|
|
4237
4237
|
return i;
|
|
4238
4238
|
};
|
|
@@ -4242,42 +4242,42 @@ var require_fsevents_handler = __commonJS((exports, module) => {
|
|
|
4242
4242
|
constructor(fsw) {
|
|
4243
4243
|
this.fsw = fsw;
|
|
4244
4244
|
}
|
|
4245
|
-
checkIgnored(
|
|
4245
|
+
checkIgnored(path7, stats) {
|
|
4246
4246
|
const ipaths = this.fsw._ignoredPaths;
|
|
4247
|
-
if (this.fsw._isIgnored(
|
|
4248
|
-
ipaths.add(
|
|
4247
|
+
if (this.fsw._isIgnored(path7, stats)) {
|
|
4248
|
+
ipaths.add(path7);
|
|
4249
4249
|
if (stats && stats.isDirectory()) {
|
|
4250
|
-
ipaths.add(
|
|
4250
|
+
ipaths.add(path7 + ROOT_GLOBSTAR);
|
|
4251
4251
|
}
|
|
4252
4252
|
return true;
|
|
4253
4253
|
}
|
|
4254
|
-
ipaths.delete(
|
|
4255
|
-
ipaths.delete(
|
|
4254
|
+
ipaths.delete(path7);
|
|
4255
|
+
ipaths.delete(path7 + ROOT_GLOBSTAR);
|
|
4256
4256
|
}
|
|
4257
|
-
addOrChange(
|
|
4257
|
+
addOrChange(path7, fullPath, realPath, parent, watchedDir, item, info, opts) {
|
|
4258
4258
|
const event = watchedDir.has(item) ? EV_CHANGE : EV_ADD;
|
|
4259
|
-
this.handleEvent(event,
|
|
4259
|
+
this.handleEvent(event, path7, fullPath, realPath, parent, watchedDir, item, info, opts);
|
|
4260
4260
|
}
|
|
4261
|
-
async checkExists(
|
|
4261
|
+
async checkExists(path7, fullPath, realPath, parent, watchedDir, item, info, opts) {
|
|
4262
4262
|
try {
|
|
4263
|
-
const stats = await stat(
|
|
4263
|
+
const stats = await stat(path7);
|
|
4264
4264
|
if (this.fsw.closed)
|
|
4265
4265
|
return;
|
|
4266
4266
|
if (sameTypes(info, stats)) {
|
|
4267
|
-
this.addOrChange(
|
|
4267
|
+
this.addOrChange(path7, fullPath, realPath, parent, watchedDir, item, info, opts);
|
|
4268
4268
|
} else {
|
|
4269
|
-
this.handleEvent(EV_UNLINK,
|
|
4269
|
+
this.handleEvent(EV_UNLINK, path7, fullPath, realPath, parent, watchedDir, item, info, opts);
|
|
4270
4270
|
}
|
|
4271
4271
|
} catch (error61) {
|
|
4272
4272
|
if (error61.code === "EACCES") {
|
|
4273
|
-
this.addOrChange(
|
|
4273
|
+
this.addOrChange(path7, fullPath, realPath, parent, watchedDir, item, info, opts);
|
|
4274
4274
|
} else {
|
|
4275
|
-
this.handleEvent(EV_UNLINK,
|
|
4275
|
+
this.handleEvent(EV_UNLINK, path7, fullPath, realPath, parent, watchedDir, item, info, opts);
|
|
4276
4276
|
}
|
|
4277
4277
|
}
|
|
4278
4278
|
}
|
|
4279
|
-
handleEvent(event,
|
|
4280
|
-
if (this.fsw.closed || this.checkIgnored(
|
|
4279
|
+
handleEvent(event, path7, fullPath, realPath, parent, watchedDir, item, info, opts) {
|
|
4280
|
+
if (this.fsw.closed || this.checkIgnored(path7))
|
|
4281
4281
|
return;
|
|
4282
4282
|
if (event === EV_UNLINK) {
|
|
4283
4283
|
const isDirectory = info.type === FSEVENT_TYPE_DIRECTORY;
|
|
@@ -4287,17 +4287,17 @@ var require_fsevents_handler = __commonJS((exports, module) => {
|
|
|
4287
4287
|
} else {
|
|
4288
4288
|
if (event === EV_ADD) {
|
|
4289
4289
|
if (info.type === FSEVENT_TYPE_DIRECTORY)
|
|
4290
|
-
this.fsw._getWatchedDir(
|
|
4290
|
+
this.fsw._getWatchedDir(path7);
|
|
4291
4291
|
if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) {
|
|
4292
4292
|
const curDepth = opts.depth === undefined ? undefined : calcDepth(fullPath, realPath) + 1;
|
|
4293
|
-
return this._addToFsEvents(
|
|
4293
|
+
return this._addToFsEvents(path7, false, true, curDepth);
|
|
4294
4294
|
}
|
|
4295
4295
|
this.fsw._getWatchedDir(parent).add(item);
|
|
4296
4296
|
}
|
|
4297
4297
|
const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event;
|
|
4298
|
-
this.fsw._emit(eventName,
|
|
4298
|
+
this.fsw._emit(eventName, path7);
|
|
4299
4299
|
if (eventName === EV_ADD_DIR)
|
|
4300
|
-
this._addToFsEvents(
|
|
4300
|
+
this._addToFsEvents(path7, false, true);
|
|
4301
4301
|
}
|
|
4302
4302
|
}
|
|
4303
4303
|
_watchWithFsEvents(watchPath, realPath, transform2, globFilter) {
|
|
@@ -4309,38 +4309,38 @@ var require_fsevents_handler = __commonJS((exports, module) => {
|
|
|
4309
4309
|
return;
|
|
4310
4310
|
if (opts.depth !== undefined && calcDepth(fullPath, realPath) > opts.depth)
|
|
4311
4311
|
return;
|
|
4312
|
-
const
|
|
4313
|
-
if (globFilter && !globFilter(
|
|
4312
|
+
const path7 = transform2(sysPath.join(watchPath, sysPath.relative(watchPath, fullPath)));
|
|
4313
|
+
if (globFilter && !globFilter(path7))
|
|
4314
4314
|
return;
|
|
4315
|
-
const parent = sysPath.dirname(
|
|
4316
|
-
const item = sysPath.basename(
|
|
4317
|
-
const watchedDir = this.fsw._getWatchedDir(info.type === FSEVENT_TYPE_DIRECTORY ?
|
|
4315
|
+
const parent = sysPath.dirname(path7);
|
|
4316
|
+
const item = sysPath.basename(path7);
|
|
4317
|
+
const watchedDir = this.fsw._getWatchedDir(info.type === FSEVENT_TYPE_DIRECTORY ? path7 : parent);
|
|
4318
4318
|
if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) {
|
|
4319
4319
|
if (typeof opts.ignored === FUNCTION_TYPE) {
|
|
4320
4320
|
let stats;
|
|
4321
4321
|
try {
|
|
4322
|
-
stats = await stat(
|
|
4322
|
+
stats = await stat(path7);
|
|
4323
4323
|
} catch (error61) {}
|
|
4324
4324
|
if (this.fsw.closed)
|
|
4325
4325
|
return;
|
|
4326
|
-
if (this.checkIgnored(
|
|
4326
|
+
if (this.checkIgnored(path7, stats))
|
|
4327
4327
|
return;
|
|
4328
4328
|
if (sameTypes(info, stats)) {
|
|
4329
|
-
this.addOrChange(
|
|
4329
|
+
this.addOrChange(path7, fullPath, realPath, parent, watchedDir, item, info, opts);
|
|
4330
4330
|
} else {
|
|
4331
|
-
this.handleEvent(EV_UNLINK,
|
|
4331
|
+
this.handleEvent(EV_UNLINK, path7, fullPath, realPath, parent, watchedDir, item, info, opts);
|
|
4332
4332
|
}
|
|
4333
4333
|
} else {
|
|
4334
|
-
this.checkExists(
|
|
4334
|
+
this.checkExists(path7, fullPath, realPath, parent, watchedDir, item, info, opts);
|
|
4335
4335
|
}
|
|
4336
4336
|
} else {
|
|
4337
4337
|
switch (info.event) {
|
|
4338
4338
|
case FSEVENT_CREATED:
|
|
4339
4339
|
case FSEVENT_MODIFIED:
|
|
4340
|
-
return this.addOrChange(
|
|
4340
|
+
return this.addOrChange(path7, fullPath, realPath, parent, watchedDir, item, info, opts);
|
|
4341
4341
|
case FSEVENT_DELETED:
|
|
4342
4342
|
case FSEVENT_MOVED:
|
|
4343
|
-
return this.checkExists(
|
|
4343
|
+
return this.checkExists(path7, fullPath, realPath, parent, watchedDir, item, info, opts);
|
|
4344
4344
|
}
|
|
4345
4345
|
}
|
|
4346
4346
|
};
|
|
@@ -4361,12 +4361,12 @@ var require_fsevents_handler = __commonJS((exports, module) => {
|
|
|
4361
4361
|
return this.fsw._emitReady();
|
|
4362
4362
|
}
|
|
4363
4363
|
this.fsw._incrReadyCount();
|
|
4364
|
-
this._addToFsEvents(linkTarget || linkPath, (
|
|
4364
|
+
this._addToFsEvents(linkTarget || linkPath, (path7) => {
|
|
4365
4365
|
let aliasedPath = linkPath;
|
|
4366
4366
|
if (linkTarget && linkTarget !== DOT_SLASH) {
|
|
4367
|
-
aliasedPath =
|
|
4368
|
-
} else if (
|
|
4369
|
-
aliasedPath = sysPath.join(linkPath,
|
|
4367
|
+
aliasedPath = path7.replace(linkTarget, linkPath);
|
|
4368
|
+
} else if (path7 !== DOT_SLASH) {
|
|
4369
|
+
aliasedPath = sysPath.join(linkPath, path7);
|
|
4370
4370
|
}
|
|
4371
4371
|
return transform2(aliasedPath);
|
|
4372
4372
|
}, false, curDepth);
|
|
@@ -4390,19 +4390,19 @@ var require_fsevents_handler = __commonJS((exports, module) => {
|
|
|
4390
4390
|
this.fsw._emit(isDir ? EV_ADD_DIR : EV_ADD, pp, stats);
|
|
4391
4391
|
}
|
|
4392
4392
|
}
|
|
4393
|
-
initWatch(realPath,
|
|
4393
|
+
initWatch(realPath, path7, wh, processPath) {
|
|
4394
4394
|
if (this.fsw.closed)
|
|
4395
4395
|
return;
|
|
4396
4396
|
const closer = this._watchWithFsEvents(wh.watchPath, sysPath.resolve(realPath || wh.watchPath), processPath, wh.globFilter);
|
|
4397
|
-
this.fsw._addPathCloser(
|
|
4397
|
+
this.fsw._addPathCloser(path7, closer);
|
|
4398
4398
|
}
|
|
4399
|
-
async _addToFsEvents(
|
|
4399
|
+
async _addToFsEvents(path7, transform2, forceAdd, priorDepth) {
|
|
4400
4400
|
if (this.fsw.closed) {
|
|
4401
4401
|
return;
|
|
4402
4402
|
}
|
|
4403
4403
|
const opts = this.fsw.options;
|
|
4404
4404
|
const processPath = typeof transform2 === FUNCTION_TYPE ? transform2 : IDENTITY_FN;
|
|
4405
|
-
const wh = this.fsw._getWatchHelpers(
|
|
4405
|
+
const wh = this.fsw._getWatchHelpers(path7);
|
|
4406
4406
|
try {
|
|
4407
4407
|
const stats = await statMethods[wh.statMethod](wh.watchPath);
|
|
4408
4408
|
if (this.fsw.closed)
|
|
@@ -4412,7 +4412,7 @@ var require_fsevents_handler = __commonJS((exports, module) => {
|
|
|
4412
4412
|
}
|
|
4413
4413
|
if (stats.isDirectory()) {
|
|
4414
4414
|
if (!wh.globFilter)
|
|
4415
|
-
this.emitAdd(processPath(
|
|
4415
|
+
this.emitAdd(processPath(path7), stats, processPath, opts, forceAdd);
|
|
4416
4416
|
if (priorDepth && priorDepth > opts.depth)
|
|
4417
4417
|
return;
|
|
4418
4418
|
this.fsw._readdirp(wh.watchPath, {
|
|
@@ -4448,13 +4448,13 @@ var require_fsevents_handler = __commonJS((exports, module) => {
|
|
|
4448
4448
|
}
|
|
4449
4449
|
if (opts.persistent && forceAdd !== true) {
|
|
4450
4450
|
if (typeof transform2 === FUNCTION_TYPE) {
|
|
4451
|
-
this.initWatch(undefined,
|
|
4451
|
+
this.initWatch(undefined, path7, wh, processPath);
|
|
4452
4452
|
} else {
|
|
4453
4453
|
let realPath;
|
|
4454
4454
|
try {
|
|
4455
4455
|
realPath = await realpath(wh.watchPath);
|
|
4456
4456
|
} catch (e) {}
|
|
4457
|
-
this.initWatch(realPath,
|
|
4457
|
+
this.initWatch(realPath, path7, wh, processPath);
|
|
4458
4458
|
}
|
|
4459
4459
|
}
|
|
4460
4460
|
}
|
|
@@ -23067,9 +23067,10 @@ var DEFAULTS = {
|
|
|
23067
23067
|
accessToken: "",
|
|
23068
23068
|
hideFromCapture: true,
|
|
23069
23069
|
showTranscript: true,
|
|
23070
|
-
|
|
23070
|
+
monitorPrompt: "",
|
|
23071
|
+
meetingPrompt: ""
|
|
23071
23072
|
};
|
|
23072
|
-
var OBSOLETE_KEYS = ["sessionMode", "hotkeyPreset"];
|
|
23073
|
+
var OBSOLETE_KEYS = ["sessionMode", "hotkeyPreset", "saveTranscript"];
|
|
23073
23074
|
var RawConfigSchema = exports_external.record(exports_external.string(), exports_external.unknown());
|
|
23074
23075
|
var HttpUrlSchema = exports_external.url().refine((value) => {
|
|
23075
23076
|
const protocol = new URL(value).protocol;
|
|
@@ -23153,8 +23154,13 @@ function loadConfig() {
|
|
|
23153
23154
|
if (user["showTranscript"] !== undefined) {
|
|
23154
23155
|
merged.showTranscript = user["showTranscript"] === true;
|
|
23155
23156
|
}
|
|
23156
|
-
|
|
23157
|
-
|
|
23157
|
+
for (const key of ["monitorPrompt", "meetingPrompt"]) {
|
|
23158
|
+
if (user[key] === undefined)
|
|
23159
|
+
continue;
|
|
23160
|
+
const prompt = exports_external.string().safeParse(user[key]);
|
|
23161
|
+
if (!prompt.success)
|
|
23162
|
+
throw new ConfigFileError(`${key} must be a string`);
|
|
23163
|
+
merged[key] = prompt.data.trim();
|
|
23158
23164
|
}
|
|
23159
23165
|
const missing = Object.keys(merged).filter((key) => !(key in persisted));
|
|
23160
23166
|
if (missing.length > 0 || hadObsolete) {
|
|
@@ -23176,9 +23182,9 @@ function getDefaults() {
|
|
|
23176
23182
|
// src/electron/app-runtime.ts
|
|
23177
23183
|
import { app as app3, globalShortcut, shell } from "electron";
|
|
23178
23184
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
23179
|
-
import
|
|
23185
|
+
import fs9 from "node:fs";
|
|
23180
23186
|
import os3 from "node:os";
|
|
23181
|
-
import
|
|
23187
|
+
import path14 from "node:path";
|
|
23182
23188
|
import { performance } from "node:perf_hooks";
|
|
23183
23189
|
|
|
23184
23190
|
// src/backends/blink-cloud-client.ts
|
|
@@ -24780,14 +24786,17 @@ var ky = createInstance();
|
|
|
24780
24786
|
var distribution_default = ky;
|
|
24781
24787
|
|
|
24782
24788
|
// src/core/cloud-protocol.ts
|
|
24789
|
+
var OptionalPrompt = exports_external.preprocess((value) => value === null || value === "" ? undefined : value, exports_external.string().trim().min(1).max(4000).optional());
|
|
24783
24790
|
var MonitorRequestSchema = exports_external.object({
|
|
24784
24791
|
kind: exports_external.literal("monitor"),
|
|
24785
|
-
image: exports_external.instanceof(File)
|
|
24792
|
+
image: exports_external.instanceof(File),
|
|
24793
|
+
prompt: OptionalPrompt
|
|
24786
24794
|
});
|
|
24787
24795
|
var MeetingRequestSchema = exports_external.object({
|
|
24788
24796
|
kind: exports_external.literal("meeting"),
|
|
24789
24797
|
text: exports_external.preprocess((value) => value === null ? undefined : value, exports_external.string().trim().min(1).optional()),
|
|
24790
|
-
images: exports_external.array(exports_external.instanceof(File)).readonly()
|
|
24798
|
+
images: exports_external.array(exports_external.instanceof(File)).readonly(),
|
|
24799
|
+
prompt: OptionalPrompt
|
|
24791
24800
|
});
|
|
24792
24801
|
var CloudAnswerRequestSchema = exports_external.discriminatedUnion("kind", [MonitorRequestSchema, MeetingRequestSchema]).superRefine((request, context) => {
|
|
24793
24802
|
if (request.kind === "meeting" && request.text === undefined && request.images.length === 0) {
|
|
@@ -24876,8 +24885,10 @@ class BlinkCloudResponseError extends Error {
|
|
|
24876
24885
|
|
|
24877
24886
|
class BlinkCloudClient {
|
|
24878
24887
|
http;
|
|
24888
|
+
prompts;
|
|
24879
24889
|
activeRequest = null;
|
|
24880
24890
|
constructor(options) {
|
|
24891
|
+
this.prompts = options.prompts;
|
|
24881
24892
|
this.http = distribution_default.create({
|
|
24882
24893
|
baseUrl: `${options.apiUrl.replace(/\/+$/, "")}/`,
|
|
24883
24894
|
headers: { Authorization: `Bearer ${options.accessToken}` },
|
|
@@ -24890,6 +24901,8 @@ class BlinkCloudClient {
|
|
|
24890
24901
|
const form = new FormData;
|
|
24891
24902
|
form.set("kind", "monitor");
|
|
24892
24903
|
form.set("image", await imageFile(screenshotPath));
|
|
24904
|
+
if (this.prompts?.monitor)
|
|
24905
|
+
form.set("prompt", this.prompts.monitor);
|
|
24893
24906
|
await this.ask(form, callbacks);
|
|
24894
24907
|
}
|
|
24895
24908
|
async answerMeeting(context, callbacks) {
|
|
@@ -24900,6 +24913,8 @@ class BlinkCloudClient {
|
|
|
24900
24913
|
for (const screenshotPath of context.screenshotPaths) {
|
|
24901
24914
|
form.append("image", await imageFile(screenshotPath));
|
|
24902
24915
|
}
|
|
24916
|
+
if (this.prompts?.meeting)
|
|
24917
|
+
form.set("prompt", this.prompts.meeting);
|
|
24903
24918
|
await this.ask(form, callbacks);
|
|
24904
24919
|
}
|
|
24905
24920
|
async resetMeeting() {
|
|
@@ -25092,6 +25107,44 @@ function appendAnswer(record2) {
|
|
|
25092
25107
|
`;
|
|
25093
25108
|
fs3.appendFileSync(logPath, line, "utf-8");
|
|
25094
25109
|
}
|
|
25110
|
+
function normalizeStoredAnswer(value) {
|
|
25111
|
+
const parsed = StoredAnswerSchema.safeParse(value);
|
|
25112
|
+
if (!parsed.success)
|
|
25113
|
+
return null;
|
|
25114
|
+
const stored = parsed.data;
|
|
25115
|
+
const source = stored.source === "meeting" || stored.source === "transcript" ? "meeting" : "monitor";
|
|
25116
|
+
const screenshotPaths = stored.screenshotPaths ?? (stored.screenshotPath === undefined || stored.screenshotPath.length === 0 ? [] : [stored.screenshotPath]);
|
|
25117
|
+
return {
|
|
25118
|
+
timestamp: stored.timestamp,
|
|
25119
|
+
source,
|
|
25120
|
+
screenshotPaths,
|
|
25121
|
+
answer: stored.answer,
|
|
25122
|
+
durationMs: stored.durationMs
|
|
25123
|
+
};
|
|
25124
|
+
}
|
|
25125
|
+
function readRecent(n) {
|
|
25126
|
+
if (n <= 0)
|
|
25127
|
+
return [];
|
|
25128
|
+
const blinkHome = getBlinkHome2();
|
|
25129
|
+
const logPath = path3.join(blinkHome, "answers.jsonl");
|
|
25130
|
+
if (!fs3.existsSync(logPath)) {
|
|
25131
|
+
return [];
|
|
25132
|
+
}
|
|
25133
|
+
const content = fs3.readFileSync(logPath, "utf-8");
|
|
25134
|
+
const lines = content.split(`
|
|
25135
|
+
`).filter((line) => line.trim().length > 0);
|
|
25136
|
+
const records = [];
|
|
25137
|
+
for (const line of lines) {
|
|
25138
|
+
try {
|
|
25139
|
+
const record2 = normalizeStoredAnswer(JSON.parse(line));
|
|
25140
|
+
if (record2 !== null)
|
|
25141
|
+
records.push(record2);
|
|
25142
|
+
} catch {
|
|
25143
|
+
continue;
|
|
25144
|
+
}
|
|
25145
|
+
}
|
|
25146
|
+
return records.slice(-n);
|
|
25147
|
+
}
|
|
25095
25148
|
|
|
25096
25149
|
// src/core/audio-manager.ts
|
|
25097
25150
|
import { spawn } from "node:child_process";
|
|
@@ -25437,29 +25490,18 @@ async function capture(targetDir, mode) {
|
|
|
25437
25490
|
|
|
25438
25491
|
// src/core/meeting-context.ts
|
|
25439
25492
|
class MeetingContextBuffer {
|
|
25440
|
-
transcript;
|
|
25441
25493
|
screenshotPaths = [];
|
|
25442
|
-
updateTranscript(transcript) {
|
|
25443
|
-
const normalized = transcript.trim();
|
|
25444
|
-
this.transcript = normalized.length === 0 ? undefined : normalized;
|
|
25445
|
-
}
|
|
25446
25494
|
stageScreenshot(screenshotPath) {
|
|
25447
25495
|
if (this.screenshotPaths.includes(screenshotPath))
|
|
25448
25496
|
return false;
|
|
25449
25497
|
this.screenshotPaths.push(screenshotPath);
|
|
25450
25498
|
return true;
|
|
25451
25499
|
}
|
|
25452
|
-
|
|
25453
|
-
return
|
|
25454
|
-
...this.transcript === undefined ? {} : { transcript: this.transcript },
|
|
25455
|
-
screenshotPaths: [...this.screenshotPaths]
|
|
25456
|
-
};
|
|
25500
|
+
staged() {
|
|
25501
|
+
return [...this.screenshotPaths];
|
|
25457
25502
|
}
|
|
25458
25503
|
summary() {
|
|
25459
|
-
return {
|
|
25460
|
-
transcriptAvailable: this.transcript !== undefined,
|
|
25461
|
-
screenshotCount: this.screenshotPaths.length
|
|
25462
|
-
};
|
|
25504
|
+
return { screenshotCount: this.screenshotPaths.length };
|
|
25463
25505
|
}
|
|
25464
25506
|
removeScreenshots(submittedPaths) {
|
|
25465
25507
|
const submitted = new Set(submittedPaths);
|
|
@@ -25472,7 +25514,6 @@ class MeetingContextBuffer {
|
|
|
25472
25514
|
}
|
|
25473
25515
|
clear() {
|
|
25474
25516
|
const screenshotPaths = [...this.screenshotPaths];
|
|
25475
|
-
this.transcript = undefined;
|
|
25476
25517
|
this.screenshotPaths.length = 0;
|
|
25477
25518
|
return screenshotPaths;
|
|
25478
25519
|
}
|
|
@@ -25728,95 +25769,211 @@ async function resolveScreenshotDir(configOverride, home = homedir3()) {
|
|
|
25728
25769
|
return defaultDir;
|
|
25729
25770
|
}
|
|
25730
25771
|
|
|
25731
|
-
// src/core/transcript-
|
|
25732
|
-
|
|
25733
|
-
|
|
25734
|
-
|
|
25735
|
-
|
|
25772
|
+
// src/core/transcript-archive.ts
|
|
25773
|
+
import * as fs4 from "node:fs";
|
|
25774
|
+
import * as path5 from "node:path";
|
|
25775
|
+
var SESSION_FILE = /^(\d{4}-\d{2}-\d{2})-(\d{2})(\d{2})(\d{2})(?:-\d+)?\.md$/;
|
|
25776
|
+
var LEGACY_TITLE = `# Blink transcript
|
|
25736
25777
|
|
|
25737
|
-
|
|
25738
|
-
|
|
25739
|
-
|
|
25740
|
-
|
|
25741
|
-
|
|
25742
|
-
|
|
25743
|
-
|
|
25744
|
-
|
|
25745
|
-
|
|
25778
|
+
`;
|
|
25779
|
+
function withoutLegacyTitle(markdown) {
|
|
25780
|
+
return markdown.startsWith(LEGACY_TITLE) ? markdown.slice(LEGACY_TITLE.length) : markdown;
|
|
25781
|
+
}
|
|
25782
|
+
function parseFileName(file2) {
|
|
25783
|
+
const match = SESSION_FILE.exec(file2);
|
|
25784
|
+
if (match === null)
|
|
25785
|
+
return;
|
|
25786
|
+
const [, day, hours, minutes, seconds] = match;
|
|
25787
|
+
return { day, startedAt: `${hours}:${minutes}:${seconds}` };
|
|
25788
|
+
}
|
|
25789
|
+
function countLines(markdown) {
|
|
25790
|
+
let count = 0;
|
|
25791
|
+
for (const line of markdown.split(`
|
|
25792
|
+
`)) {
|
|
25793
|
+
if (line.startsWith("**"))
|
|
25794
|
+
count += 1;
|
|
25795
|
+
}
|
|
25796
|
+
return count;
|
|
25797
|
+
}
|
|
25798
|
+
function countMatches(markdown, query) {
|
|
25799
|
+
if (query === "")
|
|
25800
|
+
return 0;
|
|
25801
|
+
const haystack = markdown.toLowerCase();
|
|
25802
|
+
let count = 0;
|
|
25803
|
+
let index = haystack.indexOf(query);
|
|
25804
|
+
while (index !== -1) {
|
|
25805
|
+
count += 1;
|
|
25806
|
+
index = haystack.indexOf(query, index + query.length);
|
|
25807
|
+
}
|
|
25808
|
+
return count;
|
|
25809
|
+
}
|
|
25810
|
+
function listTranscriptSessions(directory, query = "") {
|
|
25811
|
+
let entries;
|
|
25812
|
+
try {
|
|
25813
|
+
entries = fs4.readdirSync(directory);
|
|
25814
|
+
} catch {
|
|
25815
|
+
return [];
|
|
25816
|
+
}
|
|
25817
|
+
const needle = query.trim().toLowerCase();
|
|
25818
|
+
const sessions = [];
|
|
25819
|
+
for (const file2 of entries) {
|
|
25820
|
+
const parsed = parseFileName(file2);
|
|
25821
|
+
if (parsed === undefined)
|
|
25822
|
+
continue;
|
|
25823
|
+
let markdown;
|
|
25824
|
+
let byteSize;
|
|
25825
|
+
try {
|
|
25826
|
+
const full = path5.join(directory, file2);
|
|
25827
|
+
byteSize = fs4.statSync(full).size;
|
|
25828
|
+
markdown = withoutLegacyTitle(fs4.readFileSync(full, "utf8"));
|
|
25829
|
+
} catch {
|
|
25830
|
+
continue;
|
|
25746
25831
|
}
|
|
25832
|
+
const matchCount = countMatches(markdown, needle);
|
|
25833
|
+
if (needle !== "" && matchCount === 0)
|
|
25834
|
+
continue;
|
|
25835
|
+
sessions.push({
|
|
25836
|
+
file: file2,
|
|
25837
|
+
day: parsed.day,
|
|
25838
|
+
startedAt: parsed.startedAt,
|
|
25839
|
+
lineCount: countLines(markdown),
|
|
25840
|
+
byteSize,
|
|
25841
|
+
matchCount
|
|
25842
|
+
});
|
|
25843
|
+
}
|
|
25844
|
+
return sessions.sort((left, right) => right.file.localeCompare(left.file));
|
|
25845
|
+
}
|
|
25846
|
+
function readTranscriptSession(directory, file2) {
|
|
25847
|
+
const parsed = parseFileName(file2);
|
|
25848
|
+
if (parsed === undefined)
|
|
25849
|
+
return;
|
|
25850
|
+
try {
|
|
25851
|
+
const full = path5.join(directory, file2);
|
|
25852
|
+
const markdown = withoutLegacyTitle(fs4.readFileSync(full, "utf8"));
|
|
25853
|
+
return {
|
|
25854
|
+
file: file2,
|
|
25855
|
+
day: parsed.day,
|
|
25856
|
+
startedAt: parsed.startedAt,
|
|
25857
|
+
lineCount: countLines(markdown),
|
|
25858
|
+
byteSize: fs4.statSync(full).size,
|
|
25859
|
+
matchCount: 0,
|
|
25860
|
+
markdown
|
|
25861
|
+
};
|
|
25862
|
+
} catch {
|
|
25863
|
+
return;
|
|
25747
25864
|
}
|
|
25865
|
+
}
|
|
25866
|
+
|
|
25867
|
+
// src/core/transcript-history.ts
|
|
25868
|
+
function lineId(speaker, startMs) {
|
|
25869
|
+
return `${speaker}:${startMs}`;
|
|
25870
|
+
}
|
|
25871
|
+
|
|
25872
|
+
class TranscriptHistory {
|
|
25873
|
+
finalized = new Map;
|
|
25874
|
+
volatile = new Map;
|
|
25875
|
+
pending = new Map;
|
|
25748
25876
|
get size() {
|
|
25749
|
-
return this.finalized.
|
|
25877
|
+
return this.finalized.size;
|
|
25878
|
+
}
|
|
25879
|
+
volatileLines() {
|
|
25880
|
+
return [...this.volatile.values()].sort((left, right) => left.startMs - right.startMs);
|
|
25750
25881
|
}
|
|
25751
25882
|
push(segment) {
|
|
25752
|
-
const
|
|
25753
|
-
if (
|
|
25883
|
+
const text = segment.text.trim();
|
|
25884
|
+
if (text.length === 0)
|
|
25885
|
+
return;
|
|
25886
|
+
if (!Number.isFinite(segment.startMs) || segment.startMs < 0)
|
|
25887
|
+
return;
|
|
25888
|
+
const id = lineId(segment.speaker, segment.startMs);
|
|
25889
|
+
const line = {
|
|
25890
|
+
id,
|
|
25891
|
+
speaker: segment.speaker,
|
|
25892
|
+
text,
|
|
25893
|
+
startMs: segment.startMs
|
|
25894
|
+
};
|
|
25895
|
+
if (!segment.isFinal) {
|
|
25896
|
+
this.volatile.set(segment.speaker, line);
|
|
25754
25897
|
return;
|
|
25755
|
-
this.latestEndMs = Math.max(this.latestEndMs, normalized.endMs);
|
|
25756
|
-
if (normalized.isFinal) {
|
|
25757
|
-
this.volatile.delete(normalized.speaker);
|
|
25758
|
-
const existingIndex = this.finalized.findIndex((candidate) => candidate.speaker === normalized.speaker && candidate.startMs === normalized.startMs);
|
|
25759
|
-
if (existingIndex === -1)
|
|
25760
|
-
this.finalized.push(normalized);
|
|
25761
|
-
else
|
|
25762
|
-
this.finalized[existingIndex] = normalized;
|
|
25763
|
-
} else {
|
|
25764
|
-
this.volatile.set(normalized.speaker, normalized);
|
|
25765
25898
|
}
|
|
25766
|
-
this.
|
|
25767
|
-
|
|
25768
|
-
|
|
25769
|
-
|
|
25770
|
-
|
|
25771
|
-
}
|
|
25772
|
-
recentLines(limit, referenceMs = this.latestEndMs) {
|
|
25773
|
-
const segments = this.recentSegments(referenceMs);
|
|
25774
|
-
return segments.slice(Math.max(0, segments.length - limit)).map((segment) => ({ speaker: segment.speaker, text: segment.text }));
|
|
25899
|
+
this.volatile.delete(segment.speaker);
|
|
25900
|
+
if (this.finalized.get(id)?.text === text)
|
|
25901
|
+
return;
|
|
25902
|
+
this.finalized.set(id, line);
|
|
25903
|
+
this.pending.set(id, line);
|
|
25775
25904
|
}
|
|
25776
|
-
|
|
25777
|
-
this.
|
|
25778
|
-
|
|
25779
|
-
return
|
|
25905
|
+
drain() {
|
|
25906
|
+
const changed = [...this.pending.values()].sort((left, right) => left.startMs - right.startMs);
|
|
25907
|
+
this.pending.clear();
|
|
25908
|
+
return { changed, volatile: [...this.volatile.values()] };
|
|
25780
25909
|
}
|
|
25781
|
-
|
|
25782
|
-
|
|
25783
|
-
return;
|
|
25784
|
-
this.latestEndMs = Math.max(this.latestEndMs, referenceMs);
|
|
25785
|
-
this.trim(referenceMs);
|
|
25910
|
+
lines() {
|
|
25911
|
+
return [...this.finalized.values()].sort((left, right) => left.startMs - right.startMs);
|
|
25786
25912
|
}
|
|
25787
25913
|
clear() {
|
|
25788
|
-
this.finalized.
|
|
25914
|
+
this.finalized.clear();
|
|
25789
25915
|
this.volatile.clear();
|
|
25790
|
-
this.
|
|
25916
|
+
this.pending.clear();
|
|
25791
25917
|
}
|
|
25792
|
-
|
|
25793
|
-
|
|
25918
|
+
}
|
|
25919
|
+
|
|
25920
|
+
// src/core/meeting-transcript.ts
|
|
25921
|
+
var speakerLabel = {
|
|
25922
|
+
them: "Them",
|
|
25923
|
+
you: "You"
|
|
25924
|
+
};
|
|
25925
|
+
var EMPTY_CHUNK = "No new speech since the last ask.";
|
|
25926
|
+
function pad2(value) {
|
|
25927
|
+
return String(value).padStart(2, "0");
|
|
25928
|
+
}
|
|
25929
|
+
function offset(startMs) {
|
|
25930
|
+
const total = Math.max(0, Math.floor(startMs / 1000));
|
|
25931
|
+
const hours = Math.floor(total / 3600);
|
|
25932
|
+
const minutes = Math.floor(total % 3600 / 60);
|
|
25933
|
+
const seconds = total % 60;
|
|
25934
|
+
return hours > 0 ? `${hours}:${pad2(minutes)}:${pad2(seconds)}` : `${pad2(minutes)}:${pad2(seconds)}`;
|
|
25935
|
+
}
|
|
25936
|
+
|
|
25937
|
+
class MeetingTranscriptCursor {
|
|
25938
|
+
submitted = new Set;
|
|
25939
|
+
get submittedCount() {
|
|
25940
|
+
return this.submitted.size;
|
|
25941
|
+
}
|
|
25942
|
+
chunk(lines, volatile = []) {
|
|
25943
|
+
const pending = lines.filter((line) => !this.submitted.has(line.id));
|
|
25944
|
+
if (pending.length === 0 && volatile.length === 0) {
|
|
25945
|
+
return { text: EMPTY_CHUNK, lineIds: [], hasNewSpeech: false };
|
|
25946
|
+
}
|
|
25947
|
+
const continues = this.submitted.size > 0;
|
|
25948
|
+
const spoken = [
|
|
25949
|
+
...pending.map((line) => `${speakerLabel[line.speaker]} (${offset(line.startMs)}): ${line.text}`),
|
|
25950
|
+
...volatile.map((line) => `${speakerLabel[line.speaker]} (${offset(line.startMs)}, in progress): ${line.text}`)
|
|
25951
|
+
];
|
|
25952
|
+
const first = pending[0] ?? volatile[0];
|
|
25953
|
+
const last = volatile[volatile.length - 1] ?? pending[pending.length - 1];
|
|
25954
|
+
const span = first === undefined || last === undefined ? "" : ` ${offset(first.startMs)}-${offset(last.startMs)}`;
|
|
25955
|
+
const heading = continues ? `Transcript${span} (new since the last ask)` : `Transcript${span}`;
|
|
25956
|
+
return {
|
|
25957
|
+
text: `${heading}
|
|
25958
|
+
|
|
25959
|
+
${spoken.join(`
|
|
25960
|
+
`)}`,
|
|
25961
|
+
lineIds: pending.map((line) => line.id),
|
|
25962
|
+
hasNewSpeech: true
|
|
25963
|
+
};
|
|
25794
25964
|
}
|
|
25795
|
-
|
|
25796
|
-
|
|
25797
|
-
|
|
25798
|
-
if (this.finalized[index].endMs < cutoff)
|
|
25799
|
-
this.finalized.splice(index, 1);
|
|
25800
|
-
}
|
|
25801
|
-
for (const [speaker, segment] of this.volatile) {
|
|
25802
|
-
if (segment.endMs < cutoff)
|
|
25803
|
-
this.volatile.delete(speaker);
|
|
25804
|
-
}
|
|
25965
|
+
markSubmitted(lineIds) {
|
|
25966
|
+
for (const id of lineIds)
|
|
25967
|
+
this.submitted.add(id);
|
|
25805
25968
|
}
|
|
25806
|
-
|
|
25807
|
-
|
|
25808
|
-
if (text.length === 0)
|
|
25809
|
-
return;
|
|
25810
|
-
if (!Number.isFinite(segment.startMs) || !Number.isFinite(segment.endMs) || segment.startMs < 0 || segment.endMs < segment.startMs) {
|
|
25811
|
-
return;
|
|
25812
|
-
}
|
|
25813
|
-
return { ...segment, text };
|
|
25969
|
+
reset() {
|
|
25970
|
+
this.submitted.clear();
|
|
25814
25971
|
}
|
|
25815
25972
|
}
|
|
25816
25973
|
|
|
25817
25974
|
// src/core/transcript-log.ts
|
|
25818
|
-
import * as
|
|
25819
|
-
import * as
|
|
25975
|
+
import * as fs5 from "node:fs";
|
|
25976
|
+
import * as path6 from "node:path";
|
|
25820
25977
|
var speakerLabel2 = {
|
|
25821
25978
|
them: "Them",
|
|
25822
25979
|
you: "You"
|
|
@@ -25845,49 +26002,47 @@ class TranscriptLog {
|
|
|
25845
26002
|
return;
|
|
25846
26003
|
this.written.add(key);
|
|
25847
26004
|
this.ensureHeader();
|
|
25848
|
-
const line = `**${speakerLabel2[entry.speaker]}** (${
|
|
26005
|
+
const line = `**${speakerLabel2[entry.speaker]}** (${offset2(entry.startMs)}) ${text}
|
|
25849
26006
|
|
|
25850
26007
|
`;
|
|
25851
|
-
|
|
26008
|
+
fs5.appendFileSync(this.filePath, line, "utf8");
|
|
25852
26009
|
}
|
|
25853
26010
|
ensureHeader() {
|
|
25854
26011
|
if (this.headerWritten)
|
|
25855
26012
|
return;
|
|
25856
26013
|
this.headerWritten = true;
|
|
25857
|
-
|
|
25858
|
-
const header =
|
|
25859
|
-
|
|
25860
|
-
Started ${readableStamp(this.startedAt)}
|
|
26014
|
+
fs5.mkdirSync(path6.dirname(this.filePath), { recursive: true });
|
|
26015
|
+
const header = `Started ${readableStamp(this.startedAt)}
|
|
25861
26016
|
|
|
25862
26017
|
`;
|
|
25863
|
-
|
|
26018
|
+
fs5.appendFileSync(this.filePath, header, "utf8");
|
|
25864
26019
|
}
|
|
25865
26020
|
}
|
|
25866
|
-
function
|
|
26021
|
+
function pad3(value, width = 2) {
|
|
25867
26022
|
return String(value).padStart(width, "0");
|
|
25868
26023
|
}
|
|
25869
|
-
function
|
|
26024
|
+
function offset2(startMs) {
|
|
25870
26025
|
const totalSeconds = Math.max(0, Math.floor(startMs / 1000));
|
|
25871
|
-
return `${
|
|
26026
|
+
return `${pad3(Math.floor(totalSeconds / 60))}:${pad3(totalSeconds % 60)}`;
|
|
25872
26027
|
}
|
|
25873
26028
|
function fileStamp(date5) {
|
|
25874
26029
|
return [
|
|
25875
|
-
`${date5.getFullYear()}-${
|
|
25876
|
-
`${
|
|
26030
|
+
`${date5.getFullYear()}-${pad3(date5.getMonth() + 1)}-${pad3(date5.getDate())}`,
|
|
26031
|
+
`${pad3(date5.getHours())}${pad3(date5.getMinutes())}${pad3(date5.getSeconds())}`
|
|
25877
26032
|
].join("-");
|
|
25878
26033
|
}
|
|
25879
26034
|
function readableStamp(date5) {
|
|
25880
|
-
const day = `${date5.getFullYear()}-${
|
|
25881
|
-
const time3 = `${
|
|
26035
|
+
const day = `${date5.getFullYear()}-${pad3(date5.getMonth() + 1)}-${pad3(date5.getDate())}`;
|
|
26036
|
+
const time3 = `${pad3(date5.getHours())}:${pad3(date5.getMinutes())}:${pad3(date5.getSeconds())}`;
|
|
25882
26037
|
return `${day} ${time3}`;
|
|
25883
26038
|
}
|
|
25884
26039
|
function availablePath(directory, stamp) {
|
|
25885
|
-
const candidate =
|
|
25886
|
-
if (!
|
|
26040
|
+
const candidate = path6.join(directory, `${stamp}.md`);
|
|
26041
|
+
if (!fs5.existsSync(candidate))
|
|
25887
26042
|
return candidate;
|
|
25888
26043
|
for (let suffix = 2;; suffix += 1) {
|
|
25889
|
-
const next =
|
|
25890
|
-
if (!
|
|
26044
|
+
const next = path6.join(directory, `${stamp}-${suffix}.md`);
|
|
26045
|
+
if (!fs5.existsSync(next))
|
|
25891
26046
|
return next;
|
|
25892
26047
|
}
|
|
25893
26048
|
}
|
|
@@ -25900,12 +26055,12 @@ var CAPTURE_ACCELERATORS = {
|
|
|
25900
26055
|
|
|
25901
26056
|
// src/core/watcher.ts
|
|
25902
26057
|
import { EventEmitter as EventEmitter3 } from "node:events";
|
|
25903
|
-
import * as
|
|
25904
|
-
import * as
|
|
26058
|
+
import * as fs7 from "node:fs";
|
|
26059
|
+
import * as path7 from "node:path";
|
|
25905
26060
|
|
|
25906
26061
|
// node_modules/chokidar/index.js
|
|
25907
26062
|
var { EventEmitter: EventEmitter2 } = __require("events");
|
|
25908
|
-
var
|
|
26063
|
+
var fs6 = __require("fs");
|
|
25909
26064
|
var sysPath = __require("path");
|
|
25910
26065
|
var { promisify } = __require("util");
|
|
25911
26066
|
var readdirp = require_readdirp();
|
|
@@ -25950,8 +26105,8 @@ var {
|
|
|
25950
26105
|
isMacos,
|
|
25951
26106
|
isIBMi
|
|
25952
26107
|
} = require_constants3();
|
|
25953
|
-
var stat = promisify(
|
|
25954
|
-
var readdir = promisify(
|
|
26108
|
+
var stat = promisify(fs6.stat);
|
|
26109
|
+
var readdir = promisify(fs6.readdir);
|
|
25955
26110
|
var arrify = (value = []) => Array.isArray(value) ? value : [value];
|
|
25956
26111
|
var flatten = (list, result = []) => {
|
|
25957
26112
|
list.forEach((item) => {
|
|
@@ -25984,20 +26139,20 @@ var toUnix = (string4) => {
|
|
|
25984
26139
|
}
|
|
25985
26140
|
return str;
|
|
25986
26141
|
};
|
|
25987
|
-
var normalizePathToUnix = (
|
|
25988
|
-
var normalizeIgnored = (cwd = EMPTY_STR) => (
|
|
25989
|
-
if (typeof
|
|
25990
|
-
return
|
|
25991
|
-
return normalizePathToUnix(sysPath.isAbsolute(
|
|
26142
|
+
var normalizePathToUnix = (path7) => toUnix(sysPath.normalize(toUnix(path7)));
|
|
26143
|
+
var normalizeIgnored = (cwd = EMPTY_STR) => (path7) => {
|
|
26144
|
+
if (typeof path7 !== STRING_TYPE)
|
|
26145
|
+
return path7;
|
|
26146
|
+
return normalizePathToUnix(sysPath.isAbsolute(path7) ? path7 : sysPath.join(cwd, path7));
|
|
25992
26147
|
};
|
|
25993
|
-
var getAbsolutePath = (
|
|
25994
|
-
if (sysPath.isAbsolute(
|
|
25995
|
-
return
|
|
26148
|
+
var getAbsolutePath = (path7, cwd) => {
|
|
26149
|
+
if (sysPath.isAbsolute(path7)) {
|
|
26150
|
+
return path7;
|
|
25996
26151
|
}
|
|
25997
|
-
if (
|
|
25998
|
-
return BANG + sysPath.join(cwd,
|
|
26152
|
+
if (path7.startsWith(BANG)) {
|
|
26153
|
+
return BANG + sysPath.join(cwd, path7.slice(1));
|
|
25999
26154
|
}
|
|
26000
|
-
return sysPath.join(cwd,
|
|
26155
|
+
return sysPath.join(cwd, path7);
|
|
26001
26156
|
};
|
|
26002
26157
|
var undef = (opts, key) => opts[key] === undefined;
|
|
26003
26158
|
|
|
@@ -26054,17 +26209,17 @@ var STAT_METHOD_F = "stat";
|
|
|
26054
26209
|
var STAT_METHOD_L = "lstat";
|
|
26055
26210
|
|
|
26056
26211
|
class WatchHelper {
|
|
26057
|
-
constructor(
|
|
26212
|
+
constructor(path7, watchPath, follow, fsw) {
|
|
26058
26213
|
this.fsw = fsw;
|
|
26059
|
-
this.path =
|
|
26214
|
+
this.path = path7 = path7.replace(REPLACER_RE, EMPTY_STR);
|
|
26060
26215
|
this.watchPath = watchPath;
|
|
26061
26216
|
this.fullWatchPath = sysPath.resolve(watchPath);
|
|
26062
|
-
this.hasGlob = watchPath !==
|
|
26063
|
-
if (
|
|
26217
|
+
this.hasGlob = watchPath !== path7;
|
|
26218
|
+
if (path7 === EMPTY_STR)
|
|
26064
26219
|
this.hasGlob = false;
|
|
26065
26220
|
this.globSymlink = this.hasGlob && follow ? undefined : false;
|
|
26066
|
-
this.globFilter = this.hasGlob ? anymatch(
|
|
26067
|
-
this.dirParts = this.getDirParts(
|
|
26221
|
+
this.globFilter = this.hasGlob ? anymatch(path7, undefined, ANYMATCH_OPTS) : false;
|
|
26222
|
+
this.dirParts = this.getDirParts(path7);
|
|
26068
26223
|
this.dirParts.forEach((parts) => {
|
|
26069
26224
|
if (parts.length > 1)
|
|
26070
26225
|
parts.pop();
|
|
@@ -26092,13 +26247,13 @@ class WatchHelper {
|
|
|
26092
26247
|
const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ? this.globFilter(resolvedPath) : true;
|
|
26093
26248
|
return matchesGlob && this.fsw._isntIgnored(resolvedPath, stats) && this.fsw._hasReadPermissions(stats);
|
|
26094
26249
|
}
|
|
26095
|
-
getDirParts(
|
|
26250
|
+
getDirParts(path7) {
|
|
26096
26251
|
if (!this.hasGlob)
|
|
26097
26252
|
return [];
|
|
26098
26253
|
const parts = [];
|
|
26099
|
-
const expandedPath =
|
|
26100
|
-
expandedPath.forEach((
|
|
26101
|
-
parts.push(sysPath.relative(this.watchPath,
|
|
26254
|
+
const expandedPath = path7.includes(BRACE_START) ? braces.expand(path7) : [path7];
|
|
26255
|
+
expandedPath.forEach((path8) => {
|
|
26256
|
+
parts.push(sysPath.relative(this.watchPath, path8).split(SLASH_OR_BACK_SLASH_RE));
|
|
26102
26257
|
});
|
|
26103
26258
|
return parts;
|
|
26104
26259
|
}
|
|
@@ -26214,21 +26369,21 @@ class FSWatcher extends EventEmitter2 {
|
|
|
26214
26369
|
this.closed = false;
|
|
26215
26370
|
let paths = unifyPaths(paths_);
|
|
26216
26371
|
if (cwd) {
|
|
26217
|
-
paths = paths.map((
|
|
26218
|
-
const absPath = getAbsolutePath(
|
|
26219
|
-
if (disableGlobbing || !isGlob(
|
|
26372
|
+
paths = paths.map((path7) => {
|
|
26373
|
+
const absPath = getAbsolutePath(path7, cwd);
|
|
26374
|
+
if (disableGlobbing || !isGlob(path7)) {
|
|
26220
26375
|
return absPath;
|
|
26221
26376
|
}
|
|
26222
26377
|
return normalizePath(absPath);
|
|
26223
26378
|
});
|
|
26224
26379
|
}
|
|
26225
|
-
paths = paths.filter((
|
|
26226
|
-
if (
|
|
26227
|
-
this._ignoredPaths.add(
|
|
26380
|
+
paths = paths.filter((path7) => {
|
|
26381
|
+
if (path7.startsWith(BANG)) {
|
|
26382
|
+
this._ignoredPaths.add(path7.slice(1));
|
|
26228
26383
|
return false;
|
|
26229
26384
|
}
|
|
26230
|
-
this._ignoredPaths.delete(
|
|
26231
|
-
this._ignoredPaths.delete(
|
|
26385
|
+
this._ignoredPaths.delete(path7);
|
|
26386
|
+
this._ignoredPaths.delete(path7 + SLASH_GLOBSTAR);
|
|
26232
26387
|
this._userIgnored = undefined;
|
|
26233
26388
|
return true;
|
|
26234
26389
|
});
|
|
@@ -26237,13 +26392,13 @@ class FSWatcher extends EventEmitter2 {
|
|
|
26237
26392
|
this._readyCount = paths.length;
|
|
26238
26393
|
if (this.options.persistent)
|
|
26239
26394
|
this._readyCount += paths.length;
|
|
26240
|
-
paths.forEach((
|
|
26395
|
+
paths.forEach((path7) => this._fsEventsHandler._addToFsEvents(path7));
|
|
26241
26396
|
} else {
|
|
26242
26397
|
if (!this._readyCount)
|
|
26243
26398
|
this._readyCount = 0;
|
|
26244
26399
|
this._readyCount += paths.length;
|
|
26245
|
-
Promise.all(paths.map(async (
|
|
26246
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
26400
|
+
Promise.all(paths.map(async (path7) => {
|
|
26401
|
+
const res = await this._nodeFsHandler._addToNodeFs(path7, !_internal, 0, 0, _origAdd);
|
|
26247
26402
|
if (res)
|
|
26248
26403
|
this._emitReady();
|
|
26249
26404
|
return res;
|
|
@@ -26262,16 +26417,16 @@ class FSWatcher extends EventEmitter2 {
|
|
|
26262
26417
|
return this;
|
|
26263
26418
|
const paths = unifyPaths(paths_);
|
|
26264
26419
|
const { cwd } = this.options;
|
|
26265
|
-
paths.forEach((
|
|
26266
|
-
if (!sysPath.isAbsolute(
|
|
26420
|
+
paths.forEach((path7) => {
|
|
26421
|
+
if (!sysPath.isAbsolute(path7) && !this._closers.has(path7)) {
|
|
26267
26422
|
if (cwd)
|
|
26268
|
-
|
|
26269
|
-
|
|
26423
|
+
path7 = sysPath.join(cwd, path7);
|
|
26424
|
+
path7 = sysPath.resolve(path7);
|
|
26270
26425
|
}
|
|
26271
|
-
this._closePath(
|
|
26272
|
-
this._ignoredPaths.add(
|
|
26273
|
-
if (this._watched.has(
|
|
26274
|
-
this._ignoredPaths.add(
|
|
26426
|
+
this._closePath(path7);
|
|
26427
|
+
this._ignoredPaths.add(path7);
|
|
26428
|
+
if (this._watched.has(path7)) {
|
|
26429
|
+
this._ignoredPaths.add(path7 + SLASH_GLOBSTAR);
|
|
26275
26430
|
}
|
|
26276
26431
|
this._userIgnored = undefined;
|
|
26277
26432
|
});
|
|
@@ -26314,15 +26469,15 @@ class FSWatcher extends EventEmitter2 {
|
|
|
26314
26469
|
if (event !== EV_ERROR)
|
|
26315
26470
|
this.emit(EV_ALL, ...args);
|
|
26316
26471
|
}
|
|
26317
|
-
async _emit(event,
|
|
26472
|
+
async _emit(event, path7, val1, val2, val3) {
|
|
26318
26473
|
if (this.closed)
|
|
26319
26474
|
return;
|
|
26320
26475
|
const opts = this.options;
|
|
26321
26476
|
if (isWindows)
|
|
26322
|
-
|
|
26477
|
+
path7 = sysPath.normalize(path7);
|
|
26323
26478
|
if (opts.cwd)
|
|
26324
|
-
|
|
26325
|
-
const args = [event,
|
|
26479
|
+
path7 = sysPath.relative(opts.cwd, path7);
|
|
26480
|
+
const args = [event, path7];
|
|
26326
26481
|
if (val3 !== undefined)
|
|
26327
26482
|
args.push(val1, val2, val3);
|
|
26328
26483
|
else if (val2 !== undefined)
|
|
@@ -26331,25 +26486,25 @@ class FSWatcher extends EventEmitter2 {
|
|
|
26331
26486
|
args.push(val1);
|
|
26332
26487
|
const awf = opts.awaitWriteFinish;
|
|
26333
26488
|
let pw;
|
|
26334
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
26489
|
+
if (awf && (pw = this._pendingWrites.get(path7))) {
|
|
26335
26490
|
pw.lastChange = new Date;
|
|
26336
26491
|
return this;
|
|
26337
26492
|
}
|
|
26338
26493
|
if (opts.atomic) {
|
|
26339
26494
|
if (event === EV_UNLINK) {
|
|
26340
|
-
this._pendingUnlinks.set(
|
|
26495
|
+
this._pendingUnlinks.set(path7, args);
|
|
26341
26496
|
setTimeout(() => {
|
|
26342
|
-
this._pendingUnlinks.forEach((entry,
|
|
26497
|
+
this._pendingUnlinks.forEach((entry, path8) => {
|
|
26343
26498
|
this.emit(...entry);
|
|
26344
26499
|
this.emit(EV_ALL, ...entry);
|
|
26345
|
-
this._pendingUnlinks.delete(
|
|
26500
|
+
this._pendingUnlinks.delete(path8);
|
|
26346
26501
|
});
|
|
26347
26502
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
26348
26503
|
return this;
|
|
26349
26504
|
}
|
|
26350
|
-
if (event === EV_ADD && this._pendingUnlinks.has(
|
|
26505
|
+
if (event === EV_ADD && this._pendingUnlinks.has(path7)) {
|
|
26351
26506
|
event = args[0] = EV_CHANGE;
|
|
26352
|
-
this._pendingUnlinks.delete(
|
|
26507
|
+
this._pendingUnlinks.delete(path7);
|
|
26353
26508
|
}
|
|
26354
26509
|
}
|
|
26355
26510
|
if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) {
|
|
@@ -26367,16 +26522,16 @@ class FSWatcher extends EventEmitter2 {
|
|
|
26367
26522
|
this.emitWithAll(event, args);
|
|
26368
26523
|
}
|
|
26369
26524
|
};
|
|
26370
|
-
this._awaitWriteFinish(
|
|
26525
|
+
this._awaitWriteFinish(path7, awf.stabilityThreshold, event, awfEmit);
|
|
26371
26526
|
return this;
|
|
26372
26527
|
}
|
|
26373
26528
|
if (event === EV_CHANGE) {
|
|
26374
|
-
const isThrottled = !this._throttle(EV_CHANGE,
|
|
26529
|
+
const isThrottled = !this._throttle(EV_CHANGE, path7, 50);
|
|
26375
26530
|
if (isThrottled)
|
|
26376
26531
|
return this;
|
|
26377
26532
|
}
|
|
26378
26533
|
if (opts.alwaysStat && val1 === undefined && (event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE)) {
|
|
26379
|
-
const fullPath = opts.cwd ? sysPath.join(opts.cwd,
|
|
26534
|
+
const fullPath = opts.cwd ? sysPath.join(opts.cwd, path7) : path7;
|
|
26380
26535
|
let stats;
|
|
26381
26536
|
try {
|
|
26382
26537
|
stats = await stat(fullPath);
|
|
@@ -26395,21 +26550,21 @@ class FSWatcher extends EventEmitter2 {
|
|
|
26395
26550
|
}
|
|
26396
26551
|
return error61 || this.closed;
|
|
26397
26552
|
}
|
|
26398
|
-
_throttle(actionType,
|
|
26553
|
+
_throttle(actionType, path7, timeout2) {
|
|
26399
26554
|
if (!this._throttled.has(actionType)) {
|
|
26400
26555
|
this._throttled.set(actionType, new Map);
|
|
26401
26556
|
}
|
|
26402
26557
|
const action = this._throttled.get(actionType);
|
|
26403
|
-
const actionPath = action.get(
|
|
26558
|
+
const actionPath = action.get(path7);
|
|
26404
26559
|
if (actionPath) {
|
|
26405
26560
|
actionPath.count++;
|
|
26406
26561
|
return false;
|
|
26407
26562
|
}
|
|
26408
26563
|
let timeoutObject;
|
|
26409
26564
|
const clear = () => {
|
|
26410
|
-
const item = action.get(
|
|
26565
|
+
const item = action.get(path7);
|
|
26411
26566
|
const count = item ? item.count : 0;
|
|
26412
|
-
action.delete(
|
|
26567
|
+
action.delete(path7);
|
|
26413
26568
|
clearTimeout(timeoutObject);
|
|
26414
26569
|
if (item)
|
|
26415
26570
|
clearTimeout(item.timeoutObject);
|
|
@@ -26417,45 +26572,45 @@ class FSWatcher extends EventEmitter2 {
|
|
|
26417
26572
|
};
|
|
26418
26573
|
timeoutObject = setTimeout(clear, timeout2);
|
|
26419
26574
|
const thr = { timeoutObject, clear, count: 0 };
|
|
26420
|
-
action.set(
|
|
26575
|
+
action.set(path7, thr);
|
|
26421
26576
|
return thr;
|
|
26422
26577
|
}
|
|
26423
26578
|
_incrReadyCount() {
|
|
26424
26579
|
return this._readyCount++;
|
|
26425
26580
|
}
|
|
26426
|
-
_awaitWriteFinish(
|
|
26581
|
+
_awaitWriteFinish(path7, threshold, event, awfEmit) {
|
|
26427
26582
|
let timeoutHandler;
|
|
26428
|
-
let fullPath =
|
|
26429
|
-
if (this.options.cwd && !sysPath.isAbsolute(
|
|
26430
|
-
fullPath = sysPath.join(this.options.cwd,
|
|
26583
|
+
let fullPath = path7;
|
|
26584
|
+
if (this.options.cwd && !sysPath.isAbsolute(path7)) {
|
|
26585
|
+
fullPath = sysPath.join(this.options.cwd, path7);
|
|
26431
26586
|
}
|
|
26432
26587
|
const now = new Date;
|
|
26433
26588
|
const awaitWriteFinish = (prevStat) => {
|
|
26434
|
-
|
|
26435
|
-
if (err || !this._pendingWrites.has(
|
|
26589
|
+
fs6.stat(fullPath, (err, curStat) => {
|
|
26590
|
+
if (err || !this._pendingWrites.has(path7)) {
|
|
26436
26591
|
if (err && err.code !== "ENOENT")
|
|
26437
26592
|
awfEmit(err);
|
|
26438
26593
|
return;
|
|
26439
26594
|
}
|
|
26440
26595
|
const now2 = Number(new Date);
|
|
26441
26596
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
26442
|
-
this._pendingWrites.get(
|
|
26597
|
+
this._pendingWrites.get(path7).lastChange = now2;
|
|
26443
26598
|
}
|
|
26444
|
-
const pw = this._pendingWrites.get(
|
|
26599
|
+
const pw = this._pendingWrites.get(path7);
|
|
26445
26600
|
const df = now2 - pw.lastChange;
|
|
26446
26601
|
if (df >= threshold) {
|
|
26447
|
-
this._pendingWrites.delete(
|
|
26602
|
+
this._pendingWrites.delete(path7);
|
|
26448
26603
|
awfEmit(undefined, curStat);
|
|
26449
26604
|
} else {
|
|
26450
26605
|
timeoutHandler = setTimeout(awaitWriteFinish, this.options.awaitWriteFinish.pollInterval, curStat);
|
|
26451
26606
|
}
|
|
26452
26607
|
});
|
|
26453
26608
|
};
|
|
26454
|
-
if (!this._pendingWrites.has(
|
|
26455
|
-
this._pendingWrites.set(
|
|
26609
|
+
if (!this._pendingWrites.has(path7)) {
|
|
26610
|
+
this._pendingWrites.set(path7, {
|
|
26456
26611
|
lastChange: now,
|
|
26457
26612
|
cancelWait: () => {
|
|
26458
|
-
this._pendingWrites.delete(
|
|
26613
|
+
this._pendingWrites.delete(path7);
|
|
26459
26614
|
clearTimeout(timeoutHandler);
|
|
26460
26615
|
return event;
|
|
26461
26616
|
}
|
|
@@ -26466,26 +26621,26 @@ class FSWatcher extends EventEmitter2 {
|
|
|
26466
26621
|
_getGlobIgnored() {
|
|
26467
26622
|
return [...this._ignoredPaths.values()];
|
|
26468
26623
|
}
|
|
26469
|
-
_isIgnored(
|
|
26470
|
-
if (this.options.atomic && DOT_RE.test(
|
|
26624
|
+
_isIgnored(path7, stats) {
|
|
26625
|
+
if (this.options.atomic && DOT_RE.test(path7))
|
|
26471
26626
|
return true;
|
|
26472
26627
|
if (!this._userIgnored) {
|
|
26473
26628
|
const { cwd } = this.options;
|
|
26474
26629
|
const ign = this.options.ignored;
|
|
26475
26630
|
const ignored = ign && ign.map(normalizeIgnored(cwd));
|
|
26476
|
-
const paths = arrify(ignored).filter((
|
|
26631
|
+
const paths = arrify(ignored).filter((path8) => typeof path8 === STRING_TYPE && !isGlob(path8)).map((path8) => path8 + SLASH_GLOBSTAR);
|
|
26477
26632
|
const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths);
|
|
26478
26633
|
this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS);
|
|
26479
26634
|
}
|
|
26480
|
-
return this._userIgnored([
|
|
26635
|
+
return this._userIgnored([path7, stats]);
|
|
26481
26636
|
}
|
|
26482
|
-
_isntIgnored(
|
|
26483
|
-
return !this._isIgnored(
|
|
26637
|
+
_isntIgnored(path7, stat2) {
|
|
26638
|
+
return !this._isIgnored(path7, stat2);
|
|
26484
26639
|
}
|
|
26485
|
-
_getWatchHelpers(
|
|
26486
|
-
const watchPath = depth || this.options.disableGlobbing || !isGlob(
|
|
26640
|
+
_getWatchHelpers(path7, depth) {
|
|
26641
|
+
const watchPath = depth || this.options.disableGlobbing || !isGlob(path7) ? path7 : globParent(path7);
|
|
26487
26642
|
const follow = this.options.followSymlinks;
|
|
26488
|
-
return new WatchHelper(
|
|
26643
|
+
return new WatchHelper(path7, watchPath, follow, this);
|
|
26489
26644
|
}
|
|
26490
26645
|
_getWatchedDir(directory) {
|
|
26491
26646
|
if (!this._boundRemove)
|
|
@@ -26504,59 +26659,59 @@ class FSWatcher extends EventEmitter2 {
|
|
|
26504
26659
|
return Boolean(4 & it);
|
|
26505
26660
|
}
|
|
26506
26661
|
_remove(directory, item, isDirectory) {
|
|
26507
|
-
const
|
|
26508
|
-
const fullPath = sysPath.resolve(
|
|
26509
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
26510
|
-
if (!this._throttle("remove",
|
|
26662
|
+
const path7 = sysPath.join(directory, item);
|
|
26663
|
+
const fullPath = sysPath.resolve(path7);
|
|
26664
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path7) || this._watched.has(fullPath);
|
|
26665
|
+
if (!this._throttle("remove", path7, 100))
|
|
26511
26666
|
return;
|
|
26512
26667
|
if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) {
|
|
26513
26668
|
this.add(directory, item, true);
|
|
26514
26669
|
}
|
|
26515
|
-
const wp = this._getWatchedDir(
|
|
26670
|
+
const wp = this._getWatchedDir(path7);
|
|
26516
26671
|
const nestedDirectoryChildren = wp.getChildren();
|
|
26517
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
26672
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path7, nested));
|
|
26518
26673
|
const parent = this._getWatchedDir(directory);
|
|
26519
26674
|
const wasTracked = parent.has(item);
|
|
26520
26675
|
parent.remove(item);
|
|
26521
26676
|
if (this._symlinkPaths.has(fullPath)) {
|
|
26522
26677
|
this._symlinkPaths.delete(fullPath);
|
|
26523
26678
|
}
|
|
26524
|
-
let relPath =
|
|
26679
|
+
let relPath = path7;
|
|
26525
26680
|
if (this.options.cwd)
|
|
26526
|
-
relPath = sysPath.relative(this.options.cwd,
|
|
26681
|
+
relPath = sysPath.relative(this.options.cwd, path7);
|
|
26527
26682
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
26528
26683
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
26529
26684
|
if (event === EV_ADD)
|
|
26530
26685
|
return;
|
|
26531
26686
|
}
|
|
26532
|
-
this._watched.delete(
|
|
26687
|
+
this._watched.delete(path7);
|
|
26533
26688
|
this._watched.delete(fullPath);
|
|
26534
26689
|
const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK;
|
|
26535
|
-
if (wasTracked && !this._isIgnored(
|
|
26536
|
-
this._emit(eventName,
|
|
26690
|
+
if (wasTracked && !this._isIgnored(path7))
|
|
26691
|
+
this._emit(eventName, path7);
|
|
26537
26692
|
if (!this.options.useFsEvents) {
|
|
26538
|
-
this._closePath(
|
|
26693
|
+
this._closePath(path7);
|
|
26539
26694
|
}
|
|
26540
26695
|
}
|
|
26541
|
-
_closePath(
|
|
26542
|
-
this._closeFile(
|
|
26543
|
-
const dir = sysPath.dirname(
|
|
26544
|
-
this._getWatchedDir(dir).remove(sysPath.basename(
|
|
26696
|
+
_closePath(path7) {
|
|
26697
|
+
this._closeFile(path7);
|
|
26698
|
+
const dir = sysPath.dirname(path7);
|
|
26699
|
+
this._getWatchedDir(dir).remove(sysPath.basename(path7));
|
|
26545
26700
|
}
|
|
26546
|
-
_closeFile(
|
|
26547
|
-
const closers = this._closers.get(
|
|
26701
|
+
_closeFile(path7) {
|
|
26702
|
+
const closers = this._closers.get(path7);
|
|
26548
26703
|
if (!closers)
|
|
26549
26704
|
return;
|
|
26550
26705
|
closers.forEach((closer) => closer());
|
|
26551
|
-
this._closers.delete(
|
|
26706
|
+
this._closers.delete(path7);
|
|
26552
26707
|
}
|
|
26553
|
-
_addPathCloser(
|
|
26708
|
+
_addPathCloser(path7, closer) {
|
|
26554
26709
|
if (!closer)
|
|
26555
26710
|
return;
|
|
26556
|
-
let list = this._closers.get(
|
|
26711
|
+
let list = this._closers.get(path7);
|
|
26557
26712
|
if (!list) {
|
|
26558
26713
|
list = [];
|
|
26559
|
-
this._closers.set(
|
|
26714
|
+
this._closers.set(path7, list);
|
|
26560
26715
|
}
|
|
26561
26716
|
list.push(closer);
|
|
26562
26717
|
}
|
|
@@ -26633,14 +26788,14 @@ class ScreenshotWatcher extends EventEmitter3 {
|
|
|
26633
26788
|
return () => this.off("screenshot", listener);
|
|
26634
26789
|
}
|
|
26635
26790
|
async handleAdd(filePath) {
|
|
26636
|
-
const base =
|
|
26791
|
+
const base = path7.basename(filePath);
|
|
26637
26792
|
if (base.startsWith("."))
|
|
26638
26793
|
return;
|
|
26639
26794
|
if (!base.toLowerCase().endsWith(".png"))
|
|
26640
26795
|
return;
|
|
26641
26796
|
let stat2;
|
|
26642
26797
|
try {
|
|
26643
|
-
stat2 = await
|
|
26798
|
+
stat2 = await fs7.promises.stat(filePath);
|
|
26644
26799
|
} catch {
|
|
26645
26800
|
return;
|
|
26646
26801
|
}
|
|
@@ -26669,12 +26824,31 @@ class ScreenshotWatcher extends EventEmitter3 {
|
|
|
26669
26824
|
}
|
|
26670
26825
|
|
|
26671
26826
|
// src/electron/app-state.ts
|
|
26827
|
+
var ERROR_VISIBLE_MS = 9000;
|
|
26828
|
+
|
|
26672
26829
|
class AppStateStore {
|
|
26830
|
+
errorVisibleMs;
|
|
26673
26831
|
state;
|
|
26674
26832
|
listeners = new Set;
|
|
26675
|
-
|
|
26833
|
+
errorTimer = null;
|
|
26834
|
+
constructor(initial, errorVisibleMs = ERROR_VISIBLE_MS) {
|
|
26835
|
+
this.errorVisibleMs = errorVisibleMs;
|
|
26676
26836
|
this.state = { ...initial };
|
|
26677
26837
|
}
|
|
26838
|
+
scheduleErrorClear() {
|
|
26839
|
+
if (this.errorTimer !== null)
|
|
26840
|
+
clearTimeout(this.errorTimer);
|
|
26841
|
+
this.errorTimer = null;
|
|
26842
|
+
if (this.state.lastError === undefined || this.errorVisibleMs <= 0)
|
|
26843
|
+
return;
|
|
26844
|
+
const timer = setTimeout(() => {
|
|
26845
|
+
this.errorTimer = null;
|
|
26846
|
+
if (this.state.lastError !== undefined)
|
|
26847
|
+
this.update({ lastError: null });
|
|
26848
|
+
}, this.errorVisibleMs);
|
|
26849
|
+
timer.unref?.();
|
|
26850
|
+
this.errorTimer = timer;
|
|
26851
|
+
}
|
|
26678
26852
|
get() {
|
|
26679
26853
|
return { ...this.state };
|
|
26680
26854
|
}
|
|
@@ -26685,10 +26859,8 @@ class AppStateStore {
|
|
|
26685
26859
|
meeting: this.state.meeting,
|
|
26686
26860
|
meetingStarting: this.state.meetingStarting,
|
|
26687
26861
|
meetingAsking: this.state.meetingAsking,
|
|
26688
|
-
meetingTranscriptAvailable: this.state.meetingTranscriptAvailable,
|
|
26689
26862
|
meetingScreenshotCount: this.state.meetingScreenshotCount,
|
|
26690
26863
|
showTranscript: this.state.showTranscript,
|
|
26691
|
-
saveTranscript: this.state.saveTranscript,
|
|
26692
26864
|
processing: this.state.processing,
|
|
26693
26865
|
queued: this.state.queued,
|
|
26694
26866
|
inFlight: this.state.inFlight,
|
|
@@ -26706,9 +26878,6 @@ class AppStateStore {
|
|
|
26706
26878
|
if (patch.meetingAsking !== undefined) {
|
|
26707
26879
|
next.meetingAsking = patch.meetingAsking;
|
|
26708
26880
|
}
|
|
26709
|
-
if (patch.meetingTranscriptAvailable !== undefined) {
|
|
26710
|
-
next.meetingTranscriptAvailable = patch.meetingTranscriptAvailable;
|
|
26711
|
-
}
|
|
26712
26881
|
if (patch.meetingScreenshotCount !== undefined) {
|
|
26713
26882
|
next.meetingScreenshotCount = patch.meetingScreenshotCount;
|
|
26714
26883
|
}
|
|
@@ -26720,8 +26889,11 @@ class AppStateStore {
|
|
|
26720
26889
|
if (patch.showTranscript !== undefined) {
|
|
26721
26890
|
next.showTranscript = patch.showTranscript;
|
|
26722
26891
|
}
|
|
26723
|
-
if (patch.
|
|
26724
|
-
|
|
26892
|
+
if (patch.meetingStartedAt !== undefined) {
|
|
26893
|
+
if (patch.meetingStartedAt === null)
|
|
26894
|
+
delete next.meetingStartedAt;
|
|
26895
|
+
else
|
|
26896
|
+
next.meetingStartedAt = patch.meetingStartedAt;
|
|
26725
26897
|
}
|
|
26726
26898
|
if (patch.processing !== undefined)
|
|
26727
26899
|
next.processing = patch.processing;
|
|
@@ -26744,7 +26916,10 @@ class AppStateStore {
|
|
|
26744
26916
|
else
|
|
26745
26917
|
next.usage = patch.usage;
|
|
26746
26918
|
}
|
|
26919
|
+
const errorChanged = this.state.lastError !== next.lastError;
|
|
26747
26920
|
this.state = next;
|
|
26921
|
+
if (errorChanged)
|
|
26922
|
+
this.scheduleErrorClear();
|
|
26748
26923
|
const snapshot = this.get();
|
|
26749
26924
|
for (const l of this.listeners)
|
|
26750
26925
|
l(snapshot);
|
|
@@ -26758,12 +26933,12 @@ class AppStateStore {
|
|
|
26758
26933
|
}
|
|
26759
26934
|
|
|
26760
26935
|
// src/electron/meeting-listener.ts
|
|
26761
|
-
import
|
|
26936
|
+
import path8 from "node:path";
|
|
26762
26937
|
function resolveAppBundlePath(appPath) {
|
|
26763
|
-
return
|
|
26938
|
+
return path8.join(appPath, "vendor", "Blink.app");
|
|
26764
26939
|
}
|
|
26765
26940
|
function resolveAudioHelperPath(appPath) {
|
|
26766
|
-
return
|
|
26941
|
+
return path8.join(resolveAppBundlePath(appPath), "Contents", "Helpers", "BlinkAudio");
|
|
26767
26942
|
}
|
|
26768
26943
|
|
|
26769
26944
|
// src/electron/popup.ts
|
|
@@ -26773,7 +26948,7 @@ import {
|
|
|
26773
26948
|
ipcMain,
|
|
26774
26949
|
app
|
|
26775
26950
|
} from "electron";
|
|
26776
|
-
import
|
|
26951
|
+
import path9 from "node:path";
|
|
26777
26952
|
import { pathToFileURL } from "node:url";
|
|
26778
26953
|
|
|
26779
26954
|
// src/electron/ipc.ts
|
|
@@ -26802,17 +26977,28 @@ var CHANNEL_PRESENTER_DISMISS = "blink:presenter-dismiss";
|
|
|
26802
26977
|
var CHANNEL_PRESENTER_SET_PRIVACY = "blink:presenter-set-privacy";
|
|
26803
26978
|
var CHANNEL_PRESENTER_PRIVACY_CHANGED = "blink:presenter-privacy-changed";
|
|
26804
26979
|
var CHANNEL_PRESENTER_SCROLL = "blink:presenter-scroll";
|
|
26980
|
+
var CHANNEL_SETTINGS_LOAD_PROMPTS = "blink:settings-load-prompts";
|
|
26981
|
+
var CHANNEL_SETTINGS_SAVE_PROMPTS = "blink:settings-save-prompts";
|
|
26982
|
+
var CHANNEL_SETTINGS_LOAD_ANSWERS = "blink:settings-load-answers";
|
|
26983
|
+
var CHANNEL_SETTINGS_DISMISS = "blink:settings-dismiss";
|
|
26984
|
+
var CHANNEL_SETTINGS_LOAD_TRANSCRIPTS = "blink:settings-load-transcripts";
|
|
26985
|
+
var CHANNEL_SETTINGS_READ_TRANSCRIPT = "blink:settings-read-transcript";
|
|
26986
|
+
var CHANNEL_SETTINGS_SHOW_TAB = "blink:settings-show-tab";
|
|
26805
26987
|
|
|
26806
26988
|
// src/electron/popup.ts
|
|
26807
|
-
var POPUP_WIDTH =
|
|
26808
|
-
var POPUP_HEIGHT =
|
|
26809
|
-
var POPUP_EDGE_MARGIN =
|
|
26989
|
+
var POPUP_WIDTH = 520;
|
|
26990
|
+
var POPUP_HEIGHT = 520;
|
|
26991
|
+
var POPUP_EDGE_MARGIN = 0;
|
|
26810
26992
|
var POPUP_MOVE_STEP = 36;
|
|
26993
|
+
var TRANSCRIPT_COLUMN_WIDTH = 400;
|
|
26994
|
+
var POPUP_MIN_WIDTH = 360;
|
|
26995
|
+
var SPLIT_MIN_WIDTH = 480;
|
|
26996
|
+
var TRANSCRIPT_COLUMN_EXTRA_HEIGHT = 140;
|
|
26811
26997
|
function resolvePreloadPath() {
|
|
26812
|
-
return
|
|
26998
|
+
return path9.join(app.getAppPath(), "dist", "electron", "preload.cjs");
|
|
26813
26999
|
}
|
|
26814
27000
|
function resolveRendererIndexUrl() {
|
|
26815
|
-
const p =
|
|
27001
|
+
const p = path9.join(app.getAppPath(), "dist", "electron", "renderer", "popup.html");
|
|
26816
27002
|
return pathToFileURL(p).toString();
|
|
26817
27003
|
}
|
|
26818
27004
|
|
|
@@ -26823,6 +27009,7 @@ class PopupController {
|
|
|
26823
27009
|
ipcInstalled = false;
|
|
26824
27010
|
rendererReady = false;
|
|
26825
27011
|
shuttingDown = false;
|
|
27012
|
+
transcriptColumn = false;
|
|
26826
27013
|
dismissListener = () => {
|
|
26827
27014
|
this.hide();
|
|
26828
27015
|
};
|
|
@@ -26874,12 +27061,14 @@ class PopupController {
|
|
|
26874
27061
|
return this.window;
|
|
26875
27062
|
}
|
|
26876
27063
|
const workArea = screen.getPrimaryDisplay().workArea;
|
|
26877
|
-
const
|
|
27064
|
+
const width = POPUP_WIDTH + (this.transcriptColumn ? TRANSCRIPT_COLUMN_WIDTH : 0);
|
|
27065
|
+
const height = Math.min(workArea.height, POPUP_HEIGHT + (this.transcriptColumn ? TRANSCRIPT_COLUMN_EXTRA_HEIGHT : 0));
|
|
27066
|
+
const x = workArea.x + workArea.width - width - POPUP_EDGE_MARGIN;
|
|
26878
27067
|
const y = workArea.y + POPUP_EDGE_MARGIN;
|
|
26879
27068
|
const win = new BrowserWindow({
|
|
26880
|
-
width
|
|
26881
|
-
height
|
|
26882
|
-
minWidth:
|
|
27069
|
+
width,
|
|
27070
|
+
height,
|
|
27071
|
+
minWidth: this.transcriptColumn ? SPLIT_MIN_WIDTH : POPUP_MIN_WIDTH,
|
|
26883
27072
|
x,
|
|
26884
27073
|
y,
|
|
26885
27074
|
frame: false,
|
|
@@ -26922,6 +27111,7 @@ class PopupController {
|
|
|
26922
27111
|
}
|
|
26923
27112
|
}
|
|
26924
27113
|
this.pendingMessages.length = 0;
|
|
27114
|
+
this.options.onRendererReady();
|
|
26925
27115
|
});
|
|
26926
27116
|
win.loadURL(resolveRendererIndexUrl());
|
|
26927
27117
|
this.window = win;
|
|
@@ -26954,11 +27144,35 @@ class PopupController {
|
|
|
26954
27144
|
}
|
|
26955
27145
|
this.window.webContents.send(CHANNEL_POPUP_USAGE_CHANGED, payload);
|
|
26956
27146
|
}
|
|
27147
|
+
setTranscriptColumn(visible) {
|
|
27148
|
+
if (this.transcriptColumn === visible)
|
|
27149
|
+
return;
|
|
27150
|
+
this.transcriptColumn = visible;
|
|
27151
|
+
const win = this.window;
|
|
27152
|
+
if (win === null || win.isDestroyed())
|
|
27153
|
+
return;
|
|
27154
|
+
const bounds = win.getBounds();
|
|
27155
|
+
const delta = visible ? TRANSCRIPT_COLUMN_WIDTH : -TRANSCRIPT_COLUMN_WIDTH;
|
|
27156
|
+
const heightDelta = visible ? TRANSCRIPT_COLUMN_EXTRA_HEIGHT : -TRANSCRIPT_COLUMN_EXTRA_HEIGHT;
|
|
27157
|
+
const workArea = screen.getDisplayMatching(bounds).workArea;
|
|
27158
|
+
const minimum = visible ? SPLIT_MIN_WIDTH : POPUP_MIN_WIDTH;
|
|
27159
|
+
win.setMinimumSize(minimum, 240);
|
|
27160
|
+
const height = Math.max(240, Math.min(workArea.height, bounds.height + heightDelta));
|
|
27161
|
+
const y = Math.max(workArea.y, Math.min(bounds.y, workArea.y + workArea.height - height));
|
|
27162
|
+
win.setBounds({
|
|
27163
|
+
width: Math.max(minimum, bounds.width + delta),
|
|
27164
|
+
height,
|
|
27165
|
+
x: Math.max(workArea.x, bounds.x - delta),
|
|
27166
|
+
y
|
|
27167
|
+
});
|
|
27168
|
+
}
|
|
27169
|
+
get rendererLoaded() {
|
|
27170
|
+
return this.window !== null && !this.window.isDestroyed() && this.rendererReady;
|
|
27171
|
+
}
|
|
26957
27172
|
sendTranscript(payload) {
|
|
26958
|
-
if (
|
|
27173
|
+
if (!this.rendererLoaded)
|
|
26959
27174
|
return;
|
|
26960
|
-
|
|
26961
|
-
this.window.webContents.send(CHANNEL_TRANSCRIPT_UPDATE, payload);
|
|
27175
|
+
this.window?.webContents.send(CHANNEL_TRANSCRIPT_UPDATE, payload);
|
|
26962
27176
|
}
|
|
26963
27177
|
show() {
|
|
26964
27178
|
const win = this.ensureWindow();
|
|
@@ -27050,12 +27264,12 @@ import {
|
|
|
27050
27264
|
ipcMain as ipcMain2,
|
|
27051
27265
|
screen as screen2
|
|
27052
27266
|
} from "electron";
|
|
27053
|
-
import * as
|
|
27267
|
+
import * as path11 from "node:path";
|
|
27054
27268
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
27055
27269
|
|
|
27056
27270
|
// src/core/presenter-notes.ts
|
|
27057
|
-
import * as
|
|
27058
|
-
import * as
|
|
27271
|
+
import * as fs8 from "node:fs";
|
|
27272
|
+
import * as path10 from "node:path";
|
|
27059
27273
|
var MAX_PRESENTER_NOTES_BYTES = 512 * 1024;
|
|
27060
27274
|
function assertWithinSizeLimit(size) {
|
|
27061
27275
|
if (size > MAX_PRESENTER_NOTES_BYTES) {
|
|
@@ -27064,7 +27278,7 @@ function assertWithinSizeLimit(size) {
|
|
|
27064
27278
|
}
|
|
27065
27279
|
function loadPresenterNotes(filePath) {
|
|
27066
27280
|
try {
|
|
27067
|
-
const contents =
|
|
27281
|
+
const contents = fs8.readFileSync(filePath);
|
|
27068
27282
|
assertWithinSizeLimit(contents.byteLength);
|
|
27069
27283
|
return contents.toString("utf8");
|
|
27070
27284
|
} catch (error61) {
|
|
@@ -27077,16 +27291,16 @@ function loadPresenterNotes(filePath) {
|
|
|
27077
27291
|
function savePresenterNotes(filePath, markdown) {
|
|
27078
27292
|
const size = Buffer.byteLength(markdown, "utf8");
|
|
27079
27293
|
assertWithinSizeLimit(size);
|
|
27080
|
-
|
|
27294
|
+
fs8.mkdirSync(path10.dirname(filePath), { recursive: true });
|
|
27081
27295
|
const temporaryPath = `${filePath}.${process.pid}.tmp`;
|
|
27082
27296
|
try {
|
|
27083
|
-
|
|
27297
|
+
fs8.writeFileSync(temporaryPath, markdown, {
|
|
27084
27298
|
encoding: "utf8",
|
|
27085
27299
|
mode: 384
|
|
27086
27300
|
});
|
|
27087
|
-
|
|
27301
|
+
fs8.renameSync(temporaryPath, filePath);
|
|
27088
27302
|
} catch (error61) {
|
|
27089
|
-
|
|
27303
|
+
fs8.rmSync(temporaryPath, { force: true });
|
|
27090
27304
|
throw error61;
|
|
27091
27305
|
}
|
|
27092
27306
|
}
|
|
@@ -27096,10 +27310,10 @@ var WINDOW_WIDTH = 760;
|
|
|
27096
27310
|
var WINDOW_HEIGHT = 560;
|
|
27097
27311
|
var WINDOW_MARGIN = 24;
|
|
27098
27312
|
function preloadPath() {
|
|
27099
|
-
return
|
|
27313
|
+
return path11.join(app2.getAppPath(), "dist", "electron", "preload.cjs");
|
|
27100
27314
|
}
|
|
27101
27315
|
function rendererUrl() {
|
|
27102
|
-
return pathToFileURL2(
|
|
27316
|
+
return pathToFileURL2(path11.join(app2.getAppPath(), "dist", "electron", "renderer", "presenter.html")).toString();
|
|
27103
27317
|
}
|
|
27104
27318
|
|
|
27105
27319
|
class PresenterNotesController {
|
|
@@ -27238,9 +27452,94 @@ class PresenterNotesController {
|
|
|
27238
27452
|
}
|
|
27239
27453
|
}
|
|
27240
27454
|
|
|
27455
|
+
// src/electron/settings.ts
|
|
27456
|
+
import * as path12 from "node:path";
|
|
27457
|
+
import { fileURLToPath } from "node:url";
|
|
27458
|
+
import { BrowserWindow as BrowserWindow3, ipcMain as ipcMain3, screen as screen3 } from "electron";
|
|
27459
|
+
var WINDOW_WIDTH2 = 760;
|
|
27460
|
+
var WINDOW_HEIGHT2 = 620;
|
|
27461
|
+
function rendererFile(name) {
|
|
27462
|
+
return path12.join(path12.dirname(fileURLToPath(import.meta.url)), "renderer", name);
|
|
27463
|
+
}
|
|
27464
|
+
function preloadPath2() {
|
|
27465
|
+
return path12.join(path12.dirname(fileURLToPath(import.meta.url)), "preload.cjs");
|
|
27466
|
+
}
|
|
27467
|
+
|
|
27468
|
+
class SettingsWindow {
|
|
27469
|
+
callbacks;
|
|
27470
|
+
window = null;
|
|
27471
|
+
handlersBound = false;
|
|
27472
|
+
constructor(callbacks) {
|
|
27473
|
+
this.callbacks = callbacks;
|
|
27474
|
+
}
|
|
27475
|
+
show(tab) {
|
|
27476
|
+
this.bindHandlers();
|
|
27477
|
+
const win = this.ensureWindow();
|
|
27478
|
+
const send = () => win.webContents.send(CHANNEL_SETTINGS_SHOW_TAB, tab);
|
|
27479
|
+
if (win.webContents.isLoading())
|
|
27480
|
+
win.webContents.once("did-finish-load", send);
|
|
27481
|
+
else
|
|
27482
|
+
send();
|
|
27483
|
+
win.show();
|
|
27484
|
+
win.focus();
|
|
27485
|
+
}
|
|
27486
|
+
close() {
|
|
27487
|
+
this.window?.destroy();
|
|
27488
|
+
this.window = null;
|
|
27489
|
+
}
|
|
27490
|
+
bindHandlers() {
|
|
27491
|
+
if (this.handlersBound)
|
|
27492
|
+
return;
|
|
27493
|
+
this.handlersBound = true;
|
|
27494
|
+
ipcMain3.handle(CHANNEL_SETTINGS_LOAD_PROMPTS, () => this.callbacks.loadPrompts());
|
|
27495
|
+
ipcMain3.handle(CHANNEL_SETTINGS_SAVE_PROMPTS, (_event, prompts) => {
|
|
27496
|
+
const value = prompts;
|
|
27497
|
+
this.callbacks.savePrompts({
|
|
27498
|
+
monitorPrompt: typeof value.monitorPrompt === "string" ? value.monitorPrompt : "",
|
|
27499
|
+
meetingPrompt: typeof value.meetingPrompt === "string" ? value.meetingPrompt : ""
|
|
27500
|
+
});
|
|
27501
|
+
});
|
|
27502
|
+
ipcMain3.handle(CHANNEL_SETTINGS_LOAD_ANSWERS, () => this.callbacks.loadAnswers());
|
|
27503
|
+
ipcMain3.handle(CHANNEL_SETTINGS_LOAD_TRANSCRIPTS, (_event, query) => this.callbacks.loadTranscripts(typeof query === "string" ? query : ""));
|
|
27504
|
+
ipcMain3.handle(CHANNEL_SETTINGS_READ_TRANSCRIPT, (_event, file2) => typeof file2 === "string" ? this.callbacks.readTranscript(file2) : "");
|
|
27505
|
+
ipcMain3.on(CHANNEL_SETTINGS_DISMISS, () => this.close());
|
|
27506
|
+
}
|
|
27507
|
+
ensureWindow() {
|
|
27508
|
+
if (this.window?.isDestroyed() === false)
|
|
27509
|
+
return this.window;
|
|
27510
|
+
const workArea = screen3.getPrimaryDisplay().workArea;
|
|
27511
|
+
const width = Math.min(WINDOW_WIDTH2, workArea.width - 80);
|
|
27512
|
+
const height = Math.min(WINDOW_HEIGHT2, workArea.height - 80);
|
|
27513
|
+
const win = new BrowserWindow3({
|
|
27514
|
+
width,
|
|
27515
|
+
height,
|
|
27516
|
+
minWidth: 560,
|
|
27517
|
+
minHeight: 420,
|
|
27518
|
+
x: Math.round(workArea.x + (workArea.width - width) / 2),
|
|
27519
|
+
y: Math.round(workArea.y + (workArea.height - height) / 2),
|
|
27520
|
+
title: "Blink",
|
|
27521
|
+
titleBarStyle: "hiddenInset",
|
|
27522
|
+
backgroundColor: "#ffffff",
|
|
27523
|
+
show: false,
|
|
27524
|
+
webPreferences: {
|
|
27525
|
+
preload: preloadPath2(),
|
|
27526
|
+
contextIsolation: true,
|
|
27527
|
+
nodeIntegration: false,
|
|
27528
|
+
sandbox: true
|
|
27529
|
+
}
|
|
27530
|
+
});
|
|
27531
|
+
win.on("closed", () => {
|
|
27532
|
+
this.window = null;
|
|
27533
|
+
});
|
|
27534
|
+
win.loadFile(rendererFile("settings.html"));
|
|
27535
|
+
this.window = win;
|
|
27536
|
+
return win;
|
|
27537
|
+
}
|
|
27538
|
+
}
|
|
27539
|
+
|
|
27241
27540
|
// src/electron/tray.ts
|
|
27242
27541
|
import { Tray, Menu, nativeImage } from "electron";
|
|
27243
|
-
import * as
|
|
27542
|
+
import * as path13 from "node:path";
|
|
27244
27543
|
var PROCESSING_FRAME_MS = 500;
|
|
27245
27544
|
function iconFile(variant) {
|
|
27246
27545
|
switch (variant) {
|
|
@@ -27302,13 +27601,19 @@ class IconCache {
|
|
|
27302
27601
|
const cached2 = this.cache.get(variant);
|
|
27303
27602
|
if (cached2 !== undefined)
|
|
27304
27603
|
return cached2;
|
|
27305
|
-
const filepath =
|
|
27604
|
+
const filepath = path13.join(this.assetsDir, iconFile(variant));
|
|
27306
27605
|
const img = nativeImage.createFromPath(filepath);
|
|
27307
27606
|
img.setTemplateImage(true);
|
|
27308
27607
|
this.cache.set(variant, img);
|
|
27309
27608
|
return img;
|
|
27310
27609
|
}
|
|
27311
27610
|
}
|
|
27611
|
+
function meetingElapsed(state) {
|
|
27612
|
+
if (state.meetingStartedAt === undefined)
|
|
27613
|
+
return "";
|
|
27614
|
+
const minutes = Math.floor((Date.now() - state.meetingStartedAt) / 60000);
|
|
27615
|
+
return minutes < 1 ? "" : ` (${minutes} min)`;
|
|
27616
|
+
}
|
|
27312
27617
|
function buildTray(opts) {
|
|
27313
27618
|
const icons = new IconCache(opts.assetsDir);
|
|
27314
27619
|
const tray = new Tray(icons.get("idle"));
|
|
@@ -27350,7 +27655,7 @@ function buildTray(opts) {
|
|
|
27350
27655
|
}
|
|
27351
27656
|
},
|
|
27352
27657
|
{
|
|
27353
|
-
label:
|
|
27658
|
+
label: state.meetingStarting ? "Meeting: STARTING…" : state.meeting ? `Leave Meeting${meetingElapsed(state)}` : "Meeting: OFF",
|
|
27354
27659
|
type: "checkbox",
|
|
27355
27660
|
checked: state.meeting || state.meetingStarting,
|
|
27356
27661
|
enabled: !state.meetingStarting,
|
|
@@ -27358,13 +27663,6 @@ function buildTray(opts) {
|
|
|
27358
27663
|
runAction(opts.callbacks.onToggleMeeting);
|
|
27359
27664
|
}
|
|
27360
27665
|
},
|
|
27361
|
-
{
|
|
27362
|
-
label: state.meetingAsking ? "Asking Meeting…" : "Ask Meeting",
|
|
27363
|
-
enabled: state.meeting && !state.meetingAsking && (state.meetingTranscriptAvailable || state.meetingScreenshotCount > 0),
|
|
27364
|
-
click: () => {
|
|
27365
|
-
runAction(opts.callbacks.onAskMeeting);
|
|
27366
|
-
}
|
|
27367
|
-
},
|
|
27368
27666
|
{
|
|
27369
27667
|
label: `Privacy mode: ${state.hideFromCapture ? "ON" : "OFF"}`,
|
|
27370
27668
|
type: "checkbox",
|
|
@@ -27373,14 +27671,6 @@ function buildTray(opts) {
|
|
|
27373
27671
|
runAction(opts.callbacks.onToggleHideFromCapture);
|
|
27374
27672
|
}
|
|
27375
27673
|
},
|
|
27376
|
-
{
|
|
27377
|
-
label: `Save transcript: ${state.saveTranscript ? "ON" : "OFF"}`,
|
|
27378
|
-
type: "checkbox",
|
|
27379
|
-
checked: state.saveTranscript,
|
|
27380
|
-
click: () => {
|
|
27381
|
-
runAction(opts.callbacks.onToggleSaveTranscript);
|
|
27382
|
-
}
|
|
27383
|
-
},
|
|
27384
27674
|
{ type: "separator" },
|
|
27385
27675
|
{
|
|
27386
27676
|
label: "Open Answer Popup",
|
|
@@ -27394,23 +27684,30 @@ function buildTray(opts) {
|
|
|
27394
27684
|
runAction(opts.callbacks.onShowPresenter);
|
|
27395
27685
|
}
|
|
27396
27686
|
},
|
|
27687
|
+
{ type: "separator" },
|
|
27397
27688
|
{
|
|
27398
|
-
label: "
|
|
27689
|
+
label: "Custom Prompts…",
|
|
27399
27690
|
click: () => {
|
|
27400
|
-
runAction(opts.callbacks.
|
|
27691
|
+
runAction(opts.callbacks.onOpenConfig);
|
|
27401
27692
|
}
|
|
27402
27693
|
},
|
|
27403
|
-
{ type: "separator" },
|
|
27404
27694
|
{
|
|
27405
|
-
label: "
|
|
27695
|
+
label: "Answer Log…",
|
|
27406
27696
|
click: () => {
|
|
27407
|
-
runAction(opts.callbacks.
|
|
27697
|
+
runAction(opts.callbacks.onOpenAnswerLog);
|
|
27408
27698
|
}
|
|
27409
27699
|
},
|
|
27410
27700
|
{
|
|
27411
|
-
label: "
|
|
27701
|
+
label: "Meeting Transcripts…",
|
|
27412
27702
|
click: () => {
|
|
27413
|
-
runAction(opts.callbacks.
|
|
27703
|
+
runAction(opts.callbacks.onOpenTranscripts);
|
|
27704
|
+
}
|
|
27705
|
+
},
|
|
27706
|
+
{ type: "separator" },
|
|
27707
|
+
{
|
|
27708
|
+
label: "Reveal Blink.app in Finder",
|
|
27709
|
+
click: () => {
|
|
27710
|
+
runAction(opts.callbacks.onRevealBundle);
|
|
27414
27711
|
}
|
|
27415
27712
|
},
|
|
27416
27713
|
{
|
|
@@ -27459,6 +27756,8 @@ function buildTray(opts) {
|
|
|
27459
27756
|
}
|
|
27460
27757
|
|
|
27461
27758
|
// src/electron/app-runtime.ts
|
|
27759
|
+
var DEFAULT_MONITOR_PROMPT = "Answer the question shown in this screenshot. Be concise and direct. If there are multiple questions, answer each one. If the question is coding-related, include Big O time and space complexity.";
|
|
27760
|
+
var DEFAULT_MEETING_PROMPT = "The transcript and screenshots are meeting context and may not contain an explicit question. Identify the latest question, decision, or task the user needs help with, then answer directly and concisely using all supplied context.";
|
|
27462
27761
|
var PRESENTER_SCROLL_SHORTCUTS = [
|
|
27463
27762
|
["Command+Control+Up", "up"],
|
|
27464
27763
|
["Command+Control+Down", "down"]
|
|
@@ -27472,24 +27771,21 @@ var POPUP_MOVE_SHORTCUTS = [
|
|
|
27472
27771
|
var TRANSCRIPT_ASK_SHORTCUT = "Command+Control+Return";
|
|
27473
27772
|
var TRANSCRIPT_PRUNE_INTERVAL_MS = 1000;
|
|
27474
27773
|
var TRANSCRIPT_FLUSH_INTERVAL_MS = 150;
|
|
27475
|
-
var
|
|
27774
|
+
var MEETING_SESSION_IDLE_MS = 110 * 60000;
|
|
27476
27775
|
function blinkHome() {
|
|
27477
|
-
return process.env["BLINK_HOME"] ??
|
|
27776
|
+
return process.env["BLINK_HOME"] ?? path14.join(os3.homedir(), ".blink");
|
|
27478
27777
|
}
|
|
27479
27778
|
function configPath() {
|
|
27480
|
-
return
|
|
27481
|
-
}
|
|
27482
|
-
function answerLogPath() {
|
|
27483
|
-
return path12.join(blinkHome(), "answers.jsonl");
|
|
27779
|
+
return path14.join(blinkHome(), "config.json");
|
|
27484
27780
|
}
|
|
27485
27781
|
function presenterNotesPath() {
|
|
27486
|
-
return
|
|
27782
|
+
return path14.join(blinkHome(), "presenter.md");
|
|
27487
27783
|
}
|
|
27488
27784
|
function transcriptsDirectory() {
|
|
27489
|
-
return
|
|
27785
|
+
return path14.join(blinkHome(), "transcripts");
|
|
27490
27786
|
}
|
|
27491
27787
|
function meetingCapturesRoot() {
|
|
27492
|
-
return
|
|
27788
|
+
return path14.join(blinkHome(), "meeting-captures");
|
|
27493
27789
|
}
|
|
27494
27790
|
function meetingAnswerTitle(context) {
|
|
27495
27791
|
const screenshots = context.screenshotPaths.length;
|
|
@@ -27521,11 +27817,40 @@ class AppRuntime {
|
|
|
27521
27817
|
tray = null;
|
|
27522
27818
|
popup = null;
|
|
27523
27819
|
presenter = null;
|
|
27820
|
+
lastNotifiedError = undefined;
|
|
27821
|
+
settings = new SettingsWindow({
|
|
27822
|
+
loadPrompts: () => ({
|
|
27823
|
+
monitorPrompt: this.config.monitorPrompt,
|
|
27824
|
+
meetingPrompt: this.config.meetingPrompt,
|
|
27825
|
+
monitorDefault: DEFAULT_MONITOR_PROMPT,
|
|
27826
|
+
meetingDefault: DEFAULT_MEETING_PROMPT
|
|
27827
|
+
}),
|
|
27828
|
+
savePrompts: (prompts) => {
|
|
27829
|
+
this.config = {
|
|
27830
|
+
...this.config,
|
|
27831
|
+
monitorPrompt: prompts.monitorPrompt,
|
|
27832
|
+
meetingPrompt: prompts.meetingPrompt
|
|
27833
|
+
};
|
|
27834
|
+
saveConfig(this.config);
|
|
27835
|
+
this.client = null;
|
|
27836
|
+
},
|
|
27837
|
+
loadAnswers: () => readRecent(500).map((record2) => ({
|
|
27838
|
+
timestamp: record2.timestamp,
|
|
27839
|
+
source: record2.source,
|
|
27840
|
+
answer: record2.answer,
|
|
27841
|
+
durationMs: record2.durationMs
|
|
27842
|
+
})).reverse(),
|
|
27843
|
+
loadTranscripts: (query) => listTranscriptSessions(transcriptsDirectory(), query),
|
|
27844
|
+
readTranscript: (file2) => readTranscriptSession(transcriptsDirectory(), file2)?.markdown ?? ""
|
|
27845
|
+
});
|
|
27524
27846
|
client = null;
|
|
27525
27847
|
orchestrator = null;
|
|
27526
27848
|
orchestratorSetup = null;
|
|
27527
27849
|
audioManager = null;
|
|
27528
|
-
|
|
27850
|
+
transcriptHistory = new TranscriptHistory;
|
|
27851
|
+
transcriptCursor = new MeetingTranscriptCursor;
|
|
27852
|
+
meetingStartedAt = null;
|
|
27853
|
+
lastMeetingAskAt = null;
|
|
27529
27854
|
meetingContext = new MeetingContextBuffer;
|
|
27530
27855
|
transcriptLog = null;
|
|
27531
27856
|
transcriptTimelineOriginMs = null;
|
|
@@ -27533,6 +27858,7 @@ class AppRuntime {
|
|
|
27533
27858
|
transcriptFlushTimer = null;
|
|
27534
27859
|
transcriptSentAtMs = 0;
|
|
27535
27860
|
transcriptSentPayload = "";
|
|
27861
|
+
transcriptResetPending = false;
|
|
27536
27862
|
screenshotDirectory = null;
|
|
27537
27863
|
meetingCaptureDirectory = null;
|
|
27538
27864
|
monitoringToggle = null;
|
|
@@ -27554,10 +27880,8 @@ class AppRuntime {
|
|
|
27554
27880
|
meeting: false,
|
|
27555
27881
|
meetingStarting: false,
|
|
27556
27882
|
meetingAsking: false,
|
|
27557
|
-
meetingTranscriptAvailable: false,
|
|
27558
27883
|
meetingScreenshotCount: 0,
|
|
27559
27884
|
showTranscript: config2.showTranscript,
|
|
27560
|
-
saveTranscript: config2.saveTranscript,
|
|
27561
27885
|
processing: false,
|
|
27562
27886
|
queued: 0,
|
|
27563
27887
|
inFlight: 0,
|
|
@@ -27589,6 +27913,7 @@ class AppRuntime {
|
|
|
27589
27913
|
this.askMeeting();
|
|
27590
27914
|
},
|
|
27591
27915
|
onShowTranscriptChange: (show) => this.setShowTranscript(show),
|
|
27916
|
+
onRendererReady: () => this.resendFullTranscript(),
|
|
27592
27917
|
getHeaderState: () => {
|
|
27593
27918
|
const {
|
|
27594
27919
|
monitoring,
|
|
@@ -27596,10 +27921,10 @@ class AppRuntime {
|
|
|
27596
27921
|
meeting,
|
|
27597
27922
|
meetingStarting,
|
|
27598
27923
|
meetingAsking,
|
|
27599
|
-
meetingTranscriptAvailable,
|
|
27600
27924
|
meetingScreenshotCount,
|
|
27601
27925
|
showTranscript,
|
|
27602
|
-
usage
|
|
27926
|
+
usage,
|
|
27927
|
+
lastError
|
|
27603
27928
|
} = this.store.get();
|
|
27604
27929
|
return {
|
|
27605
27930
|
hideFromCapture: this.config.hideFromCapture,
|
|
@@ -27608,10 +27933,11 @@ class AppRuntime {
|
|
|
27608
27933
|
meeting,
|
|
27609
27934
|
meetingStarting,
|
|
27610
27935
|
asking: meetingAsking,
|
|
27611
|
-
transcriptAvailable: meetingTranscriptAvailable,
|
|
27612
27936
|
screenshotCount: meetingScreenshotCount,
|
|
27613
27937
|
showTranscript,
|
|
27614
|
-
|
|
27938
|
+
...this.meetingStartedAt === null ? {} : { startedAt: this.meetingStartedAt },
|
|
27939
|
+
usage: popupUsage(usage),
|
|
27940
|
+
...lastError === undefined ? {} : { lastError }
|
|
27615
27941
|
};
|
|
27616
27942
|
}
|
|
27617
27943
|
});
|
|
@@ -27622,18 +27948,23 @@ class AppRuntime {
|
|
|
27622
27948
|
meeting,
|
|
27623
27949
|
meetingStarting,
|
|
27624
27950
|
meetingAsking,
|
|
27625
|
-
meetingTranscriptAvailable,
|
|
27626
27951
|
meetingScreenshotCount,
|
|
27627
|
-
showTranscript
|
|
27952
|
+
showTranscript,
|
|
27953
|
+
lastError
|
|
27628
27954
|
}) => {
|
|
27955
|
+
if (lastError !== this.lastNotifiedError) {
|
|
27956
|
+
this.lastNotifiedError = lastError;
|
|
27957
|
+
this.popup?.refreshHeader();
|
|
27958
|
+
}
|
|
27629
27959
|
this.popup?.sendMonitoringChange({ monitoring, monitoringStarting });
|
|
27960
|
+
this.popup?.setTranscriptColumn(meeting && showTranscript);
|
|
27630
27961
|
this.popup?.sendMeetingChange({
|
|
27631
27962
|
meeting,
|
|
27632
27963
|
meetingStarting,
|
|
27633
27964
|
asking: meetingAsking,
|
|
27634
27965
|
showTranscript,
|
|
27635
|
-
|
|
27636
|
-
|
|
27966
|
+
screenshotCount: meetingScreenshotCount,
|
|
27967
|
+
...this.meetingStartedAt === null ? {} : { startedAt: this.meetingStartedAt }
|
|
27637
27968
|
});
|
|
27638
27969
|
});
|
|
27639
27970
|
this.presenter = new PresenterNotesController({
|
|
@@ -27650,18 +27981,17 @@ class AppRuntime {
|
|
|
27650
27981
|
this.presenter.registerIpcHandlers();
|
|
27651
27982
|
this.tray = buildTray({
|
|
27652
27983
|
store: this.store,
|
|
27653
|
-
assetsDir:
|
|
27984
|
+
assetsDir: path14.join(app3.getAppPath(), "assets", "tray"),
|
|
27654
27985
|
callbacks: {
|
|
27655
27986
|
onToggleMonitoring: () => this.toggleMonitoring(),
|
|
27656
27987
|
onToggleMeeting: () => this.toggleMeeting(),
|
|
27657
|
-
onAskMeeting: () => this.askMeeting(),
|
|
27658
27988
|
onShowPopup: () => this.popup?.show(),
|
|
27659
27989
|
onShowPresenter: () => this.showPresenter(),
|
|
27660
27990
|
onToggleHideFromCapture: () => this.toggleHideFromCapture(),
|
|
27661
|
-
onToggleSaveTranscript: () => this.setSaveTranscript(!this.config.saveTranscript),
|
|
27662
27991
|
onRevealBundle: () => this.revealBundle(),
|
|
27663
27992
|
onOpenConfig: () => this.openConfig(),
|
|
27664
27993
|
onOpenAnswerLog: () => this.openAnswerLog(),
|
|
27994
|
+
onOpenTranscripts: () => this.settings.show("transcripts"),
|
|
27665
27995
|
onManageSubscription: () => this.openBillingPortal(),
|
|
27666
27996
|
onQuit: () => app3.quit()
|
|
27667
27997
|
}
|
|
@@ -27678,6 +28008,7 @@ class AppRuntime {
|
|
|
27678
28008
|
toggleMonitoring() {
|
|
27679
28009
|
if (this.monitoringToggle !== null)
|
|
27680
28010
|
return this.monitoringToggle;
|
|
28011
|
+
this.store.update({ lastError: null });
|
|
27681
28012
|
this.monitoringToggle = this.performMonitoringToggle().finally(() => {
|
|
27682
28013
|
this.monitoringToggle = null;
|
|
27683
28014
|
});
|
|
@@ -27686,6 +28017,7 @@ class AppRuntime {
|
|
|
27686
28017
|
toggleMeeting() {
|
|
27687
28018
|
if (this.meetingToggle !== null)
|
|
27688
28019
|
return this.meetingToggle;
|
|
28020
|
+
this.store.update({ lastError: null });
|
|
27689
28021
|
this.meetingToggle = this.performMeetingToggle().finally(() => {
|
|
27690
28022
|
this.meetingToggle = null;
|
|
27691
28023
|
});
|
|
@@ -27744,7 +28076,6 @@ class AppRuntime {
|
|
|
27744
28076
|
meeting: false,
|
|
27745
28077
|
meetingStarting: false,
|
|
27746
28078
|
meetingAsking: false,
|
|
27747
|
-
meetingTranscriptAvailable: false,
|
|
27748
28079
|
meetingScreenshotCount: 0,
|
|
27749
28080
|
processing: false,
|
|
27750
28081
|
queued: 0,
|
|
@@ -27793,7 +28124,7 @@ class AppRuntime {
|
|
|
27793
28124
|
}
|
|
27794
28125
|
async startMeeting() {
|
|
27795
28126
|
const binary = resolveAudioHelperPath(app3.getAppPath());
|
|
27796
|
-
if (!
|
|
28127
|
+
if (!fs9.existsSync(binary)) {
|
|
27797
28128
|
this.store.update({
|
|
27798
28129
|
meeting: false,
|
|
27799
28130
|
meetingStarting: false,
|
|
@@ -27802,7 +28133,9 @@ class AppRuntime {
|
|
|
27802
28133
|
return;
|
|
27803
28134
|
}
|
|
27804
28135
|
this.clearTranscriptState();
|
|
28136
|
+
this.meetingStartedAt = Date.now();
|
|
27805
28137
|
this.store.update({
|
|
28138
|
+
meetingStartedAt: this.meetingStartedAt,
|
|
27806
28139
|
meeting: false,
|
|
27807
28140
|
meetingStarting: true,
|
|
27808
28141
|
lastError: null
|
|
@@ -27837,8 +28170,8 @@ class AppRuntime {
|
|
|
27837
28170
|
if (this.audioManager !== manager || this.shuttingDown)
|
|
27838
28171
|
return;
|
|
27839
28172
|
this.alignTranscriptTimeline(event.endMs);
|
|
27840
|
-
this.
|
|
27841
|
-
this.
|
|
28173
|
+
this.transcriptHistory.push(event);
|
|
28174
|
+
this.syncMeetingContextState();
|
|
27842
28175
|
this.appendToTranscriptLog(event);
|
|
27843
28176
|
this.scheduleTranscriptFlush();
|
|
27844
28177
|
});
|
|
@@ -27903,6 +28236,8 @@ class AppRuntime {
|
|
|
27903
28236
|
if (this.audioManager !== manager)
|
|
27904
28237
|
return;
|
|
27905
28238
|
this.audioManager = null;
|
|
28239
|
+
this.meetingStartedAt = null;
|
|
28240
|
+
this.store.update({ meetingStartedAt: null });
|
|
27906
28241
|
this.meetingAbortController?.abort();
|
|
27907
28242
|
if (this.meetingAsk !== null)
|
|
27908
28243
|
await this.meetingAsk;
|
|
@@ -27925,6 +28260,8 @@ class AppRuntime {
|
|
|
27925
28260
|
async stopMeeting() {
|
|
27926
28261
|
const manager = this.audioManager;
|
|
27927
28262
|
this.audioManager = null;
|
|
28263
|
+
this.meetingStartedAt = null;
|
|
28264
|
+
this.store.update({ meetingStartedAt: null });
|
|
27928
28265
|
this.meetingAbortController?.abort();
|
|
27929
28266
|
if (this.meetingAsk !== null)
|
|
27930
28267
|
await this.meetingAsk;
|
|
@@ -27960,42 +28297,30 @@ class AppRuntime {
|
|
|
27960
28297
|
return;
|
|
27961
28298
|
this.transcriptTimelineOriginMs = performance.now() - Math.max(0, streamPositionMs);
|
|
27962
28299
|
this.transcriptPruneTimer = setInterval(() => {
|
|
27963
|
-
const referenceMs = this.currentTranscriptReferenceMs();
|
|
27964
|
-
if (referenceMs === null)
|
|
27965
|
-
return;
|
|
27966
|
-
this.transcriptBuffer.prune(referenceMs);
|
|
27967
|
-
this.updateMeetingTranscript(referenceMs);
|
|
27968
28300
|
this.flushTranscriptLines();
|
|
27969
28301
|
}, TRANSCRIPT_PRUNE_INTERVAL_MS);
|
|
27970
28302
|
this.transcriptPruneTimer.unref();
|
|
27971
28303
|
}
|
|
27972
|
-
|
|
27973
|
-
|
|
27974
|
-
|
|
27975
|
-
|
|
27976
|
-
|
|
27977
|
-
updateMeetingTranscript(referenceMs) {
|
|
27978
|
-
const { meeting, meetingStarting } = this.store.get();
|
|
27979
|
-
if (!meeting && !meetingStarting)
|
|
27980
|
-
return;
|
|
27981
|
-
this.meetingContext.updateTranscript(this.transcriptBuffer.formatRecent(referenceMs));
|
|
27982
|
-
this.syncMeetingContextState();
|
|
28304
|
+
meetingSessionExpired() {
|
|
28305
|
+
const lastAskAt = this.lastMeetingAskAt;
|
|
28306
|
+
if (lastAskAt === null)
|
|
28307
|
+
return false;
|
|
28308
|
+
return Date.now() - lastAskAt >= MEETING_SESSION_IDLE_MS;
|
|
27983
28309
|
}
|
|
27984
28310
|
syncMeetingContextState() {
|
|
27985
|
-
const {
|
|
27986
|
-
this.store.
|
|
27987
|
-
|
|
27988
|
-
|
|
27989
|
-
});
|
|
28311
|
+
const { screenshotCount } = this.meetingContext.summary();
|
|
28312
|
+
if (this.store.get().meetingScreenshotCount === screenshotCount)
|
|
28313
|
+
return;
|
|
28314
|
+
this.store.update({ meetingScreenshotCount: screenshotCount });
|
|
27990
28315
|
}
|
|
27991
28316
|
async prepareMeetingContext() {
|
|
27992
28317
|
await this.clearMeetingContext();
|
|
27993
28318
|
const root = meetingCapturesRoot();
|
|
27994
|
-
await
|
|
27995
|
-
await
|
|
27996
|
-
await
|
|
27997
|
-
const directory =
|
|
27998
|
-
await
|
|
28319
|
+
await fs9.promises.rm(root, { recursive: true, force: true });
|
|
28320
|
+
await fs9.promises.mkdir(root, { recursive: true, mode: 448 });
|
|
28321
|
+
await fs9.promises.chmod(root, 448);
|
|
28322
|
+
const directory = path14.join(root, randomUUID2());
|
|
28323
|
+
await fs9.promises.mkdir(directory, { mode: 448 });
|
|
27999
28324
|
this.meetingCaptureDirectory = directory;
|
|
28000
28325
|
}
|
|
28001
28326
|
async clearMeetingContext() {
|
|
@@ -28006,7 +28331,7 @@ class AppRuntime {
|
|
|
28006
28331
|
if (directory === null)
|
|
28007
28332
|
return;
|
|
28008
28333
|
try {
|
|
28009
|
-
await
|
|
28334
|
+
await fs9.promises.rm(directory, { recursive: true, force: true });
|
|
28010
28335
|
} catch (error61) {
|
|
28011
28336
|
if (!this.shuttingDown) {
|
|
28012
28337
|
this.store.update({
|
|
@@ -28018,7 +28343,7 @@ class AppRuntime {
|
|
|
28018
28343
|
async removeSubmittedScreenshots(screenshotPaths) {
|
|
28019
28344
|
this.meetingContext.removeScreenshots(screenshotPaths);
|
|
28020
28345
|
this.syncMeetingContextState();
|
|
28021
|
-
const results = await Promise.allSettled(screenshotPaths.map((screenshotPath) =>
|
|
28346
|
+
const results = await Promise.allSettled(screenshotPaths.map((screenshotPath) => fs9.promises.rm(screenshotPath, { force: true })));
|
|
28022
28347
|
const failed = results.find((result) => result.status === "rejected");
|
|
28023
28348
|
if (failed !== undefined && !this.shuttingDown) {
|
|
28024
28349
|
this.store.update({
|
|
@@ -28043,8 +28368,6 @@ class AppRuntime {
|
|
|
28043
28368
|
};
|
|
28044
28369
|
}
|
|
28045
28370
|
appendToTranscriptLog(event) {
|
|
28046
|
-
if (!this.store.get().saveTranscript)
|
|
28047
|
-
return;
|
|
28048
28371
|
try {
|
|
28049
28372
|
this.transcriptLog ??= new TranscriptLog(transcriptsDirectory());
|
|
28050
28373
|
this.transcriptLog.append(event);
|
|
@@ -28055,15 +28378,6 @@ class AppRuntime {
|
|
|
28055
28378
|
});
|
|
28056
28379
|
}
|
|
28057
28380
|
}
|
|
28058
|
-
setSaveTranscript(save) {
|
|
28059
|
-
if (this.config.saveTranscript === save)
|
|
28060
|
-
return;
|
|
28061
|
-
this.config.saveTranscript = save;
|
|
28062
|
-
saveConfig(this.config);
|
|
28063
|
-
if (!save)
|
|
28064
|
-
this.transcriptLog = null;
|
|
28065
|
-
this.store.update({ saveTranscript: save });
|
|
28066
|
-
}
|
|
28067
28381
|
clearTranscriptState() {
|
|
28068
28382
|
this.transcriptLog = null;
|
|
28069
28383
|
if (this.transcriptPruneTimer !== null) {
|
|
@@ -28075,7 +28389,10 @@ class AppRuntime {
|
|
|
28075
28389
|
this.transcriptFlushTimer = null;
|
|
28076
28390
|
}
|
|
28077
28391
|
this.transcriptTimelineOriginMs = null;
|
|
28078
|
-
this.
|
|
28392
|
+
this.transcriptHistory.clear();
|
|
28393
|
+
this.transcriptCursor.reset();
|
|
28394
|
+
this.lastMeetingAskAt = null;
|
|
28395
|
+
this.transcriptResetPending = true;
|
|
28079
28396
|
this.flushTranscriptLines();
|
|
28080
28397
|
}
|
|
28081
28398
|
scheduleTranscriptFlush() {
|
|
@@ -28090,14 +28407,35 @@ class AppRuntime {
|
|
|
28090
28407
|
this.transcriptFlushTimer.unref();
|
|
28091
28408
|
}
|
|
28092
28409
|
flushTranscriptLines() {
|
|
28093
|
-
|
|
28094
|
-
|
|
28095
|
-
const
|
|
28096
|
-
|
|
28410
|
+
if (this.popup === null || !this.popup.rendererLoaded)
|
|
28411
|
+
return;
|
|
28412
|
+
const { changed, volatile } = this.transcriptHistory.drain();
|
|
28413
|
+
const serializedVolatile = JSON.stringify(volatile);
|
|
28414
|
+
const reset = this.transcriptResetPending;
|
|
28415
|
+
if (!reset && changed.length === 0 && serializedVolatile === this.transcriptSentPayload) {
|
|
28097
28416
|
return;
|
|
28098
|
-
|
|
28417
|
+
}
|
|
28418
|
+
this.transcriptResetPending = false;
|
|
28419
|
+
this.transcriptSentPayload = serializedVolatile;
|
|
28099
28420
|
this.transcriptSentAtMs = performance.now();
|
|
28100
|
-
this.popup
|
|
28421
|
+
this.popup.sendTranscript({
|
|
28422
|
+
changed: [...changed],
|
|
28423
|
+
volatile: [...volatile],
|
|
28424
|
+
reset
|
|
28425
|
+
});
|
|
28426
|
+
}
|
|
28427
|
+
resendFullTranscript() {
|
|
28428
|
+
if (this.popup === null || !this.popup.rendererLoaded)
|
|
28429
|
+
return;
|
|
28430
|
+
const { volatile } = this.transcriptHistory.drain();
|
|
28431
|
+
this.transcriptResetPending = false;
|
|
28432
|
+
this.transcriptSentPayload = JSON.stringify(volatile);
|
|
28433
|
+
this.transcriptSentAtMs = performance.now();
|
|
28434
|
+
this.popup.sendTranscript({
|
|
28435
|
+
changed: [...this.transcriptHistory.lines()],
|
|
28436
|
+
volatile: [...volatile],
|
|
28437
|
+
reset: true
|
|
28438
|
+
});
|
|
28101
28439
|
}
|
|
28102
28440
|
setShowTranscript(show) {
|
|
28103
28441
|
if (this.config.showTranscript === show)
|
|
@@ -28131,14 +28469,8 @@ class AppRuntime {
|
|
|
28131
28469
|
this.showMeetingError("Start Meeting before asking");
|
|
28132
28470
|
return;
|
|
28133
28471
|
}
|
|
28134
|
-
const
|
|
28135
|
-
|
|
28136
|
-
this.updateMeetingTranscript(referenceMs);
|
|
28137
|
-
const context = this.meetingContext.snapshot();
|
|
28138
|
-
if (context.transcript === undefined && context.screenshotPaths.length === 0) {
|
|
28139
|
-
this.showMeetingError("Meeting has no transcript or screenshots yet");
|
|
28140
|
-
return;
|
|
28141
|
-
}
|
|
28472
|
+
const screenshotPaths = this.meetingContext.staged();
|
|
28473
|
+
let chunk = this.transcriptCursor.chunk(this.transcriptHistory.lines(), this.transcriptHistory.volatileLines());
|
|
28142
28474
|
const abortController = new AbortController;
|
|
28143
28475
|
this.meetingAbortController = abortController;
|
|
28144
28476
|
this.store.update({ meetingAsking: true, lastError: null });
|
|
@@ -28149,6 +28481,15 @@ class AppRuntime {
|
|
|
28149
28481
|
return;
|
|
28150
28482
|
}
|
|
28151
28483
|
const client = await this.ensureClient();
|
|
28484
|
+
if (this.meetingSessionExpired()) {
|
|
28485
|
+
await client.resetMeeting();
|
|
28486
|
+
this.transcriptCursor.reset();
|
|
28487
|
+
chunk = this.transcriptCursor.chunk(this.transcriptHistory.lines(), this.transcriptHistory.volatileLines());
|
|
28488
|
+
}
|
|
28489
|
+
const context = {
|
|
28490
|
+
transcript: chunk.text,
|
|
28491
|
+
screenshotPaths: [...screenshotPaths]
|
|
28492
|
+
};
|
|
28152
28493
|
const detectedAt = new Date().toISOString();
|
|
28153
28494
|
this.popup?.sendStart({
|
|
28154
28495
|
source: "meeting",
|
|
@@ -28198,6 +28539,8 @@ class AppRuntime {
|
|
|
28198
28539
|
answer: outcome.text,
|
|
28199
28540
|
durationMs: outcome.durationMs
|
|
28200
28541
|
});
|
|
28542
|
+
this.transcriptCursor.markSubmitted(chunk.lineIds);
|
|
28543
|
+
this.lastMeetingAskAt = Date.now();
|
|
28201
28544
|
await this.removeSubmittedScreenshots(context.screenshotPaths);
|
|
28202
28545
|
this.popup?.sendDone({
|
|
28203
28546
|
type: "complete",
|
|
@@ -28351,7 +28694,7 @@ class AppRuntime {
|
|
|
28351
28694
|
this.meetingContext.stageScreenshot(result.path);
|
|
28352
28695
|
this.syncMeetingContextState();
|
|
28353
28696
|
} else {
|
|
28354
|
-
await
|
|
28697
|
+
await fs9.promises.rm(result.path, { force: true });
|
|
28355
28698
|
}
|
|
28356
28699
|
}
|
|
28357
28700
|
} catch (error61) {
|
|
@@ -28407,7 +28750,7 @@ class AppRuntime {
|
|
|
28407
28750
|
onStart: (event) => {
|
|
28408
28751
|
this.popup?.sendStart({
|
|
28409
28752
|
source: "monitor",
|
|
28410
|
-
title:
|
|
28753
|
+
title: path14.basename(event.path),
|
|
28411
28754
|
detectedAt: event.detectedAt.toISOString()
|
|
28412
28755
|
});
|
|
28413
28756
|
},
|
|
@@ -28453,26 +28796,19 @@ class AppRuntime {
|
|
|
28453
28796
|
}
|
|
28454
28797
|
this.client = new BlinkCloudClient({
|
|
28455
28798
|
apiUrl: this.config.apiUrl,
|
|
28456
|
-
accessToken: this.config.accessToken
|
|
28799
|
+
accessToken: this.config.accessToken,
|
|
28800
|
+
prompts: {
|
|
28801
|
+
...this.config.monitorPrompt === "" ? {} : { monitor: this.config.monitorPrompt },
|
|
28802
|
+
...this.config.meetingPrompt === "" ? {} : { meeting: this.config.meetingPrompt }
|
|
28803
|
+
}
|
|
28457
28804
|
});
|
|
28458
28805
|
return Promise.resolve(this.client);
|
|
28459
28806
|
}
|
|
28460
|
-
|
|
28461
|
-
|
|
28462
|
-
|
|
28463
|
-
|
|
28464
|
-
|
|
28465
|
-
if (error61 !== "")
|
|
28466
|
-
this.store.update({ lastError: `open config: ${error61}` });
|
|
28467
|
-
}
|
|
28468
|
-
async openAnswerLog() {
|
|
28469
|
-
const target = answerLogPath();
|
|
28470
|
-
fs8.mkdirSync(path12.dirname(target), { recursive: true });
|
|
28471
|
-
if (!fs8.existsSync(target))
|
|
28472
|
-
fs8.writeFileSync(target, "");
|
|
28473
|
-
const error61 = await shell.openPath(target);
|
|
28474
|
-
if (error61 !== "")
|
|
28475
|
-
this.store.update({ lastError: `open log: ${error61}` });
|
|
28807
|
+
openConfig() {
|
|
28808
|
+
this.settings.show("prompts");
|
|
28809
|
+
}
|
|
28810
|
+
openAnswerLog() {
|
|
28811
|
+
this.settings.show("answers");
|
|
28476
28812
|
}
|
|
28477
28813
|
async openBillingPortal() {
|
|
28478
28814
|
const client = await this.ensureClient();
|
|
@@ -28485,7 +28821,7 @@ class AppRuntime {
|
|
|
28485
28821
|
}
|
|
28486
28822
|
revealBundle() {
|
|
28487
28823
|
const bundle = resolveAppBundlePath(app3.getAppPath());
|
|
28488
|
-
if (!
|
|
28824
|
+
if (!fs9.existsSync(bundle)) {
|
|
28489
28825
|
this.store.update({ lastError: `Blink.app is missing at ${bundle}` });
|
|
28490
28826
|
return;
|
|
28491
28827
|
}
|