psyclaw 0.29.12 → 0.29.13
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 -4
- package/dist/apps/panel/index.html +186 -44
- package/dist/src/adapters/pi/extension.js +47 -14
- package/dist/src/adapters/pi/extension.js.map +1 -1
- package/dist/src/analysis/stats-router.js +1 -1
- package/dist/src/analysis/stats-router.js.map +1 -1
- package/dist/src/branding.js +5 -5
- package/dist/src/branding.js.map +1 -1
- package/dist/src/cli.js +27 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/panel/server.js +8 -3
- package/dist/src/panel/server.js.map +1 -1
- package/dist/src/project/workspace.js +3 -3
- package/dist/src/project/workspace.js.map +1 -1
- package/dist/src/session/help.d.ts +3 -0
- package/dist/src/session/help.js +67 -42
- package/dist/src/session/help.js.map +1 -1
- package/dist/src/session/modes.js +7 -7
- package/dist/src/session/modes.js.map +1 -1
- package/dist/src/style/cli-ui.d.ts +1 -0
- package/dist/src/style/cli-ui.js +26 -15
- package/dist/src/style/cli-ui.js.map +1 -1
- package/dist/src/updates/update.d.ts +8 -1
- package/dist/src/updates/update.js +68 -2
- package/dist/src/updates/update.js.map +1 -1
- package/dist/src/verify/checklist.d.ts +44 -5
- package/dist/src/verify/checklist.js +103 -15
- package/dist/src/verify/checklist.js.map +1 -1
- package/dist/src/wake-options/runtime.js +1 -1
- package/dist/src/wake-options/runtime.js.map +1 -1
- package/package.json +1 -1
- package/skills/recommended/catalog.json +24 -154
- package/skills/recommended/mcp-catalog.json +16 -4
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ PsyClaw 是面向社会科学研究的智能体工作台。它把研究项目、
|
|
|
4
4
|
|
|
5
5
|
PsyClaw 自有代码使用 MIT 许可证;随 npm 包内置的 Academic Research Skills 位于 `vendor/ars`,保持上游署名并单独遵循 CC BY-NC 4.0,仅限非商业用途。
|
|
6
6
|
|
|
7
|
-
当前版本:`0.29.
|
|
7
|
+
当前版本:`0.29.13`。正式命令、用户配置目录和后续发布统一使用 `psyclaw`。
|
|
8
8
|
|
|
9
9
|
## 发布流程
|
|
10
10
|
|
|
@@ -21,19 +21,19 @@ RELEASE_MESSAGE="release: describe the change" pnpm release:push
|
|
|
21
21
|
需要 Node.js `>=22.19.0`。官方 npm 源:
|
|
22
22
|
|
|
23
23
|
```powershell
|
|
24
|
-
npm install -g psyclaw@0.29.
|
|
24
|
+
npm install -g psyclaw@0.29.13
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
如果本机 npm 配置把 registry 误写成带有 `~/` 的地址,请显式指定官方源:
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
npm install -g psyclaw@0.29.
|
|
30
|
+
npm install -g psyclaw@0.29.13 --registry=https://registry.npmjs.org/
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
中国大陆网络较慢或无法访问官方源时:
|
|
34
34
|
|
|
35
35
|
```powershell
|
|
36
|
-
npm install -g psyclaw@0.29.
|
|
36
|
+
npm install -g psyclaw@0.29.13 --registry=https://registry.npmmirror.com
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
或安装脚本:
|
|
@@ -337,23 +337,41 @@
|
|
|
337
337
|
.help-grid {
|
|
338
338
|
display: grid;
|
|
339
339
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
340
|
-
gap:
|
|
341
|
-
margin-bottom:
|
|
340
|
+
gap: 14px;
|
|
341
|
+
margin-bottom: 28px;
|
|
342
342
|
}
|
|
343
343
|
.help-mode-card {
|
|
344
|
+
position: relative;
|
|
344
345
|
border: 1px solid var(--border-subtle);
|
|
345
|
-
background: var(--
|
|
346
|
-
border-radius:
|
|
347
|
-
padding:
|
|
348
|
-
|
|
346
|
+
background: linear-gradient(165deg, #ffffff 0%, var(--brand-primary-light) 140%);
|
|
347
|
+
border-radius: 14px;
|
|
348
|
+
padding: 18px 18px 16px;
|
|
349
|
+
overflow: hidden;
|
|
350
|
+
}
|
|
351
|
+
.help-mode-card::before {
|
|
352
|
+
content: "";
|
|
353
|
+
position: absolute;
|
|
354
|
+
left: 0;
|
|
355
|
+
top: 0;
|
|
356
|
+
bottom: 0;
|
|
357
|
+
width: 3px;
|
|
358
|
+
background: var(--brand-primary);
|
|
349
359
|
}
|
|
350
360
|
.help-mode-card .mode-id {
|
|
351
361
|
font-family: var(--font-mono);
|
|
352
|
-
font-size:
|
|
353
|
-
|
|
354
|
-
|
|
362
|
+
font-size: 10px;
|
|
363
|
+
font-weight: 600;
|
|
364
|
+
color: var(--brand-primary);
|
|
365
|
+
letter-spacing: 0.08em;
|
|
355
366
|
text-transform: uppercase;
|
|
356
|
-
margin-bottom:
|
|
367
|
+
margin-bottom: 8px;
|
|
368
|
+
}
|
|
369
|
+
.help-mode-card .mode-label {
|
|
370
|
+
font-size: 16px;
|
|
371
|
+
font-weight: 650;
|
|
372
|
+
color: var(--text-main);
|
|
373
|
+
letter-spacing: -0.02em;
|
|
374
|
+
margin: 0 0 8px;
|
|
357
375
|
}
|
|
358
376
|
.help-mode-card p {
|
|
359
377
|
margin: 0;
|
|
@@ -361,56 +379,164 @@
|
|
|
361
379
|
line-height: 1.55;
|
|
362
380
|
color: var(--text-secondary);
|
|
363
381
|
}
|
|
364
|
-
.help-
|
|
382
|
+
.help-hero {
|
|
383
|
+
display: flex;
|
|
384
|
+
align-items: flex-end;
|
|
385
|
+
justify-content: space-between;
|
|
386
|
+
gap: 16px;
|
|
365
387
|
margin-bottom: 22px;
|
|
388
|
+
padding: 20px 22px;
|
|
389
|
+
border-radius: 16px;
|
|
390
|
+
border: 1px solid var(--brand-primary-border);
|
|
391
|
+
background:
|
|
392
|
+
radial-gradient(120% 80% at 100% 0%, rgba(13, 118, 110, 0.10), transparent 55%),
|
|
393
|
+
linear-gradient(180deg, #ffffff, #f8fafc);
|
|
366
394
|
}
|
|
367
|
-
.help-
|
|
368
|
-
margin: 0 0
|
|
369
|
-
font-size:
|
|
370
|
-
font-weight:
|
|
395
|
+
.help-hero h1 {
|
|
396
|
+
margin: 0 0 6px;
|
|
397
|
+
font-size: 22px;
|
|
398
|
+
font-weight: 700;
|
|
399
|
+
letter-spacing: -0.03em;
|
|
371
400
|
color: var(--text-main);
|
|
372
401
|
}
|
|
402
|
+
.help-hero p {
|
|
403
|
+
margin: 0;
|
|
404
|
+
color: var(--text-muted);
|
|
405
|
+
font-size: 13px;
|
|
406
|
+
max-width: 42rem;
|
|
407
|
+
line-height: 1.5;
|
|
408
|
+
}
|
|
409
|
+
.help-kbd {
|
|
410
|
+
display: inline-flex;
|
|
411
|
+
align-items: center;
|
|
412
|
+
gap: 6px;
|
|
413
|
+
padding: 6px 10px;
|
|
414
|
+
border-radius: 999px;
|
|
415
|
+
border: 1px solid var(--border-subtle);
|
|
416
|
+
background: var(--bg-surface);
|
|
417
|
+
color: var(--text-secondary);
|
|
418
|
+
font-size: 11px;
|
|
419
|
+
font-family: var(--font-mono);
|
|
420
|
+
white-space: nowrap;
|
|
421
|
+
}
|
|
422
|
+
.help-block {
|
|
423
|
+
margin-bottom: 26px;
|
|
424
|
+
}
|
|
425
|
+
.help-block h2 {
|
|
426
|
+
margin: 0 0 12px;
|
|
427
|
+
font-size: 13px;
|
|
428
|
+
font-weight: 700;
|
|
429
|
+
letter-spacing: 0.04em;
|
|
430
|
+
text-transform: uppercase;
|
|
431
|
+
color: var(--text-muted);
|
|
432
|
+
}
|
|
373
433
|
.help-steps {
|
|
374
434
|
margin: 0;
|
|
375
|
-
padding
|
|
435
|
+
padding: 0;
|
|
436
|
+
list-style: none;
|
|
437
|
+
display: grid;
|
|
438
|
+
gap: 8px;
|
|
439
|
+
}
|
|
440
|
+
.help-steps li {
|
|
441
|
+
display: grid;
|
|
442
|
+
grid-template-columns: 28px 1fr;
|
|
443
|
+
gap: 12px;
|
|
444
|
+
align-items: start;
|
|
445
|
+
padding: 12px 14px;
|
|
446
|
+
border-radius: 12px;
|
|
447
|
+
border: 1px solid var(--border-subtle);
|
|
448
|
+
background: var(--bg-surface);
|
|
376
449
|
color: var(--text-secondary);
|
|
377
450
|
font-size: 13px;
|
|
378
|
-
line-height: 1.
|
|
451
|
+
line-height: 1.55;
|
|
452
|
+
}
|
|
453
|
+
.help-steps li::before {
|
|
454
|
+
content: attr(data-step);
|
|
455
|
+
width: 28px;
|
|
456
|
+
height: 28px;
|
|
457
|
+
border-radius: 9px;
|
|
458
|
+
display: grid;
|
|
459
|
+
place-items: center;
|
|
460
|
+
background: var(--brand-primary-light);
|
|
461
|
+
color: var(--brand-primary);
|
|
462
|
+
font-family: var(--font-mono);
|
|
463
|
+
font-size: 12px;
|
|
464
|
+
font-weight: 700;
|
|
379
465
|
}
|
|
380
466
|
.help-commands {
|
|
467
|
+
display: grid;
|
|
468
|
+
gap: 18px;
|
|
469
|
+
}
|
|
470
|
+
.help-cmd-group h3 {
|
|
471
|
+
margin: 0 0 8px;
|
|
472
|
+
font-size: 12px;
|
|
473
|
+
font-weight: 650;
|
|
474
|
+
color: var(--text-muted);
|
|
475
|
+
letter-spacing: 0.02em;
|
|
476
|
+
}
|
|
477
|
+
.help-cmd-list {
|
|
381
478
|
display: grid;
|
|
382
479
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
383
480
|
gap: 8px;
|
|
384
481
|
}
|
|
385
482
|
.help-cmd {
|
|
386
|
-
display:
|
|
387
|
-
|
|
388
|
-
|
|
483
|
+
display: grid;
|
|
484
|
+
grid-template-columns: minmax(7.5rem, auto) 1fr;
|
|
485
|
+
gap: 12px;
|
|
486
|
+
align-items: center;
|
|
389
487
|
border: 1px solid var(--border-subtle);
|
|
390
|
-
border-radius:
|
|
391
|
-
padding:
|
|
392
|
-
background: var(--bg-surface
|
|
488
|
+
border-radius: 12px;
|
|
489
|
+
padding: 11px 13px;
|
|
490
|
+
background: var(--bg-surface);
|
|
491
|
+
transition: border-color 120ms ease, background 120ms ease;
|
|
492
|
+
}
|
|
493
|
+
.help-cmd:hover {
|
|
494
|
+
border-color: var(--brand-primary-border);
|
|
495
|
+
background: var(--brand-primary-light);
|
|
393
496
|
}
|
|
394
497
|
.help-cmd code {
|
|
395
498
|
font-family: var(--font-mono);
|
|
396
499
|
font-size: 12px;
|
|
397
|
-
|
|
500
|
+
font-weight: 600;
|
|
501
|
+
color: var(--brand-primary);
|
|
398
502
|
white-space: nowrap;
|
|
399
503
|
}
|
|
400
504
|
.help-cmd span {
|
|
401
505
|
font-size: 12.5px;
|
|
402
|
-
color: var(--text-
|
|
403
|
-
line-height: 1.
|
|
506
|
+
color: var(--text-secondary);
|
|
507
|
+
line-height: 1.4;
|
|
404
508
|
}
|
|
405
509
|
.help-notes {
|
|
406
510
|
margin: 0;
|
|
407
|
-
padding
|
|
511
|
+
padding: 14px 16px;
|
|
512
|
+
list-style: none;
|
|
513
|
+
display: grid;
|
|
514
|
+
gap: 8px;
|
|
515
|
+
border-radius: 14px;
|
|
516
|
+
border: 1px solid var(--border-subtle);
|
|
517
|
+
background: var(--bg-surface-subtle);
|
|
518
|
+
}
|
|
519
|
+
.help-notes li {
|
|
520
|
+
position: relative;
|
|
521
|
+
padding-left: 14px;
|
|
408
522
|
color: var(--text-muted);
|
|
409
523
|
font-size: 12.5px;
|
|
410
|
-
line-height: 1.
|
|
524
|
+
line-height: 1.55;
|
|
525
|
+
}
|
|
526
|
+
.help-notes li::before {
|
|
527
|
+
content: "";
|
|
528
|
+
position: absolute;
|
|
529
|
+
left: 0;
|
|
530
|
+
top: 0.55em;
|
|
531
|
+
width: 6px;
|
|
532
|
+
height: 6px;
|
|
533
|
+
border-radius: 50%;
|
|
534
|
+
background: var(--brand-primary);
|
|
535
|
+
opacity: 0.55;
|
|
411
536
|
}
|
|
412
537
|
@media (max-width: 960px) {
|
|
413
|
-
.help-grid, .help-
|
|
538
|
+
.help-grid, .help-cmd-list { grid-template-columns: 1fr; }
|
|
539
|
+
.help-hero { flex-direction: column; align-items: flex-start; }
|
|
414
540
|
}
|
|
415
541
|
|
|
416
542
|
.button {
|
|
@@ -1561,9 +1687,9 @@
|
|
|
1561
1687
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg>
|
|
1562
1688
|
/plan 方案
|
|
1563
1689
|
</button>
|
|
1564
|
-
<button id="cmd-verify-btn" class="topbar-btn" title="
|
|
1690
|
+
<button id="cmd-verify-btn" class="topbar-btn" title="AI 核查清单;人审在此核实 (/crosscheck)">
|
|
1565
1691
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
|
|
1566
|
-
/
|
|
1692
|
+
/crosscheck
|
|
1567
1693
|
</button>
|
|
1568
1694
|
</div>
|
|
1569
1695
|
<div class="local-badge">
|
|
@@ -1809,11 +1935,12 @@
|
|
|
1809
1935
|
</section>
|
|
1810
1936
|
|
|
1811
1937
|
<section id="view-help" class="view">
|
|
1812
|
-
<div class="
|
|
1938
|
+
<div class="help-hero">
|
|
1813
1939
|
<div>
|
|
1814
1940
|
<h1 id="help-title">使用速览</h1>
|
|
1815
|
-
<p id="help-
|
|
1941
|
+
<p id="help-subtitle">三种模式 · AI 交叉核验 · 内置学术工作流</p>
|
|
1816
1942
|
</div>
|
|
1943
|
+
<div id="help-thinking" class="help-kbd">加载中…</div>
|
|
1817
1944
|
</div>
|
|
1818
1945
|
<div class="help-grid" id="help-modes"></div>
|
|
1819
1946
|
<div class="help-block">
|
|
@@ -1821,7 +1948,7 @@
|
|
|
1821
1948
|
<ol id="help-steps" class="help-steps"></ol>
|
|
1822
1949
|
</div>
|
|
1823
1950
|
<div class="help-block">
|
|
1824
|
-
<h2
|
|
1951
|
+
<h2>常用命令</h2>
|
|
1825
1952
|
<div id="help-commands" class="help-commands"></div>
|
|
1826
1953
|
</div>
|
|
1827
1954
|
<div class="help-block">
|
|
@@ -1834,11 +1961,11 @@
|
|
|
1834
1961
|
<div class="page-head">
|
|
1835
1962
|
<div>
|
|
1836
1963
|
<h1>交叉核验清单</h1>
|
|
1837
|
-
<p
|
|
1964
|
+
<p>AI 用 <code>/crosscheck</code> 核查字段;<strong>analysis / academic 收尾必须在此点「核实」</strong>(或终端 <code>/crosscheck <id> human</code>)。AI 已核与跳过都不算通过。</p>
|
|
1838
1965
|
</div>
|
|
1839
1966
|
<div style="display:flex;gap:8px">
|
|
1840
1967
|
<button id="refresh-checklist" class="button">刷新</button>
|
|
1841
|
-
<button id="skip-checklist" class="button" title="
|
|
1968
|
+
<button id="skip-checklist" class="button" title="标为跳过;不解除 analysis/academic 人审门禁">跳过未核项</button>
|
|
1842
1969
|
</div>
|
|
1843
1970
|
</div>
|
|
1844
1971
|
<div class="panel section">
|
|
@@ -1881,7 +2008,7 @@
|
|
|
1881
2008
|
<div id="console-log" class="console-log">
|
|
1882
2009
|
<div class="log-entry sys">
|
|
1883
2010
|
<div class="log-sys">
|
|
1884
|
-
💡 <strong>对话已就绪</strong>:与 PsyClaw
|
|
2011
|
+
💡 <strong>对话已就绪</strong>:与 PsyClaw 智能体安全连接。支持 <code>/init</code>、<code>/plan</code>、<code>/grill</code>、<code>/crosscheck</code>(AI 核验)等指令。
|
|
1885
2012
|
</div>
|
|
1886
2013
|
</div>
|
|
1887
2014
|
</div>
|
|
@@ -1891,9 +2018,9 @@
|
|
|
1891
2018
|
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg>
|
|
1892
2019
|
/plan status
|
|
1893
2020
|
</span>
|
|
1894
|
-
<span class="chip" data-cmd="/
|
|
2021
|
+
<span class="chip" data-cmd="/crosscheck list">
|
|
1895
2022
|
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 11l3 3L22 4"/></svg>
|
|
1896
|
-
/
|
|
2023
|
+
/crosscheck list
|
|
1897
2024
|
</span>
|
|
1898
2025
|
<span class="chip" data-cmd="/grill">
|
|
1899
2026
|
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/></svg>
|
|
@@ -2035,16 +2162,31 @@ async function loadHelp() {
|
|
|
2035
2162
|
try {
|
|
2036
2163
|
const doc = await json("/api/help");
|
|
2037
2164
|
$("help-title").textContent = doc.title || "使用速览";
|
|
2165
|
+
$("help-subtitle").textContent = doc.subtitle || "";
|
|
2038
2166
|
$("help-thinking").textContent = doc.thinking || "";
|
|
2039
2167
|
$("help-modes").innerHTML = (doc.modes || []).map(mode => `
|
|
2040
2168
|
<article class="help-mode-card">
|
|
2041
|
-
<div class="mode-id">${esc(mode.
|
|
2169
|
+
<div class="mode-id">${esc(mode.hint || mode.id)}</div>
|
|
2170
|
+
<div class="mode-label">${esc(mode.label || mode.id)}</div>
|
|
2042
2171
|
<p>${esc(mode.blurb)}</p>
|
|
2043
2172
|
</article>
|
|
2044
2173
|
`).join("");
|
|
2045
|
-
$("help-steps").innerHTML = (doc.steps || []).map(step =>
|
|
2046
|
-
|
|
2047
|
-
|
|
2174
|
+
$("help-steps").innerHTML = (doc.steps || []).map((step, index) =>
|
|
2175
|
+
`<li data-step="${index + 1}">${esc(step)}</li>`
|
|
2176
|
+
).join("");
|
|
2177
|
+
const groups = new Map();
|
|
2178
|
+
for (const row of (doc.commands || [])) {
|
|
2179
|
+
const key = row.group || "其他";
|
|
2180
|
+
if (!groups.has(key)) groups.set(key, []);
|
|
2181
|
+
groups.get(key).push(row);
|
|
2182
|
+
}
|
|
2183
|
+
$("help-commands").innerHTML = [...groups.entries()].map(([group, rows]) => `
|
|
2184
|
+
<div class="help-cmd-group">
|
|
2185
|
+
<h3>${esc(group)}</h3>
|
|
2186
|
+
<div class="help-cmd-list">
|
|
2187
|
+
${rows.map(row => `<div class="help-cmd"><code>${esc(row.cmd)}</code><span>${esc(row.blurb)}</span></div>`).join("")}
|
|
2188
|
+
</div>
|
|
2189
|
+
</div>
|
|
2048
2190
|
`).join("");
|
|
2049
2191
|
$("help-notes").innerHTML = (doc.notes || []).map(note => `<li>${esc(note)}</li>`).join("");
|
|
2050
2192
|
} catch (error) {
|
|
@@ -2091,7 +2233,7 @@ async function loadChecklist() {
|
|
|
2091
2233
|
|
|
2092
2234
|
$("refresh-checklist")?.addEventListener("click", loadChecklist);
|
|
2093
2235
|
$("skip-checklist")?.addEventListener("click", async () => {
|
|
2094
|
-
if (!confirm("
|
|
2236
|
+
if (!confirm("将把未核/AI已核项标为跳过。注意:这不会解除 analysis/academic 收尾人审门禁。继续?")) return;
|
|
2095
2237
|
await json("/api/crosscheck", {
|
|
2096
2238
|
method: "POST",
|
|
2097
2239
|
headers: { "content-type": "application/json" },
|
|
@@ -33,7 +33,7 @@ import { arsRoot } from "../../ars/pi-panel-executor.js";
|
|
|
33
33
|
import { ArsModeEditor, isArsModeEditorText } from "../../ars/mode-editor.js";
|
|
34
34
|
import { MODE_STATUS, nextSessionMode, parseSessionMode, sessionModePrompt, } from "../../session/modes.js";
|
|
35
35
|
import { continuouslyWorkWarningText, isContinuouslyWorkEnabled, } from "../../session/continuously-work.js";
|
|
36
|
-
import { formatVerifyChecklist, isNaturalPlanConfirm, loadVerifyChecklist, markVerifyItem, skipUnverifiedItems } from "../../verify/checklist.js";
|
|
36
|
+
import { assertHumanVerifyGate, formatVerifyChecklist, isNaturalPlanConfirm, loadVerifyChecklist, markVerifyItem, skipUnverifiedItems } from "../../verify/checklist.js";
|
|
37
37
|
import { formatSessionHelp, formatSessionHelpBrief } from "../../session/help.js";
|
|
38
38
|
import { openResearchWorkbench } from "../../panel/workbench.js";
|
|
39
39
|
const PARADIGMS = new Set([
|
|
@@ -1291,40 +1291,48 @@ export default function psyclawExtension(pi) {
|
|
|
1291
1291
|
return;
|
|
1292
1292
|
}
|
|
1293
1293
|
if (parts[0] === "skip") {
|
|
1294
|
-
ctx.ui.notify(formatVerifyChecklist(await skipUnverifiedItems(ctx.cwd))
|
|
1294
|
+
ctx.ui.notify(`${formatVerifyChecklist(await skipUnverifiedItems(ctx.cwd))}\n注意:skip 不解除 analysis/academic 人审硬门禁。`, "warning");
|
|
1295
1295
|
return;
|
|
1296
1296
|
}
|
|
1297
1297
|
if (parts[0] === "kind") {
|
|
1298
1298
|
const kind = (parts[1] ?? "general");
|
|
1299
1299
|
pi.sendUserMessage([
|
|
1300
|
-
"
|
|
1300
|
+
"交叉核验任务:请作为助手主动提出核对项并执行字段核查,不要等用户自己去「申请确认」。",
|
|
1301
1301
|
`核验类别:${kind}(citations=引文,format=格式,requirements=研究要求,stats=统计结果,general=综合)。`,
|
|
1302
|
-
"
|
|
1302
|
+
"核查完成后用 /crosscheck <id> verified 记为 AI 已核(ai-checked),不得自称已过人审。",
|
|
1303
|
+
"analysis / academic 模式下,全文或分析收尾前必须请人在 Panel「核实」或 /crosscheck <id> human;跳过不算通过。",
|
|
1303
1304
|
"分析前与分析后都要有清单,不能默认跳过。",
|
|
1304
1305
|
].join("\n"), ctx.isIdle() ? {} : { deliverAs: "followUp" });
|
|
1305
|
-
ctx.ui.notify(`已启动 ${kind}
|
|
1306
|
+
ctx.ui.notify(`已启动 ${kind} 交叉核验;人审请打开 /panel → 核对清单。`, "info");
|
|
1306
1307
|
return;
|
|
1307
1308
|
}
|
|
1308
1309
|
const id = parts[0];
|
|
1309
|
-
const
|
|
1310
|
-
|
|
1311
|
-
|
|
1310
|
+
const statusRaw = (parts[1] ?? "verified").toLowerCase();
|
|
1311
|
+
const allowed = new Set(["verified", "ai-checked", "unverified", "flagged", "skipped", "human"]);
|
|
1312
|
+
if (!allowed.has(statusRaw)) {
|
|
1313
|
+
ctx.ui.notify("Usage: /crosscheck list | skip | kind <citations|format|requirements|stats> | <id> verified|ai-checked|human|unverified|flagged|skipped [备注]", "info");
|
|
1312
1314
|
return;
|
|
1313
1315
|
}
|
|
1314
1316
|
const notes = parts.slice(2).join(" ") || undefined;
|
|
1315
|
-
const
|
|
1316
|
-
ctx.
|
|
1317
|
+
const source = statusRaw === "human" ? "human" : "ai";
|
|
1318
|
+
const checklist = await markVerifyItem(ctx.cwd, id, statusRaw, notes, undefined, { source });
|
|
1319
|
+
const tip = statusRaw === "human" || (statusRaw === "verified" && source === "human")
|
|
1320
|
+
? "已记为人审通过。"
|
|
1321
|
+
: statusRaw === "verified" || statusRaw === "ai-checked"
|
|
1322
|
+
? "已记为 AI 已核;analysis/academic 收尾前仍须人在 Panel 点「核实」或 /crosscheck <id> human。"
|
|
1323
|
+
: undefined;
|
|
1324
|
+
ctx.ui.notify(tip ? `${formatVerifyChecklist(checklist)}\n${tip}` : formatVerifyChecklist(checklist), "info");
|
|
1317
1325
|
}
|
|
1318
1326
|
catch (error) {
|
|
1319
1327
|
await notifyError(ctx, error);
|
|
1320
1328
|
}
|
|
1321
1329
|
};
|
|
1322
1330
|
pi.registerCommand("crosscheck", {
|
|
1323
|
-
description: "
|
|
1331
|
+
description: "AI 交叉核验 + 人审:/crosscheck list|skip|kind|<id> verified|human|…",
|
|
1324
1332
|
handler: async (args, ctx) => handleCrosscheck(args, ctx),
|
|
1325
1333
|
});
|
|
1326
1334
|
pi.registerCommand("verify", {
|
|
1327
|
-
description: "
|
|
1335
|
+
description: "同 /crosscheck;AI 核查后 analysis/academic 须人审",
|
|
1328
1336
|
handler: async (args, ctx) => handleCrosscheck(args, ctx),
|
|
1329
1337
|
});
|
|
1330
1338
|
pi.registerCommand("help", {
|
|
@@ -1436,6 +1444,11 @@ export default function psyclawExtension(pi) {
|
|
|
1436
1444
|
return;
|
|
1437
1445
|
}
|
|
1438
1446
|
if (cmd === "handoff") {
|
|
1447
|
+
const gate = await assertHumanVerifyGate(ctx.cwd, "analysis-complete");
|
|
1448
|
+
if (!gate.ok) {
|
|
1449
|
+
ctx.ui.notify(gate.message, "error");
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1439
1452
|
const path = await syncHandoffFromAnalysisPlan(ctx.cwd, plan);
|
|
1440
1453
|
if (plan.status === "running") {
|
|
1441
1454
|
plan = advanceAnalysisPlan(plan, plan.scriptEntrypoint
|
|
@@ -1494,6 +1507,19 @@ export default function psyclawExtension(pi) {
|
|
|
1494
1507
|
ctx.ui.notify("已启动学术追问。完成后会先展示文档更新建议,并询问是否写回。", "info");
|
|
1495
1508
|
},
|
|
1496
1509
|
});
|
|
1510
|
+
if (!legacyTestApi)
|
|
1511
|
+
pi.registerCommand("brainstorm", {
|
|
1512
|
+
description: "显式启动研究方向头脑风暴(逐题澄清)",
|
|
1513
|
+
handler: async (args, ctx) => {
|
|
1514
|
+
const subject = args.trim();
|
|
1515
|
+
pi.sendUserMessage([
|
|
1516
|
+
"使用 academic-grill Skill 的头脑风暴入口,先提出 2-4 个有理论意义、可回答的研究方向,比较价值、可行性与边界并推荐一个。",
|
|
1517
|
+
"随后按研究者需要逐题澄清,每轮只问一个实质问题,同时给出推荐答案和主要取舍;不要直接替用户执行完整研究或写论文。",
|
|
1518
|
+
subject ? `本次头脑风暴主题:${subject}` : "请根据当前对话和项目材料确定头脑风暴主题;已有信息不要重复询问。",
|
|
1519
|
+
].join("\n"), ctx.isIdle() ? {} : { deliverAs: "followUp" });
|
|
1520
|
+
ctx.ui.notify("已启动研究方向头脑风暴。完成后可用 /grill 继续严格压力测试。", "info");
|
|
1521
|
+
},
|
|
1522
|
+
});
|
|
1497
1523
|
if (!legacyTestApi)
|
|
1498
1524
|
pi.registerCommand("review", {
|
|
1499
1525
|
description: "并发运行多角色模拟同行评审",
|
|
@@ -2215,11 +2241,11 @@ export default function psyclawExtension(pi) {
|
|
|
2215
2241
|
executionMode: "sequential",
|
|
2216
2242
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
2217
2243
|
try {
|
|
2218
|
-
// Soft gate
|
|
2244
|
+
// Soft gate for missing /init only. Analysis/academic completion still requires human verify.
|
|
2219
2245
|
const project = await readActiveProject(ctx.cwd);
|
|
2220
2246
|
const softNote = project
|
|
2221
2247
|
? undefined
|
|
2222
|
-
: "尚未 /init
|
|
2248
|
+
: "尚未 /init(软门禁):继续执行;收尾前须 AI /crosscheck 后人审。建议先 /init 建仓。";
|
|
2223
2249
|
const request = params.request.trim();
|
|
2224
2250
|
const combined = `${request} ${params.identifier ?? ""}`;
|
|
2225
2251
|
const explicitWorkflow = params.workflow?.trim();
|
|
@@ -2252,6 +2278,13 @@ export default function psyclawExtension(pi) {
|
|
|
2252
2278
|
}
|
|
2253
2279
|
if (publishIntent) {
|
|
2254
2280
|
try {
|
|
2281
|
+
const gate = await assertHumanVerifyGate(ctx.cwd, "academic-finalize");
|
|
2282
|
+
if (!gate.ok) {
|
|
2283
|
+
return {
|
|
2284
|
+
content: [{ type: "text", text: gate.message }],
|
|
2285
|
+
details: { workflow: "publish-manuscript", blocked: true, reason: "human-verify-gate" },
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2255
2288
|
const result = await exportAcademicDocument(ctx.cwd);
|
|
2256
2289
|
return {
|
|
2257
2290
|
content: [{ type: "text", text: JSON.stringify({
|