dsh-as-aistudio 0.4.0 → 0.4.1
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/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
## 中文
|
|
6
6
|
|
|
7
|
+
**0.4.1** —— 编辑过的消息,复制按钮被宿主重画之后仍然复制改写后的文本。
|
|
8
|
+
|
|
9
|
+
- **组件跟进**:`dsh-edit-turn` **0.5.7**(另三个不变:`dsh-rerun-turn` 0.2.6、`dsh-delete-turn` 0.1.15、`dsh-markdown-bubble` 0.1.5)。
|
|
10
|
+
|
|
11
|
+
- **复制拿到的是改写前的原文**:编辑一条消息后,界面上显示的是改写后的文本,但点那一排的复制按钮,粘出来的是原文。原因是这次按下原本由**挂在宿主那个按钮节点上**的捕获期监听回答,而动作条是宿主 React 画的——任何一次重渲染都可能换掉那个按钮节点,监听就跟着旧节点一起消失,按下于是落到宿主自己的处理上(它复制"这一行被画出来时的那条消息")。现在改由**文档级捕获期监听按行**回答:与按钮是不是同一个节点无关,捕获期在 React 根节点之前,宿主自己的处理看不到这次按下。本包已把修好的 `dsh-edit-turn` 0.5.7 重新 vendor 进来并重建了浏览器 bundle。
|
|
12
|
+
|
|
7
13
|
**0.4.0** —— 少要一个平台包;四个组件跟进到最新。
|
|
8
14
|
|
|
9
15
|
- **不再要求 `dsh-tools`**:本包内置的宿主半部以前要 `@deepseek-ai/dsh-tools`,唯一原因是 `dsh-edit-turn` 向模型暴露了一个工具(`edit_turn_targets`)。那个工具已经删掉——编辑是靠 UI 面板做的,模型不需要知道这件事——于是整族插件都不再声明模型可见的工具,宿主半部的解析只需要 `dsh-session`。少一个平台包,就少一处跟宿主版本绑定的地方。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-as-aistudio",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Google-AI-Studio-style turn controls for DeepSeek Harness, in one install: edit a prompt and re-run it, re-run a reply in place, delete a turn from the model context, and render sent prompts as Markdown. Self-contained: the plugin list shows this one row, and the four components are vendored inside it - installing the studio installs nothing else.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
package/src/client.js
CHANGED
|
@@ -43,7 +43,7 @@ window.__ModuleLoader__.load({
|
|
|
43
43
|
const RERUN_PREFIX = '/dsh-rerun-turn'
|
|
44
44
|
|
|
45
45
|
/** Keep in sync with package.json and lib/index.js. */
|
|
46
|
-
const PLUGIN_VERSION = '0.5.
|
|
46
|
+
const PLUGIN_VERSION = '0.5.7'
|
|
47
47
|
|
|
48
48
|
// --- copy -----------------------------------------------------------------
|
|
49
49
|
|
|
@@ -1935,6 +1935,17 @@ window.__ModuleLoader__.load({
|
|
|
1935
1935
|
const COPY_TIMER = 'dshetCopyTimer'
|
|
1936
1936
|
/** The host draws its own check for a second; this is the same second. */
|
|
1937
1937
|
const COPY_FEEDBACK_MS = 1000
|
|
1938
|
+
/**
|
|
1939
|
+
* Row key -> the text that row's copy button must hand over.
|
|
1940
|
+
*
|
|
1941
|
+
* The host's copy button copies the message the row was drawn for, so on a row
|
|
1942
|
+
* this plugin rewrote it would copy the wording the user just replaced. The
|
|
1943
|
+
* press is answered from a document-level listener keyed by ROW rather than by
|
|
1944
|
+
* button node: the host re-renders its action bar, and a listener planted on
|
|
1945
|
+
* the button it drew goes away with that node (the button it draws next is a
|
|
1946
|
+
* different one).
|
|
1947
|
+
*/
|
|
1948
|
+
const rowCopyText = new Map()
|
|
1938
1949
|
|
|
1939
1950
|
/**
|
|
1940
1951
|
* A button another plugin put in this bar.
|
|
@@ -1999,6 +2010,13 @@ window.__ModuleLoader__.load({
|
|
|
1999
2010
|
* takeover that cannot copy is worse than none.
|
|
2000
2011
|
*/
|
|
2001
2012
|
function takeOverRowCopy(row, text, t) {
|
|
2013
|
+
// Registered before the button lookup on purpose: the handover has to work
|
|
2014
|
+
// even when this pass cannot find the button to mark (the next one may, and
|
|
2015
|
+
// the document-level press answers from this table either way).
|
|
2016
|
+
{
|
|
2017
|
+
const key = row.getAttribute('data-chat-flow-key')
|
|
2018
|
+
if (typeof key === 'string' && key !== '') rowCopyText.set(key, text)
|
|
2019
|
+
}
|
|
2002
2020
|
const button = nativeCopyButton(row, t)
|
|
2003
2021
|
if (button === null) return
|
|
2004
2022
|
const write = primitives !== null && primitives !== undefined && typeof primitives.writeClipboard === 'function'
|
|
@@ -2127,6 +2145,8 @@ window.__ModuleLoader__.load({
|
|
|
2127
2145
|
|
|
2128
2146
|
/** The copy handover of a row, wherever the last pass left it. */
|
|
2129
2147
|
function releaseRowCopy(row) {
|
|
2148
|
+
const key = row.getAttribute('data-chat-flow-key')
|
|
2149
|
+
if (typeof key === 'string' && key !== '') rowCopyText.delete(key)
|
|
2130
2150
|
const button = nativeCopyButton(row)
|
|
2131
2151
|
if (button !== null) releaseCopyButton(button)
|
|
2132
2152
|
}
|
|
@@ -4775,6 +4795,45 @@ window.__ModuleLoader__.load({
|
|
|
4775
4795
|
// left". Blur cannot be that signal: a host re-render replaces the node
|
|
4776
4796
|
// (blur without a related target) and a save temporarily disables it -
|
|
4777
4797
|
// both used to drop the caret for good.
|
|
4798
|
+
// The press that matters: the host's own copy button on a row this plugin
|
|
4799
|
+
// rewrote. Capture phase, so the host's handler (which listens at the React
|
|
4800
|
+
// root, below the document) never sees the press; by row key, so a button
|
|
4801
|
+
// the host re-rendered is still answered.
|
|
4802
|
+
react.useEffect(() => {
|
|
4803
|
+
if (typeof document.addEventListener !== 'function' || typeof document.removeEventListener !== 'function') {
|
|
4804
|
+
return undefined
|
|
4805
|
+
}
|
|
4806
|
+
const onCopyPress = (event) => {
|
|
4807
|
+
const target = event.target
|
|
4808
|
+
if (target === null || target === undefined || typeof target.closest !== 'function') return
|
|
4809
|
+
const button = target.closest('button')
|
|
4810
|
+
if (button === null) return
|
|
4811
|
+
// Our own buttons sit in the same bar: theirs is not this press.
|
|
4812
|
+
if (pluginOwned(button)) return
|
|
4813
|
+
const row = button.closest('[data-chat-flow-key]')
|
|
4814
|
+
if (row === null) return
|
|
4815
|
+
const key = row.getAttribute('data-chat-flow-key')
|
|
4816
|
+
if (typeof key !== 'string' || key === '') return
|
|
4817
|
+
const text = rowCopyText.get(key)
|
|
4818
|
+
if (typeof text !== 'string') return
|
|
4819
|
+
const write = primitives !== null && primitives !== undefined && typeof primitives.writeClipboard === 'function'
|
|
4820
|
+
? primitives.writeClipboard
|
|
4821
|
+
: null
|
|
4822
|
+
if (write === null) return
|
|
4823
|
+
if (typeof event.preventDefault === 'function') event.preventDefault()
|
|
4824
|
+
if (typeof event.stopPropagation === 'function') event.stopPropagation()
|
|
4825
|
+
if (typeof event.stopImmediatePropagation === 'function') event.stopImmediatePropagation()
|
|
4826
|
+
Promise.resolve(write(text)).then(
|
|
4827
|
+
(ok) => {
|
|
4828
|
+
if (ok === true) flashRowCopy(button, typeof t === 'function' ? t('action.copied') : null)
|
|
4829
|
+
},
|
|
4830
|
+
() => {},
|
|
4831
|
+
)
|
|
4832
|
+
}
|
|
4833
|
+
document.addEventListener('click', onCopyPress, true)
|
|
4834
|
+
return () => document.removeEventListener('click', onCopyPress, true)
|
|
4835
|
+
}, [t])
|
|
4836
|
+
|
|
4778
4837
|
react.useEffect(() => {
|
|
4779
4838
|
if (typeof document.addEventListener !== 'function' || typeof document.removeEventListener !== 'function') {
|
|
4780
4839
|
return undefined
|
|
@@ -8979,7 +9038,7 @@ window.__ModuleLoader__.load({
|
|
|
8979
9038
|
const NS = 'dsh-as-aistudio'
|
|
8980
9039
|
|
|
8981
9040
|
/** Keep in sync with package.json and src/components.js. */
|
|
8982
|
-
const PLUGIN_VERSION = '0.4.
|
|
9041
|
+
const PLUGIN_VERSION = '0.4.1'
|
|
8983
9042
|
|
|
8984
9043
|
/** Presence marker the live verifier reads. */
|
|
8985
9044
|
const DEBUG_KEY = '__DSH_AS_AISTUDIO__'
|
package/src/components.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
export const STUDIO_ID = 'dsh-as-aistudio'
|
|
27
27
|
|
|
28
28
|
/** Keep in sync with package.json and src/client.js. */
|
|
29
|
-
export const STUDIO_VERSION = '0.4.
|
|
29
|
+
export const STUDIO_VERSION = '0.4.1'
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* The AI Studio action strip this studio composes, in the order the user meets
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// dsh-edit-turn host half (dsh-edit-turn.js), VENDORED by tools/vendor.mjs - DO NOT EDIT.
|
|
2
2
|
//
|
|
3
|
-
// Source: ../dsh-edit-turn/lib/index.js (v0.5.
|
|
3
|
+
// Source: ../dsh-edit-turn/lib/index.js (v0.5.7, sha256 32dc3ed4d66bb063)
|
|
4
4
|
// Regenerate with `npm run vendor`; test/sync.test.js fails when this is stale.
|
|
5
5
|
//
|
|
6
6
|
// src/shell.js imports the copy named after the component, which is why the
|
|
@@ -85,7 +85,7 @@ export const PLUGIN_ID = 'dsh-edit-turn'
|
|
|
85
85
|
export const name = PLUGIN_ID
|
|
86
86
|
|
|
87
87
|
/** Keep in sync with package.json and lib/client.js. */
|
|
88
|
-
export const PLUGIN_VERSION = '0.5.
|
|
88
|
+
export const PLUGIN_VERSION = '0.5.7'
|
|
89
89
|
|
|
90
90
|
// A ring of the last few requests, answering "did the browser half even ask, and
|
|
91
91
|
// what did it get?" without needing its console. Read-only diagnostics: the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// dsh-edit-turn host half (dsh-edit-turn.patch.js), VENDORED by tools/vendor.mjs - DO NOT EDIT.
|
|
2
2
|
//
|
|
3
|
-
// Source: ../dsh-edit-turn/lib/patch.js (v0.5.
|
|
3
|
+
// Source: ../dsh-edit-turn/lib/patch.js (v0.5.7, sha256 5e1e8cce1d168f6c)
|
|
4
4
|
// Regenerate with `npm run vendor`; test/sync.test.js fails when this is stale.
|
|
5
5
|
//
|
|
6
6
|
// src/shell.js imports the copy named after the component, which is why the
|
package/src/vendor/versions.json
CHANGED