@lyra_wang/dsh-terminal-context 0.3.0 → 0.4.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/client.js +53 -33
- package/locale/en.json +6 -1
- package/locale/zh.json +6 -1
- package/package.json +2 -2
package/client.js
CHANGED
|
@@ -1,56 +1,76 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 界面侧 ·
|
|
2
|
+
* 界面侧 · 读侧边栏(v0.4.0)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* 原来只读终端的 .xterm-rows。但侧边栏不止终端 —— 还可能挂着浏览器面板,
|
|
5
|
+
* 两者都是"你眼前的东西",都该进 Agent 的上下文。
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* 做法:先按已知结构读终端;再扫一遍可能的侧边栏容器,把它们的结构一起推回去。
|
|
8
|
+
* 为什么要推结构:不同面板的 DOM 差别很大,与其猜选择器,不如让页面自己报告
|
|
9
|
+
* "有哪些容器、各有多少字",下一版照着写就一次到位。
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* 三条硬约束(v0.1 事故的教训):
|
|
12
|
+
* inject: [] 不声明依赖 → 不可能 pending → 不会拖垮启动
|
|
13
|
+
* 全部 try/catch 读失败只是"没数据",不白屏
|
|
14
|
+
* 只读 不点击、不输入
|
|
14
15
|
*/
|
|
15
16
|
window.__ModuleLoader__.load({
|
|
16
17
|
id: '@lyra_wang/dsh-terminal-context',
|
|
17
18
|
factory() {
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
19
|
+
const MAX = 80
|
|
20
|
+
const clean = (t) => (t || '').replace(/\u00a0/g, ' ').replace(/[ \t]+$/gm, '')
|
|
21
|
+
|
|
22
|
+
const readTerminal = () => {
|
|
21
23
|
const rows = document.querySelectorAll('.xterm-rows > div')
|
|
22
|
-
if (!rows.length)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
if (!rows.length) return null
|
|
25
|
+
const out = []
|
|
26
|
+
for (const r of rows) out.push(clean(r.textContent))
|
|
27
|
+
while (out.length && !out[0].trim()) out.shift()
|
|
28
|
+
while (out.length && !out[out.length - 1].trim()) out.pop()
|
|
29
|
+
return out.slice(-MAX)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 扫可能的侧边栏容器。命中后连结构和样本一起带回去,供下一版锁定选择器。
|
|
33
|
+
const scanPanels = () => {
|
|
34
|
+
const hits = []
|
|
35
|
+
const seen = new Set()
|
|
36
|
+
const nodes = document.querySelectorAll('[class*="sidebar"],[class*="rightbar"],[class*="panel"],[class*="terminal"],[class*="browser"],[id*="sidebar"],[id*="panel"]')
|
|
37
|
+
for (const el of nodes) {
|
|
38
|
+
if (seen.has(el) || el === document.body) continue
|
|
39
|
+
seen.add(el)
|
|
40
|
+
const text = clean(el.innerText || '')
|
|
41
|
+
if (text.length < 40) continue
|
|
42
|
+
hits.push({
|
|
43
|
+
tag: el.tagName.toLowerCase(),
|
|
44
|
+
cls: String(el.className || '').slice(0, 80),
|
|
45
|
+
chars: text.length,
|
|
46
|
+
sample: text.slice(0, 120).replace(/\n+/g, ' ⏎ '),
|
|
47
|
+
})
|
|
48
|
+
if (hits.length >= 8) break
|
|
32
49
|
}
|
|
33
|
-
|
|
34
|
-
while (lines.length && !lines[lines.length - 1].trim()) lines.pop()
|
|
35
|
-
return lines.slice(-MAX_LINES)
|
|
50
|
+
return hits
|
|
36
51
|
}
|
|
52
|
+
|
|
37
53
|
return {
|
|
38
54
|
inject: [],
|
|
39
55
|
apply(ctx) {
|
|
40
|
-
let
|
|
56
|
+
let lastKey = ''
|
|
41
57
|
const push = () => {
|
|
42
58
|
try {
|
|
43
|
-
const lines =
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
47
|
-
|
|
59
|
+
const lines = readTerminal()
|
|
60
|
+
const panels = scanPanels()
|
|
61
|
+
const key = JSON.stringify([lines && lines.slice(-5), panels.map((p) => p.cls + p.chars)])
|
|
62
|
+
if (key === lastKey) return
|
|
63
|
+
lastKey = key
|
|
48
64
|
fetch('/plugins/terminal-context/push', {
|
|
49
65
|
method: 'POST',
|
|
50
66
|
headers: { 'content-type': 'application/json' },
|
|
51
|
-
body: JSON.stringify({
|
|
67
|
+
body: JSON.stringify({
|
|
68
|
+
lines: lines || [],
|
|
69
|
+
truncated: !!(lines && lines.length >= MAX),
|
|
70
|
+
diag: panels.length ? { panels } : null,
|
|
71
|
+
}),
|
|
52
72
|
}).catch(() => {})
|
|
53
|
-
} catch { /*
|
|
73
|
+
} catch { /* 静默 */ }
|
|
54
74
|
}
|
|
55
75
|
try {
|
|
56
76
|
ctx.effect(() => {
|
package/locale/en.json
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"title": "DSH Sidebar Context",
|
|
4
|
+
"description": "Feeds the DSH sidebar's current content (terminal / browser panel) to the agent so its next step matches what is on screen."
|
|
5
|
+
}
|
|
6
|
+
}
|
package/locale/zh.json
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lyra_wang/dsh-terminal-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "把 DSH 侧边栏当前显示的内容(终端 / 浏览器面板)交给 Agent,作为它判断当前处境的上下文。",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./index.js",
|
|
8
8
|
"./locale/*.json": "./locale/*.json",
|