psyclaw 0.29.14 → 0.29.16
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 +14 -14
- package/dist/apps/panel/index.html +381 -141
- package/dist/src/adapters/pi/extension.js +145 -518
- package/dist/src/adapters/pi/extension.js.map +1 -1
- package/dist/src/agents/recommended-personas.d.ts +1 -1
- package/dist/src/agents/recommended-personas.js +2 -2
- package/dist/src/agents/recommended-personas.js.map +1 -1
- package/dist/src/analysis/plan.js +2 -2
- package/dist/src/analysis/plan.js.map +1 -1
- package/dist/src/analysis/stats-router.js +2 -2
- package/dist/src/analysis/stats-router.js.map +1 -1
- package/dist/src/branding.js +3 -3
- package/dist/src/branding.js.map +1 -1
- package/dist/src/orchestration/bundled-personas.d.ts +1 -1
- package/dist/src/orchestration/bundled-personas.js +1 -1
- package/dist/src/orchestration/bundled-personas.js.map +1 -1
- package/dist/src/orchestration/personas.js +2 -5
- package/dist/src/orchestration/personas.js.map +1 -1
- package/dist/src/panel/extension.js +3 -7
- package/dist/src/panel/extension.js.map +1 -1
- package/dist/src/panel/server.js +4 -4
- package/dist/src/panel/server.js.map +1 -1
- package/dist/src/session/help.d.ts +1 -1
- package/dist/src/session/help.js +26 -27
- package/dist/src/session/help.js.map +1 -1
- package/dist/src/session/modes.js +3 -3
- package/dist/src/session/modes.js.map +1 -1
- package/dist/src/skills/recommended.js +1 -1
- package/dist/src/skills/recommended.js.map +1 -1
- package/dist/src/style/cli-ui.js +14 -13
- package/dist/src/style/cli-ui.js.map +1 -1
- package/dist/src/verify/checklist.d.ts +5 -4
- package/dist/src/verify/checklist.js +7 -8
- package/dist/src/verify/checklist.js.map +1 -1
- package/package.json +1 -1
- package/skills/recommended/catalog.json +36 -3
|
@@ -102,15 +102,19 @@
|
|
|
102
102
|
.brand-mark {
|
|
103
103
|
display: grid;
|
|
104
104
|
place-items: center;
|
|
105
|
-
width:
|
|
106
|
-
height:
|
|
107
|
-
background: linear-gradient(135deg, #
|
|
105
|
+
width: 30px;
|
|
106
|
+
height: 30px;
|
|
107
|
+
background: linear-gradient(135deg, #38bdf8 0%, #818cf8 50%, #a855f7 100%);
|
|
108
108
|
color: #ffffff;
|
|
109
109
|
border-radius: var(--radius-sm);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
box-shadow: 0 2px 10px rgba(129, 140, 248, 0.35);
|
|
111
|
+
border: 1px solid rgba(255, 255, 255, 0.25);
|
|
112
|
+
flex-shrink: 0;
|
|
113
|
+
}
|
|
114
|
+
.brand-mark svg {
|
|
115
|
+
width: 17px;
|
|
116
|
+
height: 17px;
|
|
117
|
+
fill: currentColor;
|
|
114
118
|
}
|
|
115
119
|
.brand-title {
|
|
116
120
|
font-weight: 650;
|
|
@@ -123,18 +127,43 @@
|
|
|
123
127
|
}
|
|
124
128
|
.brand-badge {
|
|
125
129
|
font-size: 10.5px;
|
|
126
|
-
font-weight:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
border: 1px solid
|
|
130
|
-
padding: 1px
|
|
130
|
+
font-weight: 600;
|
|
131
|
+
background: linear-gradient(135deg, rgba(56, 189, 248, 0.12) 0%, rgba(168, 85, 247, 0.12) 100%);
|
|
132
|
+
color: #6366f1;
|
|
133
|
+
border: 1px solid rgba(129, 140, 248, 0.3);
|
|
134
|
+
padding: 1px 7px;
|
|
131
135
|
border-radius: 999px;
|
|
132
136
|
letter-spacing: 0.02em;
|
|
133
137
|
}
|
|
134
138
|
.topbar-meta {
|
|
135
139
|
display: flex;
|
|
136
140
|
align-items: center;
|
|
137
|
-
gap:
|
|
141
|
+
gap: 12px;
|
|
142
|
+
}
|
|
143
|
+
.github-link {
|
|
144
|
+
display: inline-flex;
|
|
145
|
+
align-items: center;
|
|
146
|
+
gap: 6px;
|
|
147
|
+
padding: 4px 10px;
|
|
148
|
+
font-size: 12px;
|
|
149
|
+
font-weight: 550;
|
|
150
|
+
color: var(--text-secondary);
|
|
151
|
+
background: var(--bg-surface-subtle);
|
|
152
|
+
border: 1px solid var(--border-subtle);
|
|
153
|
+
border-radius: var(--radius-sm);
|
|
154
|
+
text-decoration: none;
|
|
155
|
+
transition: all 0.15s ease;
|
|
156
|
+
}
|
|
157
|
+
.github-link:hover {
|
|
158
|
+
background: var(--bg-surface-hover);
|
|
159
|
+
color: var(--text-main);
|
|
160
|
+
border-color: rgba(129, 140, 248, 0.4);
|
|
161
|
+
box-shadow: 0 1px 4px rgba(129, 140, 248, 0.15);
|
|
162
|
+
}
|
|
163
|
+
.github-link svg {
|
|
164
|
+
width: 14px;
|
|
165
|
+
height: 14px;
|
|
166
|
+
fill: currentColor;
|
|
138
167
|
}
|
|
139
168
|
.local-badge {
|
|
140
169
|
display: inline-flex;
|
|
@@ -593,15 +622,32 @@
|
|
|
593
622
|
|
|
594
623
|
.workspace {
|
|
595
624
|
display: grid;
|
|
596
|
-
grid-template-columns:
|
|
625
|
+
grid-template-columns: minmax(480px, 1.25fr) 180px minmax(0, 1.6fr);
|
|
597
626
|
height: calc(100vh - 130px);
|
|
598
627
|
overflow: hidden;
|
|
599
628
|
background: var(--bg-surface);
|
|
629
|
+
transition: grid-template-columns 0.22s cubic-bezier(0.4, 0, 0.2, 1);
|
|
630
|
+
}
|
|
631
|
+
.workspace.chat-collapsed {
|
|
632
|
+
grid-template-columns: 46px 180px minmax(0, 1fr);
|
|
633
|
+
}
|
|
634
|
+
/* 当未打开具体文件时,对话框自动铺满工作台主区域 */
|
|
635
|
+
.workspace.no-file-open {
|
|
636
|
+
grid-template-columns: minmax(0, 1fr) 180px 0px;
|
|
637
|
+
}
|
|
638
|
+
.workspace.no-file-open .viewer {
|
|
639
|
+
display: none !important;
|
|
640
|
+
}
|
|
641
|
+
.workspace.no-file-open.chat-collapsed {
|
|
642
|
+
grid-template-columns: 46px minmax(0, 1fr) 0px;
|
|
643
|
+
}
|
|
644
|
+
.workspace.no-file-open.chat-collapsed .viewer {
|
|
645
|
+
display: none !important;
|
|
600
646
|
}
|
|
601
647
|
.tree {
|
|
602
648
|
border-right: 1px solid var(--border-subtle);
|
|
603
649
|
overflow-y: auto;
|
|
604
|
-
padding:
|
|
650
|
+
padding: 10px 6px;
|
|
605
651
|
background: #fafbfc;
|
|
606
652
|
}
|
|
607
653
|
.tree-section {
|
|
@@ -1132,40 +1178,45 @@
|
|
|
1132
1178
|
background: var(--brand-primary-hover);
|
|
1133
1179
|
}
|
|
1134
1180
|
|
|
1135
|
-
/* In-page chat: Modern Codex / Gemini style */
|
|
1181
|
+
/* In-page chat: Modern Codex / Gemini style inside workspace */
|
|
1136
1182
|
.console-drawer {
|
|
1137
1183
|
position: relative;
|
|
1138
1184
|
width: 100%;
|
|
1139
1185
|
height: 100%;
|
|
1140
|
-
min-height:
|
|
1186
|
+
min-height: 0;
|
|
1141
1187
|
flex: 1;
|
|
1142
1188
|
background: var(--bg-surface);
|
|
1143
1189
|
color: var(--text-main);
|
|
1144
|
-
border:
|
|
1190
|
+
border-right: 1px solid var(--border-subtle);
|
|
1145
1191
|
display: flex;
|
|
1146
1192
|
flex-direction: column;
|
|
1147
1193
|
font-family: var(--font-sans);
|
|
1194
|
+
overflow: hidden;
|
|
1195
|
+
transition: width 0.2s ease;
|
|
1148
1196
|
}
|
|
1149
1197
|
.console-header {
|
|
1150
1198
|
display: flex;
|
|
1151
1199
|
align-items: center;
|
|
1152
1200
|
justify-content: space-between;
|
|
1153
|
-
padding:
|
|
1201
|
+
padding: 10px 14px;
|
|
1154
1202
|
border-bottom: 1px solid var(--border-subtle);
|
|
1155
1203
|
background: var(--bg-surface);
|
|
1204
|
+
min-height: 48px;
|
|
1156
1205
|
}
|
|
1157
1206
|
.console-title {
|
|
1158
|
-
font-size:
|
|
1207
|
+
font-size: 13px;
|
|
1159
1208
|
font-weight: 650;
|
|
1160
1209
|
color: var(--text-main);
|
|
1161
1210
|
display: flex;
|
|
1162
1211
|
align-items: center;
|
|
1163
|
-
gap:
|
|
1212
|
+
gap: 8px;
|
|
1213
|
+
overflow: hidden;
|
|
1214
|
+
white-space: nowrap;
|
|
1164
1215
|
}
|
|
1165
1216
|
.console-status-tag {
|
|
1166
|
-
font-size:
|
|
1217
|
+
font-size: 10px;
|
|
1167
1218
|
font-weight: 600;
|
|
1168
|
-
padding: 1px
|
|
1219
|
+
padding: 1px 6px;
|
|
1169
1220
|
border-radius: 999px;
|
|
1170
1221
|
background: var(--ok-bg);
|
|
1171
1222
|
color: var(--ok-text);
|
|
@@ -1177,7 +1228,8 @@
|
|
|
1177
1228
|
.console-actions {
|
|
1178
1229
|
display: flex;
|
|
1179
1230
|
align-items: center;
|
|
1180
|
-
gap:
|
|
1231
|
+
gap: 6px;
|
|
1232
|
+
flex-shrink: 0;
|
|
1181
1233
|
}
|
|
1182
1234
|
.console-btn-icon {
|
|
1183
1235
|
background: transparent;
|
|
@@ -1196,6 +1248,50 @@
|
|
|
1196
1248
|
background: var(--bg-surface-subtle);
|
|
1197
1249
|
}
|
|
1198
1250
|
|
|
1251
|
+
/* Collapsed state for workspace chat drawer */
|
|
1252
|
+
.workspace.chat-collapsed .console-header {
|
|
1253
|
+
padding: 10px 6px;
|
|
1254
|
+
justify-content: center;
|
|
1255
|
+
}
|
|
1256
|
+
.workspace.chat-collapsed .console-title span,
|
|
1257
|
+
.workspace.chat-collapsed .console-status-tag,
|
|
1258
|
+
.workspace.chat-collapsed #console-clear-btn,
|
|
1259
|
+
.workspace.chat-collapsed .console-log,
|
|
1260
|
+
.workspace.chat-collapsed .console-quick-chips,
|
|
1261
|
+
.workspace.chat-collapsed .console-input-wrap {
|
|
1262
|
+
display: none !important;
|
|
1263
|
+
}
|
|
1264
|
+
.workspace.chat-collapsed #chat-collapse-btn svg {
|
|
1265
|
+
transform: rotate(180deg);
|
|
1266
|
+
}
|
|
1267
|
+
.workspace.chat-collapsed .console-collapsed-bar {
|
|
1268
|
+
display: flex !important;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
.console-collapsed-bar {
|
|
1272
|
+
display: none;
|
|
1273
|
+
flex-direction: column;
|
|
1274
|
+
align-items: center;
|
|
1275
|
+
padding: 16px 0;
|
|
1276
|
+
gap: 16px;
|
|
1277
|
+
height: 100%;
|
|
1278
|
+
cursor: pointer;
|
|
1279
|
+
background: var(--bg-surface-subtle);
|
|
1280
|
+
}
|
|
1281
|
+
.console-collapsed-bar:hover {
|
|
1282
|
+
background: var(--bg-surface-hover);
|
|
1283
|
+
}
|
|
1284
|
+
.console-vertical-label {
|
|
1285
|
+
writing-mode: vertical-rl;
|
|
1286
|
+
text-orientation: mixed;
|
|
1287
|
+
letter-spacing: 0.12em;
|
|
1288
|
+
font-size: 11px;
|
|
1289
|
+
font-weight: 650;
|
|
1290
|
+
color: var(--text-muted);
|
|
1291
|
+
text-transform: uppercase;
|
|
1292
|
+
user-select: none;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1199
1295
|
.console-log {
|
|
1200
1296
|
flex: 1;
|
|
1201
1297
|
overflow-y: auto;
|
|
@@ -1249,17 +1345,21 @@
|
|
|
1249
1345
|
|
|
1250
1346
|
/* Agent Message: Codex/Gemini open conversational layout */
|
|
1251
1347
|
.agent-avatar {
|
|
1252
|
-
width:
|
|
1253
|
-
height:
|
|
1348
|
+
width: 30px;
|
|
1349
|
+
height: 30px;
|
|
1254
1350
|
border-radius: 50%;
|
|
1255
|
-
background: linear-gradient(135deg, #
|
|
1351
|
+
background: linear-gradient(135deg, #38bdf8 0%, #818cf8 50%, #a855f7 100%);
|
|
1256
1352
|
color: #ffffff;
|
|
1257
1353
|
display: grid;
|
|
1258
1354
|
place-items: center;
|
|
1259
|
-
font-weight: 700;
|
|
1260
|
-
font-size: 15px;
|
|
1261
1355
|
flex-shrink: 0;
|
|
1262
|
-
box-shadow: 0 2px
|
|
1356
|
+
box-shadow: 0 2px 8px rgba(129, 140, 248, 0.35);
|
|
1357
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
1358
|
+
}
|
|
1359
|
+
.agent-avatar svg {
|
|
1360
|
+
width: 15px;
|
|
1361
|
+
height: 15px;
|
|
1362
|
+
fill: currentColor;
|
|
1263
1363
|
}
|
|
1264
1364
|
.agent-content-wrap {
|
|
1265
1365
|
flex: 1;
|
|
@@ -1394,6 +1494,38 @@
|
|
|
1394
1494
|
border-radius: 4px;
|
|
1395
1495
|
}
|
|
1396
1496
|
|
|
1497
|
+
/* Antigravity-like clickable file jump pill in chat */
|
|
1498
|
+
.file-jump-pill {
|
|
1499
|
+
display: inline-flex;
|
|
1500
|
+
align-items: center;
|
|
1501
|
+
gap: 4px;
|
|
1502
|
+
padding: 1.5px 7px;
|
|
1503
|
+
border-radius: 4px;
|
|
1504
|
+
background: linear-gradient(135deg, rgba(56, 189, 248, 0.08) 0%, rgba(129, 140, 248, 0.08) 100%);
|
|
1505
|
+
color: #4338ca;
|
|
1506
|
+
border: 1px solid rgba(129, 140, 248, 0.3);
|
|
1507
|
+
font-family: var(--font-mono);
|
|
1508
|
+
font-size: 11.5px;
|
|
1509
|
+
font-weight: 550;
|
|
1510
|
+
text-decoration: none;
|
|
1511
|
+
cursor: pointer;
|
|
1512
|
+
vertical-align: baseline;
|
|
1513
|
+
transition: all 0.15s ease;
|
|
1514
|
+
}
|
|
1515
|
+
.file-jump-pill:hover {
|
|
1516
|
+
background: linear-gradient(135deg, rgba(56, 189, 248, 0.18) 0%, rgba(129, 140, 248, 0.18) 100%);
|
|
1517
|
+
border-color: #6366f1;
|
|
1518
|
+
color: #312e81;
|
|
1519
|
+
box-shadow: 0 1px 3px rgba(99, 102, 241, 0.15);
|
|
1520
|
+
transform: translateY(-0.5px);
|
|
1521
|
+
}
|
|
1522
|
+
.file-jump-pill svg {
|
|
1523
|
+
width: 12px;
|
|
1524
|
+
height: 12px;
|
|
1525
|
+
flex-shrink: 0;
|
|
1526
|
+
stroke-width: 2.2;
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1397
1529
|
/* Shimmering Pulsing Dots for Streaming */
|
|
1398
1530
|
.agent-typing-indicator {
|
|
1399
1531
|
display: inline-flex;
|
|
@@ -1659,6 +1791,8 @@
|
|
|
1659
1791
|
.nav button { width: auto; white-space: nowrap; }
|
|
1660
1792
|
.main { padding: 16px; }
|
|
1661
1793
|
.workspace { grid-template-columns: 1fr; height: auto; }
|
|
1794
|
+
.workspace.chat-collapsed { grid-template-columns: 1fr; }
|
|
1795
|
+
.console-drawer { min-height: 360px; border-right: 0; border-bottom: 1px solid var(--border-subtle); }
|
|
1662
1796
|
.tree { max-height: 260px; border-right: 0; border-bottom: 1px solid var(--border-subtle); }
|
|
1663
1797
|
.viewer { min-height: 480px; }
|
|
1664
1798
|
.provider-grid, .cost-metrics { grid-template-columns: 1fr; }
|
|
@@ -1671,7 +1805,9 @@
|
|
|
1671
1805
|
<!-- 顶栏 Header -->
|
|
1672
1806
|
<header class="topbar">
|
|
1673
1807
|
<div class="brand">
|
|
1674
|
-
<span class="brand-mark"
|
|
1808
|
+
<span class="brand-mark" title="PsyClaw Academic AI">
|
|
1809
|
+
<svg viewBox="0 0 24 24"><path d="M12 2v20M12 2c-3.3 0-6 2.7-6 6v3c0 3.3 2.7 6 6 6s6-2.7 6-6V8c0-3.3-2.7-6-6-6zM4 9h4M16 9h4M9 22h6"/></svg>
|
|
1810
|
+
</span>
|
|
1675
1811
|
<div class="brand-title">
|
|
1676
1812
|
PsyClaw Panel
|
|
1677
1813
|
<span class="brand-badge">Academic Studio</span>
|
|
@@ -1692,6 +1828,10 @@
|
|
|
1692
1828
|
/crosscheck
|
|
1693
1829
|
</button>
|
|
1694
1830
|
</div>
|
|
1831
|
+
<a href="https://github.com/Exekiel179/psyclaw" target="_blank" rel="noopener noreferrer" class="github-link" title="前往 PsyClaw GitHub 仓库">
|
|
1832
|
+
<svg viewBox="0 0 24 24"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z"/></svg>
|
|
1833
|
+
<span>GitHub</span>
|
|
1834
|
+
</a>
|
|
1695
1835
|
<div class="local-badge">
|
|
1696
1836
|
<span class="pulse-dot"></span>
|
|
1697
1837
|
安全沙盒 · 本地隔离
|
|
@@ -1700,7 +1840,7 @@
|
|
|
1700
1840
|
</header>
|
|
1701
1841
|
|
|
1702
1842
|
<!-- 主体工作区 Layout -->
|
|
1703
|
-
<div class="layout">
|
|
1843
|
+
<div class="layout nav-collapsed">
|
|
1704
1844
|
<!-- 侧边导航栏 Sidebar -->
|
|
1705
1845
|
<nav class="nav" id="workbench-nav" aria-label="Panel 导航">
|
|
1706
1846
|
<div class="nav-group">
|
|
@@ -1710,30 +1850,26 @@
|
|
|
1710
1850
|
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg>
|
|
1711
1851
|
</button>
|
|
1712
1852
|
</div>
|
|
1713
|
-
<button class="active" data-view="project" title="
|
|
1714
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="
|
|
1715
|
-
<span class="nav-btn-text"
|
|
1853
|
+
<button class="active" data-view="project" title="工作台与对话">
|
|
1854
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><line x1="9" y1="4" x2="9" y2="20"/><line x1="15" y1="4" x2="15" y2="20"/></svg>
|
|
1855
|
+
<span class="nav-btn-text">工作台与对话</span>
|
|
1716
1856
|
</button>
|
|
1717
1857
|
<button data-view="ecosystem" title="能力生态">
|
|
1718
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="
|
|
1858
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>
|
|
1719
1859
|
<span class="nav-btn-text">能力生态</span>
|
|
1720
1860
|
</button>
|
|
1721
1861
|
<button data-view="provider" title="模型与成本">
|
|
1722
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="
|
|
1862
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
|
|
1723
1863
|
<span class="nav-btn-text">模型与成本</span>
|
|
1724
1864
|
</button>
|
|
1725
1865
|
<button data-view="help" title="使用速览">
|
|
1726
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="
|
|
1866
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
|
|
1727
1867
|
<span class="nav-btn-text">使用速览</span>
|
|
1728
1868
|
</button>
|
|
1729
1869
|
<button data-view="checklist" title="核对清单">
|
|
1730
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="
|
|
1870
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>
|
|
1731
1871
|
<span class="nav-btn-text">核对清单</span>
|
|
1732
1872
|
</button>
|
|
1733
|
-
<button data-view="chat" title="对话">
|
|
1734
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
|
|
1735
|
-
<span class="nav-btn-text">对话</span>
|
|
1736
|
-
</button>
|
|
1737
1873
|
</div>
|
|
1738
1874
|
<div class="nav-footer">
|
|
1739
1875
|
<div style="font-weight:600;margin-bottom:2px;color:var(--text-secondary)">PsyClaw 运行提示</div>
|
|
@@ -1743,13 +1879,12 @@
|
|
|
1743
1879
|
|
|
1744
1880
|
<!-- 主面板内容区 Main -->
|
|
1745
1881
|
<main class="main">
|
|
1746
|
-
<!-- 视图 1
|
|
1882
|
+
<!-- 视图 1:项目工作台 (默认主界面) -->
|
|
1747
1883
|
<section id="view-project" class="view active">
|
|
1748
|
-
<!--
|
|
1749
|
-
<div class="pipeline-stepper"
|
|
1750
|
-
<
|
|
1751
|
-
|
|
1752
|
-
<span>① 选题与入口</span>
|
|
1884
|
+
<!-- 科研全流程阶段导航条 Pipeline Stepper -->
|
|
1885
|
+
<div class="pipeline-stepper" aria-label="科研流程阶段">
|
|
1886
|
+
<div class="step-item active" data-stage="intake" title="研究问题与范式目标 (notes/goal.md)">
|
|
1887
|
+
<span>① 课题界定</span>
|
|
1753
1888
|
</div>
|
|
1754
1889
|
<span class="step-arrow">➔</span>
|
|
1755
1890
|
<div class="step-item" data-stage="evidence" title="证据溯源与文献账本 (notes/evidence.jsonl, claims.jsonl)">
|
|
@@ -1779,7 +1914,85 @@
|
|
|
1779
1914
|
刷新文档
|
|
1780
1915
|
</button>
|
|
1781
1916
|
</div>
|
|
1782
|
-
<div class="panel workspace">
|
|
1917
|
+
<div class="panel workspace no-file-open" id="project-workspace">
|
|
1918
|
+
<!-- 智能体交互对话抽屉(平时折叠,点击展开) -->
|
|
1919
|
+
<div id="console-drawer" class="console-drawer">
|
|
1920
|
+
<div class="console-header">
|
|
1921
|
+
<div class="console-title">
|
|
1922
|
+
<span class="agent-avatar" style="width:24px;height:24px;">
|
|
1923
|
+
<svg viewBox="0 0 24 24"><path d="M12 2v20M12 2c-3.3 0-6 2.7-6 6v3c0 3.3 2.7 6 6 6s6-2.7 6-6V8c0-3.3-2.7-6-6-6zM4 9h4M16 9h4M9 22h6"/></svg>
|
|
1924
|
+
</span>
|
|
1925
|
+
<span>智能体对话</span>
|
|
1926
|
+
<span id="console-status-badge" class="console-status-tag">
|
|
1927
|
+
<span class="pulse-dot" style="width:5px;height:5px;"></span>
|
|
1928
|
+
已连接
|
|
1929
|
+
</span>
|
|
1930
|
+
</div>
|
|
1931
|
+
<div class="console-actions">
|
|
1932
|
+
<button id="console-clear-btn" class="console-btn-icon" title="清空对话记录">
|
|
1933
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
|
|
1934
|
+
</button>
|
|
1935
|
+
<button id="chat-collapse-btn" class="console-btn-icon" title="收起/展开对话侧栏" aria-label="收起/展开对话侧栏">
|
|
1936
|
+
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="transition:transform 0.2s ease;"><polyline points="15 18 9 12 15 6"/></svg>
|
|
1937
|
+
</button>
|
|
1938
|
+
</div>
|
|
1939
|
+
</div>
|
|
1940
|
+
|
|
1941
|
+
<!-- 折叠时竖条提示区,点击可直接展开 -->
|
|
1942
|
+
<div class="console-collapsed-bar" id="console-collapsed-bar" title="点击展开智能体对话">
|
|
1943
|
+
<span class="agent-avatar" style="width:24px;height:24px;">
|
|
1944
|
+
<svg viewBox="0 0 24 24"><path d="M12 2v20M12 2c-3.3 0-6 2.7-6 6v3c0 3.3 2.7 6 6 6s6-2.7 6-6V8c0-3.3-2.7-6-6-6zM4 9h4M16 9h4M9 22h6"/></svg>
|
|
1945
|
+
</span>
|
|
1946
|
+
<span class="console-vertical-label">AI 对话</span>
|
|
1947
|
+
</div>
|
|
1948
|
+
|
|
1949
|
+
<div id="console-log" class="console-log">
|
|
1950
|
+
<div class="log-entry sys">
|
|
1951
|
+
<div class="log-sys">
|
|
1952
|
+
💡 <strong>对话已就绪</strong>:与 PsyClaw 智能体安全连接。支持 <code>/init</code>、<code>/plan</code>、<code>/grill</code>、<code>/crosscheck</code>(AI 核验)等指令。
|
|
1953
|
+
</div>
|
|
1954
|
+
</div>
|
|
1955
|
+
</div>
|
|
1956
|
+
|
|
1957
|
+
<div class="console-quick-chips">
|
|
1958
|
+
<span class="chip" data-cmd="/plan status">
|
|
1959
|
+
<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>
|
|
1960
|
+
/plan status
|
|
1961
|
+
</span>
|
|
1962
|
+
<span class="chip" data-cmd="/crosscheck list">
|
|
1963
|
+
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 11l3 3L22 4"/></svg>
|
|
1964
|
+
/crosscheck
|
|
1965
|
+
</span>
|
|
1966
|
+
<span class="chip" data-cmd="/grill">
|
|
1967
|
+
<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>
|
|
1968
|
+
/grill 压力追问
|
|
1969
|
+
</span>
|
|
1970
|
+
<span class="chip" data-cmd="/review">
|
|
1971
|
+
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/></svg>
|
|
1972
|
+
/review
|
|
1973
|
+
</span>
|
|
1974
|
+
<span class="chip" data-cmd="/agents">
|
|
1975
|
+
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/></svg>
|
|
1976
|
+
/agents
|
|
1977
|
+
</span>
|
|
1978
|
+
</div>
|
|
1979
|
+
|
|
1980
|
+
<div class="console-input-wrap">
|
|
1981
|
+
<div class="console-input-container">
|
|
1982
|
+
<div class="console-input-box">
|
|
1983
|
+
<textarea id="console-input" class="console-textarea" placeholder="向智能体提问或输入指令(Enter 发送)…" rows="1"></textarea>
|
|
1984
|
+
<button id="console-send-btn" class="console-send-btn" title="发送消息 (Enter)">
|
|
1985
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
|
|
1986
|
+
</button>
|
|
1987
|
+
</div>
|
|
1988
|
+
<div class="console-input-footer">
|
|
1989
|
+
<span>支持 Markdown 与学术指令</span>
|
|
1990
|
+
<span>PsyClaw 本地隔离环境</span>
|
|
1991
|
+
</div>
|
|
1992
|
+
</div>
|
|
1993
|
+
</div>
|
|
1994
|
+
</div>
|
|
1995
|
+
|
|
1783
1996
|
<aside id="file-tree" class="tree">
|
|
1784
1997
|
<div class="empty">读取项目文档中...</div>
|
|
1785
1998
|
</aside>
|
|
@@ -1795,6 +2008,9 @@
|
|
|
1795
2008
|
<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="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
|
1796
2009
|
复制
|
|
1797
2010
|
</button>
|
|
2011
|
+
<button id="viewer-close-btn" class="console-btn-icon" title="关闭文件,展开对话视图" style="padding:4px;color:var(--text-muted);">
|
|
2012
|
+
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
|
2013
|
+
</button>
|
|
1798
2014
|
</div>
|
|
1799
2015
|
</div>
|
|
1800
2016
|
<div id="viewer-body" class="viewer-body empty">
|
|
@@ -1979,80 +2195,6 @@
|
|
|
1979
2195
|
</table>
|
|
1980
2196
|
</div>
|
|
1981
2197
|
</section>
|
|
1982
|
-
|
|
1983
|
-
<section id="view-chat" class="view">
|
|
1984
|
-
<div class="page-head" style="margin-bottom: 12px;">
|
|
1985
|
-
<div>
|
|
1986
|
-
<h1>交互对话</h1>
|
|
1987
|
-
<p>提问将接入当前 PsyClaw 会话;助手回复经 SSE 流式同步,支持学术指令与「唤醒选项」决策。</p>
|
|
1988
|
-
</div>
|
|
1989
|
-
</div>
|
|
1990
|
-
<div id="chat-console-host" class="panel section" style="min-height:74vh;padding:0;overflow:hidden;display:flex;flex-direction:column;border-radius:var(--radius-md);">
|
|
1991
|
-
<div id="console-drawer" class="console-drawer">
|
|
1992
|
-
<div class="console-header">
|
|
1993
|
-
<div class="console-title">
|
|
1994
|
-
<span class="agent-avatar" style="width:24px;height:24px;font-size:12px">ψ</span>
|
|
1995
|
-
<span>PsyClaw Research Assistant</span>
|
|
1996
|
-
<span id="console-status-badge" class="console-status-tag">
|
|
1997
|
-
<span class="pulse-dot" style="width:5px;height:5px;"></span>
|
|
1998
|
-
已连接
|
|
1999
|
-
</span>
|
|
2000
|
-
</div>
|
|
2001
|
-
<div class="console-actions">
|
|
2002
|
-
<button id="console-clear-btn" class="console-btn-icon" title="清空对话记录">
|
|
2003
|
-
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
|
|
2004
|
-
</button>
|
|
2005
|
-
</div>
|
|
2006
|
-
</div>
|
|
2007
|
-
|
|
2008
|
-
<div id="console-log" class="console-log">
|
|
2009
|
-
<div class="log-entry sys">
|
|
2010
|
-
<div class="log-sys">
|
|
2011
|
-
💡 <strong>对话已就绪</strong>:与 PsyClaw 智能体安全连接。支持 <code>/init</code>、<code>/plan</code>、<code>/grill</code>、<code>/crosscheck</code>(AI 核验)等指令。
|
|
2012
|
-
</div>
|
|
2013
|
-
</div>
|
|
2014
|
-
</div>
|
|
2015
|
-
|
|
2016
|
-
<div class="console-quick-chips">
|
|
2017
|
-
<span class="chip" data-cmd="/plan status">
|
|
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>
|
|
2019
|
-
/plan status
|
|
2020
|
-
</span>
|
|
2021
|
-
<span class="chip" data-cmd="/crosscheck list">
|
|
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>
|
|
2023
|
-
/crosscheck list
|
|
2024
|
-
</span>
|
|
2025
|
-
<span class="chip" data-cmd="/grill">
|
|
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>
|
|
2027
|
-
/grill 压力追问
|
|
2028
|
-
</span>
|
|
2029
|
-
<span class="chip" data-cmd="/review">
|
|
2030
|
-
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/></svg>
|
|
2031
|
-
/review 评审
|
|
2032
|
-
</span>
|
|
2033
|
-
<span class="chip" data-cmd="/agents">
|
|
2034
|
-
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/></svg>
|
|
2035
|
-
/agents 角色
|
|
2036
|
-
</span>
|
|
2037
|
-
</div>
|
|
2038
|
-
|
|
2039
|
-
<div class="console-input-wrap">
|
|
2040
|
-
<div class="console-input-container">
|
|
2041
|
-
<div class="console-input-box">
|
|
2042
|
-
<textarea id="console-input" class="console-textarea" placeholder="输入研究问题或指令(Enter 发送,Shift+Enter 换行)…" rows="1"></textarea>
|
|
2043
|
-
<button id="console-send-btn" class="console-send-btn" title="发送消息 (Enter)">
|
|
2044
|
-
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
|
|
2045
|
-
</button>
|
|
2046
|
-
</div>
|
|
2047
|
-
<div class="console-input-footer">
|
|
2048
|
-
<span>支持 Markdown 与学术指令</span>
|
|
2049
|
-
<span>PsyClaw 本地隔离环境</span>
|
|
2050
|
-
</div>
|
|
2051
|
-
</div>
|
|
2052
|
-
</div>
|
|
2053
|
-
</div>
|
|
2054
|
-
</div>
|
|
2055
|
-
</section>
|
|
2056
2198
|
</main>
|
|
2057
2199
|
</div>
|
|
2058
2200
|
</div>
|
|
@@ -2141,6 +2283,12 @@ async function json(url, options) {
|
|
|
2141
2283
|
}
|
|
2142
2284
|
|
|
2143
2285
|
function setView(view) {
|
|
2286
|
+
if (view === "chat") {
|
|
2287
|
+
// 对话框直接位于第一个界面(工作台),自动切换到项目视图并展开对话
|
|
2288
|
+
setView("project");
|
|
2289
|
+
expandChat();
|
|
2290
|
+
return;
|
|
2291
|
+
}
|
|
2144
2292
|
state.view = view;
|
|
2145
2293
|
if (location.hash.replace(/^#/, "") !== view) {
|
|
2146
2294
|
history.replaceState(null, "", `#${view}`);
|
|
@@ -2155,7 +2303,6 @@ function setView(view) {
|
|
|
2155
2303
|
if (view === "provider") loadProvider();
|
|
2156
2304
|
if (view === "checklist") loadChecklist();
|
|
2157
2305
|
if (view === "help") loadHelp();
|
|
2158
|
-
if (view === "chat") queueMicrotask(() => $("console-input")?.focus());
|
|
2159
2306
|
}
|
|
2160
2307
|
|
|
2161
2308
|
async function loadHelp() {
|
|
@@ -2246,15 +2393,33 @@ document.querySelectorAll(".nav button[data-view]").forEach(button => {
|
|
|
2246
2393
|
button.addEventListener("click", () => setView(button.dataset.view));
|
|
2247
2394
|
});
|
|
2248
2395
|
|
|
2396
|
+
function renderFileJumpPill(path) {
|
|
2397
|
+
const cleanPath = esc(path);
|
|
2398
|
+
const fileName = esc(path.split("/").at(-1));
|
|
2399
|
+
return `<button type="button" class="file-jump-pill" data-jump-file="${cleanPath}" title="点击在工作台查看 ${cleanPath}"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg><span>${fileName}</span></button>`;
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2249
2402
|
function inlineMarkdown(text) {
|
|
2250
2403
|
let value = esc(text);
|
|
2404
|
+
// 解析反引号中的文件路径,如 `notes/goal.md`、`paper/draft.md`
|
|
2405
|
+
value = value.replace(/`((?:notes|paper|docs|outputs|analysis|\.psyclaw)\/[a-zA-Z0-9_\-./]+|\b[a-zA-Z0-9_\-]+\.(?:md|json|jsonl|txt|py|r|tex)\b)`/g, (_, path) => renderFileJumpPill(path));
|
|
2251
2406
|
value = value.replace(/`([^`]+)`/g, "<code>$1</code>")
|
|
2252
2407
|
.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>")
|
|
2253
2408
|
.replace(/\*([^*]+)\*/g, "<em>$1</em>");
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
: label
|
|
2409
|
+
// 解析 Markdown 链接,区分网页链接与本地文件相对路径
|
|
2410
|
+
value = value.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, target) => {
|
|
2411
|
+
if (/^https?:\/\//i.test(target)) {
|
|
2412
|
+
return `<a href="${esc(target)}" target="_blank" rel="noreferrer" style="color:var(--brand-accent);text-decoration:none;border-bottom:1px dashed currentColor">${label}</a>`;
|
|
2413
|
+
}
|
|
2414
|
+
// 本地文件相对链接
|
|
2415
|
+
if (/\.(md|json|jsonl|txt|py|r|tex)$/i.test(target) || /^(notes|paper|docs|outputs|analysis|\.psyclaw)\//.test(target)) {
|
|
2416
|
+
return renderFileJumpPill(target.replace(/^\.\//, ""));
|
|
2417
|
+
}
|
|
2418
|
+
return label;
|
|
2419
|
+
});
|
|
2420
|
+
// 识别未被标签包裹的独立文件相对路径
|
|
2421
|
+
value = value.replace(/(^|[\s((])((?:notes|paper|docs|outputs|analysis|\.psyclaw)\/[a-zA-Z0-9_\-./]+\.[a-zA-Z0-9]+)(?=[)\s,。!?,!?)]|$)/g,
|
|
2422
|
+
(_, prefix, path) => `${prefix}${renderFileJumpPill(path)}`
|
|
2258
2423
|
);
|
|
2259
2424
|
return value;
|
|
2260
2425
|
}
|
|
@@ -2391,8 +2556,24 @@ function selectTree(button) {
|
|
|
2391
2556
|
document.querySelectorAll(".tree-item").forEach(item => item.classList.toggle("active", item === button));
|
|
2392
2557
|
}
|
|
2393
2558
|
|
|
2559
|
+
function closeFile() {
|
|
2560
|
+
const ws = $("project-workspace");
|
|
2561
|
+
if (ws) ws.classList.add("no-file-open");
|
|
2562
|
+
selectTree(null);
|
|
2563
|
+
state.currentContent = "";
|
|
2564
|
+
$("viewer-path").textContent = "选择左侧文件";
|
|
2565
|
+
$("viewer-kind").textContent = "未打开";
|
|
2566
|
+
$("viewer-body").className = "viewer-body empty";
|
|
2567
|
+
$("viewer-body").textContent = "请在文件树或对话中选择文件进行查看";
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2394
2570
|
async function openFile(path, button) {
|
|
2395
|
-
|
|
2571
|
+
const ws = $("project-workspace");
|
|
2572
|
+
if (ws) {
|
|
2573
|
+
ws.classList.remove("no-file-open");
|
|
2574
|
+
}
|
|
2575
|
+
const btn = button || document.querySelector(`[data-file="${path}"]`);
|
|
2576
|
+
selectTree(btn);
|
|
2396
2577
|
$("viewer-path").textContent = path;
|
|
2397
2578
|
$("viewer-kind").textContent = "读取中";
|
|
2398
2579
|
$("viewer-body").className = "viewer-body empty";
|
|
@@ -2428,12 +2609,16 @@ $("viewer-copy-btn").addEventListener("click", async () => {
|
|
|
2428
2609
|
}
|
|
2429
2610
|
});
|
|
2430
2611
|
|
|
2612
|
+
// 关闭文件预览按钮,恢复对话框铺满状态
|
|
2613
|
+
$("viewer-close-btn")?.addEventListener("click", () => {
|
|
2614
|
+
closeFile();
|
|
2615
|
+
});
|
|
2616
|
+
|
|
2431
2617
|
async function loadProject() {
|
|
2432
2618
|
const files = await json("/api/project-files");
|
|
2433
2619
|
state.files = files.files || [];
|
|
2434
2620
|
renderTree();
|
|
2435
|
-
|
|
2436
|
-
if (goal) goal.click();
|
|
2621
|
+
// 默认不自动打开文件,让对话框铺满工作台主区域;用户点击文件树或对话中文件链接时再展示
|
|
2437
2622
|
}
|
|
2438
2623
|
|
|
2439
2624
|
async function loadEcosystem() {
|
|
@@ -2745,8 +2930,25 @@ const streamBubbles = new Map();
|
|
|
2745
2930
|
let lastLocalUserText = "";
|
|
2746
2931
|
let wakeState = null;
|
|
2747
2932
|
|
|
2933
|
+
function expandChat() {
|
|
2934
|
+
const ws = $("project-workspace");
|
|
2935
|
+
if (ws && ws.classList.contains("chat-collapsed")) {
|
|
2936
|
+
ws.classList.remove("chat-collapsed");
|
|
2937
|
+
localStorage.setItem("psyclaw_chat_collapsed", "false");
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
|
|
2941
|
+
function collapseChat() {
|
|
2942
|
+
const ws = $("project-workspace");
|
|
2943
|
+
if (ws && !ws.classList.contains("chat-collapsed")) {
|
|
2944
|
+
ws.classList.add("chat-collapsed");
|
|
2945
|
+
localStorage.setItem("psyclaw_chat_collapsed", "true");
|
|
2946
|
+
}
|
|
2947
|
+
}
|
|
2948
|
+
|
|
2748
2949
|
function openConsole() {
|
|
2749
|
-
setView("
|
|
2950
|
+
setView("project");
|
|
2951
|
+
expandChat();
|
|
2750
2952
|
queueMicrotask(() => consoleInput?.focus());
|
|
2751
2953
|
}
|
|
2752
2954
|
|
|
@@ -2755,6 +2957,8 @@ function openConsoleWithMessage(text) {
|
|
|
2755
2957
|
appendLog("sys", text);
|
|
2756
2958
|
}
|
|
2757
2959
|
|
|
2960
|
+
const PSYCLAW_AVATAR_SVG = `<svg viewBox="0 0 24 24"><path d="M12 2v20M12 2c-3.3 0-6 2.7-6 6v3c0 3.3 2.7 6 6 6s6-2.7 6-6V8c0-3.3-2.7-6-6-6zM4 9h4M16 9h4M9 22h6"/></svg>`;
|
|
2961
|
+
|
|
2758
2962
|
function appendLog(role, text) {
|
|
2759
2963
|
const entry = document.createElement("div");
|
|
2760
2964
|
entry.className = `log-entry ${role}`;
|
|
@@ -2766,7 +2970,7 @@ function appendLog(role, text) {
|
|
|
2766
2970
|
`;
|
|
2767
2971
|
} else if (role === "agent") {
|
|
2768
2972
|
entry.innerHTML = `
|
|
2769
|
-
<div class="agent-avatar"
|
|
2973
|
+
<div class="agent-avatar">${PSYCLAW_AVATAR_SVG}</div>
|
|
2770
2974
|
<div class="agent-content-wrap">
|
|
2771
2975
|
<div class="agent-meta">
|
|
2772
2976
|
<span>PsyClaw Assistant</span>
|
|
@@ -2790,7 +2994,7 @@ function ensureStreamBubble(messageId) {
|
|
|
2790
2994
|
entry.className = "log-entry agent";
|
|
2791
2995
|
entry.dataset.messageId = messageId;
|
|
2792
2996
|
entry.innerHTML = `
|
|
2793
|
-
<div class="agent-avatar"
|
|
2997
|
+
<div class="agent-avatar">${PSYCLAW_AVATAR_SVG}</div>
|
|
2794
2998
|
<div class="agent-content-wrap">
|
|
2795
2999
|
<div class="agent-meta">
|
|
2796
3000
|
<span>PsyClaw Assistant</span>
|
|
@@ -3081,14 +3285,28 @@ document.querySelectorAll(".chip").forEach(chip => {
|
|
|
3081
3285
|
});
|
|
3082
3286
|
});
|
|
3083
3287
|
|
|
3084
|
-
/* ---
|
|
3288
|
+
/* --- 侧边栏与工作台对话框折叠交互 --- */
|
|
3085
3289
|
const layoutEl = document.querySelector(".layout");
|
|
3086
3290
|
const navToggleBtn = $("nav-toggle-btn");
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3291
|
+
const chatCollapseBtn = $("chat-collapse-btn");
|
|
3292
|
+
const consoleCollapsedBar = $("console-collapsed-bar");
|
|
3293
|
+
const workspaceEl = $("project-workspace");
|
|
3294
|
+
|
|
3295
|
+
function initWorkbenchCollapse() {
|
|
3296
|
+
const savedNav = localStorage.getItem("psyclaw_nav_collapsed");
|
|
3297
|
+
// 平时默认折叠成图标;除非用户主动展开(存为 "false")
|
|
3298
|
+
if (savedNav !== "false") {
|
|
3091
3299
|
layoutEl?.classList.add("nav-collapsed");
|
|
3300
|
+
} else {
|
|
3301
|
+
layoutEl?.classList.remove("nav-collapsed");
|
|
3302
|
+
}
|
|
3303
|
+
|
|
3304
|
+
// 对话框折叠态记忆
|
|
3305
|
+
const savedChat = localStorage.getItem("psyclaw_chat_collapsed");
|
|
3306
|
+
if (savedChat === "true") {
|
|
3307
|
+
workspaceEl?.classList.add("chat-collapsed");
|
|
3308
|
+
} else {
|
|
3309
|
+
workspaceEl?.classList.remove("chat-collapsed");
|
|
3092
3310
|
}
|
|
3093
3311
|
}
|
|
3094
3312
|
|
|
@@ -3098,7 +3316,29 @@ navToggleBtn?.addEventListener("click", () => {
|
|
|
3098
3316
|
localStorage.setItem("psyclaw_nav_collapsed", isCollapsed ? "true" : "false");
|
|
3099
3317
|
});
|
|
3100
3318
|
|
|
3101
|
-
|
|
3319
|
+
chatCollapseBtn?.addEventListener("click", () => {
|
|
3320
|
+
if (!workspaceEl) return;
|
|
3321
|
+
const isCollapsed = workspaceEl.classList.toggle("chat-collapsed");
|
|
3322
|
+
localStorage.setItem("psyclaw_chat_collapsed", isCollapsed ? "true" : "false");
|
|
3323
|
+
});
|
|
3324
|
+
|
|
3325
|
+
consoleCollapsedBar?.addEventListener("click", () => {
|
|
3326
|
+
expandChat();
|
|
3327
|
+
queueMicrotask(() => consoleInput?.focus());
|
|
3328
|
+
});
|
|
3329
|
+
|
|
3330
|
+
// 全局监听对话框中的文件跳转胶囊 (.file-jump-pill) 点击
|
|
3331
|
+
document.addEventListener("click", (e) => {
|
|
3332
|
+
const pill = e.target.closest(".file-jump-pill");
|
|
3333
|
+
if (!pill) return;
|
|
3334
|
+
const targetPath = pill.dataset.jumpFile;
|
|
3335
|
+
if (targetPath) {
|
|
3336
|
+
e.preventDefault();
|
|
3337
|
+
openFile(targetPath);
|
|
3338
|
+
}
|
|
3339
|
+
});
|
|
3340
|
+
|
|
3341
|
+
initWorkbenchCollapse();
|
|
3102
3342
|
|
|
3103
3343
|
/* --- 顶栏快捷命令 Quick Actions --- */
|
|
3104
3344
|
const initModal = $("init-modal");
|