@gavinc-cn/touchstone-dsh 0.1.1 → 0.3.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.
Files changed (90) hide show
  1. package/README.md +39 -11
  2. package/README.zh.md +25 -10
  3. package/backend/lib/access.js +44 -0
  4. package/backend/lib/agents.js +341 -0
  5. package/backend/lib/args.js +94 -0
  6. package/backend/lib/auth.js +195 -0
  7. package/backend/lib/board.js +6154 -0
  8. package/backend/lib/builtin-assets.js +1177 -0
  9. package/backend/lib/casescan.js +456 -0
  10. package/backend/lib/chat.js +2053 -0
  11. package/backend/lib/cookie.js +76 -0
  12. package/backend/lib/db.js +2260 -0
  13. package/backend/lib/dshdriver.js +1148 -0
  14. package/backend/lib/dshevents.js +851 -0
  15. package/backend/lib/export-cases.js +261 -0
  16. package/backend/lib/feishu.js +1738 -0
  17. package/backend/lib/feishu_cfg.js +228 -0
  18. package/backend/lib/feishu_conv.js +1484 -0
  19. package/backend/lib/feishu_device.js +428 -0
  20. package/backend/lib/feishu_inbound.js +1674 -0
  21. package/backend/lib/feishu_provision.js +855 -0
  22. package/backend/lib/feishu_rest.js +398 -0
  23. package/backend/lib/feishu_slash.js +568 -0
  24. package/backend/lib/feishu_ws.js +950 -0
  25. package/backend/lib/http.js +312 -0
  26. package/backend/lib/lib.js +973 -0
  27. package/backend/lib/loadcase.js +749 -0
  28. package/backend/lib/loadgen.js +1407 -0
  29. package/backend/lib/localbus.js +164 -0
  30. package/backend/lib/lock.js +405 -0
  31. package/backend/lib/proc.js +278 -0
  32. package/backend/lib/prompts.js +1021 -0
  33. package/backend/lib/pybase64.js +114 -0
  34. package/backend/lib/pyjson.js +214 -0
  35. package/backend/lib/query.js +125 -0
  36. package/backend/lib/rag.js +1310 -0
  37. package/backend/lib/runner.js +4520 -0
  38. package/backend/lib/servercaps.js +182 -0
  39. package/backend/lib/serverstate.js +237 -0
  40. package/backend/lib/sessparse.js +1176 -0
  41. package/backend/lib/sse.js +207 -0
  42. package/backend/lib/static.js +84 -0
  43. package/backend/lib/taskjson.js +302 -0
  44. package/backend/lib/waitq.js +2114 -0
  45. package/backend/lib/worktree.js +588 -0
  46. package/backend/lib/zstd-frames.js +218 -0
  47. package/backend/routes/admin.js +553 -0
  48. package/backend/routes/agents.js +149 -0
  49. package/backend/routes/assets.js +145 -0
  50. package/backend/routes/board.js +1220 -0
  51. package/backend/routes/feishu.js +269 -0
  52. package/backend/routes/feishu_app.js +215 -0
  53. package/backend/routes/feishu_hook.js +358 -0
  54. package/backend/routes/index.js +297 -0
  55. package/backend/routes/projects.js +1059 -0
  56. package/backend/routes/sessions.js +946 -0
  57. package/backend/routes/tasks.js +1530 -0
  58. package/backend/schema/fixtures/ancient.sql +189 -0
  59. package/backend/schema/fixtures/pre_alter.sql +177 -0
  60. package/backend/schema/migrations.json +154 -0
  61. package/backend/schema/schema.json +1451 -0
  62. package/backend/schema/schema.sql +216 -0
  63. package/backend/server.js +498 -0
  64. package/board.py +805 -72
  65. package/chat.py +590 -17
  66. package/db.py +356 -140
  67. package/dsh-plugin/cordis.patch.yml +7 -3
  68. package/dsh-plugin/install.sh +28 -11
  69. package/dsh-plugin/lib/agent-driver.js +710 -89
  70. package/dsh-plugin/lib/client.bundle.js +94 -9
  71. package/dsh-plugin/lib/index.js +529 -39
  72. package/dsh-plugin/lib/pack-closure.mjs +291 -0
  73. package/dsh-plugin/scripts/prepack-check.mjs +30 -2
  74. package/dsh-plugin/src/client.js +94 -9
  75. package/dshdriver.py +74 -5
  76. package/dshevents.py +65 -3
  77. package/feishu.py +1197 -34
  78. package/feishu_conv.py +920 -0
  79. package/lifecycle.py +116 -13
  80. package/package.json +6 -1
  81. package/requirements.txt +2 -1
  82. package/server.py +218 -26
  83. package/sessparse.py +150 -44
  84. package/touchstone.py +6 -3
  85. package/waitq.py +23 -0
  86. package/webui/dist-plugin/assets/index-ChP3sg6y.css +1 -0
  87. package/webui/dist-plugin/assets/index-UrMyeAXF.js +484 -0
  88. package/webui/dist-plugin/index.html +2 -2
  89. package/webui/dist-plugin/assets/index-B0WoP1Qy.css +0 -1
  90. package/webui/dist-plugin/assets/index-DtwKoi1T.js +0 -473
@@ -112,20 +112,103 @@ function toggleByKey(e) {
112
112
  /** 宿主页 keydown 监听体(capture 阶段; 函数引用稳定, 便于 dispose 时精确解绑)。 */
113
113
  function onHostKey(e) { toggleByKey(e); }
114
114
 
115
+ // ── 侧栏入口按钮的配色与几何(2026-10-09 修) ──────────────────────────────────
116
+ // 血案: 原先写 color:'var(--dsw-alias-text-l1, #e8e8e8)' —— dsh **没有** text-l1 这族
117
+ // token(真实族是 --dsw-alias-label-primary/secondary/tertiary/caption/dimmed), var() 取不到
118
+ // 就一直吃 fallback: 浅色档在 #f9fafb 的侧栏底上画 #e8e8e8 的字(实测对比度 1.17, 同排的
119
+ // 「插件」「设置」是 18.08), 只有深色档碰巧能看。教训: 引用宿主 token 一律先核实名字。
120
+ // 现行口径(明暗两档都跟宿主走):
121
+ // · 颜色**只取 dsh 语义 token 且不写死 fallback** —— token 缺席时该声明失效并回落到继承
122
+ // (侧栏根 .hHd-Xa_root 已设 label-primary), 而不是钉死一个只对某一档成立的灰;
123
+ // · 尺寸/圆角/gap/行高逐条对齐 dsh 自己的 .SidebarRoot_panelRow(min-height 36 / 内边距
124
+ // 7px 8px / margin 0 2px / gap 8 / line-height 22 / --dsw-radius-md), 收起态对齐
125
+ // .hHd-Xa_collapsed .panelRow(36x36 居中);
126
+ // · 图标盒 16x16 —— 与 dsh 侧栏 SVG 图标同尺寸; 文字继承侧栏根的 14px。
127
+ const ENTRY_TITLE = 'Touchstone 测试平台(Alt+T 开关)';
128
+ const ENTRY_GLYPH_STYLE = {
129
+ flex: '0 0 16px', width: 16, height: 16, display: 'inline-flex',
130
+ alignItems: 'center', justifyContent: 'center', fontSize: 16, lineHeight: '16px',
131
+ };
132
+ const ENTRY_LABEL_STYLE = {
133
+ minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
134
+ };
135
+
136
+ // 交互态样式(悬停/开合/键盘聚焦环): 伪类没法写在 inline style 里, 落一张最小样式表。
137
+ // 取值逐条对齐 dsh 侧栏行(.hHd-Xa_panelRow:hover 与 :focus-visible)。
138
+ const ENTRY_CSS = [
139
+ '.ts-sb-entry{background:transparent}',
140
+ '.ts-sb-entry:hover,.ts-sb-entry.ts-sb-on{background:'
141
+ + 'var(--dsw-alias-interactive-bg-hover,color-mix(in srgb,currentColor 8%,transparent))}',
142
+ '.ts-sb-entry:focus-visible{outline-width:var(--dsw-focus-ring-width,2px);outline-style:solid;'
143
+ + 'outline-color:var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));'
144
+ + 'outline-offset:-2px}',
145
+ ].join('');
146
+ const ENTRY_CSS_ID = 'touchstone/sidebar-entry.css';
147
+
148
+ /** 幂等挂上入口行交互态样式表(形态与 dsh 插件自身的注入方式一致)。
149
+ * **失败一律吞掉**: 挂不上只是少了悬停/聚焦环的观感, 绝不能让侧栏入口或面板受影响
150
+ * (桩 DOM 自检环境里 document 面本就不全, 真机异常同理)。
151
+ * @returns 摘除函数(插件卸载时调用; 已存在/挂不上时返回空操作)。 */
152
+ function mountEntryStyle() {
153
+ try {
154
+ if (typeof document === 'undefined' || !document.head
155
+ || typeof document.createElement !== 'function'
156
+ || typeof document.querySelector !== 'function') {
157
+ return () => {};
158
+ }
159
+ if (document.querySelector('style[data-plugin-css=' + JSON.stringify(ENTRY_CSS_ID) + ']')) {
160
+ return () => {};
161
+ }
162
+ const tag = document.createElement('style');
163
+ tag.dataset.plugin = 'touchstone';
164
+ tag.dataset.pluginCss = ENTRY_CSS_ID;
165
+ tag.textContent = ENTRY_CSS;
166
+ document.head.appendChild(tag);
167
+ return () => tag.remove();
168
+ } catch (error) {
169
+ console.warn('[touchstone] 侧栏入口样式注入失败(只影响悬停/聚焦观感):', error);
170
+ return () => {};
171
+ }
172
+ }
173
+
115
174
  // 侧栏入口按钮(footer.action 槽; wide=侧栏展开态显示文字)
116
175
  function Toggle(props) {
117
- const wide = props && props.wide;
176
+ const wide = !!(props && props.wide);
118
177
  const isOpen = useOpen();
178
+ const style = {
179
+ boxSizing: 'border-box', display: 'flex', alignItems: 'center',
180
+ border: 'none', cursor: 'pointer', textAlign: 'left',
181
+ color: 'var(--dsw-alias-label-primary)', // 无 fallback: 取不到即回落继承(见上注)
182
+ borderRadius: 'var(--dsw-radius-md, 8px)',
183
+ fontSize: 'inherit', // 侧栏根是 14px, 不再自带 13px
184
+ };
185
+ if (wide) {
186
+ style.gap = 8;
187
+ style.margin = '0 2px';
188
+ style.padding = '7px 8px';
189
+ style.minHeight = 36;
190
+ style.lineHeight = '22px';
191
+ style.flex = '1 1 auto';
192
+ style.minWidth = 0;
193
+ } else {
194
+ style.width = 36;
195
+ style.height = 36;
196
+ style.margin = 0;
197
+ style.padding = 0;
198
+ style.flex = 'none';
199
+ style.justifyContent = 'center';
200
+ }
119
201
  return h('button', {
120
- style: {
121
- display: 'flex', alignItems: 'center', gap: 6, width: '100%', boxSizing: 'border-box',
122
- padding: '6px 12px', margin: '2px 0', borderRadius: 8, cursor: 'pointer', border: 'none',
123
- color: 'var(--dsw-alias-text-l1, #e8e8e8)', fontSize: 13, textAlign: 'left',
124
- background: 'transparent',
125
- },
126
- title: 'Touchstone 测试平台(Alt+T 开关)',
202
+ type: 'button',
203
+ className: 'ts-sb-entry' + (isOpen ? ' ts-sb-on' : ''),
204
+ style,
205
+ title: ENTRY_TITLE,
206
+ 'aria-label': ENTRY_TITLE,
207
+ 'aria-expanded': isOpen,
127
208
  onClick: () => setOpen(!isOpen),
128
- }, wide ? (isOpen ? '🧪 关闭 Touchstone' : '🧪 Touchstone') : '🧪');
209
+ },
210
+ h('span', { style: ENTRY_GLYPH_STYLE, 'aria-hidden': 'true' }, '🧪'),
211
+ wide ? h('span', { style: ENTRY_LABEL_STYLE }, isOpen ? '关闭 Touchstone' : 'Touchstone') : null);
129
212
  }
130
213
 
131
214
  // 关闭按钮自动隐藏(2026-10-03): 常显会盖住被嵌 SPA 侧栏底部的用户名, 所以平时完全隐藏,
@@ -337,6 +420,8 @@ function Panel() {
337
420
 
338
421
  // cordis 客户端插件入口: 等 slots 服务就位后注册两个 UI 槽, 再挂快捷键
339
422
  function apply(ctx) {
423
+ // 侧栏入口的交互态样式表(悬停/开合/聚焦环), 与本插件同生命周期
424
+ ctx.effect(() => mountEntryStyle(), 'touchstone: 侧栏入口样式');
340
425
  const slots = ctx.get('slots');
341
426
  if (!slots) return;
342
427
  slots.inject('sidebar.footer.action', () => slots.register(