misakanet 2.42.2 → 2.43.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/.codex-plugin/plugin.json +3 -1
- package/README.ja.md +0 -4
- package/README.md +6 -9
- package/README.zh-CN.md +33 -1
- package/index.js +13 -0
- package/lib/client.js +67 -25
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "misakanet",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.43.0",
|
|
4
4
|
"description": "Failure-memory network for AI coding agents: search evidence-rated failure lessons, submit new failures, and turn crashes into reusable knowledge.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Ikalus1988",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"misakanet_submit_intake",
|
|
33
33
|
"misakanet_write_lesson",
|
|
34
34
|
"misakanet_preflight",
|
|
35
|
+
"misakanet_me_inbox",
|
|
35
36
|
"misakanet_me_events"
|
|
36
37
|
],
|
|
37
38
|
"local": {
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
"misakanet_submit_intake",
|
|
48
49
|
"misakanet_write_lesson",
|
|
49
50
|
"misakanet_preflight",
|
|
51
|
+
"misakanet_me_inbox",
|
|
50
52
|
"misakanet_me_events",
|
|
51
53
|
"misakanet_submit_usage",
|
|
52
54
|
"misakanet_usage_status",
|
package/README.ja.md
CHANGED
|
@@ -335,10 +335,6 @@ jobs:
|
|
|
335
335
|
|
|
336
336
|
→ [入力と出力](docs/agents/external-usage.md) · [`actions: read` が省略できない理由](docs/agents/external-usage.md)
|
|
337
337
|
|
|
338
|
-
### 8秒で見る
|
|
339
|
-
|
|
340
|
-

|
|
341
|
-
|
|
342
338
|
## ドキュメント
|
|
343
339
|
|
|
344
340
|
**ジャーニーを選んでください** — MisakaNet の使い方は、やりたいことに応じて異なります:
|
package/README.md
CHANGED
|
@@ -203,19 +203,20 @@ previous copy go stale while the paragraph directly above it explained what the
|
|
|
203
203
|
| 2026-09-06 | 48.3% | 24.1% | 455 |
|
|
204
204
|
| 2026-09-14 | 46.6% | 23.4% | 494 |
|
|
205
205
|
| 2026-09-21 | 46.1% | 23.3% | 512 |
|
|
206
|
+
| 2026-10-12 | 43.8% | 26.1% | 34 |
|
|
206
207
|
|
|
207
208
|
_1155 run(s) in `latest.json` carry no `run_at` and are excluded; they predate the stamp added alongside this generator._
|
|
208
209
|
|
|
209
210
|
```
|
|
210
211
|
with_lesson hit rate (per run date)
|
|
211
|
-
|
|
212
|
-
46.
|
|
212
|
+
43.8% │ ▁
|
|
213
|
+
46.1% │ ▄
|
|
214
|
+
46.6% │ ▄
|
|
213
215
|
48.3% │ ▆
|
|
214
216
|
49.1% │ █
|
|
215
|
-
46.4% │ ▁
|
|
216
217
|
└──────────────────
|
|
217
|
-
08
|
|
218
|
-
|
|
218
|
+
08 09 09 09 10
|
|
219
|
+
31 06 14 21 12
|
|
219
220
|
```
|
|
220
221
|
|
|
221
222
|
<!-- END generated: benchmark-trend -->
|
|
@@ -346,10 +347,6 @@ jobs:
|
|
|
346
347
|
|
|
347
348
|
→ [inputs and outputs](docs/agents/external-usage.md) · [why `actions: read` is not optional](docs/agents/external-usage.md)
|
|
348
349
|
|
|
349
|
-
### See it in 8 seconds
|
|
350
|
-
|
|
351
|
-

|
|
352
|
-
|
|
353
350
|
## Documentation
|
|
354
351
|
|
|
355
352
|
**Choose your journey** — MisakaNet is useful in different ways depending on what you are trying to do:
|
package/README.zh-CN.md
CHANGED
|
@@ -13,10 +13,42 @@
|
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
16
|
-
<
|
|
16
|
+
<em>核心</em>
|
|
17
|
+
|
|
18
|
+
<a href="https://github.com/Ikalus1988/MisakaNet/actions/workflows/pr-quality-gate.yml"><img src="https://github.com/Ikalus1988/MisakaNet/actions/workflows/pr-quality-gate.yml/badge.svg" alt="CI"/></a>
|
|
17
19
|
<a href="https://github.com/Ikalus1988/MisakaNet/tree/main/lessons"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Ikalus1988/MisakaNet/data/badges/lessons.json" alt="知识"/></a>
|
|
20
|
+
<a href="https://github.com/Ikalus1988/MisakaNet/blob/main/scripts/mcp_server.py"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Ikalus1988/MisakaNet/data/badges/tools.json" alt="MCP 工具"/></a>
|
|
21
|
+
<a href="https://misakanet.org/api/search-index"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Ikalus1988/MisakaNet/data/badges/retrieval.json" alt="检索后端(今日)"/></a>
|
|
18
22
|
<a href="https://github.com/Ikalus1988/MisakaNet/blob/main/LICENSE"><img src="https://img.shields.io/github/license/Ikalus1988/MisakaNet?style=flat&color=blueviolet" alt="License"/></a>
|
|
23
|
+
<a href="https://github.com/Ikalus1988/MisakaNet/stargazers"><img src="https://img.shields.io/github/stars/Ikalus1988/MisakaNet?style=social" alt="Stars"/></a>
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
<p align="center">
|
|
27
|
+
<em>安装</em>
|
|
28
|
+
|
|
29
|
+
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10+-blue" alt="Python"/></a>
|
|
30
|
+
<a href="https://pypi.org/project/misakanet/"><img src="https://img.shields.io/pypi/v/misakanet" alt="PyPI"/></a>
|
|
31
|
+
<a href="https://www.npmjs.com/package/misakanet"><img src="https://img.shields.io/npm/v/misakanet" alt="npm"/></a>
|
|
19
32
|
<a href="https://github.com/marketplace/actions/misakanet-intake-bot"><img src="https://img.shields.io/badge/Marketplace-MisakaNet%20Intake%20Bot-blue?logo=github" alt="GitHub Marketplace"/></a>
|
|
33
|
+
<a href="https://dsh-plugin.org/plugins/ikalus1988/misakanet"><img src="https://dsh-plugin.org/badges/listed.svg" alt="已收录于 dsh-plugin.org"/></a>
|
|
34
|
+
<a href="https://dsh.directory/plugins/ikalus1988/misakanet"><img src="https://dsh.directory/badges/listed.svg" alt="已收录于 DSH Directory"/></a>
|
|
35
|
+
<a href="https://www.dsh.so/artifact/misakanet/"><img src="https://www.dsh.so/badge/install/misakanet.svg" alt="dsh.so 安装"/></a>
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<em>生态</em>
|
|
40
|
+
|
|
41
|
+
<a href="https://glama.ai/mcp/servers/Ikalus1988/MisakaNet/score"><img src="https://glama.ai/mcp/servers/Ikalus1988/MisakaNet/badges/score.svg" alt="Glama 评分"/></a>
|
|
42
|
+
<a href="https://glama.ai/mcp/connectors/org.misakanet/misaka-net"><img src="https://glama.ai/mcp/connectors/org.misakanet/misaka-net/badges/score.svg" alt="MisakaNet MCP 连接器 — Glama 上的工具定义质量与端点健康度"/></a>
|
|
43
|
+
<a href="https://mcptoplist.com/server/io.github.Ikalus1988%2Fmisakanet"><img src="https://mcptoplist.com/badge/io.github.Ikalus1988%2Fmisakanet.svg" alt="MCP Toplist"/></a>
|
|
44
|
+
<!-- Smithery 徽章使用 shields.io 的 'endpoint' 徽章,动态读取 data/badges/smithery.json 里的
|
|
45
|
+
Kin 评分 —— 由 update-smithery-badge 工作流每日刷新,因此无需手工 PR 也能保持同步。 -->
|
|
46
|
+
<a href="https://smithery.ai/servers/misakanet/misakanet"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Ikalus1988/MisakaNet/refs/heads/data/badges/smithery.json" alt="Smithery"/></a>
|
|
47
|
+
<!-- HOL 徽章:链接仍指向 hol.org(其收录检测会在 README 里找这块徽章,值 +2% 信任分),
|
|
48
|
+
但图片是一块静态 flat 盾牌 —— 走 shields.io 访问实时的 hol.org/api/... 端点过慢且不稳定,
|
|
49
|
+
曾渲染成 "inaccessible" / 样式不符。 -->
|
|
50
|
+
<a href="https://hol.org/registry/plugins/Ikalus1988%2FMisakaNet"><img src="https://img.shields.io/badge/HOL%20Registry-listed-5599FE?style=flat" alt="MisakaNet 已上架 HOL Registry"/></a>
|
|
51
|
+
<a href="https://github.com/Ikalus1988/MisakaNet/tree/main/docs/benchmarks"><img src="https://img.shields.io/badge/Benchmark-Weekly%20Workers%20AI-blue" alt="Benchmark"/></a>
|
|
20
52
|
</p>
|
|
21
53
|
|
|
22
54
|
---
|
package/index.js
CHANGED
|
@@ -109,6 +109,19 @@ export async function apply(ctx, config = {}) {
|
|
|
109
109
|
if (options.failOnStartupError) throw error;
|
|
110
110
|
// Expected on npm skill-only installs: the skill (SKILL.md) is the payload,
|
|
111
111
|
// and a missing client must not take the whole profile down with it.
|
|
112
|
+
//
|
|
113
|
+
// Returning quietly is right for **boot** and wrong for **diagnosis**. `lib/client.js`
|
|
114
|
+
// mounts the browser half either way, so the observable result is a rendered MisakaNet
|
|
115
|
+
// panel whose tools never reach the agent — intake #2759 reported exactly that ("the
|
|
116
|
+
// sidebar is decorative", zero requests to misakanet.org) with nothing in the host log
|
|
117
|
+
// to separate "this profile never installed the client" from "this profile is broken".
|
|
118
|
+
// The other two guarded paths already log; this one was the only silent branch, and it is
|
|
119
|
+
// the branch that runs most often. Measured 2026-10-08 with the client unresolvable:
|
|
120
|
+
// `apply()` returned and `logger.warn` was called 0 times.
|
|
121
|
+
ctx?.logger?.warn?.(
|
|
122
|
+
'misakanet: @deepseek-ai/dsh-mcp-client is not resolvable, so the MCP tools are not '
|
|
123
|
+
+ `mounted (the skill still works): ${error?.message ?? error}`,
|
|
124
|
+
);
|
|
112
125
|
return;
|
|
113
126
|
}
|
|
114
127
|
|
package/lib/client.js
CHANGED
|
@@ -41,10 +41,13 @@
|
|
|
41
41
|
*
|
|
42
42
|
* WHAT IT DELIBERATELY DOES NOT DO
|
|
43
43
|
* --------------------------------
|
|
44
|
-
* No
|
|
45
|
-
* gap-report button (that belongs with the intake side, not with a satisfaction vote), and no
|
|
44
|
+
* No gap-report button (that belongs with the intake side, not with a satisfaction vote), and no
|
|
46
45
|
* credentials — the endpoints are public, anonymous and rate-limited. And no auto-voting, ever.
|
|
47
46
|
*
|
|
47
|
+
* Lesson links, by contrast, ARE built, in two places. A lesson's `id` is the slug its page is
|
|
48
|
+
* published under, so `/lessons/<id>` is a real address rather than a guess — and both
|
|
49
|
+
* call sites build it the same way (`MisakanetOverlayRow`, `MisakanetShellToast`).
|
|
50
|
+
*
|
|
48
51
|
* KNOWN LIMITS (v1, stated rather than hidden)
|
|
49
52
|
* --------------------------------------------
|
|
50
53
|
* The verdict learns that a search happened from this module's own per-session memory, not from a host
|
|
@@ -191,7 +194,7 @@ window.__ModuleLoader__.load({
|
|
|
191
194
|
"panel.trust.checking": "checking…",
|
|
192
195
|
"panel.trust.unavailable": "unavailable",
|
|
193
196
|
"panel.trust.human": "human confirmation",
|
|
194
|
-
"panel.trust.
|
|
197
|
+
"panel.trust.noLevel": "no level",
|
|
195
198
|
"panel.trust.used": " · used ",
|
|
196
199
|
"panel.trust.footnote": "The level is the lesson's own stored evidence. The count is other people's confirmations, not yours: one makes the reuse event appear, the second is what agents read as E4.",
|
|
197
200
|
"panel.activity.session": "this session: ",
|
|
@@ -300,7 +303,7 @@ window.__ModuleLoader__.load({
|
|
|
300
303
|
"panel.trust.checking": "核验中……",
|
|
301
304
|
"panel.trust.unavailable": "不可用",
|
|
302
305
|
"panel.trust.human": "人工确认",
|
|
303
|
-
"panel.trust.
|
|
306
|
+
"panel.trust.noLevel": "无等级",
|
|
304
307
|
"panel.trust.used": " · 已复用 ",
|
|
305
308
|
"panel.trust.footnote": "等级来自课程自己存的证据;计数是别人的确认,不是你的:前者让复用事件出现,后者才是 agent 读到的 E4。",
|
|
306
309
|
"panel.activity.session": "本会话:",
|
|
@@ -441,18 +444,30 @@ window.__ModuleLoader__.load({
|
|
|
441
444
|
if (sessionId) lastSessionId = sessionId;
|
|
442
445
|
}
|
|
443
446
|
|
|
447
|
+
/**
|
|
448
|
+
* One shape for a session record, because two places can create one.
|
|
449
|
+
*
|
|
450
|
+
* `overlayOf()` creates a record too, and it used to build a smaller literal. Whoever created
|
|
451
|
+
* the record first won, and the overlay always renders first — so the record that
|
|
452
|
+
* `sessionLog()` found already there had no `sessionId`, and nothing ever added it. That is
|
|
453
|
+
* not a warning, it is a dead end: every recorder ends in `notify(log.sessionId)`, which
|
|
454
|
+
* returns immediately on a null id, so the panel and the toasts stopped repainting while the
|
|
455
|
+
* numbers underneath them kept changing.
|
|
456
|
+
*/
|
|
457
|
+
function newSessionLog(sessionId) {
|
|
458
|
+
return {
|
|
459
|
+
sessionId: sessionId,
|
|
460
|
+
searches: [], intakes: [], votes: [],
|
|
461
|
+
lessons: Object.create(null),
|
|
462
|
+
// The verdict's own state: which message it was offered on, and whether it is spent.
|
|
463
|
+
shownFor: "", voted: false,
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
|
|
444
467
|
function sessionLog(sessionId) {
|
|
445
468
|
if (!sessionId) return null;
|
|
446
469
|
touchSession(sessionId);
|
|
447
|
-
if (!sessions[sessionId])
|
|
448
|
-
sessions[sessionId] = {
|
|
449
|
-
sessionId: sessionId,
|
|
450
|
-
searches: [], intakes: [], votes: [],
|
|
451
|
-
lessons: Object.create(null),
|
|
452
|
-
// The verdict's own state: which message it was offered on, and whether it is spent.
|
|
453
|
-
shownFor: "", voted: false,
|
|
454
|
-
};
|
|
455
|
-
}
|
|
470
|
+
if (!sessions[sessionId]) sessions[sessionId] = newSessionLog(sessionId);
|
|
456
471
|
return sessions[sessionId];
|
|
457
472
|
}
|
|
458
473
|
|
|
@@ -521,6 +536,12 @@ window.__ModuleLoader__.load({
|
|
|
521
536
|
*/
|
|
522
537
|
function playCue(cue) {
|
|
523
538
|
if (!cue || !voiceEnabled()) return false;
|
|
539
|
+
// The cue is the one string in this file that comes straight out of a response body and
|
|
540
|
+
// lands in a URL. Every cue the server names is `[a-z0-9-]` (`connect-success`,
|
|
541
|
+
// `pair-success`, `lesson-found`, `failure-warning`), so anything outside that shape is not a
|
|
542
|
+
// cue we ship: refuse it instead of letting it walk out of the path. Same-origin either
|
|
543
|
+
// way, so this is hardening and not a fix for a live defect.
|
|
544
|
+
if (!/^[a-z0-9-]+$/.test(String(cue))) return false;
|
|
524
545
|
try {
|
|
525
546
|
var audio = new window.Audio(API + "/assets/voice/" + cue + ".mp3");
|
|
526
547
|
var played = audio.play();
|
|
@@ -575,9 +596,11 @@ var DEFAULT_MCP_URL = "https://misakanet.org/mcp";
|
|
|
575
596
|
|
|
576
597
|
function overlayOf(sessionId) {
|
|
577
598
|
var log = sessions[sessionId];
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
599
|
+
// The overlay renders before any tool row does, so this is the record a session really
|
|
600
|
+
// starts with — same constructor as `sessionLog()`, and deliberately no
|
|
601
|
+
// `touchSession()`: merely mounting the card must not claim the frame-wide seats'
|
|
602
|
+
// "last session".
|
|
603
|
+
if (!log) log = sessions[sessionId] = newSessionLog(sessionId);
|
|
581
604
|
if (!log.overlay) {
|
|
582
605
|
log.overlay = { open: false, query: "", status: "idle", results: [], error: null };
|
|
583
606
|
}
|
|
@@ -610,7 +633,16 @@ var DEFAULT_MCP_URL = "https://misakanet.org/mcp";
|
|
|
610
633
|
}
|
|
611
634
|
setOverlay(sessionId, { open: true, query: query, status: "loading", results: [], error: null });
|
|
612
635
|
var timedOut = false;
|
|
613
|
-
var timer = setTimeout(function () {
|
|
636
|
+
var timer = setTimeout(function () {
|
|
637
|
+
timedOut = true;
|
|
638
|
+
// The flag below silences a late answer, and that was the whole effect: the card sat on
|
|
639
|
+
// "Searching…" for good, with no error and nothing to retry, so
|
|
640
|
+
// `OVERLAY_TIMEOUT_MS` was inert. Someone is looking at this card, so a stalled request
|
|
641
|
+
// has to land in the same state a failed one does — `setOverlay` draws the
|
|
642
|
+
// reason through `overlay.failed`, which already knows how to say it.
|
|
643
|
+
setOverlay(sessionId, { status: "error", results: [],
|
|
644
|
+
error: "no answer after " + Math.round(OVERLAY_TIMEOUT_MS / 1000) + "s" });
|
|
645
|
+
}, OVERLAY_TIMEOUT_MS);
|
|
614
646
|
var url = SEARCH_ENDPOINT + "?q=" + encodeURIComponent(query) + "&limit=" + OVERLAY_LIMIT;
|
|
615
647
|
fetch(url, { headers: { accept: "application/json" } })
|
|
616
648
|
.then(function (response) {
|
|
@@ -734,8 +766,8 @@ var DEFAULT_MCP_URL = "https://misakanet.org/mcp";
|
|
|
734
766
|
log.lessons[entry.lessonId].count += 1;
|
|
735
767
|
log.lessons[entry.lessonId].last = entry.at;
|
|
736
768
|
}
|
|
737
|
-
return entry;
|
|
738
769
|
notifyShell();
|
|
770
|
+
return entry;
|
|
739
771
|
}
|
|
740
772
|
|
|
741
773
|
/** Record a vote and retire the sighting it answered. */
|
|
@@ -766,7 +798,12 @@ var DEFAULT_MCP_URL = "https://misakanet.org/mcp";
|
|
|
766
798
|
function intakeState(payload) {
|
|
767
799
|
if (!payload || typeof payload !== "object") return "unknown";
|
|
768
800
|
if (payload.converted) return "converted";
|
|
769
|
-
|
|
801
|
+
// An ASCII state id, like every other state here. It used to return the localized
|
|
802
|
+
// `T("intake.answered")` instead, which the panel then compared against the literal
|
|
803
|
+
// `"answered"`: on a Chinese interface an answered report never matched, so it stayed in
|
|
804
|
+
// the pending count with the "we will re-check this" line attached. The copy is the
|
|
805
|
+
// labels' job; see `MisakanetIntakeRow` and the panel.
|
|
806
|
+
if (payload.answered) return "answered";
|
|
770
807
|
if (payload.already_have) return "already_have";
|
|
771
808
|
if (payload.pending || payload.duplicate || payload.submitted) return "pending";
|
|
772
809
|
return "unknown";
|
|
@@ -805,8 +842,8 @@ var DEFAULT_MCP_URL = "https://misakanet.org/mcp";
|
|
|
805
842
|
bumpStat("reportsFiled");
|
|
806
843
|
if (entry.state === "converted") bumpStat("reportsConverted");
|
|
807
844
|
notify(log.sessionId);
|
|
808
|
-
return entry;
|
|
809
845
|
notifyShell();
|
|
846
|
+
return entry;
|
|
810
847
|
}
|
|
811
848
|
|
|
812
849
|
/** Concatenate the text blocks of a result node; "" when there are none. */
|
|
@@ -1071,7 +1108,7 @@ var DEFAULT_MCP_URL = "https://misakanet.org/mcp";
|
|
|
1071
1108
|
var labels = {
|
|
1072
1109
|
filing: "filing…",
|
|
1073
1110
|
pending: "filed — waiting for a maintainer",
|
|
1074
|
-
answered: "answered",
|
|
1111
|
+
answered: T("intake.answered"),
|
|
1075
1112
|
already_have: "not filed — the corpus already covers this",
|
|
1076
1113
|
converted: "your report is cited by a lesson",
|
|
1077
1114
|
unknown: T("intake.submitted"),
|
|
@@ -1220,7 +1257,7 @@ var DEFAULT_MCP_URL = "https://misakanet.org/mcp";
|
|
|
1220
1257
|
} else {
|
|
1221
1258
|
rows.push(h("div", { key: "s2r" }, intakes.slice().reverse().map(function (entry) {
|
|
1222
1259
|
var labels = {
|
|
1223
|
-
filing: "filing", pending: T("intake.waiting"), answered: "answered",
|
|
1260
|
+
filing: "filing", pending: T("intake.waiting"), answered: T("intake.answered"),
|
|
1224
1261
|
already_have: T("intake.alreadyHave"), converted: T("intake.cited"), unknown: "submitted",
|
|
1225
1262
|
};
|
|
1226
1263
|
var issue = String(entry.issue || "").replace(/^issue-/, "#").replace(/^.*\/issues\//, "#");
|
|
@@ -1250,7 +1287,7 @@ var DEFAULT_MCP_URL = "https://misakanet.org/mcp";
|
|
|
1250
1287
|
: count(confirmations, T("panel.trust.human")) + (confirmations >= 2 ? " → E4" : ""));
|
|
1251
1288
|
return h("div", { key: "l" + lesson.lessonId, style: { borderTop: "1px solid " + MUTED, padding: "4px 0" } },
|
|
1252
1289
|
h("span", {}, lesson.title || lesson.lessonId),
|
|
1253
|
-
h("span", { style: DIM }, " " + (lesson.evidence || T("panel.trust.
|
|
1290
|
+
h("span", { style: DIM }, " " + (lesson.evidence || T("panel.trust.noLevel")) + " · " + counted +
|
|
1254
1291
|
T("panel.trust.used") + lesson.count + "× · " + timeRange(lesson)));
|
|
1255
1292
|
})));
|
|
1256
1293
|
}
|
|
@@ -1325,7 +1362,9 @@ var DEFAULT_MCP_URL = "https://misakanet.org/mcp";
|
|
|
1325
1362
|
/** One result row: the title, where it came from, and a link to read it. */
|
|
1326
1363
|
function MisakanetOverlayRow(result) {
|
|
1327
1364
|
var path = String(result && result.id ? result.id : "");
|
|
1328
|
-
|
|
1365
|
+
// Encoded, like the shell toast at the other call site: a no-op for the `[a-z0-9-]` slugs
|
|
1366
|
+
// the server hands out, and a correct URL for anything else.
|
|
1367
|
+
var href = path ? "https://misakanet.org/lessons/" + encodeURIComponent(path) : "https://misakanet.org/";
|
|
1329
1368
|
return h("a", {
|
|
1330
1369
|
href: href, target: "_blank", rel: "noreferrer",
|
|
1331
1370
|
style: { display: "block", padding: "7px 8px", borderRadius: "8px", textDecoration: "none",
|
|
@@ -1469,7 +1508,10 @@ var DEFAULT_MCP_URL = "https://misakanet.org/mcp";
|
|
|
1469
1508
|
var searched = log.searches ? log.searches.length : 0;
|
|
1470
1509
|
var withLesson = log.searches ? log.searches.filter(function (s) { return s.lessonId; }).length : 0;
|
|
1471
1510
|
var ids = log.searches ? log.searches.map(function (s) { return s.lessonId; }).filter(Boolean) : [];
|
|
1472
|
-
|
|
1511
|
+
// `recordVote` stores the verdict under `kind`; filtering a `helpful` field nothing writes
|
|
1512
|
+
// made this line print 0 for every session, next to the panel's own count of the same
|
|
1513
|
+
// votes. Same expression the panel uses.
|
|
1514
|
+
var helpful = log.votes ? log.votes.filter(function (v) { return v && v.kind === "helpful"; }).length : 0;
|
|
1473
1515
|
var overlay = log.overlay || {};
|
|
1474
1516
|
var lines = [
|
|
1475
1517
|
"MisakaNet — this session",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "misakanet",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.43.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "MisakaNet failure-memory skill — evidence-rated failure lessons for AI agents. DSH bundle: registers the MCP tools as mcp__misakanet__* (misakanet_search/get_lesson/…), served by the public Streamable HTTP endpoint https://misakanet.org/mcp — live tools from an npm install, in any profile, with no local python. A profile that prefers the repo's own stdio server can override the bundle row.",
|
|
6
6
|
"icon": "icon.svg",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"preview": "wrangler dev"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
-
"wrangler": "^4.
|
|
83
|
+
"wrangler": "^4.149.0"
|
|
84
84
|
},
|
|
85
85
|
"overrides": {
|
|
86
86
|
"sharp": "0.35.5"
|