dsh-dock 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/client.js +661 -98
- package/features/notify/host.js +44 -0
- package/features/notify/view.jsx +590 -49
- package/package.json +2 -2
- package/src/client.jsx +1 -1
- package/src/host-core.js +31 -0
- package/src/task-track.js +48 -3
package/client.js
CHANGED
|
@@ -40,18 +40,18 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
40
40
|
));
|
|
41
41
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
42
42
|
|
|
43
|
-
//
|
|
43
|
+
// node_modules/qrcode/lib/can-promise.js
|
|
44
44
|
var require_can_promise = __commonJS({
|
|
45
|
-
"
|
|
45
|
+
"node_modules/qrcode/lib/can-promise.js"(exports, module2) {
|
|
46
46
|
module2.exports = function() {
|
|
47
47
|
return typeof Promise === "function" && Promise.prototype && Promise.prototype.then;
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
//
|
|
52
|
+
// node_modules/qrcode/lib/core/utils.js
|
|
53
53
|
var require_utils = __commonJS({
|
|
54
|
-
"
|
|
54
|
+
"node_modules/qrcode/lib/core/utils.js"(exports) {
|
|
55
55
|
var toSJISFunction;
|
|
56
56
|
var CODEWORDS_COUNT = [
|
|
57
57
|
0,
|
|
@@ -128,9 +128,9 @@ var require_utils = __commonJS({
|
|
|
128
128
|
}
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
-
//
|
|
131
|
+
// node_modules/qrcode/lib/core/error-correction-level.js
|
|
132
132
|
var require_error_correction_level = __commonJS({
|
|
133
|
-
"
|
|
133
|
+
"node_modules/qrcode/lib/core/error-correction-level.js"(exports) {
|
|
134
134
|
exports.L = { bit: 1 };
|
|
135
135
|
exports.M = { bit: 0 };
|
|
136
136
|
exports.Q = { bit: 3 };
|
|
@@ -173,9 +173,9 @@ var require_error_correction_level = __commonJS({
|
|
|
173
173
|
}
|
|
174
174
|
});
|
|
175
175
|
|
|
176
|
-
//
|
|
176
|
+
// node_modules/qrcode/lib/core/bit-buffer.js
|
|
177
177
|
var require_bit_buffer = __commonJS({
|
|
178
|
-
"
|
|
178
|
+
"node_modules/qrcode/lib/core/bit-buffer.js"(exports, module2) {
|
|
179
179
|
function BitBuffer() {
|
|
180
180
|
this.buffer = [];
|
|
181
181
|
this.length = 0;
|
|
@@ -208,9 +208,9 @@ var require_bit_buffer = __commonJS({
|
|
|
208
208
|
}
|
|
209
209
|
});
|
|
210
210
|
|
|
211
|
-
//
|
|
211
|
+
// node_modules/qrcode/lib/core/bit-matrix.js
|
|
212
212
|
var require_bit_matrix = __commonJS({
|
|
213
|
-
"
|
|
213
|
+
"node_modules/qrcode/lib/core/bit-matrix.js"(exports, module2) {
|
|
214
214
|
function BitMatrix(size) {
|
|
215
215
|
if (!size || size < 1) {
|
|
216
216
|
throw new Error("BitMatrix size must be defined and greater than 0");
|
|
@@ -237,9 +237,9 @@ var require_bit_matrix = __commonJS({
|
|
|
237
237
|
}
|
|
238
238
|
});
|
|
239
239
|
|
|
240
|
-
//
|
|
240
|
+
// node_modules/qrcode/lib/core/alignment-pattern.js
|
|
241
241
|
var require_alignment_pattern = __commonJS({
|
|
242
|
-
"
|
|
242
|
+
"node_modules/qrcode/lib/core/alignment-pattern.js"(exports) {
|
|
243
243
|
var getSymbolSize = require_utils().getSymbolSize;
|
|
244
244
|
exports.getRowColCoords = function getRowColCoords(version) {
|
|
245
245
|
if (version === 1) return [];
|
|
@@ -272,9 +272,9 @@ var require_alignment_pattern = __commonJS({
|
|
|
272
272
|
}
|
|
273
273
|
});
|
|
274
274
|
|
|
275
|
-
//
|
|
275
|
+
// node_modules/qrcode/lib/core/finder-pattern.js
|
|
276
276
|
var require_finder_pattern = __commonJS({
|
|
277
|
-
"
|
|
277
|
+
"node_modules/qrcode/lib/core/finder-pattern.js"(exports) {
|
|
278
278
|
var getSymbolSize = require_utils().getSymbolSize;
|
|
279
279
|
var FINDER_PATTERN_SIZE = 7;
|
|
280
280
|
exports.getPositions = function getPositions(version) {
|
|
@@ -291,9 +291,9 @@ var require_finder_pattern = __commonJS({
|
|
|
291
291
|
}
|
|
292
292
|
});
|
|
293
293
|
|
|
294
|
-
//
|
|
294
|
+
// node_modules/qrcode/lib/core/mask-pattern.js
|
|
295
295
|
var require_mask_pattern = __commonJS({
|
|
296
|
-
"
|
|
296
|
+
"node_modules/qrcode/lib/core/mask-pattern.js"(exports) {
|
|
297
297
|
exports.Patterns = {
|
|
298
298
|
PATTERN000: 0,
|
|
299
299
|
PATTERN001: 1,
|
|
@@ -433,9 +433,9 @@ var require_mask_pattern = __commonJS({
|
|
|
433
433
|
}
|
|
434
434
|
});
|
|
435
435
|
|
|
436
|
-
//
|
|
436
|
+
// node_modules/qrcode/lib/core/error-correction-code.js
|
|
437
437
|
var require_error_correction_code = __commonJS({
|
|
438
|
-
"
|
|
438
|
+
"node_modules/qrcode/lib/core/error-correction-code.js"(exports) {
|
|
439
439
|
var ECLevel = require_error_correction_level();
|
|
440
440
|
var EC_BLOCKS_TABLE = [
|
|
441
441
|
// L M Q H
|
|
@@ -794,9 +794,9 @@ var require_error_correction_code = __commonJS({
|
|
|
794
794
|
}
|
|
795
795
|
});
|
|
796
796
|
|
|
797
|
-
//
|
|
797
|
+
// node_modules/qrcode/lib/core/galois-field.js
|
|
798
798
|
var require_galois_field = __commonJS({
|
|
799
|
-
"
|
|
799
|
+
"node_modules/qrcode/lib/core/galois-field.js"(exports) {
|
|
800
800
|
var EXP_TABLE = new Uint8Array(512);
|
|
801
801
|
var LOG_TABLE = new Uint8Array(256);
|
|
802
802
|
(function initTables() {
|
|
@@ -827,9 +827,9 @@ var require_galois_field = __commonJS({
|
|
|
827
827
|
}
|
|
828
828
|
});
|
|
829
829
|
|
|
830
|
-
//
|
|
830
|
+
// node_modules/qrcode/lib/core/polynomial.js
|
|
831
831
|
var require_polynomial = __commonJS({
|
|
832
|
-
"
|
|
832
|
+
"node_modules/qrcode/lib/core/polynomial.js"(exports) {
|
|
833
833
|
var GF = require_galois_field();
|
|
834
834
|
exports.mul = function mul(p1, p2) {
|
|
835
835
|
const coeff = new Uint8Array(p1.length + p2.length - 1);
|
|
@@ -863,9 +863,9 @@ var require_polynomial = __commonJS({
|
|
|
863
863
|
}
|
|
864
864
|
});
|
|
865
865
|
|
|
866
|
-
//
|
|
866
|
+
// node_modules/qrcode/lib/core/reed-solomon-encoder.js
|
|
867
867
|
var require_reed_solomon_encoder = __commonJS({
|
|
868
|
-
"
|
|
868
|
+
"node_modules/qrcode/lib/core/reed-solomon-encoder.js"(exports, module2) {
|
|
869
869
|
var Polynomial = require_polynomial();
|
|
870
870
|
function ReedSolomonEncoder(degree) {
|
|
871
871
|
this.genPoly = void 0;
|
|
@@ -895,18 +895,18 @@ var require_reed_solomon_encoder = __commonJS({
|
|
|
895
895
|
}
|
|
896
896
|
});
|
|
897
897
|
|
|
898
|
-
//
|
|
898
|
+
// node_modules/qrcode/lib/core/version-check.js
|
|
899
899
|
var require_version_check = __commonJS({
|
|
900
|
-
"
|
|
900
|
+
"node_modules/qrcode/lib/core/version-check.js"(exports) {
|
|
901
901
|
exports.isValid = function isValid(version) {
|
|
902
902
|
return !isNaN(version) && version >= 1 && version <= 40;
|
|
903
903
|
};
|
|
904
904
|
}
|
|
905
905
|
});
|
|
906
906
|
|
|
907
|
-
//
|
|
907
|
+
// node_modules/qrcode/lib/core/regex.js
|
|
908
908
|
var require_regex = __commonJS({
|
|
909
|
-
"
|
|
909
|
+
"node_modules/qrcode/lib/core/regex.js"(exports) {
|
|
910
910
|
var numeric = "[0-9]+";
|
|
911
911
|
var alphanumeric = "[A-Z $%*+\\-./:]+";
|
|
912
912
|
var kanji = "(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";
|
|
@@ -932,9 +932,9 @@ var require_regex = __commonJS({
|
|
|
932
932
|
}
|
|
933
933
|
});
|
|
934
934
|
|
|
935
|
-
//
|
|
935
|
+
// node_modules/qrcode/lib/core/mode.js
|
|
936
936
|
var require_mode = __commonJS({
|
|
937
|
-
"
|
|
937
|
+
"node_modules/qrcode/lib/core/mode.js"(exports) {
|
|
938
938
|
var VersionCheck = require_version_check();
|
|
939
939
|
var Regex = require_regex();
|
|
940
940
|
exports.NUMERIC = {
|
|
@@ -1013,9 +1013,9 @@ var require_mode = __commonJS({
|
|
|
1013
1013
|
}
|
|
1014
1014
|
});
|
|
1015
1015
|
|
|
1016
|
-
//
|
|
1016
|
+
// node_modules/qrcode/lib/core/version.js
|
|
1017
1017
|
var require_version = __commonJS({
|
|
1018
|
-
"
|
|
1018
|
+
"node_modules/qrcode/lib/core/version.js"(exports) {
|
|
1019
1019
|
var Utils = require_utils();
|
|
1020
1020
|
var ECCode = require_error_correction_code();
|
|
1021
1021
|
var ECLevel = require_error_correction_level();
|
|
@@ -1108,9 +1108,9 @@ var require_version = __commonJS({
|
|
|
1108
1108
|
}
|
|
1109
1109
|
});
|
|
1110
1110
|
|
|
1111
|
-
//
|
|
1111
|
+
// node_modules/qrcode/lib/core/format-info.js
|
|
1112
1112
|
var require_format_info = __commonJS({
|
|
1113
|
-
"
|
|
1113
|
+
"node_modules/qrcode/lib/core/format-info.js"(exports) {
|
|
1114
1114
|
var Utils = require_utils();
|
|
1115
1115
|
var G15 = 1 << 10 | 1 << 8 | 1 << 5 | 1 << 4 | 1 << 2 | 1 << 1 | 1 << 0;
|
|
1116
1116
|
var G15_MASK = 1 << 14 | 1 << 12 | 1 << 10 | 1 << 4 | 1 << 1;
|
|
@@ -1126,9 +1126,9 @@ var require_format_info = __commonJS({
|
|
|
1126
1126
|
}
|
|
1127
1127
|
});
|
|
1128
1128
|
|
|
1129
|
-
//
|
|
1129
|
+
// node_modules/qrcode/lib/core/numeric-data.js
|
|
1130
1130
|
var require_numeric_data = __commonJS({
|
|
1131
|
-
"
|
|
1131
|
+
"node_modules/qrcode/lib/core/numeric-data.js"(exports, module2) {
|
|
1132
1132
|
var Mode = require_mode();
|
|
1133
1133
|
function NumericData(data) {
|
|
1134
1134
|
this.mode = Mode.NUMERIC;
|
|
@@ -1161,9 +1161,9 @@ var require_numeric_data = __commonJS({
|
|
|
1161
1161
|
}
|
|
1162
1162
|
});
|
|
1163
1163
|
|
|
1164
|
-
//
|
|
1164
|
+
// node_modules/qrcode/lib/core/alphanumeric-data.js
|
|
1165
1165
|
var require_alphanumeric_data = __commonJS({
|
|
1166
|
-
"
|
|
1166
|
+
"node_modules/qrcode/lib/core/alphanumeric-data.js"(exports, module2) {
|
|
1167
1167
|
var Mode = require_mode();
|
|
1168
1168
|
var ALPHA_NUM_CHARS = [
|
|
1169
1169
|
"0",
|
|
@@ -1240,9 +1240,9 @@ var require_alphanumeric_data = __commonJS({
|
|
|
1240
1240
|
}
|
|
1241
1241
|
});
|
|
1242
1242
|
|
|
1243
|
-
//
|
|
1243
|
+
// node_modules/qrcode/lib/core/byte-data.js
|
|
1244
1244
|
var require_byte_data = __commonJS({
|
|
1245
|
-
"
|
|
1245
|
+
"node_modules/qrcode/lib/core/byte-data.js"(exports, module2) {
|
|
1246
1246
|
var Mode = require_mode();
|
|
1247
1247
|
function ByteData(data) {
|
|
1248
1248
|
this.mode = Mode.BYTE;
|
|
@@ -1270,9 +1270,9 @@ var require_byte_data = __commonJS({
|
|
|
1270
1270
|
}
|
|
1271
1271
|
});
|
|
1272
1272
|
|
|
1273
|
-
//
|
|
1273
|
+
// node_modules/qrcode/lib/core/kanji-data.js
|
|
1274
1274
|
var require_kanji_data = __commonJS({
|
|
1275
|
-
"
|
|
1275
|
+
"node_modules/qrcode/lib/core/kanji-data.js"(exports, module2) {
|
|
1276
1276
|
var Mode = require_mode();
|
|
1277
1277
|
var Utils = require_utils();
|
|
1278
1278
|
function KanjiData(data) {
|
|
@@ -1309,9 +1309,9 @@ var require_kanji_data = __commonJS({
|
|
|
1309
1309
|
}
|
|
1310
1310
|
});
|
|
1311
1311
|
|
|
1312
|
-
//
|
|
1312
|
+
// node_modules/dijkstrajs/dijkstra.js
|
|
1313
1313
|
var require_dijkstra = __commonJS({
|
|
1314
|
-
"
|
|
1314
|
+
"node_modules/dijkstrajs/dijkstra.js"(exports, module2) {
|
|
1315
1315
|
"use strict";
|
|
1316
1316
|
var dijkstra = {
|
|
1317
1317
|
single_source_shortest_paths: function(graph, s, d) {
|
|
@@ -1410,9 +1410,9 @@ var require_dijkstra = __commonJS({
|
|
|
1410
1410
|
}
|
|
1411
1411
|
});
|
|
1412
1412
|
|
|
1413
|
-
//
|
|
1413
|
+
// node_modules/qrcode/lib/core/segments.js
|
|
1414
1414
|
var require_segments = __commonJS({
|
|
1415
|
-
"
|
|
1415
|
+
"node_modules/qrcode/lib/core/segments.js"(exports) {
|
|
1416
1416
|
var Mode = require_mode();
|
|
1417
1417
|
var NumericData = require_numeric_data();
|
|
1418
1418
|
var AlphanumericData = require_alphanumeric_data();
|
|
@@ -1596,9 +1596,9 @@ var require_segments = __commonJS({
|
|
|
1596
1596
|
}
|
|
1597
1597
|
});
|
|
1598
1598
|
|
|
1599
|
-
//
|
|
1599
|
+
// node_modules/qrcode/lib/core/qrcode.js
|
|
1600
1600
|
var require_qrcode = __commonJS({
|
|
1601
|
-
"
|
|
1601
|
+
"node_modules/qrcode/lib/core/qrcode.js"(exports) {
|
|
1602
1602
|
var Utils = require_utils();
|
|
1603
1603
|
var ECLevel = require_error_correction_level();
|
|
1604
1604
|
var BitBuffer = require_bit_buffer();
|
|
@@ -1857,9 +1857,9 @@ var require_qrcode = __commonJS({
|
|
|
1857
1857
|
}
|
|
1858
1858
|
});
|
|
1859
1859
|
|
|
1860
|
-
//
|
|
1860
|
+
// node_modules/qrcode/lib/renderer/utils.js
|
|
1861
1861
|
var require_utils2 = __commonJS({
|
|
1862
|
-
"
|
|
1862
|
+
"node_modules/qrcode/lib/renderer/utils.js"(exports) {
|
|
1863
1863
|
function hex2rgba(hex) {
|
|
1864
1864
|
if (typeof hex === "number") {
|
|
1865
1865
|
hex = hex.toString();
|
|
@@ -1937,9 +1937,9 @@ var require_utils2 = __commonJS({
|
|
|
1937
1937
|
}
|
|
1938
1938
|
});
|
|
1939
1939
|
|
|
1940
|
-
//
|
|
1940
|
+
// node_modules/qrcode/lib/renderer/canvas.js
|
|
1941
1941
|
var require_canvas = __commonJS({
|
|
1942
|
-
"
|
|
1942
|
+
"node_modules/qrcode/lib/renderer/canvas.js"(exports) {
|
|
1943
1943
|
var Utils = require_utils2();
|
|
1944
1944
|
function clearCanvas(ctx, canvas, size) {
|
|
1945
1945
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
@@ -1990,9 +1990,9 @@ var require_canvas = __commonJS({
|
|
|
1990
1990
|
}
|
|
1991
1991
|
});
|
|
1992
1992
|
|
|
1993
|
-
//
|
|
1993
|
+
// node_modules/qrcode/lib/renderer/svg-tag.js
|
|
1994
1994
|
var require_svg_tag = __commonJS({
|
|
1995
|
-
"
|
|
1995
|
+
"node_modules/qrcode/lib/renderer/svg-tag.js"(exports) {
|
|
1996
1996
|
var Utils = require_utils2();
|
|
1997
1997
|
function getColorAttrib(color, attrib) {
|
|
1998
1998
|
const alpha = color.a / 255;
|
|
@@ -2048,9 +2048,9 @@ var require_svg_tag = __commonJS({
|
|
|
2048
2048
|
}
|
|
2049
2049
|
});
|
|
2050
2050
|
|
|
2051
|
-
//
|
|
2051
|
+
// node_modules/qrcode/lib/browser.js
|
|
2052
2052
|
var require_browser = __commonJS({
|
|
2053
|
-
"
|
|
2053
|
+
"node_modules/qrcode/lib/browser.js"(exports) {
|
|
2054
2054
|
var canPromise = require_can_promise();
|
|
2055
2055
|
var QRCode2 = require_qrcode();
|
|
2056
2056
|
var CanvasRenderer = require_canvas();
|
|
@@ -7275,6 +7275,216 @@ function previewSound(effect) {
|
|
|
7275
7275
|
const delayed = lib.notes.err.map(([f, at, dur, wave]) => [f, at + 0.55, dur, wave]);
|
|
7276
7276
|
playTone(delayed);
|
|
7277
7277
|
}
|
|
7278
|
+
function synthOf() {
|
|
7279
|
+
try {
|
|
7280
|
+
const g = typeof globalThis !== "undefined" ? globalThis : null;
|
|
7281
|
+
if (g && g.speechSynthesis) return g.speechSynthesis;
|
|
7282
|
+
if (typeof window !== "undefined" && window.speechSynthesis) return window.speechSynthesis;
|
|
7283
|
+
} catch {
|
|
7284
|
+
}
|
|
7285
|
+
return null;
|
|
7286
|
+
}
|
|
7287
|
+
function utterCtor() {
|
|
7288
|
+
try {
|
|
7289
|
+
const g = typeof globalThis !== "undefined" && globalThis.SpeechSynthesisUtterance ? globalThis.SpeechSynthesisUtterance : typeof window !== "undefined" ? window.SpeechSynthesisUtterance : null;
|
|
7290
|
+
return g;
|
|
7291
|
+
} catch {
|
|
7292
|
+
return null;
|
|
7293
|
+
}
|
|
7294
|
+
}
|
|
7295
|
+
function voiceSupported() {
|
|
7296
|
+
return synthOf() !== null && utterCtor() !== null;
|
|
7297
|
+
}
|
|
7298
|
+
function localVoices() {
|
|
7299
|
+
const s = synthOf();
|
|
7300
|
+
if (!s) return [];
|
|
7301
|
+
try {
|
|
7302
|
+
return (typeof s.getVoices === "function" ? s.getVoices() : []) || [];
|
|
7303
|
+
} catch {
|
|
7304
|
+
return [];
|
|
7305
|
+
}
|
|
7306
|
+
}
|
|
7307
|
+
function pickVoice(cfg, text) {
|
|
7308
|
+
const voices = localVoices();
|
|
7309
|
+
if (voices.length === 0) return null;
|
|
7310
|
+
const want = String(cfg && cfg.voiceURI || "");
|
|
7311
|
+
if (want) {
|
|
7312
|
+
const hit = voices.find((v) => v && v.voiceURI === want);
|
|
7313
|
+
if (hit) return hit;
|
|
7314
|
+
}
|
|
7315
|
+
const lang = String(cfg && cfg.voiceLang || "");
|
|
7316
|
+
if (lang) {
|
|
7317
|
+
const base = lang.split("-")[0].toLowerCase();
|
|
7318
|
+
return voices.find((v) => String(v.lang || "").toLowerCase() === lang.toLowerCase()) || voices.find((v) => String(v.lang || "").toLowerCase().startsWith(base)) || null;
|
|
7319
|
+
}
|
|
7320
|
+
if (!text || /[\u4E00-\u9FFF]/.test(text)) {
|
|
7321
|
+
const zh = voices.find((v) => /^zh/i.test(String(v.lang || "")));
|
|
7322
|
+
if (zh) return zh;
|
|
7323
|
+
}
|
|
7324
|
+
return null;
|
|
7325
|
+
}
|
|
7326
|
+
function useLocalVoices() {
|
|
7327
|
+
const [, force] = (0, import_react10.useState)(0);
|
|
7328
|
+
const ref = (0, import_react10.useRef)(null);
|
|
7329
|
+
if (ref.current === null) ref.current = localVoices();
|
|
7330
|
+
(0, import_react10.useEffect)(() => {
|
|
7331
|
+
const s = synthOf();
|
|
7332
|
+
const onChange = () => {
|
|
7333
|
+
ref.current = localVoices();
|
|
7334
|
+
force((n) => n + 1);
|
|
7335
|
+
};
|
|
7336
|
+
if (s && typeof s.addEventListener === "function") {
|
|
7337
|
+
try {
|
|
7338
|
+
s.addEventListener("voiceschanged", onChange);
|
|
7339
|
+
} catch {
|
|
7340
|
+
}
|
|
7341
|
+
}
|
|
7342
|
+
if (ref.current.length === 0) onChange();
|
|
7343
|
+
return () => {
|
|
7344
|
+
if (s && typeof s.removeEventListener === "function") {
|
|
7345
|
+
try {
|
|
7346
|
+
s.removeEventListener("voiceschanged", onChange);
|
|
7347
|
+
} catch {
|
|
7348
|
+
}
|
|
7349
|
+
}
|
|
7350
|
+
};
|
|
7351
|
+
}, []);
|
|
7352
|
+
return ref.current;
|
|
7353
|
+
}
|
|
7354
|
+
var voiceEpoch = 0;
|
|
7355
|
+
function speakVoice(text, cfg) {
|
|
7356
|
+
const t = String(text || "").trim();
|
|
7357
|
+
if (!t) return false;
|
|
7358
|
+
const s = synthOf();
|
|
7359
|
+
const Ctor = utterCtor();
|
|
7360
|
+
if (!s || !Ctor) return false;
|
|
7361
|
+
const c = cfg || {};
|
|
7362
|
+
let utt = null;
|
|
7363
|
+
try {
|
|
7364
|
+
utt = new Ctor(t);
|
|
7365
|
+
} catch {
|
|
7366
|
+
return false;
|
|
7367
|
+
}
|
|
7368
|
+
if (!utt) return false;
|
|
7369
|
+
utt.rate = typeof c.voiceRate === "number" ? Math.min(2, Math.max(0.5, c.voiceRate)) : 1;
|
|
7370
|
+
utt.volume = typeof c.voiceVolume === "number" ? Math.min(1, Math.max(0, c.voiceVolume)) : 1;
|
|
7371
|
+
let lang = String(c.voiceLang || "");
|
|
7372
|
+
if (!lang && /[\u4E00-\u9FFF]/.test(t)) lang = "zh-CN";
|
|
7373
|
+
if (lang) utt.lang = lang;
|
|
7374
|
+
const voice = pickVoice(c, t);
|
|
7375
|
+
if (voice) {
|
|
7376
|
+
utt.voice = voice;
|
|
7377
|
+
if (voice.lang) utt.lang = voice.lang;
|
|
7378
|
+
}
|
|
7379
|
+
const epoch = ++voiceEpoch;
|
|
7380
|
+
try {
|
|
7381
|
+
s.cancel();
|
|
7382
|
+
} catch {
|
|
7383
|
+
}
|
|
7384
|
+
const delay = () => {
|
|
7385
|
+
if (epoch !== voiceEpoch) return;
|
|
7386
|
+
try {
|
|
7387
|
+
s.speak(utt);
|
|
7388
|
+
} catch {
|
|
7389
|
+
}
|
|
7390
|
+
};
|
|
7391
|
+
let waited = 0;
|
|
7392
|
+
const poll = () => {
|
|
7393
|
+
if (epoch !== voiceEpoch) return;
|
|
7394
|
+
let busy = false;
|
|
7395
|
+
try {
|
|
7396
|
+
busy = s.speaking === true || s.pending === true;
|
|
7397
|
+
} catch {
|
|
7398
|
+
busy = false;
|
|
7399
|
+
}
|
|
7400
|
+
if (!busy || waited >= 800) {
|
|
7401
|
+
delay();
|
|
7402
|
+
return;
|
|
7403
|
+
}
|
|
7404
|
+
waited += 20;
|
|
7405
|
+
setTimeout(poll, 20);
|
|
7406
|
+
};
|
|
7407
|
+
poll();
|
|
7408
|
+
return true;
|
|
7409
|
+
}
|
|
7410
|
+
function voiceTone(cfg) {
|
|
7411
|
+
const m = cfg && cfg.voiceMode;
|
|
7412
|
+
return m === "detailed" || m === "medium" ? m : "brief";
|
|
7413
|
+
}
|
|
7414
|
+
function cardTone(cfg) {
|
|
7415
|
+
const m = cfg && cfg.cardMode;
|
|
7416
|
+
return m === "brief" || m === "medium" ? m : "detailed";
|
|
7417
|
+
}
|
|
7418
|
+
function endReasonSpeech(reason) {
|
|
7419
|
+
if (reason === "error") return "\u51FA\u9519\u4E86";
|
|
7420
|
+
if (reason === "aborted") return "\u5DF2\u505C\u6B62";
|
|
7421
|
+
if (reason === "blocked") return "\u53D7\u963B\u505C\u6B62\u4E86";
|
|
7422
|
+
if (reason === "max-tokens") return "\u8FBE\u5230\u8F93\u51FA\u4E0A\u9650\u505C\u6B62\u4E86";
|
|
7423
|
+
if (reason === "interrupted") return "\u88AB\u6253\u65AD\u4E86";
|
|
7424
|
+
return "\u5B8C\u6210\u4E86";
|
|
7425
|
+
}
|
|
7426
|
+
function endBroadcastText(success, record, task, cfg) {
|
|
7427
|
+
const mode = voiceTone(cfg);
|
|
7428
|
+
const reason = record && record.endReason || "";
|
|
7429
|
+
const title = record && record.title || task && task.title || "";
|
|
7430
|
+
if (mode === "brief") {
|
|
7431
|
+
return success ? "\u4EFB\u52A1\u5B8C\u6210" : "\u4EFB\u52A1\u505C\u6B62\u4E86";
|
|
7432
|
+
}
|
|
7433
|
+
if (mode === "medium") {
|
|
7434
|
+
const who = title ? "\u4EFB\u52A1\u300C" + truncate2(title, 30) + "\u300D" : "\u4EFB\u52A1";
|
|
7435
|
+
const parts2 = [success ? who + "\u5B8C\u6210\u4E86" : who + "\u505C\u6B62\u4E86"];
|
|
7436
|
+
if (!success) parts2.push("\uFF0C\u539F\u56E0\uFF1A" + endReasonSpeech(reason));
|
|
7437
|
+
const dur2 = record && record.duration || 0;
|
|
7438
|
+
if (dur2 > 0) parts2.push("\uFF0C\u8017\u65F6" + fmtDur(dur2));
|
|
7439
|
+
parts2.push("\u3002");
|
|
7440
|
+
return parts2.join("");
|
|
7441
|
+
}
|
|
7442
|
+
const parts = [];
|
|
7443
|
+
if (title) parts.push("\u4EFB\u52A1\uFF1A" + truncate2(title, 30) + "\u3002");
|
|
7444
|
+
parts.push(success ? "\u5DF2\u5B8C\u6210\u3002" : "\u7ED3\u675F\uFF0C\u539F\u56E0\uFF1A" + endReasonSpeech(reason) + "\u3002");
|
|
7445
|
+
const dur = record && record.duration || 0;
|
|
7446
|
+
if (dur > 0) parts.push("\u8017\u65F6" + fmtDur(dur) + "\u3002");
|
|
7447
|
+
const turns = record && record.turns || task && task.turns || 0;
|
|
7448
|
+
const steps = record && record.steps || task && task.steps || 0;
|
|
7449
|
+
const tools = record && record.toolCalls || task && task.toolCalls || 0;
|
|
7450
|
+
if (turns || steps) parts.push("\u5171" + turns + "\u56DE\u5408" + steps + "\u6B65" + (tools ? "\u3001\u5DE5\u5177" + tools + "\u6B21" : "") + "\u3002");
|
|
7451
|
+
if (!success && record && record.errorMessage) parts.push("\u9519\u8BEF\uFF1A" + truncate2(String(record.errorMessage).replace(/[`*_#>\[\]()]/g, " "), 50) + "\u3002");
|
|
7452
|
+
if (success && record && record.lastText) {
|
|
7453
|
+
const plain = truncate2(String(record.lastText).replace(/[#*_`>\[\]()!]/g, "").replace(/\s+/g, " "), 40);
|
|
7454
|
+
if (plain) parts.push("\u56DE\u590D\u6458\u8981\uFF1A" + plain);
|
|
7455
|
+
}
|
|
7456
|
+
return parts.join("");
|
|
7457
|
+
}
|
|
7458
|
+
function confirmBroadcastText(task, approval, cfg) {
|
|
7459
|
+
const mode = voiceTone(cfg);
|
|
7460
|
+
if (mode === "brief") return "\u4EFB\u52A1\u9700\u8981\u6388\u6743";
|
|
7461
|
+
const tool = approval && approval.toolName || "\u5DE5\u5177";
|
|
7462
|
+
const scene = toolLabel(tool);
|
|
7463
|
+
if (mode === "medium") {
|
|
7464
|
+
const who = task && task.title ? "\u4EFB\u52A1\u300C" + truncate2(task.title, 30) + "\u300D" : "\u4EFB\u52A1";
|
|
7465
|
+
return who + "\u9700\u8981\u6388\u6743\uFF0C\u6B63\u5728\u7B49\u4F60\u6279\u51C6" + (scene || "\u5DE5\u5177 " + tool) + "\u3002";
|
|
7466
|
+
}
|
|
7467
|
+
const parts = [];
|
|
7468
|
+
if (task && task.title) parts.push("\u4EFB\u52A1\uFF1A" + truncate2(task.title, 30) + "\u3002");
|
|
7469
|
+
parts.push("\u6B63\u5728\u7B49\u5F85\u4F60\u6279\u51C6" + (scene ? "\u6267\u884C" + scene : "") + "\uFF0C\u5DE5\u5177\u662F" + tool + "\uFF0C\u8BF7\u56DE\u5230\u4F1A\u8BDD\u5904\u7406\u3002");
|
|
7470
|
+
return parts.join("");
|
|
7471
|
+
}
|
|
7472
|
+
function stuckBroadcastText(task, cfg) {
|
|
7473
|
+
const mode = voiceTone(cfg);
|
|
7474
|
+
const where = (task && task.isSubtask ? "\u5B50\u4EFB\u52A1" : "\u4E3B\u4EFB\u52A1") + (task && task.title ? "\u300C" + truncate2(task.title, 30) + "\u300D" : "");
|
|
7475
|
+
if (mode === "brief") return where + "\u5361\u4F4F\u4E86";
|
|
7476
|
+
if (mode === "medium") {
|
|
7477
|
+
return where + "\u5361\u4F4F\u4E86\uFF0C\u5DF2\u7ECF" + fmtDur(Math.max(0, cfg && cfg.stuckMs || STUCK_MS)) + "\u6CA1\u6709\u4EFB\u4F55\u52A8\u9759\u3002";
|
|
7478
|
+
}
|
|
7479
|
+
const parts = [where + "\u5361\u4F4F\u4E86\u3002"];
|
|
7480
|
+
parts.push("\u7F16\u7A0B\u9636\u6BB5\u5DF2\u7ECF" + fmtDur(Math.max(0, cfg && cfg.stuckMs || STUCK_MS)) + "\u6CA1\u6709\u4EFB\u4F55\u52A8\u9759\uFF0C");
|
|
7481
|
+
const tool = task && task.lastToolName || "";
|
|
7482
|
+
const scene = tool ? toolLabel(tool) : "";
|
|
7483
|
+
parts.push(tool ? "\u6700\u540E\u5728\u6267\u884C" + tool + (scene ? "\uFF08" + scene + "\uFF09" : "") + "\uFF0C" : "");
|
|
7484
|
+
parts.push("\u8BF7\u67E5\u770B\u3002");
|
|
7485
|
+
return parts.join("");
|
|
7486
|
+
}
|
|
7487
|
+
var STUCK_MS = 18e3;
|
|
7278
7488
|
var notifyStore = {
|
|
7279
7489
|
snap: { status: null, loading: false, error: null },
|
|
7280
7490
|
listeners: /* @__PURE__ */ new Set(),
|
|
@@ -7314,27 +7524,56 @@ function useNotify() {
|
|
|
7314
7524
|
function pageVisible() {
|
|
7315
7525
|
return typeof document === "undefined" || document.visibilityState === "visible";
|
|
7316
7526
|
}
|
|
7317
|
-
function
|
|
7318
|
-
if (typeof document === "undefined" || typeof window === "undefined") return "";
|
|
7319
|
-
if (typeof document.querySelectorAll !== "function") return "";
|
|
7527
|
+
function currentSelectedSession() {
|
|
7528
|
+
if (typeof document === "undefined" || typeof window === "undefined") return { id: "", title: "" };
|
|
7529
|
+
if (typeof document.querySelectorAll !== "function") return { id: "", title: "" };
|
|
7530
|
+
let byTitle = null;
|
|
7320
7531
|
for (const el of document.querySelectorAll('[role="treeitem"][aria-selected="true"]')) {
|
|
7321
|
-
const
|
|
7322
|
-
if (
|
|
7323
|
-
|
|
7324
|
-
|
|
7532
|
+
const k = typeof el.getAttribute === "function" ? el.getAttribute("data-row-key") : null;
|
|
7533
|
+
if (typeof k === "string" && k.indexOf("session:") === 0) {
|
|
7534
|
+
return { id: k.slice(8), title: (el.textContent || "").trim() };
|
|
7535
|
+
}
|
|
7536
|
+
if (!byTitle) {
|
|
7537
|
+
const r = typeof el.getBoundingClientRect === "function" ? el.getBoundingClientRect() : null;
|
|
7538
|
+
if (r && r.width > 0 && r.height > 0 && r.right <= window.innerWidth * 0.35) {
|
|
7539
|
+
const text = (el.textContent || "").trim();
|
|
7540
|
+
if (text) byTitle = text;
|
|
7541
|
+
}
|
|
7325
7542
|
}
|
|
7326
7543
|
}
|
|
7327
|
-
return "";
|
|
7544
|
+
return { id: "", title: byTitle || "" };
|
|
7328
7545
|
}
|
|
7329
7546
|
function titleMatches(a, b) {
|
|
7330
7547
|
return !!a && !!b && (a === b || a.indexOf(b) !== -1 || b.indexOf(a) !== -1);
|
|
7331
7548
|
}
|
|
7549
|
+
var overlayCtx = null;
|
|
7550
|
+
function openSessionById(sessionId) {
|
|
7551
|
+
if (!sessionId || !overlayCtx) return false;
|
|
7552
|
+
let uiw = null;
|
|
7553
|
+
try {
|
|
7554
|
+
uiw = typeof overlayCtx.get === "function" ? overlayCtx.get("uiWorkspace") : overlayCtx.uiWorkspace;
|
|
7555
|
+
} catch {
|
|
7556
|
+
return false;
|
|
7557
|
+
}
|
|
7558
|
+
if (!uiw || typeof uiw.openSession !== "function") return false;
|
|
7559
|
+
try {
|
|
7560
|
+
uiw.openSession(sessionId);
|
|
7561
|
+
return true;
|
|
7562
|
+
} catch {
|
|
7563
|
+
return false;
|
|
7564
|
+
}
|
|
7565
|
+
}
|
|
7332
7566
|
function openSessionByTitle(title) {
|
|
7333
7567
|
if (typeof document === "undefined" || typeof window === "undefined") return false;
|
|
7334
7568
|
if (typeof document.querySelectorAll !== "function" || !title) return false;
|
|
7335
7569
|
for (const el of document.querySelectorAll('[role="treeitem"]')) {
|
|
7336
|
-
const
|
|
7337
|
-
|
|
7570
|
+
const k = typeof el.getAttribute === "function" ? el.getAttribute("data-row-key") : null;
|
|
7571
|
+
const isSessionRow = typeof k === "string" ? k.indexOf("session:") === 0 : true;
|
|
7572
|
+
if (!isSessionRow) continue;
|
|
7573
|
+
if (typeof k !== "string") {
|
|
7574
|
+
const r = typeof el.getBoundingClientRect === "function" ? el.getBoundingClientRect() : null;
|
|
7575
|
+
if (!r || r.width <= 0 || r.height <= 0 || r.right > window.innerWidth * 0.35) continue;
|
|
7576
|
+
}
|
|
7338
7577
|
if (!titleMatches((el.textContent || "").trim(), title)) continue;
|
|
7339
7578
|
const link = typeof el.querySelector === "function" ? el.querySelector("a,button") : null;
|
|
7340
7579
|
const target = link || el;
|
|
@@ -7353,9 +7592,10 @@ function Toast(props) {
|
|
|
7353
7592
|
setClosing(true);
|
|
7354
7593
|
}, []);
|
|
7355
7594
|
const jump = (0, import_react10.useCallback)(() => {
|
|
7356
|
-
if (!t.sessionTitle) return;
|
|
7357
|
-
|
|
7358
|
-
|
|
7595
|
+
if (!t.sessionTitle && !t.sessionId) return;
|
|
7596
|
+
const ok = openSessionById(t.sessionId) || (t.fallbackSessionId ? openSessionById(t.fallbackSessionId) : false) || (t.sessionTitle ? openSessionByTitle(t.sessionTitle) : false);
|
|
7597
|
+
if (ok && t.kind !== "confirm" && t.kind !== "stuck") setClosing(true);
|
|
7598
|
+
}, [t.sessionId, t.sessionTitle, t.fallbackSessionId, t.kind]);
|
|
7359
7599
|
(0, import_react10.useEffect)(() => {
|
|
7360
7600
|
if (t.closing && !closing) setClosing(true);
|
|
7361
7601
|
}, [t.closing, closing]);
|
|
@@ -7368,13 +7608,13 @@ function Toast(props) {
|
|
|
7368
7608
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
7369
7609
|
"div",
|
|
7370
7610
|
{
|
|
7371
|
-
className: "dknt-toast" + (t.kind === "confirm" ? " dknt-toast-confirm" : "") + (t.sessionTitle ? " clickable" : "") + (props.collapsed ? " collapsed" : "") + (closing ? " out" : ""),
|
|
7372
|
-
onClick: t.sessionTitle ? jump : void 0,
|
|
7611
|
+
className: "dknt-toast" + (t.kind === "confirm" ? " dknt-toast-confirm" : "") + (t.sessionTitle || t.sessionId ? " clickable" : "") + (props.collapsed ? " collapsed" : "") + (closing ? " out" : ""),
|
|
7612
|
+
onClick: t.sessionTitle || t.sessionId ? jump : void 0,
|
|
7373
7613
|
children: [
|
|
7374
7614
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-toast-head", children: [
|
|
7375
7615
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-toast-mark", style: { background: markColor } }),
|
|
7376
7616
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dknt-toast-title", title: t.sessionTitle || t.title, children: [
|
|
7377
|
-
t.kind === "confirm" ? "\u270B " : "",
|
|
7617
|
+
t.kind === "confirm" ? "\u270B " : t.kind === "stuck" ? "\u23F3 " : "",
|
|
7378
7618
|
props.collapsed ? t.sessionTitle || t.title : t.title,
|
|
7379
7619
|
!props.collapsed && t.sessionTitle && t.kind !== "confirm" ? " \xB7 " + t.sessionTitle : ""
|
|
7380
7620
|
] }),
|
|
@@ -7398,6 +7638,7 @@ function Toast(props) {
|
|
|
7398
7638
|
);
|
|
7399
7639
|
}
|
|
7400
7640
|
function NotifyOverlay(props) {
|
|
7641
|
+
if (props && props.ctx) overlayCtx = props.ctx;
|
|
7401
7642
|
const snap = useNotify();
|
|
7402
7643
|
const [toasts, setToasts] = (0, import_react10.useState)([]);
|
|
7403
7644
|
const [stackHover, setStackHover] = (0, import_react10.useState)(false);
|
|
@@ -7405,8 +7646,15 @@ function NotifyOverlay(props) {
|
|
|
7405
7646
|
const remindedApprovalsRef = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
|
|
7406
7647
|
const toastSeqRef = (0, import_react10.useRef)(0);
|
|
7407
7648
|
const pushToast = (0, import_react10.useCallback)((toast) => {
|
|
7649
|
+
const st = notifyStore.snap.status;
|
|
7650
|
+
const cfg = st && st.config;
|
|
7651
|
+
if (cfg && cfg.notifyCards === false) return;
|
|
7408
7652
|
setToasts((prev) => prev.concat([toast]).slice(-12));
|
|
7409
7653
|
}, []);
|
|
7654
|
+
(0, import_react10.useEffect)(() => {
|
|
7655
|
+
const cfg = snap.status && snap.status.config;
|
|
7656
|
+
if (cfg && cfg.notifyCards === false) setToasts((prev) => prev.length ? [] : prev);
|
|
7657
|
+
}, [snap.status]);
|
|
7410
7658
|
(0, import_react10.useEffect)(() => {
|
|
7411
7659
|
let stopped = false;
|
|
7412
7660
|
let timer = null;
|
|
@@ -7460,21 +7708,30 @@ function NotifyOverlay(props) {
|
|
|
7460
7708
|
const fresh = approvals.filter((a) => a && !seen.has(a.id));
|
|
7461
7709
|
if (fresh.length === 0) continue;
|
|
7462
7710
|
for (const a of fresh) seen.add(a.id);
|
|
7711
|
+
if (cfg.voiceNotify === true && cfg.voiceOnConfirm !== false) {
|
|
7712
|
+
speakVoice(confirmBroadcastText(task, fresh[0], cfg), cfg);
|
|
7713
|
+
}
|
|
7463
7714
|
if (cfg.notifyOnConfirm === false) continue;
|
|
7464
7715
|
const toolName = fresh[0].toolName || "";
|
|
7465
7716
|
const scene = toolLabel(toolName);
|
|
7717
|
+
const tone = cardTone(cfg);
|
|
7466
7718
|
const lines = [
|
|
7467
7719
|
"\u4EFB\u52A1\uFF1A" + (task.title || "(\u65E0\u6807\u9898)"),
|
|
7468
7720
|
"\u5DE5\u5177\uFF1A" + (toolName || "\u672A\u77E5") + (scene ? "\uFF08" + scene + "\uFF09" : "")
|
|
7469
7721
|
];
|
|
7470
|
-
if (fresh[0].reason) lines.push("\u8BF4\u660E\uFF1A" + truncate2(fresh[0].reason, 140));
|
|
7471
|
-
|
|
7722
|
+
if (tone !== "brief" && fresh[0].reason) lines.push("\u8BF4\u660E\uFF1A" + truncate2(fresh[0].reason, 140));
|
|
7723
|
+
if (fresh.length > 1) {
|
|
7724
|
+
lines.push(tone === "brief" ? "\u5171 " + fresh.length + " \u9879\u7B49\u5F85\u786E\u8BA4" : "\u5171 " + fresh.length + " \u9879\u7B49\u5F85\u4F60\u7684\u786E\u8BA4");
|
|
7725
|
+
} else if (tone === "detailed") {
|
|
7726
|
+
lines.push("\u8BF7\u5728\u4F1A\u8BDD\u91CC\u786E\u8BA4\u540E\u7EE7\u7EED");
|
|
7727
|
+
}
|
|
7472
7728
|
pushToast({
|
|
7473
7729
|
id: ++toastSeqRef.current,
|
|
7474
7730
|
kind: "confirm",
|
|
7475
7731
|
title: "\u4EFB\u52A1\u9700\u8981\u786E\u8BA4",
|
|
7476
7732
|
body: lines.join("\n"),
|
|
7477
7733
|
// 点卡片直达该会话去处理审批(需确认卡跳转后不收起——审批没处理完它就该在)
|
|
7734
|
+
sessionId: task.sessionId || "",
|
|
7478
7735
|
sessionTitle: task.title || "",
|
|
7479
7736
|
// 卡片与这批审批项绑定:approval/decided 后宿主把它们移出 approvals,
|
|
7480
7737
|
// 下面的对账 effect 据此自动收起卡片(处理完就不该再占着右上角)。
|
|
@@ -7515,13 +7772,15 @@ function NotifyOverlay(props) {
|
|
|
7515
7772
|
(0, import_react10.useEffect)(() => {
|
|
7516
7773
|
const timer = setInterval(() => {
|
|
7517
7774
|
if (!pageVisible()) return;
|
|
7518
|
-
const
|
|
7519
|
-
if (!
|
|
7775
|
+
const cur = currentSelectedSession();
|
|
7776
|
+
if (!cur.id && !cur.title) return;
|
|
7520
7777
|
setToasts((prev) => {
|
|
7521
7778
|
let changed = false;
|
|
7522
7779
|
const next = prev.map((x) => {
|
|
7523
|
-
if (x.kind === "confirm" || x.
|
|
7524
|
-
if (!
|
|
7780
|
+
if (x.kind === "confirm" || x.kind === "stuck" || x.closing) return x;
|
|
7781
|
+
if (!x.sessionTitle && !x.sessionId) return x;
|
|
7782
|
+
const hit = cur.id && x.sessionId && cur.id === x.sessionId || !cur.id && x.sessionTitle && titleMatches(x.sessionTitle, cur.title);
|
|
7783
|
+
if (!hit) return x;
|
|
7525
7784
|
changed = true;
|
|
7526
7785
|
return Object.assign({}, x, { closing: true });
|
|
7527
7786
|
});
|
|
@@ -7530,33 +7789,115 @@ function NotifyOverlay(props) {
|
|
|
7530
7789
|
}, 500);
|
|
7531
7790
|
return () => clearInterval(timer);
|
|
7532
7791
|
}, []);
|
|
7792
|
+
const stuckSeenRef = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
|
|
7793
|
+
(0, import_react10.useEffect)(() => {
|
|
7794
|
+
const st = snap.status;
|
|
7795
|
+
if (!st || !st.active) return;
|
|
7796
|
+
const cfg = st.config || {};
|
|
7797
|
+
const now = st.now || Date.now();
|
|
7798
|
+
const activeIds = new Set(st.active.map((x) => x.sessionId));
|
|
7799
|
+
for (const sid of Array.from(stuckSeenRef.current.keys())) {
|
|
7800
|
+
if (!activeIds.has(sid)) stuckSeenRef.current.delete(sid);
|
|
7801
|
+
}
|
|
7802
|
+
const parentsWaitingOnSubtask = /* @__PURE__ */ new Set();
|
|
7803
|
+
for (const t of st.active) {
|
|
7804
|
+
if (t.isSubtask && t.parentSessionId) parentsWaitingOnSubtask.add(t.parentSessionId);
|
|
7805
|
+
}
|
|
7806
|
+
for (const task of st.active) {
|
|
7807
|
+
const approvals = Array.isArray(task.approvals) ? task.approvals : [];
|
|
7808
|
+
if (approvals.length > 0) {
|
|
7809
|
+
stuckSeenRef.current.delete(task.sessionId);
|
|
7810
|
+
continue;
|
|
7811
|
+
}
|
|
7812
|
+
if (task.phase !== "code") {
|
|
7813
|
+
continue;
|
|
7814
|
+
}
|
|
7815
|
+
if (parentsWaitingOnSubtask.has(task.sessionId)) continue;
|
|
7816
|
+
const lastAct = task.lastActivityAt || task.phaseAt || 0;
|
|
7817
|
+
if (!lastAct || now - lastAct < STUCK_MS) continue;
|
|
7818
|
+
const prev = stuckSeenRef.current.get(task.sessionId);
|
|
7819
|
+
if (prev === lastAct) continue;
|
|
7820
|
+
stuckSeenRef.current.set(task.sessionId, lastAct);
|
|
7821
|
+
const stuckMs = now - lastAct;
|
|
7822
|
+
if (cfg.voiceNotify === true && cfg.voiceOnStuck !== false) {
|
|
7823
|
+
speakVoice(stuckBroadcastText(task, Object.assign({}, cfg, { stuckMs })), cfg);
|
|
7824
|
+
}
|
|
7825
|
+
if (cfg.notifyOnStuck === false) continue;
|
|
7826
|
+
const label = task.isSubtask ? "\u5B50\u4EFB\u52A1" : "\u4E3B\u4EFB\u52A1";
|
|
7827
|
+
const title = task.title || "(\u65E0\u6807\u9898)";
|
|
7828
|
+
const tool = task.lastToolName || "";
|
|
7829
|
+
const tone = cardTone(cfg);
|
|
7830
|
+
const lines = ["\u4EFB\u52A1\uFF1A" + label + "\xB7" + title];
|
|
7831
|
+
if (tone !== "brief") lines.push("\u5DF2\u505C\u6EDE\uFF1A" + fmtDur(stuckMs) + "\uFF08\u7F16\u7A0B\u9636\u6BB5\u65E0\u6D3B\u52A8\uFF09");
|
|
7832
|
+
if (tone === "detailed") {
|
|
7833
|
+
if (tool) lines.push("\u6700\u540E\u52A8\u4F5C\uFF1A" + tool + (toolLabel(tool) ? "\uFF08" + toolLabel(tool) + "\uFF09" : ""));
|
|
7834
|
+
lines.push("\u6062\u590D\u6D3B\u52A8\u6216\u4EFB\u52A1\u7ED3\u675F\u540E\u81EA\u52A8\u6536\u8D77\uFF1B\u70B9\u51FB\u5361\u7247\u76F4\u8FBE\u4F1A\u8BDD");
|
|
7835
|
+
}
|
|
7836
|
+
pushToast({
|
|
7837
|
+
id: ++toastSeqRef.current,
|
|
7838
|
+
kind: "stuck",
|
|
7839
|
+
title: label + "\u5361\u4F4F\u4E86",
|
|
7840
|
+
body: lines.join("\n"),
|
|
7841
|
+
sessionId: task.sessionId || "",
|
|
7842
|
+
sessionTitle: title,
|
|
7843
|
+
// 子任务会话通常不在侧栏里:跳不到自己时回退到父会话(看主会话里的子代理进度)
|
|
7844
|
+
fallbackSessionId: task.isSubtask && task.parentSessionId ? task.parentSessionId : "",
|
|
7845
|
+
// 停点指纹:恢复活动(lastActivityAt 变了)即由下面的对账 effect 收起
|
|
7846
|
+
stuckAt: lastAct
|
|
7847
|
+
});
|
|
7848
|
+
}
|
|
7849
|
+
}, [snap.status]);
|
|
7850
|
+
(0, import_react10.useEffect)(() => {
|
|
7851
|
+
const st = snap.status;
|
|
7852
|
+
if (!st || !st.active) return;
|
|
7853
|
+
const byId = new Map(st.active.map((x) => [x.sessionId, x]));
|
|
7854
|
+
setToasts((prev) => {
|
|
7855
|
+
let changed = false;
|
|
7856
|
+
const next = prev.map((x) => {
|
|
7857
|
+
if (x.kind !== "stuck" || x.closing) return x;
|
|
7858
|
+
const task = byId.get(x.sessionId);
|
|
7859
|
+
const stillStalled = !!task && (task.lastActivityAt || task.phaseAt || 0) === x.stuckAt && (Array.isArray(task.approvals) ? task.approvals.length : 0) === 0;
|
|
7860
|
+
if (stillStalled) return x;
|
|
7861
|
+
changed = true;
|
|
7862
|
+
return Object.assign({}, x, { closing: true });
|
|
7863
|
+
});
|
|
7864
|
+
return changed ? next : prev;
|
|
7865
|
+
});
|
|
7866
|
+
}, [snap.status]);
|
|
7533
7867
|
const handleTaskEnd = (task, record, cfg) => {
|
|
7534
7868
|
const reason = record && record.endReason || "";
|
|
7535
7869
|
const success = isSuccessReason2(reason);
|
|
7536
7870
|
const info = endInfo(reason);
|
|
7537
7871
|
const wanted = success ? cfg.notifyOnComplete : cfg.notifyOnError;
|
|
7872
|
+
if (cfg.voiceNotify === true && (success ? cfg.voiceOnComplete !== false : cfg.voiceOnError !== false)) {
|
|
7873
|
+
speakVoice(endBroadcastText(success, record, task, cfg), cfg);
|
|
7874
|
+
}
|
|
7538
7875
|
if (wanted === false) return;
|
|
7539
7876
|
const models = record && record.models && record.models.length ? record.models.join(", ") : task.models && task.models.length ? task.models.join(", ") : "\u672A\u77E5\u6A21\u578B";
|
|
7540
7877
|
const provider = record && record.provider || task.provider || "";
|
|
7541
7878
|
const startTs = record && record.startTime || task.startTime;
|
|
7542
7879
|
const endTs = record && record.endTime || Date.now();
|
|
7543
|
-
const
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7880
|
+
const tone = cardTone(cfg);
|
|
7881
|
+
const durText = fmtDur(record && record.duration || endTs - startTs);
|
|
7882
|
+
const lines = ["\u4EFB\u52A1\uFF1A" + (record && record.title || task.title || "(\u65E0\u6807\u9898)")];
|
|
7883
|
+
if (tone !== "brief") lines.push("\u6A21\u578B\uFF1A" + models + (provider ? "\uFF08" + provider + "\uFF09" : ""));
|
|
7884
|
+
lines.push(tone === "brief" ? "\u8017\u65F6\uFF1A" + durText : "\u8017\u65F6\uFF1A" + durText + "\uFF08" + fmtTime2(startTs) + " \u2192 " + fmtTime2(endTs) + "\uFF09");
|
|
7885
|
+
if (tone === "detailed") {
|
|
7886
|
+
lines.push("\u56DE\u5408 " + (record && record.turns || task.turns || 0) + " \xB7 \u6B65\u9AA4 " + (record && record.steps || task.steps || 0) + (record && record.toolCalls || task.toolCalls ? " \xB7 \u5DE5\u5177 " + (record && record.toolCalls || task.toolCalls) + " \u6B21" : ""));
|
|
7887
|
+
lines.push("Token\uFF1A\u8F93\u5165 " + fmtNum2(record && record.inputTokens || task.inputTokens) + " / \u8F93\u51FA " + fmtNum2(record && record.outputTokens || task.outputTokens));
|
|
7888
|
+
if (record && record.lastText) lines.push("\u6458\u8981\uFF1A" + truncate2(record.lastText, 140));
|
|
7889
|
+
if (!success && record && record.errorMessage) lines.push("\u9519\u8BEF\uFF1A" + truncate2(record.errorMessage, 120));
|
|
7890
|
+
}
|
|
7552
7891
|
const title = success ? "\u4EFB\u52A1\u5B8C\u6210" : "\u4EFB\u52A1" + info.label;
|
|
7553
7892
|
pushToast({
|
|
7554
7893
|
id: ++toastSeqRef.current,
|
|
7555
7894
|
kind: success ? "success" : info.cls === "err" ? "error" : "warn",
|
|
7556
7895
|
title,
|
|
7557
7896
|
body: lines.join("\n"),
|
|
7558
|
-
//
|
|
7897
|
+
// 绑定会话:点卡片直达该会话;用户点进这个会话(侧栏选中)也视为
|
|
7559
7898
|
// 看到了结果,巡检 effect 据此自动收起卡片。没看过就一直挂着。
|
|
7899
|
+
// sessionId 是权威标识(跳转/对账都用它),标题只作旧宿主回退。
|
|
7900
|
+
sessionId: task.sessionId || "",
|
|
7560
7901
|
sessionTitle: record && record.title || task.title || ""
|
|
7561
7902
|
});
|
|
7562
7903
|
if (cfg.soundNotify !== false) playDoneSound(success, cfg.soundEffect);
|
|
@@ -7593,6 +7934,7 @@ function NotifyOverlay(props) {
|
|
|
7593
7934
|
}
|
|
7594
7935
|
function NotifyView(props) {
|
|
7595
7936
|
const snap = useNotify();
|
|
7937
|
+
const voices = useLocalVoices();
|
|
7596
7938
|
const [cfg, setCfg] = (0, import_react10.useState)(null);
|
|
7597
7939
|
const [saveErr, setSaveErr] = (0, import_react10.useState)("");
|
|
7598
7940
|
const [testing, setTesting] = (0, import_react10.useState)(false);
|
|
@@ -7718,6 +8060,19 @@ function NotifyView(props) {
|
|
|
7718
8060
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-sec-sub", children: "\u54EA\u4E9B\u65F6\u523B\u63D0\u9192\u4F60\uFF1B\u4E0E\u3010\u4EFB\u52A1\u52A8\u753B\u3011\u7684\u52A8\u6548\u4E92\u4E0D\u4F9D\u8D56" })
|
|
7719
8061
|
] }),
|
|
7720
8062
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-rows-narrow", children: [
|
|
8063
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8064
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u9875\u5185\u5361\u7247" }),
|
|
8065
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
8066
|
+
"button",
|
|
8067
|
+
{
|
|
8068
|
+
type: "button",
|
|
8069
|
+
className: "dknt-miniswitch" + (cfg.notifyCards !== false ? " on" : ""),
|
|
8070
|
+
onClick: () => patch({ notifyCards: cfg.notifyCards === false }),
|
|
8071
|
+
children: cfg.notifyCards !== false ? "\u5F00" : "\u5173"
|
|
8072
|
+
}
|
|
8073
|
+
),
|
|
8074
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u53F3\u4FA7\u901A\u77E5\u5361\u7247\u603B\u5F00\u5173\uFF1A\u5173\u95ED\u540E\u4E0B\u9762\u5404\u7C7B\u5361\u7247\uFF08\u5B8C\u6210 / \u5F02\u5E38 / \u9700\u786E\u8BA4 / \u5361\u4F4F\uFF09\u4E00\u5F8B\u4E0D\u5F39\uFF0C\u5DF2\u6302\u7740\u7684\u4E00\u5E76\u6536\u8D77\uFF1B\u8BED\u97F3\u64AD\u62A5\u3001\u63D0\u793A\u97F3\u3001\u7CFB\u7EDF\u901A\u77E5\u3001\u9489\u9489\u98DE\u4E66\u63A8\u9001\u4E0D\u53D7\u5F71\u54CD" })
|
|
8075
|
+
] }),
|
|
7721
8076
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
7722
8077
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u5B8C\u6210\u901A\u77E5" }),
|
|
7723
8078
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -7756,6 +8111,19 @@ function NotifyView(props) {
|
|
|
7756
8111
|
}
|
|
7757
8112
|
),
|
|
7758
8113
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u5DE5\u5177\u7B49\u5F85\u4F60\u6279\u51C6\u65F6\u5F39\u5361\u7247\u5E76\u54CD\u786E\u8BA4\u97F3\uFF1B\u5BA1\u6279\u5904\u7406\u5B8C\u81EA\u52A8\u6536\u8D77\uFF0C\u6CA1\u5904\u7406\u5B8C\u5C31\u4E00\u76F4\u663E\u793A\uFF08\u70B9\u5361\u7247\u76F4\u8FBE\u4F1A\u8BDD\uFF09" })
|
|
8114
|
+
] }),
|
|
8115
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8116
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u5361\u4F4F\u63D0\u9192" }),
|
|
8117
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
8118
|
+
"button",
|
|
8119
|
+
{
|
|
8120
|
+
type: "button",
|
|
8121
|
+
className: "dknt-miniswitch" + (cfg.notifyOnStuck !== false ? " on" : ""),
|
|
8122
|
+
onClick: () => patch({ notifyOnStuck: cfg.notifyOnStuck === false }),
|
|
8123
|
+
children: cfg.notifyOnStuck !== false ? "\u5F00" : "\u5173"
|
|
8124
|
+
}
|
|
8125
|
+
),
|
|
8126
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u7F16\u7A0B\u9636\u6BB5 18 \u79D2\u6CA1\u6709\u52A8\u9759\u65F6\u5F39\u5361\u7247\uFF0C\u5199\u660E\u662F\u4E3B\u4EFB\u52A1\u8FD8\u662F\u5B50\u4EFB\u52A1\u3001\u505C\u6EDE\u4E86\u591A\u4E45\u3001\u6700\u540E\u5728\u6267\u884C\u4EC0\u4E48\uFF1B\u6062\u590D\u6D3B\u52A8 / \u4EFB\u52A1\u7ED3\u675F\u81EA\u52A8\u6536\u8D77\uFF0C\u540C\u4E00\u505C\u70B9\u53EA\u5F39\u4E00\u6B21\uFF08\u8BED\u97F3\u64AD\u62A5\u8D70\u300C\u8BED\u97F3\u64AD\u62A5\u300D\u533A\u7684\u5361\u4F4F\u5F00\u5173\uFF0C\u4E92\u4E0D\u5E72\u6270\uFF09" })
|
|
7759
8127
|
] })
|
|
7760
8128
|
] })
|
|
7761
8129
|
] }, "events"),
|
|
@@ -7765,9 +8133,25 @@ function NotifyView(props) {
|
|
|
7765
8133
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-sec-sub", children: "\u9875\u5185\u5361\u7247\u3001\u63D0\u793A\u97F3\u3001\u6D4F\u89C8\u5668\u7CFB\u7EDF\u901A\u77E5\u53EF\u81EA\u7531\u7EC4\u5408" })
|
|
7766
8134
|
] }),
|
|
7767
8135
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-rows-narrow", children: [
|
|
8136
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8137
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u5361\u7247\u53E3\u5F84" }),
|
|
8138
|
+
[["brief", "\u7B80\u6D01"], ["medium", "\u9002\u4E2D"], ["detailed", "\u8BE6\u7EC6"]].map(([v, label]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
8139
|
+
"button",
|
|
8140
|
+
{
|
|
8141
|
+
type: "button",
|
|
8142
|
+
className: "dknt-miniswitch" + (cardTone(cfg) === v ? " on" : ""),
|
|
8143
|
+
style: { marginRight: 6 },
|
|
8144
|
+
title: "\u53F3\u4FA7\u901A\u77E5\u5361\u7247\u6B63\u6587\u6309" + label + "\u6863\u663E\u793A",
|
|
8145
|
+
onClick: () => patch({ cardMode: v }),
|
|
8146
|
+
children: label
|
|
8147
|
+
},
|
|
8148
|
+
v
|
|
8149
|
+
)),
|
|
8150
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u53F3\u4FA7\u5361\u7247\u6B63\u6587\u5199\u591A\u5C11\uFF08\u4E0E\u5404\u7C7B\u578B\u5F00\u5173\u3001\u8BED\u97F3\u64AD\u62A5\u4E92\u4E0D\u5F71\u54CD\uFF09\uFF1A\u7B80\u6D01\uFF1D\u4EFB\u52A1\u4E0E\u8017\u65F6 / \u8C01\u5361\u4F4F\uFF1B\u9002\u4E2D\uFF1D\u52A0\u6A21\u578B\u3001\u8D77\u6B62\u65F6\u95F4\u3001\u505C\u6EDE\u65F6\u957F\uFF1B\u8BE6\u7EC6\uFF1D\u5168\u90E8\uFF08\u56DE\u5408\u6B65\u9AA4\u3001Token\u3001\u6458\u8981\u6216\u9519\u8BEF\u3001\u6700\u540E\u52A8\u4F5C\uFF09" })
|
|
8151
|
+
] }),
|
|
7768
8152
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
7769
8153
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u5361\u7247\u6536\u7EB3" }),
|
|
7770
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u6240\u6709\u5361\u7247\u90FD\u4E0D\u8D85\u65F6\u81EA\u52A8\u6D88\u5931\uFF1A\u7ED3\u675F\u5361\u7247\u6CA1\u770B\u8FC7\u5C31\u4E00\u76F4\u6302\u7740\uFF08\u540E\u53F0\u8DD1\u5B8C\u7684\u5207\u56DE\u6765\u4E5F\u5728\uFF09\uFF0C\u70B9\u5361\u7247\u76F4\u8FBE\u5BF9\u5E94\u4F1A\u8BDD\uFF0C\u6216\u70B9\u8FDB\u8BE5\u4F1A\u8BDD\uFF0C\u5361\u7247\u81EA\u52A8\u6536\u8D77\uFF1B\u9700\u786E\u8BA4\u5361\u7247\u6302\u5230\u5BA1\u6279\u5904\u7406\u5B8C\u30023 \u5F20\u53CA\u4EE5\u4E0A\u81EA\u52A8\u53E0\u653E\u6210\u6807\u9898\u6761\uFF0C\u9F20\u6807\u79FB\u4E0A\u53BB\u6574\u4F53\u5C55\u5F00" })
|
|
8154
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u6240\u6709\u5361\u7247\u90FD\u4E0D\u8D85\u65F6\u81EA\u52A8\u6D88\u5931\uFF1A\u7ED3\u675F\u5361\u7247\u6CA1\u770B\u8FC7\u5C31\u4E00\u76F4\u6302\u7740\uFF08\u540E\u53F0\u8DD1\u5B8C\u7684\u5207\u56DE\u6765\u4E5F\u5728\uFF09\uFF0C\u70B9\u5361\u7247\u76F4\u8FBE\u5BF9\u5E94\u4F1A\u8BDD\uFF0C\u6216\u70B9\u8FDB\u8BE5\u4F1A\u8BDD\uFF0C\u5361\u7247\u81EA\u52A8\u6536\u8D77\uFF1B\u9700\u786E\u8BA4\u5361\u7247\u6302\u5230\u5BA1\u6279\u5904\u7406\u5B8C\uFF1B\u5361\u4F4F\u5361\u7247\u6302\u5230\u6062\u590D\u6D3B\u52A8\u30023 \u5F20\u53CA\u4EE5\u4E0A\u81EA\u52A8\u53E0\u653E\u6210\u6807\u9898\u6761\uFF0C\u9F20\u6807\u79FB\u4E0A\u53BB\u6574\u4F53\u5C55\u5F00\uFF1B\u8981\u6574\u4F53\u4E0D\u5F39\u770B\u4E0A\u9762\u300C\u9875\u5185\u5361\u7247\u300D\u603B\u5F00\u5173" })
|
|
7771
8155
|
] }),
|
|
7772
8156
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
7773
8157
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u7CFB\u7EDF\u901A\u77E5" }),
|
|
@@ -7833,6 +8217,185 @@ function NotifyView(props) {
|
|
|
7833
8217
|
)) }) : null
|
|
7834
8218
|
] })
|
|
7835
8219
|
] }, "style"),
|
|
8220
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-sec", children: [
|
|
8221
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-sec-head", children: [
|
|
8222
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-sec-title", children: "\u8BED\u97F3\u64AD\u62A5" }),
|
|
8223
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-sec-sub", children: "\u4EFB\u52A1\u5B8C\u6210 / \u505C\u6B62 / \u9700\u8981\u6388\u6743 / \u5361\u4F4F\u65F6\u7528\u6D4F\u89C8\u5668\u8BED\u97F3\uFF08TTS\uFF09\u8BF4\u4E00\u53E5\u8BDD\uFF1B\u4E0E\u63D0\u793A\u97F3\u3001\u7CFB\u7EDF\u901A\u77E5\u4E92\u4E0D\u51B2\u7A81" }),
|
|
8224
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dknt-sec-sw", children: [
|
|
8225
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-sec-swlabel" + (cfg.voiceNotify ? " on" : ""), children: cfg.voiceNotify ? "\u5DF2\u5F00\u542F" : "\u5DF2\u5173\u95ED" }),
|
|
8226
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
8227
|
+
"button",
|
|
8228
|
+
{
|
|
8229
|
+
type: "button",
|
|
8230
|
+
className: "dock-sw" + (cfg.voiceNotify ? " on" : ""),
|
|
8231
|
+
role: "switch",
|
|
8232
|
+
"aria-checked": cfg.voiceNotify,
|
|
8233
|
+
"aria-label": "\u5F00\u5173\u8BED\u97F3\u64AD\u62A5",
|
|
8234
|
+
title: cfg.voiceNotify ? "\u5173\u95ED\u8BED\u97F3\u64AD\u62A5" : "\u5F00\u542F\u8BED\u97F3\u64AD\u62A5",
|
|
8235
|
+
onClick: () => patch({ voiceNotify: !cfg.voiceNotify })
|
|
8236
|
+
}
|
|
8237
|
+
)
|
|
8238
|
+
] })
|
|
8239
|
+
] }),
|
|
8240
|
+
cfg.voiceNotify ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-rows-narrow", children: [
|
|
8241
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8242
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u64AD\u62A5\u53E3\u5F84" }),
|
|
8243
|
+
[["brief", "\u7B80\u6D01"], ["medium", "\u9002\u4E2D"], ["detailed", "\u8BE6\u7EC6"]].map(([v, label]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
8244
|
+
"button",
|
|
8245
|
+
{
|
|
8246
|
+
type: "button",
|
|
8247
|
+
className: "dknt-miniswitch" + (voiceTone(cfg) === v ? " on" : ""),
|
|
8248
|
+
style: { marginRight: 6 },
|
|
8249
|
+
title: "\u8BED\u97F3\u64AD\u62A5\u6309" + label + "\u6863\u8BF4",
|
|
8250
|
+
onClick: () => patch({ voiceMode: v }),
|
|
8251
|
+
children: label
|
|
8252
|
+
},
|
|
8253
|
+
v
|
|
8254
|
+
)),
|
|
8255
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u7B80\u6D01\uFF1A\u4E00\u53E5\u300C\u4EFB\u52A1\u5B8C\u6210 / \u4EFB\u52A1\u505C\u6B62\u4E86 / \u4EFB\u52A1\u9700\u8981\u6388\u6743 / \u4E3B\u4EFB\u52A1\uFF08\u6216\u5B50\u4EFB\u52A1\uFF09\xB7\u6807\u9898 \u5361\u4F4F\u4E86\u300D\uFF1B\u9002\u4E2D\uFF1A\u70B9\u540D\u4EFB\u52A1\uFF0C\u7ED3\u675F\u5E26\u539F\u56E0\u4E0E\u8017\u65F6\u3001\u5361\u4F4F\u5E26\u505C\u6EDE\u65F6\u957F\uFF1B\u8BE6\u7EC6\uFF1A\u7ED3\u675F\u5E26\u56DE\u5408\u7EDF\u8BA1\u4E0E\u56DE\u590D\u6458\u8981\uFF0C\u9700\u6388\u6743\u5E26\u5DE5\u5177\u540D\uFF0C\u5361\u4F4F\u5E26\u6700\u540E\u52A8\u4F5C" })
|
|
8256
|
+
] }),
|
|
8257
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8258
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u64AD\u62A5\u65F6\u523B" }),
|
|
8259
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", style: { minWidth: 0 }, children: [
|
|
8260
|
+
["voiceOnComplete", "\u5B8C\u6210", cfg.voiceOnComplete !== false],
|
|
8261
|
+
["voiceOnError", "\u505C\u6B62", cfg.voiceOnError !== false],
|
|
8262
|
+
["voiceOnConfirm", "\u9700\u6388\u6743", cfg.voiceOnConfirm !== false],
|
|
8263
|
+
["voiceOnStuck", "\u5361\u4F4F", cfg.voiceOnStuck !== false]
|
|
8264
|
+
].map(([key, label, on]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
8265
|
+
"button",
|
|
8266
|
+
{
|
|
8267
|
+
type: "button",
|
|
8268
|
+
className: "dknt-miniswitch" + (on ? " on" : ""),
|
|
8269
|
+
style: { marginRight: 6 },
|
|
8270
|
+
title: key === "voiceOnStuck" ? "\u7F16\u7A0B\u9636\u6BB5 18 \u79D2\u6CA1\u6709\u52A8\u9759\u65F6\u64AD\u62A5\u4E00\u6B21\uFF08\u6062\u590D\u540E\u53EF\u518D\u62A5\uFF09" : "",
|
|
8271
|
+
onClick: () => patch({ [key]: !on }),
|
|
8272
|
+
children: [
|
|
8273
|
+
label,
|
|
8274
|
+
on ? "\xB7\u5F00" : "\xB7\u5173"
|
|
8275
|
+
]
|
|
8276
|
+
},
|
|
8277
|
+
key
|
|
8278
|
+
)) })
|
|
8279
|
+
] }),
|
|
8280
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8281
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u8BED\u901F" }),
|
|
8282
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
8283
|
+
"input",
|
|
8284
|
+
{
|
|
8285
|
+
type: "range",
|
|
8286
|
+
min: "0.5",
|
|
8287
|
+
max: "2",
|
|
8288
|
+
step: "0.05",
|
|
8289
|
+
value: String(cfg.voiceRate || 1),
|
|
8290
|
+
"aria-label": "\u64AD\u62A5\u8BED\u901F",
|
|
8291
|
+
style: { width: 120, accentColor: "var(--dk-accent)" },
|
|
8292
|
+
onChange: (e) => patch({ voiceRate: Number(e.target.value) || 1 })
|
|
8293
|
+
}
|
|
8294
|
+
),
|
|
8295
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dknt-row-sub", children: [
|
|
8296
|
+
Number(cfg.voiceRate || 1).toFixed(2),
|
|
8297
|
+
"\xD7\uFF08\u64AD\u62A5\u6BD4\u6B63\u6587\u6717\u8BFB\u7565\u5FEB\u66F4\u5229\u843D\uFF09"
|
|
8298
|
+
] })
|
|
8299
|
+
] }),
|
|
8300
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8301
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u97F3\u91CF" }),
|
|
8302
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
8303
|
+
"input",
|
|
8304
|
+
{
|
|
8305
|
+
type: "range",
|
|
8306
|
+
min: "0",
|
|
8307
|
+
max: "1",
|
|
8308
|
+
step: "0.05",
|
|
8309
|
+
value: String(cfg.voiceVolume == null ? 1 : cfg.voiceVolume),
|
|
8310
|
+
"aria-label": "\u64AD\u62A5\u97F3\u91CF",
|
|
8311
|
+
style: { width: 120, accentColor: "var(--dk-accent)" },
|
|
8312
|
+
onChange: (e) => patch({ voiceVolume: Number(e.target.value) })
|
|
8313
|
+
}
|
|
8314
|
+
),
|
|
8315
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dknt-row-sub", children: [
|
|
8316
|
+
Math.round((cfg.voiceVolume == null ? 1 : cfg.voiceVolume) * 100),
|
|
8317
|
+
"%"
|
|
8318
|
+
] })
|
|
8319
|
+
] }),
|
|
8320
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8321
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u97F3\u8272" }),
|
|
8322
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
8323
|
+
"select",
|
|
8324
|
+
{
|
|
8325
|
+
className: "dknt-input",
|
|
8326
|
+
style: { maxWidth: 260 },
|
|
8327
|
+
value: cfg.voiceURI || "",
|
|
8328
|
+
"aria-label": "\u64AD\u62A5\u97F3\u8272",
|
|
8329
|
+
onChange: (e) => patch({ voiceURI: e.target.value }),
|
|
8330
|
+
children: [
|
|
8331
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: "\u81EA\u52A8\uFF08\u6309\u8BED\u8A00\u6311\uFF09" }),
|
|
8332
|
+
(() => {
|
|
8333
|
+
const zh = [], other = [];
|
|
8334
|
+
for (const v of voices) {
|
|
8335
|
+
if (!v || !v.voiceURI) continue;
|
|
8336
|
+
if (/^zh/i.test(String(v.lang || ""))) zh.push(v);
|
|
8337
|
+
else other.push(v);
|
|
8338
|
+
}
|
|
8339
|
+
const groups = [];
|
|
8340
|
+
if (zh.length) groups.push(["\u4E2D\u6587\u97F3\u8272", zh]);
|
|
8341
|
+
if (other.length) groups.push(["\u5176\u4ED6\u97F3\u8272", other]);
|
|
8342
|
+
return groups.map(([gname, vs]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("optgroup", { label: gname, children: vs.map((v) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: v.voiceURI, children: (v.name || v.voiceURI) + "\uFF08" + (v.lang || "?") + "\uFF09" }, v.voiceURI)) }, gname));
|
|
8343
|
+
})()
|
|
8344
|
+
]
|
|
8345
|
+
}
|
|
8346
|
+
),
|
|
8347
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: voices.length ? "\u97F3\u8272\u662F\u672C\u673A\u6D4F\u89C8\u5668\u7ED9\u7684\uFF0C\u6362\u8BBE\u5907\u53EF\u80FD\u8981\u91CD\u9009\uFF1B\u672C\u673A\u627E\u4E0D\u5230\u6240\u9009\u97F3\u8272\u65F6\u81EA\u52A8\u6309\u8BED\u8A00\u56DE\u843D" : "\u672C\u673A\u6682\u672A\u8BFB\u5230\u97F3\u8272\uFF08\u7CFB\u7EDF\u8BED\u97F3\u672A\u88C5/\u672A\u542F\u7528\uFF09\uFF0C\u5C06\u6309\u8BED\u8A00\u81EA\u52A8\u6311" })
|
|
8348
|
+
] }),
|
|
8349
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8350
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u8BD5\u542C" }),
|
|
8351
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
8352
|
+
"button",
|
|
8353
|
+
{
|
|
8354
|
+
type: "button",
|
|
8355
|
+
className: "dknt-btn",
|
|
8356
|
+
disabled: !voiceSupported(),
|
|
8357
|
+
onClick: () => {
|
|
8358
|
+
const preview = Object.assign({}, cfg, { voiceNotify: true });
|
|
8359
|
+
speakVoice(endBroadcastText(true, { title: "\u793A\u4F8B\u4EFB\u52A1", duration: 125e3, turns: 3, steps: 9, toolCalls: 4, lastText: "\u597D\u7684\uFF0C\u4E09\u4EFD\u6587\u6863\u90FD\u5DF2\u66F4\u65B0\u5B8C\u6BD5\u3002" }, null, preview), preview);
|
|
8360
|
+
},
|
|
8361
|
+
children: "\u64AD\u4E00\u53E5"
|
|
8362
|
+
}
|
|
8363
|
+
),
|
|
8364
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
8365
|
+
"button",
|
|
8366
|
+
{
|
|
8367
|
+
type: "button",
|
|
8368
|
+
className: "dknt-btn",
|
|
8369
|
+
disabled: !voiceSupported(),
|
|
8370
|
+
onClick: () => {
|
|
8371
|
+
const preview = Object.assign({}, cfg, { voiceNotify: true });
|
|
8372
|
+
speakVoice(confirmBroadcastText({ title: "\u793A\u4F8B\u4EFB\u52A1" }, { toolName: "pwsh" }, preview), preview);
|
|
8373
|
+
},
|
|
8374
|
+
children: "\u9700\u6388\u6743"
|
|
8375
|
+
}
|
|
8376
|
+
),
|
|
8377
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: voiceSupported() ? "\u6D4F\u89C8\u5668\u8BED\u97F3\u5408\u6210\uFF08\u4E0E\u3010\u8BED\u97F3\u6717\u8BFB\u3011\u540C\u4E00\u5957\u58F0\u97F3\uFF0C\u72EC\u7ACB\u5F00\u5173\uFF1B\u6253\u65AD\u5F0F\u2014\u2014\u64AD\u62A5\u4FE1\u65F6\u6B63\u5728\u6717\u8BFB\u7684\u6B63\u6587\u4F1A\u8BA9\u4F4D\uFF09" : "\u672C\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u8BED\u97F3\u5408\u6210\uFF08speechSynthesis \u4E0D\u53EF\u7528\uFF09" })
|
|
8378
|
+
] }),
|
|
8379
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8380
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u8BED\u8A00" }),
|
|
8381
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
8382
|
+
"select",
|
|
8383
|
+
{
|
|
8384
|
+
className: "dknt-input",
|
|
8385
|
+
style: { maxWidth: 180 },
|
|
8386
|
+
value: cfg.voiceLang || "",
|
|
8387
|
+
"aria-label": "\u64AD\u62A5\u8BED\u8A00",
|
|
8388
|
+
onChange: (e) => patch({ voiceLang: e.target.value }),
|
|
8389
|
+
children: [
|
|
8390
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: "\u81EA\u52A8\uFF08\u4E2D\u6587\u4F18\u5148\uFF09" }),
|
|
8391
|
+
["zh-CN", "zh-TW", "en-US", "en-GB", "ja-JP", "ko-KR"].map((l) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: l, children: l }, l))
|
|
8392
|
+
]
|
|
8393
|
+
}
|
|
8394
|
+
),
|
|
8395
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u672A\u6307\u5B9A\u97F3\u8272\u65F6\u6309\u8BED\u8A00\u81EA\u52A8\u6311\uFF1B\u5DF2\u9009\u97F3\u8272\u7684\u8BED\u8A00\u4F1A\u8986\u76D6\u8FD9\u91CC" })
|
|
8396
|
+
] })
|
|
8397
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dknt-note", children: "\u672A\u5F00\u542F\u2014\u2014\u4EFB\u52A1\u4E8B\u4EF6\u4E0D\u64AD\u62A5\u8BED\u97F3\uFF08\u63D0\u793A\u97F3\u3001\u7CFB\u7EDF\u901A\u77E5\u4E0D\u53D7\u5F71\u54CD\uFF09\u3002" })
|
|
8398
|
+
] }, "voice"),
|
|
7836
8399
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-sec", children: [
|
|
7837
8400
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-sec-head", children: [
|
|
7838
8401
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-sec-title", children: "\u9489\u9489\u63A8\u9001" }),
|
|
@@ -7965,7 +8528,7 @@ function NotifyStat(props) {
|
|
|
7965
8528
|
if (snap.error) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-err", children: "\u901A\u77E5\u72B6\u6001\u4E0D\u53EF\u7528\uFF08\u5BBF\u4E3B\u9700\u91CD\u542F\u52A0\u8F7D\u901A\u77E5\u8DEF\u7531\uFF09" });
|
|
7966
8529
|
if (!cfg) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u7B49\u5F85\u901A\u77E5\u914D\u7F6E\u2026" });
|
|
7967
8530
|
const events = [cfg.notifyOnComplete ? "\u5B8C\u6210" : "", cfg.notifyOnError ? "\u5F02\u5E38" : "", cfg.notifyOnConfirm !== false ? "\u9700\u786E\u8BA4" : ""].filter(Boolean);
|
|
7968
|
-
const extras = [cfg.soundNotify !== false ? "\u63D0\u793A\u97F3" : "", cfg.systemNotify ? "\u7CFB\u7EDF\u901A\u77E5" : ""].filter(Boolean);
|
|
8531
|
+
const extras = [cfg.soundNotify !== false ? "\u63D0\u793A\u97F3" : "", cfg.systemNotify ? "\u7CFB\u7EDF\u901A\u77E5" : "", cfg.voiceNotify ? "\u8BED\u97F3\u64AD\u62A5" + (cfg.voiceMode === "detailed" ? "\xB7\u8BE6" : cfg.voiceMode === "medium" ? "\xB7\u9002" : "\xB7\u7B80") : ""].filter(Boolean);
|
|
7969
8532
|
const push = [cfg.dingtalkEnabled ? "\u9489\u9489" : "", cfg.feishuEnabled ? "\u98DE\u4E66" : ""].filter(Boolean);
|
|
7970
8533
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: (events.length ? "\u901A\u77E5\uFF1A" + events.join("/") : "\u901A\u77E5\u4E8B\u4EF6\u5168\u5173") + (extras.length ? " \xB7 " + extras.join("/") : "") + (push.length ? " \xB7 \u63A8\u9001\uFF1A" + push.join("/") : "") });
|
|
7971
8534
|
}
|
|
@@ -8285,7 +8848,7 @@ function makeUtterance(text) {
|
|
|
8285
8848
|
return null;
|
|
8286
8849
|
}
|
|
8287
8850
|
}
|
|
8288
|
-
function
|
|
8851
|
+
function localVoices2() {
|
|
8289
8852
|
const s = synth();
|
|
8290
8853
|
if (!s) return [];
|
|
8291
8854
|
try {
|
|
@@ -8545,8 +9108,8 @@ function chunkForSpeech(text, limit) {
|
|
|
8545
9108
|
if (buf.trim()) chunks.push(buf);
|
|
8546
9109
|
return chunks;
|
|
8547
9110
|
}
|
|
8548
|
-
function
|
|
8549
|
-
const voices =
|
|
9111
|
+
function pickVoice2(cfg) {
|
|
9112
|
+
const voices = localVoices2();
|
|
8550
9113
|
if (voices.length === 0) return null;
|
|
8551
9114
|
const want = String(cfg && cfg.voiceURI || "");
|
|
8552
9115
|
if (want) {
|
|
@@ -8648,7 +9211,7 @@ function startSession(opts) {
|
|
|
8648
9211
|
const chunks = chunkForSpeech(text, 180);
|
|
8649
9212
|
if (chunks.length === 0) return false;
|
|
8650
9213
|
const epoch = ++engine.epoch;
|
|
8651
|
-
const voice =
|
|
9214
|
+
const voice = pickVoice2(cfg);
|
|
8652
9215
|
const session = { key, raw: text, chunks, index: 0, epoch, cfg, label: String(o.label || "") };
|
|
8653
9216
|
engine.session = session;
|
|
8654
9217
|
setEngineState({ phase: "playing", key, label: session.label });
|
|
@@ -9168,13 +9731,13 @@ function TtsView() {
|
|
|
9168
9731
|
const eng = useEngineState();
|
|
9169
9732
|
const [, force] = (0, import_react12.useState)(0);
|
|
9170
9733
|
const [saved, setSaved] = (0, import_react12.useState)("");
|
|
9171
|
-
const voices = (0, import_react12.useRef)(
|
|
9734
|
+
const voices = (0, import_react12.useRef)(localVoices2());
|
|
9172
9735
|
(0, import_react12.useEffect)(() => {
|
|
9173
9736
|
ensureConfigLoaded();
|
|
9174
9737
|
const s = synth();
|
|
9175
9738
|
if (!s || typeof s.addEventListener !== "function") return;
|
|
9176
9739
|
const onChange = () => {
|
|
9177
|
-
voices.current =
|
|
9740
|
+
voices.current = localVoices2();
|
|
9178
9741
|
force((n) => n + 1);
|
|
9179
9742
|
};
|
|
9180
9743
|
try {
|
|
@@ -9191,7 +9754,7 @@ function TtsView() {
|
|
|
9191
9754
|
}, []);
|
|
9192
9755
|
(0, import_react12.useEffect)(() => {
|
|
9193
9756
|
if (voices.current.length === 0) {
|
|
9194
|
-
voices.current =
|
|
9757
|
+
voices.current = localVoices2();
|
|
9195
9758
|
force((n) => n + 1);
|
|
9196
9759
|
}
|
|
9197
9760
|
}, []);
|
|
@@ -13894,7 +14457,7 @@ var feature13 = {
|
|
|
13894
14457
|
};
|
|
13895
14458
|
|
|
13896
14459
|
// src/client.jsx
|
|
13897
|
-
var DOCK_VERSION = "0.
|
|
14460
|
+
var DOCK_VERSION = "0.19.0";
|
|
13898
14461
|
var BUILTIN_FEATURES = [feature, feature2, feature3, feature4, feature5, feature6, feature7, feature8, feature9, feature10, feature11, feature12, feature13];
|
|
13899
14462
|
var PLANNED_FEATURES = [];
|
|
13900
14463
|
var PLANNED_NOTES = {};
|