dsh-click 0.3.27 → 0.3.28
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 +7 -0
- package/README.en.md +441 -0
- package/README.es.md +441 -0
- package/README.hi.md +441 -0
- package/README.md +262 -194
- package/README.pt.md +441 -0
- package/lib/index.js +1 -1
- package/lib/types/version.d.ts +1 -1
- package/native/win32/dsh-click-helper.ps1 +70 -0
- package/package.json +1 -1
- package/README-es.md +0 -377
- package/README-hi.md +0 -377
- package/README-pt.md +0 -377
- package/README-zh.md +0 -377
package/README.pt.md
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/dsh-click-hero-en-dark.webp">
|
|
5
|
+
<img src="docs/assets/dsh-click-hero-en-light.webp" width="100%" alt="dsh-click: os elementos de acessibilidade de uma janela (e12 Edit, e13 Button) são lidos por screen_read e viram um observationId; as ações citam-no em basedOn, atravessam a fronteira de segurança de frescura, aprovação e identidade do processo, executam pelo helper UIA do Windows e ficam nos eventos de auditoria dsh-click/observed e dsh-click/action">
|
|
6
|
+
</picture>
|
|
7
|
+
|
|
8
|
+
# dsh-click
|
|
9
|
+
|
|
10
|
+
**Ver a tela e depois agir: cada clique é autorizado e cada observação e ação fica auditada.**
|
|
11
|
+
|
|
12
|
+
Controle nativo do desktop para o DeepSeek Harness (Windows primeiro): a árvore de acessibilidade e as dicas de píxeis deixam um modelo só de texto «ver», o clique e a entrada com escopo de janela deixam-no «agir», e a aprovação, a frescura e a identidade do processo ficam pelo meio.
|
|
13
|
+
|
|
14
|
+
[Instalar](#instalação-em-três-passos) · [Configuração](#configuração) · [FAQ](#faq) · [简体中文](README.md) · [English](README.en.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
|
|
15
|
+
|
|
16
|
+
[](LICENSE)
|
|
17
|
+
[](#compatibilidade)
|
|
18
|
+
[](https://www.npmjs.com/package/dsh-click)
|
|
19
|
+
[](https://github.com/PerryLink/dsh-click/actions/workflows/ci.yml)
|
|
20
|
+
[](#compatibilidade)
|
|
21
|
+
|
|
22
|
+
[](https://github.com/PerryLink/dsh-click/stargazers)
|
|
23
|
+
[](https://www.npmjs.com/package/dsh-click)
|
|
24
|
+
[](https://dshfind.com/plugins/PerryLink/dsh-click?ref=badge)
|
|
25
|
+
[](https://securityscorecards.dev/viewer/?uri=github.com/PerryLink/dsh-click)
|
|
26
|
+
[](https://dsh.market/)
|
|
27
|
+
[](https://gitee.com/perrylink/dsh-click)
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
dsh plugin --profile <name> add dsh-click
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<sub>Plugin da comunidade, sem afiliação com a DeepSeek. Repositório canônico: <https://github.com/PerryLink/dsh-click> (o Gitee é um espelho).</sub>
|
|
36
|
+
|
|
37
|
+
## O que é
|
|
38
|
+
|
|
39
|
+
O `dsh-click` dá ao modelo um ciclo completo de observar → agir: `screen_read` lê a árvore de acessibilidade de uma janela (ids de elemento, tipos, nomes, retângulos, padrões suportados) mais dicas de posição e cor, ou `screen_shot` captura uma imagem; depois `click` / `type` / `scroll` / `key` agem nessa mesma janela por id de elemento ou coordenadas. Toda ação mutante precisa citar uma observação fresca (`basedOn`); se a tela mudou ou a observação expirou, a ação é recusada com um motivo legível para o modelo; além disso passa por `ctx.approval` por padrão, e a identidade do processo alvo é verificada antes e depois. Não rouba o foco de primeiro plano por padrão (`focusFallback: never`), e cada observação e ação vira um evento de auditoria `dsh-click/observed` / `dsh-click/action` já sanitizado.
|
|
40
|
+
|
|
41
|
+
<picture>
|
|
42
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/dsh-click-flow-v5-dark.svg">
|
|
43
|
+
<img src="docs/assets/dsh-click-flow-v5-light.svg" width="100%" alt="Estrutura de dois lados do dsh-click: o plano de observação só de leitura à esquerda produz um observationId; a SAFETY BOUNDARY central verifica basedOn, frescura, aprovação, despacho ao helper e identidade do processo, devolvendo recusas a screen_read; o plano de ações mutantes à direita atua pelo helper; os dois eventos de auditoria saneados ficam na barra inferior">
|
|
44
|
+
</picture>
|
|
45
|
+
|
|
46
|
+
## Instalação em três passos
|
|
47
|
+
|
|
48
|
+
1. **Instale** (escolha um canal):
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
# canal git (último main; equivalente a git+https://github.com/PerryLink/dsh-click.git)
|
|
52
|
+
dsh plugin --profile web add github:PerryLink/dsh-click
|
|
53
|
+
# canal npm (versões publicadas)
|
|
54
|
+
dsh plugin --profile web add dsh-click
|
|
55
|
+
# canal tarball: pnpm pack neste repo e depois
|
|
56
|
+
dsh plugin --profile web add ./dsh-click-<version>.tgz
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
O script `prepare` do canal git compila apenas com dependências de produção.
|
|
60
|
+
|
|
61
|
+
2. **Configuração mínima** (os padrões já funcionam; mexa em `autoApproveWindows` só para isentar janelas específicas):
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
- insert:
|
|
65
|
+
- id: dsh-click
|
|
66
|
+
name: dsh-click
|
|
67
|
+
config:
|
|
68
|
+
requireApproval: true
|
|
69
|
+
autoApproveWindows: ['^Notepad']
|
|
70
|
+
focusFallback: never
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
3. **Verifique que montou** (após reiniciar):
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
dsh --profile web --dump-config | grep -A3 'id: dsh-click'
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Depois peça ao agente para olhar uma janela e agir: o pedido de aprovação aparece para cada ação mutante:
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
> Abra o Bloco de Notas, digite "hello" e leia de volta o que está na tela.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Desinstalar**: `dsh plugin --profile web remove dsh-click` (ou remova a linha do patch de perfil).
|
|
86
|
+
|
|
87
|
+
> Se o pnpm reportar `ERR_PNPM_IGNORED_BUILDS` para este pacote (a validação inofensiva do binário de plataforma do esbuild), adicione `allowBuilds: { esbuild: true }` ao seu `pnpm-workspace.yaml`; a CLI do `dsh` imprime o trecho exato.
|
|
88
|
+
|
|
89
|
+
<details>
|
|
90
|
+
<summary>Instalar a partir do mercado do DSH Desktop</summary>
|
|
91
|
+
|
|
92
|
+
Todo plugin PerryLink está listado no mercado integrado do DSH Desktop: **Market → Sources → Add source → colar** `https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json` **→ selecionar**. A instalação ainda exige a verificação de identidade npm do mercado e a sua confirmação.
|
|
93
|
+
|
|
94
|
+
</details>
|
|
95
|
+
|
|
96
|
+
## Capacidades principais
|
|
97
|
+
|
|
98
|
+
O `dsh-click` separa o desktop nativo numa face de observação e noutra de ação, ambas auditáveis:
|
|
99
|
+
|
|
100
|
+
- **`screen_shot`** — captura uma janela (ou a tela principal) e a reduz para `maxScreenshotSide`. Com um modelo que aceita imagens o resultado leva a imagem; modelos só de texto recebem uma descrição textual e continuam funcionando.
|
|
101
|
+
- **`screen_read`** — a observação estruturada: a árvore de acessibilidade (ids de elemento, tipos, nomes, retângulos, padrões suportados) mais dicas de posição de píxeis com cores; texto puro, sem precisar de modelo de imagem.
|
|
102
|
+
- **`screen_find`** — para aplicações sem árvore de acessibilidade, encontra texto clicável ou um alvo visual descrito via OCR opcional (`ocr.*`, tesseract sondado ao montar) ou grounding visual, devolvendo coordenadas de tela mais um `observationId`; é só leitura e nunca pede aprovação.
|
|
103
|
+
- **`click` / `type` / `scroll` / `key`** — ações com escopo de janela endereçadas por id de elemento ou coordenadas. A entrega prefere invocação UIA e recorre a mensagens de janela postadas, e por padrão nunca rouba o foco de primeiro plano; `type` usa o caminho rápido `ValuePattern` do UIA e, se falhar, injeta teclas reais via `SendInput` (seguro para CJK); `key` reporta com honestidade quando uma app ignora a entrada postada.
|
|
104
|
+
- **`app_list` / `app_launch`** — enumera aplicações em execução e as suas janelas visíveis; lança uma por nome ou caminho do executável.
|
|
105
|
+
|
|
106
|
+
Toda ação mutante cruza a mesma fronteira de segurança:
|
|
107
|
+
|
|
108
|
+
1. **Frescura** — a ação precisa citar uma observação `basedOn`; a janela é recapturada imediatamente antes de agir e a ação é recusada se o hash de píxeis (`staleCheckPixels`) ou a árvore (`staleCheckTree`) mudou, ou se a observação passou de `maxObservationAgeMs`.
|
|
109
|
+
2. **Aprovação** — `ctx.approval` controla cada ação por padrão; os regex de título/executável de `autoApproveWindows` podem isentar janelas específicas (continuam a passar por frescura, identidade de processo e auditoria).
|
|
110
|
+
3. **Identidade do processo** — o pid e o caminho do executável proprietário são verificados antes **e** depois de agir; uma troca a meio da ação falha em voz alta (`PROCESS_CHANGED`).
|
|
111
|
+
4. **Auditoria** — observações e ações ficam no registro de sessão como eventos `dsh-click/observed` / `dsh-click/action` (sanitizados, só registro).
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
modelo harness
|
|
115
|
+
│ screen_read ──▶ observationId (+ elementos, píxeis) ← texto estruturado
|
|
116
|
+
│ click {basedOn, target} ──▶ checagem de frescura ──▶ aprovação ──▶ helper (UIA)
|
|
117
|
+
│ hash de píxeis mudou? ── recusa + re-observa
|
|
118
|
+
│ pid/exe mudou após agir? ── PROCESS_CHANGED
|
|
119
|
+
│ ◀── JSON canônico + eventos de auditoria (dsh-click/action)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Superfície de ferramentas
|
|
123
|
+
|
|
124
|
+
| Ferramenta | Só leitura | Precisa de aprovação | Notas |
|
|
125
|
+
|---|---|---|---|
|
|
126
|
+
| `screen_shot` | ✅ | — | Devolve um `observationId` que ações posteriores citam em `basedOn`; anexa imagem quando o modelo aceita imagens |
|
|
127
|
+
| `screen_read` | ✅ | — | Árvore de acessibilidade + dicas de píxeis; os ids de elemento são o endereço das ações |
|
|
128
|
+
| `screen_find` | ✅ | — | OCR/grounding visual quando não há árvore UIA; devolve alvos por coordenadas + um `observationId` |
|
|
129
|
+
| `click` | | ✅ | Exatamente um de `elementId` ou `(x, y)`; prefere UIA invoke, com mensagens postadas como fallback |
|
|
130
|
+
| `type` | | ✅ | Só elementos com padrão de valor; faz backup e restaura o texto do controle se falhar |
|
|
131
|
+
| `scroll` | | ✅ | Elemento (padrão scroll) ou janela (roda postada) |
|
|
132
|
+
| `key` | | ✅ | Combinações de teclas postadas (`"Ctrl+S"`); apps que ignoram a entrada postada são recusadas em voz alta |
|
|
133
|
+
| `app_list` | ✅ | — | Aplicações em execução e as suas janelas visíveis |
|
|
134
|
+
| `app_launch` | | ✅ | Por nome ou caminho do executável, com argumentos opcionais |
|
|
135
|
+
|
|
136
|
+
### Exemplos
|
|
137
|
+
|
|
138
|
+
Estes são os pontos de entrada reais do plugin; instale uma vez e chame um.
|
|
139
|
+
|
|
140
|
+
**Exemplo detalhado** — comando `app_list`, entrada:
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Saída:
|
|
147
|
+
|
|
148
|
+
```text
|
|
149
|
+
1 running application(s) with windows:
|
|
150
|
+
- Demo (pid 4242, C:\Apps\demo.exe)
|
|
151
|
+
- [windowId 1122867] "Demo App" at (10, 20) 800x600
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
*Observed from `plugins/dsh-click/tests/tools.spec.ts:159-185; renderer at src/tools.ts:933-942`*
|
|
155
|
+
|
|
156
|
+
**Ramo de falha** — entrada:
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
{}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Saída:
|
|
163
|
+
|
|
164
|
+
```text
|
|
165
|
+
Error: dsh-click backend unavailable on linux: Linux backend is reserved but not implemented yet (Windows-first); only Windows can act today
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
*Observed from `plugins/dsh-click/src/platform/selection.ts:61-62,81; plugins/dsh-click/src/tools.ts:133-136; plugins/dsh-click/tests/tools.spec.ts:226-245`*
|
|
169
|
+
|
|
170
|
+
**Exemplos breves**: `screen_read` · `app_list`
|
|
171
|
+
|
|
172
|
+
## Configuração
|
|
173
|
+
|
|
174
|
+
Todas as opções são campos Schemastery `Config` (alteráveis via cordis.yml). Uma sobrescrita direcionada por id substitui a linha inteira: repita todas as chaves de que precisar. O `cordis.patch.yml` documenta cada chave inline.
|
|
175
|
+
|
|
176
|
+
Chaves mais usadas:
|
|
177
|
+
|
|
178
|
+
| Chave | Padrão | Significado |
|
|
179
|
+
|---|---|---|
|
|
180
|
+
| `requireApproval` | `true` | Toda ação mutante passa por aprovação; observadores nunca perguntam |
|
|
181
|
+
| `autoApproveWindows` | `[]` | Regex de título/executável que dispensam a pergunta de aprovação (continuam com frescura, identidade de processo e auditoria) |
|
|
182
|
+
| `focusFallback` | `never` | Se uma ação pode trazer a janela alvo para o primeiro plano como último recurso (`never` / `allow`) |
|
|
183
|
+
| `imageMode` | `auto` | Renderização de `screen_shot`: `auto` (imagem quando o modelo aceita imagens, texto caso contrário) ou `text` |
|
|
184
|
+
| `staleCheckPixels` | `true` | Compara um hash de píxeis fresco antes de cada ação e recusa se mudou |
|
|
185
|
+
| `staleCheckTree` | `target` | Frescura da árvore de acessibilidade: `target` verifica o elemento endereçado (padrão), `strict` recusa qualquer nó alterado, `off` ignora o hash da árvore (identidade/idade/píxeis continuam valendo) |
|
|
186
|
+
| `maxObservationAgeMs` | `30000` | Idade máxima em ms de uma observação que uma ação pode citar (1000..600000) |
|
|
187
|
+
| `auditSessionEvents` | `true` | Se anexa os eventos de auditoria `dsh-click/observed` / `dsh-click/action`; `false` interrompe por completo os appends de auditoria |
|
|
188
|
+
|
|
189
|
+
<details>
|
|
190
|
+
<summary>Tabela completa de configuração (17 linhas)</summary>
|
|
191
|
+
|
|
192
|
+
| Chave | Padrão | Significado |
|
|
193
|
+
|---|---|---|
|
|
194
|
+
| `requireApproval` | `true` | Toda ação mutante passa por aprovação; observadores nunca perguntam |
|
|
195
|
+
| `autoApproveWindows` | `[]` | Regex de título/executável que dispensam a pergunta de aprovação (continuam com frescura, identidade de processo e auditoria) |
|
|
196
|
+
| `auditSessionEvents` | `true` | Anexa os eventos de sessão `dsh-click/observed` / `dsh-click/action`. O portão adaptativo já dispensa o append em hosts sem envelope (rc.6–rc.8, 0.1.1-rc.2 e 0.1.2-rc.1, que falha fechado para tipos desconhecidos na leitura); `false` interrompe por completo os appends de auditoria. `0.1.2-rc.1` (adaptado em 2026-09-02): o envelope de sessão mantém o campo ignorable apenas para compatibilidade de leitura de logs armazenados — o `Session.append` ainda não consegue estampá-lo, então o comportamento do portão não muda |
|
|
197
|
+
| `focusFallback` | `never` | Se uma ação pode trazer a janela alvo para o primeiro plano como último recurso (`never` / `allow`) |
|
|
198
|
+
| `imageMode` | `auto` | Renderização de `screen_shot`: `auto` (imagem quando o modelo aceita imagens, texto caso contrário) ou `text` |
|
|
199
|
+
| `helperTimeoutMs` | `30000` | Timeout por chamada ao helper em ms (1..300000) |
|
|
200
|
+
| `maxHelperOutputBytes` | `25165824` | Limite de uma resposta do helper em bytes (1024..67108864) |
|
|
201
|
+
| `maxScreenshotSide` | `2560` | Lado mais longo de uma captura em píxeis (320..7680); capturas maiores são reduzidas |
|
|
202
|
+
| `staleCheckPixels` | `true` | Compara um hash de píxeis fresco antes de cada ação e recusa se mudou |
|
|
203
|
+
| `staleCheckTree` | `target` | Frescura da árvore de acessibilidade: `target` verifica o elemento endereçado (padrão), `strict` recusa qualquer nó alterado, `off` ignora o hash da árvore inteira em janelas com relógio/cursor em movimento (identidade/idade/píxeis continuam valendo) |
|
|
204
|
+
| `maxObservationAgeMs` | `30000` | Idade máxima em ms de uma observação que uma ação pode citar (1000..600000) |
|
|
205
|
+
| `maxCachedObservations` | `8` | Limite LRU de observações em cache (1..64) |
|
|
206
|
+
| `maxElements` | `500` | Limite de elementos de acessibilidade por `screen_read` (1..2000) |
|
|
207
|
+
| `maxTreeDepth` | `32` | Profundidade máxima da travessia da árvore de acessibilidade (1..64) |
|
|
208
|
+
| `maxTextLength` | `200` | Comprimento de truncamento das strings visíveis ao modelo já sanitizadas (16..10000) |
|
|
209
|
+
| `rollbackEnabled` | `true` | Faz backup e restaura o texto do controle quando `type` falha |
|
|
210
|
+
| `ocr.enabled` / `command` / `language` | `true` / `tesseract` / `eng` | OCR opcional para o caminho `screen_find` (sondado ao montar; degrada para indisponível sem tesseract) |
|
|
211
|
+
|
|
212
|
+
</details>
|
|
213
|
+
|
|
214
|
+
Exemplo de sobrescrita no seu patch de perfil:
|
|
215
|
+
|
|
216
|
+
```yaml
|
|
217
|
+
- insert:
|
|
218
|
+
- id: dsh-click
|
|
219
|
+
name: dsh-click
|
|
220
|
+
config:
|
|
221
|
+
requireApproval: true
|
|
222
|
+
autoApproveWindows: ['^Notepad']
|
|
223
|
+
focusFallback: never
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## FAQ
|
|
227
|
+
|
|
228
|
+
<details>
|
|
229
|
+
<summary>Onde ficam as capturas e as observações? O conteúdo da tela pode parar no disco?</summary>
|
|
230
|
+
|
|
231
|
+
A imagem de `screen_shot` vai para o attachment store do harness (endereçada por conteúdo, sob a política de anexos do host) e é entregue ao modelo apenas por esse resultado de ferramenta. As observações ficam em memória (LRU limitada, `maxCachedObservations`, perdidas ao reiniciar); fora disso o plugin não escreve nada no disco, não faz requisições de rede e não guarda credenciais. O único conteúdo que chega ao registro de sessão são os eventos de auditoria `dsh-click/*`, e títulos de janela, caminhos e texto livre são sanitizados e truncados antes de serem escritos ou exibidos.
|
|
232
|
+
|
|
233
|
+
</details>
|
|
234
|
+
|
|
235
|
+
<details>
|
|
236
|
+
<summary>O que acontece no macOS / Linux? Quebra silenciosa?</summary>
|
|
237
|
+
|
|
238
|
+
Nada é silencioso. Ambos os backends estão reservados mas não implementados, então cada chamada falha fechada com um motivo legível para o modelo (`dsh-click backend unavailable on linux: ...`), e o perfil continua iniciando em qualquer plataforma. No Windows, um serviço `subprocess` ausente ou um helper indisponível recusam a chamada em voz alta em vez de fingir sucesso.
|
|
239
|
+
|
|
240
|
+
</details>
|
|
241
|
+
|
|
242
|
+
<details>
|
|
243
|
+
<summary>Ele briga com outros plugins por comandos, serviços ou slots?</summary>
|
|
244
|
+
|
|
245
|
+
Não fornece nenhuma chave de serviço e consome apenas dois seams opcionais (`dsh-click/backend`, `dsh-click/grounding`, para testes/embeddings); não registra slots de cliente, nem rotas `webServer`, nem listeners waterfall; cada evento de auditoria vive no namespace `dsh-click/*`. Cada registro de ferramenta fica dentro de `ctx.effect`, então parar ou recarregar a quente remove exatamente as ferramentas que ele registrou.
|
|
246
|
+
|
|
247
|
+
</details>
|
|
248
|
+
|
|
249
|
+
<details>
|
|
250
|
+
<summary>Qual é o custo de desempenho? Cada ação recaptura a tela?</summary>
|
|
251
|
+
|
|
252
|
+
As observações são produzidas sob demanda: `screen_read` só percorre a árvore de acessibilidade (texto puro), enquanto `screen_shot` codifica um PNG. Cada ação mutante recaptura uma vez a janela alvo para a comparação de frescura (hash de píxeis mais árvore por padrão), e isso faz parte da fronteira de segurança. As chamadas ao helper são limitadas por `helperTimeoutMs` / `maxHelperOutputBytes`, e o cache de observações guarda 8 entradas por padrão.
|
|
253
|
+
|
|
254
|
+
</details>
|
|
255
|
+
|
|
256
|
+
## Limites de segurança
|
|
257
|
+
|
|
258
|
+
- **Observar antes de agir, sempre.** As ações precisam citar uma observação fresca; uma tela alterada (hash de píxeis) ou uma observação expirada são recusadas com um motivo legível para o modelo que exige re-observar.
|
|
259
|
+
- **Aprovação é o padrão.** `requireApproval: true` a menos que isente janelas específicas; cada ação — permitida ou não — fica auditada.
|
|
260
|
+
- **Sem roubo de primeiro plano.** O helper nunca traz uma janela alvo para o primeiro plano (`focusFallback: 'never'` por padrão); a entrada é entregue por UIA ou mensagens postadas para não perturbar janelas em segundo plano. `focusFallback: 'allow'` é a única exceção sancionada.
|
|
261
|
+
- **A identidade do processo é re-verificada** imediatamente antes e depois de cada ação; uma troca de processo a meio da ação falha o resultado (`PROCESS_CHANGED`).
|
|
262
|
+
- **Saída sanitizada.** Caracteres de controle são removidos, tabulações são colapsadas e valores com forma de credencial (chaves, tokens, JWTs, cabeçalhos bearer) são redigidos antes de chegarem ao modelo ou ao log.
|
|
263
|
+
- **Falha fechada.** Plataformas não suportadas, um serviço de subprocesso ausente ou um helper indisponível recusam cada chamada em voz alta; os perfis continuam iniciando em qualquer lugar.
|
|
264
|
+
|
|
265
|
+
## Permissões e dados
|
|
266
|
+
|
|
267
|
+
- **Permissões**: as ações mutantes cruzam o seam oficial `ctx.approval`; o plugin nunca o reimplementa nem o contorna. `autoApproveWindows` apenas *dispensa a pergunta para janelas específicas*; não consegue desativar as checagens de frescura nem de identidade de processo. O manifest `dshWorkshop` declara `fs:read`, `subprocess:spawn`, `session:append`, `network:none`, `native-code:none`.
|
|
268
|
+
- **Dados**: o plugin não grava nada no disco além das capturas que o attachment store mantém (endereçadas por conteúdo, sob a política de anexos do harness). As observações ficam em cache na memória (LRU limitada). Sem requisições de rede nem armazenamento de credenciais.
|
|
269
|
+
- **Registro de sessão**: `dsh-click/observed` e `dsh-click/action` são eventos de auditoria só-registro que carregam fatos sanitizados de janela/processo; títulos, caminhos e texto livre são redigidos e truncados antes de serem escritos ou exibidos.
|
|
270
|
+
|
|
271
|
+
## Limitações conhecidas
|
|
272
|
+
|
|
273
|
+
- **Windows primeiro.** Os backends de macOS e Linux estão reservados; nessas plataformas cada chamada falha fechada com um motivo claro.
|
|
274
|
+
- **Fidelidade de só texto.** `screen_read` depende de a aplicação expor UIAutomation; apps sem árvore acessível dão apenas dicas de píxeis, mais o caminho OCR/grounding do `screen_find`. Os cliques por coordenadas continuam disponíveis.
|
|
275
|
+
- **Apps de entrada postada.** Algumas aplicações ignoram mensagens de janela postadas (jogos, algumas superfícies Electron); `key` reporta isso com honestidade em vez de fingir sucesso. Desde 0.3.24 o fallback `SendInput` do `type` cobre entrada de teclado real e texto CJK, mas continua limitado pelo modelo de entrada da app alvo.
|
|
276
|
+
- **Auditoria de sessão em builds sem envelope.** Os eventos de auditoria passam por um portão adaptativo: hosts que conhecem o vocabulário anexam diretamente, hosts com envelope `ignorable` anexam com o marcador, e hosts sem envelope — `0.1.0-rc.6`–`0.1.0-rc.8`, `0.1.1-rc.2` e `0.1.2-rc.1` (que não consegue estampar o marcador ignorable — o campo do envelope é mantido apenas para compatibilidade de leitura de logs armazenados — e falha fechado para tipos desconhecidos na leitura) — não recebem append de auditoria; os resultados das ferramentas continuam sendo o rastro de auditoria reconstruível. Defina `auditSessionEvents: false` para interromper por completo os appends de auditoria.
|
|
277
|
+
|
|
278
|
+
## Interoperabilidade com outros plugins DSH
|
|
279
|
+
|
|
280
|
+
O `dsh-click` expõe apenas uma superfície de ferramentas e não entra nos seams de outros plugins:
|
|
281
|
+
|
|
282
|
+
- **Apenas dois serviços duros.** `inject = ['tools', 'subprocess']`; não fornece nenhuma chave de serviço, então não pode colidir numa.
|
|
283
|
+
- **Sem recursos de cliente nem HTTP.** Não registra slots de cliente, nem rotas `webServer`, nem listeners waterfall `agent/pre-step` / `tools/post-execute`, e não muta globais.
|
|
284
|
+
- **Auditoria com namespace.** Escreve apenas `dsh-click/observed` e `dsh-click/action`; quando um host não conhece o vocabulário, o portão adaptativo os dispensa e os resultados das ferramentas continuam sendo o rastro reconstruível.
|
|
285
|
+
- **Seams opcionais que degradam.** `dsh-click/backend` e `dsh-click/grounding` existem só para testes/embeddings; implantações reais caem na seleção de plataforma e não exigem nenhum outro plugin.
|
|
286
|
+
- **Registros são efeitos.** Cada `ctx.tools.register` fica envolvido em `ctx.effect`, então parar ou recarregar a quente remove exatamente as ferramentas que ele registrou.
|
|
287
|
+
|
|
288
|
+
## Compatibilidade
|
|
289
|
+
|
|
290
|
+
| Superfície | Status |
|
|
291
|
+
|---|---|
|
|
292
|
+
| Harness | DeepSeek Harness `dsh-v0.2.1-alpha.1` (tag do GitHub, verificado em 2026-09-25). Verificado em 2026-09-11 contra o checkout master `dsh-v0.1.7-alpha.1` (cadeia completa de portões + smoke de instalação de perfil). `engines.dsh`: `>=0.2.1-0 <0.3.0 \|\| >=0.2.2-0 <0.3.0` |
|
|
293
|
+
| Node | `^22.19.0 \|\| >=24.9.0` |
|
|
294
|
+
| Plataformas | **Windows primeiro** (UIAutomation + entrada Win32, via um helper PowerShell incluído); os backends de macOS/Linux estão reservados e falham fechados com um motivo claro |
|
|
295
|
+
| Modelo | Modelos só de texto totalmente suportados (`screen_read` devolve texto estruturado); modelos de visão recebem além disso imagens do `screen_shot` |
|
|
296
|
+
|
|
297
|
+
## Ecossistema e qualidade
|
|
298
|
+
|
|
299
|
+
- [Espelho Gitee](https://gitee.com/perrylink/dsh-click) (espelho de sincronização; o GitHub é o canônico)
|
|
300
|
+
- [Página do plugin no dshfind](https://dshfind.com/plugins/PerryLink/dsh-click) (instalações e ranking)
|
|
301
|
+
- [Relatório OpenSSF Scorecard](https://securityscorecards.dev/viewer/?uri=github.com/PerryLink/dsh-click) (alimentado por [.github/workflows/scorecard.yml](.github/workflows/scorecard.yml))
|
|
302
|
+
- [Relatório de verificação dsh-plugin-doctor](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章) (K10–K13 todos `pass`)
|
|
303
|
+
- [DSH Market](https://dsh.market/) (listado)
|
|
304
|
+
- **Canal 1024 store**: `npm i -g dsh1024` uma vez, depois `dsh1024 plugin --profile web add dsh-click` (conta para o ranking de instalações do [deepseek1024.com](https://deepseek1024.com))
|
|
305
|
+
- [Base de conhecimento do ecossistema](https://perrylink.github.io/dsh-plugin-guide/) — dados medidos, não marketing: guia de desenvolvimento de plugins · dados de seleção · critérios de manutenção
|
|
306
|
+
|
|
307
|
+
## Desenvolvimento
|
|
308
|
+
|
|
309
|
+
```sh
|
|
310
|
+
pnpm install # node ^22.19 || >=24
|
|
311
|
+
pnpm run typecheck # tsc: src + tests contra o checkout local do harness
|
|
312
|
+
pnpm run typecheck:ci # tsc contra os tipos publicados do host (sem paths)
|
|
313
|
+
pnpm test # vitest: 79 testes, 13 arquivos (o smoke do helper roda no Windows)
|
|
314
|
+
pnpm run build # bundle tsdown + declarações tsc (lib/)
|
|
315
|
+
pnpm run verify:self-contained # as specs de dependências resolvem pelo registry
|
|
316
|
+
pnpm run verify:artifacts # face ESM construída + helper nativo presente
|
|
317
|
+
pnpm run check:readmes # consistência dos README em cinco idiomas
|
|
318
|
+
pnpm pack # o tarball publicado
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
As imagens do README são geradas programaticamente por [`scripts/gen-readme-assets.py`](scripts/gen-readme-assets.py) (Python + Pillow) e podem ser reexecutadas com segurança: `python scripts/gen-readme-assets.py`.
|
|
322
|
+
|
|
323
|
+
Topics: `dsh`, `dsh-plugin`, `deepseek-harness`, `deepseek`, `cordis`, `computer-use`, `windows-automation`, `uiautomation`, `desktop-control`, `screen-reader`
|
|
324
|
+
|
|
325
|
+
## Família e agradecimentos
|
|
326
|
+
|
|
327
|
+
Este projeto faz parte da família de plugins do DeepSeek Harness da [PerryLink](https://github.com/PerryLink) (todos Apache-2.0). Se for útil, **uma estrela ajuda a próxima pessoa a encontrá-lo** — nada fica bloqueado atrás dela.
|
|
328
|
+
|
|
329
|
+
- [Checklist de smoke do helper do Windows](docs/windows-smoke.md) — verificação real de entrada/foco para 0.3.24+.
|
|
330
|
+
- [@LIU12312-Source](https://github.com/LIU12312-Source) — fallback real de `SendInput`/foco em primeiro plano para o helper do Windows (PR #21).
|
|
331
|
+
- [@Mchsd](https://github.com/Mchsd) — adicionou a opção `auditSessionEvents` para hosts cujo leitor de sessão recusa os eventos de auditoria do `dsh-click` (#2).
|
|
332
|
+
- [@PerryLink](https://github.com/PerryLink) — criador e mantenedor: superfície de ferramentas, fronteira de segurança das ações, helper nativo do Windows, sanitizadores e a documentação em cinco idiomas.
|
|
333
|
+
|
|
334
|
+
<details>
|
|
335
|
+
<summary>Expandir todos os plugins</summary>
|
|
336
|
+
|
|
337
|
+
| Plugin | Status |
|
|
338
|
+
|---|---|
|
|
339
|
+
| **[dsh-aqua-input-check](https://github.com/PerryLink/dsh-aqua-input-check)** | |
|
|
340
|
+
| **[dsh-archive-check](https://github.com/PerryLink/dsh-archive-check)** | |
|
|
341
|
+
| **[dsh-auto-review](https://github.com/PerryLink/dsh-auto-review)** | |
|
|
342
|
+
| **[dsh-autotier](https://github.com/PerryLink/dsh-autotier)** | 🧊 CONGELADO — ver o README do repo |
|
|
343
|
+
| **[dsh-bid-ca-precheck](https://github.com/PerryLink/dsh-bid-ca-precheck)** | |
|
|
344
|
+
| **[dsh-bid-qual-check](https://github.com/PerryLink/dsh-bid-qual-check)** | |
|
|
345
|
+
| **[dsh-cert-mcp](https://github.com/PerryLink/dsh-cert-mcp)** | 🧊 CONGELADO — ver o README do repo |
|
|
346
|
+
| **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | |
|
|
347
|
+
| **[dsh-click](https://github.com/PerryLink/dsh-click)** | |
|
|
348
|
+
| **[dsh-composer-history](https://github.com/PerryLink/dsh-composer-history)** | |
|
|
349
|
+
| **[dsh-contract-stance](https://github.com/PerryLink/dsh-contract-stance)** | |
|
|
350
|
+
| **[dsh-customs-doc-check](https://github.com/PerryLink/dsh-customs-doc-check)** | |
|
|
351
|
+
| **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | 🧊 CONGELADO — ver o README do repo |
|
|
352
|
+
| **[dsh-demurrage-ledger](https://github.com/PerryLink/dsh-demurrage-ledger)** | |
|
|
353
|
+
| **[dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck)** | |
|
|
354
|
+
| **[dsh-drill-script-check](https://github.com/PerryLink/dsh-drill-script-check)** | |
|
|
355
|
+
| **[dsh-eia-guide-check](https://github.com/PerryLink/dsh-eia-guide-check)** | |
|
|
356
|
+
| **[dsh-emergency-plan](https://github.com/PerryLink/dsh-emergency-plan)** | |
|
|
357
|
+
| **[dsh-essay-rubric-check](https://github.com/PerryLink/dsh-essay-rubric-check)** | |
|
|
358
|
+
| **[dsh-evidence-check](https://github.com/PerryLink/dsh-evidence-check)** | |
|
|
359
|
+
| **[dsh-export-ctl-check](https://github.com/PerryLink/dsh-export-ctl-check)** | |
|
|
360
|
+
| **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | |
|
|
361
|
+
| **[dsh-fmea-table-check](https://github.com/PerryLink/dsh-fmea-table-check)** | |
|
|
362
|
+
| **[dsh-forecast-penalty](https://github.com/PerryLink/dsh-forecast-penalty)** | |
|
|
363
|
+
| **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | |
|
|
364
|
+
| **[dsh-github](https://github.com/PerryLink/dsh-github)** | |
|
|
365
|
+
| **[dsh-gongwen-flow-check](https://github.com/PerryLink/dsh-gongwen-flow-check)** | |
|
|
366
|
+
| **[dsh-gongwen-word-check](https://github.com/PerryLink/dsh-gongwen-word-check)** | |
|
|
367
|
+
| **[dsh-guard-plan-qc](https://github.com/PerryLink/dsh-guard-plan-qc)** | |
|
|
368
|
+
| **[dsh-hazchem-check](https://github.com/PerryLink/dsh-hazchem-check)** | |
|
|
369
|
+
| **[dsh-hazplan-check](https://github.com/PerryLink/dsh-hazplan-check)** | |
|
|
370
|
+
| **[dsh-hidden-risk-map](https://github.com/PerryLink/dsh-hidden-risk-map)** | |
|
|
371
|
+
| **[dsh-hs-classify](https://github.com/PerryLink/dsh-hs-classify)** | |
|
|
372
|
+
| **[dsh-icd-rule-check](https://github.com/PerryLink/dsh-icd-rule-check)** | |
|
|
373
|
+
| **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | |
|
|
374
|
+
| **[dsh-lawcite-adapter](https://github.com/PerryLink/dsh-lawcite-adapter)** | |
|
|
375
|
+
| **[dsh-laya](https://github.com/PerryLink/dsh-laya)** | |
|
|
376
|
+
| **[dsh-lc-doc-check](https://github.com/PerryLink/dsh-lc-doc-check)** | |
|
|
377
|
+
| **[dsh-learning-gap-check](https://github.com/PerryLink/dsh-learning-gap-check)** | |
|
|
378
|
+
| **[dsh-library](https://github.com/PerryLink/dsh-library)** | |
|
|
379
|
+
| **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | |
|
|
380
|
+
| **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | |
|
|
381
|
+
| **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | |
|
|
382
|
+
| **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | |
|
|
383
|
+
| **[dsh-medrec-qc](https://github.com/PerryLink/dsh-medrec-qc)** | |
|
|
384
|
+
| **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | 🧊 CONGELADO — ver o README do repo |
|
|
385
|
+
| **[dsh-nsfc-form-check](https://github.com/PerryLink/dsh-nsfc-form-check)** | |
|
|
386
|
+
| **[dsh-nurse-record-check](https://github.com/PerryLink/dsh-nurse-record-check)** | |
|
|
387
|
+
| **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | |
|
|
388
|
+
| **[dsh-origin-rvc-check](https://github.com/PerryLink/dsh-origin-rvc-check)** | |
|
|
389
|
+
| **[dsh-ota-review-check](https://github.com/PerryLink/dsh-ota-review-check)** | |
|
|
390
|
+
| **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | |
|
|
391
|
+
| **[dsh-paper-doc-adapter](https://github.com/PerryLink/dsh-paper-doc-adapter)** | |
|
|
392
|
+
| **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | |
|
|
393
|
+
| **[dsh-permit-report-check](https://github.com/PerryLink/dsh-permit-report-check)** | |
|
|
394
|
+
| **[dsh-pipeline-check](https://github.com/PerryLink/dsh-pipeline-check)** | |
|
|
395
|
+
| **[dsh-pleading-draft](https://github.com/PerryLink/dsh-pleading-draft)** | |
|
|
396
|
+
| **[dsh-plugin-doctor](https://github.com/PerryLink/dsh-plugin-doctor)** | 🚫 APOSENTADO (repo arquivado) |
|
|
397
|
+
| **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | |
|
|
398
|
+
| **[dsh-plugin-kit](https://github.com/PerryLink/dsh-plugin-kit)** | 🚫 APOSENTADO (repo arquivado) |
|
|
399
|
+
| **[dsh-plugin-upgrade](https://github.com/PerryLink/dsh-plugin-upgrade)** | 🚫 APOSENTADO (repo arquivado) |
|
|
400
|
+
| **[dsh-policy-brief-draft](https://github.com/PerryLink/dsh-policy-brief-draft)** | |
|
|
401
|
+
| **[dsh-power-loss-split](https://github.com/PerryLink/dsh-power-loss-split)** | |
|
|
402
|
+
| **[dsh-power-ticket-check](https://github.com/PerryLink/dsh-power-ticket-check)** | |
|
|
403
|
+
| **[dsh-ppap-check](https://github.com/PerryLink/dsh-ppap-check)** | |
|
|
404
|
+
| **[dsh-protest-deadline](https://github.com/PerryLink/dsh-protest-deadline)** | |
|
|
405
|
+
| **[dsh-railway-window](https://github.com/PerryLink/dsh-railway-window)** | |
|
|
406
|
+
| **[dsh-repair-order-qc](https://github.com/PerryLink/dsh-repair-order-qc)** | |
|
|
407
|
+
| **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | |
|
|
408
|
+
| **[dsh-review-reply-check](https://github.com/PerryLink/dsh-review-reply-check)** | |
|
|
409
|
+
| **[dsh-rulefile-check](https://github.com/PerryLink/dsh-rulefile-check)** | |
|
|
410
|
+
| **[dsh-safety-brief-check](https://github.com/PerryLink/dsh-safety-brief-check)** | |
|
|
411
|
+
| **[dsh-score](https://github.com/PerryLink/dsh-score)** | 🧊 CONGELADO — ver o README do repo |
|
|
412
|
+
| **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | |
|
|
413
|
+
| **[dsh-site-log-check](https://github.com/PerryLink/dsh-site-log-check)** | |
|
|
414
|
+
| **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | |
|
|
415
|
+
| **[dsh-soe-decision-check](https://github.com/PerryLink/dsh-soe-decision-check)** | |
|
|
416
|
+
| **[dsh-soilwater-check](https://github.com/PerryLink/dsh-soilwater-check)** | |
|
|
417
|
+
| **[dsh-sop-sync-check](https://github.com/PerryLink/dsh-sop-sync-check)** | |
|
|
418
|
+
| **[dsh-spc-gbt-adapter](https://github.com/PerryLink/dsh-spc-gbt-adapter)** | |
|
|
419
|
+
| **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | |
|
|
420
|
+
| **[dsh-tender-extract](https://github.com/PerryLink/dsh-tender-extract)** | |
|
|
421
|
+
| **[dsh-tender-matrix](https://github.com/PerryLink/dsh-tender-matrix)** | |
|
|
422
|
+
| **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | |
|
|
423
|
+
| **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | 🚫 APOSENTADO (repo arquivado) |
|
|
424
|
+
| **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | |
|
|
425
|
+
| **[dsh-warranty-calc](https://github.com/PerryLink/dsh-warranty-calc)** | |
|
|
426
|
+
| **[dsh-budget](https://github.com/PerryLink/dsh-budget)** | 🧊 CONGELADO — ver o README do repo |
|
|
427
|
+
| **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | 🧊 CONGELADO — ver o README do repo |
|
|
428
|
+
| **[dsh-defend](https://github.com/PerryLink/dsh-defend)** | 🧊 CONGELADO — ver o README do repo |
|
|
429
|
+
| **[dsh-draw](https://github.com/PerryLink/dsh-draw)** | 🧊 CONGELADO — ver o README do repo |
|
|
430
|
+
| **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | 🧊 CONGELADO — ver o README do repo |
|
|
431
|
+
| **[dsh-background-agents](https://github.com/PerryLink/dsh-background-agents)** | 🚫 APOSENTADO (repo arquivado) |
|
|
432
|
+
| **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | 🚫 APOSENTADO (repo arquivado) |
|
|
433
|
+
| **[dsh-team-rooms](https://github.com/PerryLink/dsh-team-rooms)** | 🚫 APOSENTADO (repo arquivado) |
|
|
434
|
+
|
|
435
|
+
</details>
|
|
436
|
+
|
|
437
|
+
## Licença
|
|
438
|
+
|
|
439
|
+
[LICENSE](LICENSE) (Apache License 2.0) © 2026 dsh-click contributors
|
|
440
|
+
|
|
441
|
+
<p align="center"><sub>Apache-2.0 · Plugin da comunidade, sem afiliação com a DeepSeek.</sub></p>
|
package/lib/index.js
CHANGED
|
@@ -623,7 +623,7 @@ var ObservationStore = class {
|
|
|
623
623
|
* @module dsh-click/version
|
|
624
624
|
*/
|
|
625
625
|
/** Plugin version advertised in the helper-protocol handshake. */
|
|
626
|
-
const VERSION = "0.3.
|
|
626
|
+
const VERSION = "0.3.28";
|
|
627
627
|
/** The helper protocol revision; bump only on incompatible wire changes. */
|
|
628
628
|
const HELPER_PROTOCOL_VERSION = 1;
|
|
629
629
|
//#endregion
|
package/lib/types/version.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @module dsh-click/version
|
|
8
8
|
*/
|
|
9
9
|
/** Plugin version advertised in the helper-protocol handshake. */
|
|
10
|
-
export declare const VERSION = "0.3.
|
|
10
|
+
export declare const VERSION = "0.3.28";
|
|
11
11
|
/** The helper protocol revision; bump only on incompatible wire changes. */
|
|
12
12
|
export declare const HELPER_PROTOCOL_VERSION = 1;
|
|
13
13
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -150,6 +150,27 @@ public static class DshClickWin32 {
|
|
|
150
150
|
[DllImport("user32.dll")]
|
|
151
151
|
public static extern int GetSystemMetrics(int index);
|
|
152
152
|
|
|
153
|
+
// DPI awareness. The helper is hosted by powershell.exe, whose manifest
|
|
154
|
+
// declares no DPI awareness, so GetWindowRect/GetSystemMetrics/GetClientRect
|
|
155
|
+
// return logical pixels while UIA BoundingRectangle and the screen DC are
|
|
156
|
+
// physical. On a 200% display that is a clean 2x mismatch (and a 1:1 BitBlt
|
|
157
|
+
// of a logical-sized rect is a crop of the physical surface, not a scaled
|
|
158
|
+
// image). Per-Monitor V2 is set before any window or metric API runs.
|
|
159
|
+
[DllImport("user32.dll", SetLastError = true)]
|
|
160
|
+
public static extern bool SetProcessDpiAwarenessContext(IntPtr context);
|
|
161
|
+
|
|
162
|
+
[DllImport("user32.dll")]
|
|
163
|
+
public static extern IntPtr GetThreadDpiAwarenessContext();
|
|
164
|
+
|
|
165
|
+
[DllImport("user32.dll")]
|
|
166
|
+
public static extern int GetAwarenessFromDpiAwarenessContext(IntPtr context);
|
|
167
|
+
|
|
168
|
+
[DllImport("shcore.dll")]
|
|
169
|
+
public static extern int SetProcessDpiAwareness(int awareness);
|
|
170
|
+
|
|
171
|
+
[DllImport("user32.dll")]
|
|
172
|
+
public static extern bool SetProcessDPIAware();
|
|
173
|
+
|
|
153
174
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
154
175
|
public static extern IntPtr OpenProcess(uint access, bool inherit, uint processId);
|
|
155
176
|
|
|
@@ -187,6 +208,33 @@ public static class DshClickWin32 {
|
|
|
187
208
|
}
|
|
188
209
|
'@ | Out-Null
|
|
189
210
|
|
|
211
|
+
# ---------------------------------------------------------------------------
|
|
212
|
+
# DPI awareness (must run before any HWND/metric API).
|
|
213
|
+
# ---------------------------------------------------------------------------
|
|
214
|
+
# DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = -4. Each helper process serves
|
|
215
|
+
# exactly one request, so setting it once here is enough. Fall back to the
|
|
216
|
+
# 8.1+ shcore call and then to the Vista-era system-aware call; if every call
|
|
217
|
+
# fails, keep the old behaviour instead of breaking the request.
|
|
218
|
+
$script:DpiAwareness = 0
|
|
219
|
+
try {
|
|
220
|
+
if ([DshClickWin32]::SetProcessDpiAwarenessContext([IntPtr](-4))) { $script:DpiAwareness = 2 }
|
|
221
|
+
} catch { }
|
|
222
|
+
if ($script:DpiAwareness -eq 0) {
|
|
223
|
+
try {
|
|
224
|
+
if ([DshClickWin32]::SetProcessDpiAwareness(2) -eq 0) { $script:DpiAwareness = 2 }
|
|
225
|
+
} catch { }
|
|
226
|
+
}
|
|
227
|
+
if ($script:DpiAwareness -eq 0) {
|
|
228
|
+
try {
|
|
229
|
+
if ([DshClickWin32]::SetProcessDPIAware()) { $script:DpiAwareness = 1 }
|
|
230
|
+
} catch { }
|
|
231
|
+
}
|
|
232
|
+
if ($script:DpiAwareness -eq 0) {
|
|
233
|
+
try {
|
|
234
|
+
$script:DpiAwareness = [DshClickWin32]::GetAwarenessFromDpiAwarenessContext([DshClickWin32]::GetThreadDpiAwarenessContext())
|
|
235
|
+
} catch { }
|
|
236
|
+
}
|
|
237
|
+
|
|
190
238
|
# ---------------------------------------------------------------------------
|
|
191
239
|
# Response plumbing.
|
|
192
240
|
# ---------------------------------------------------------------------------
|
|
@@ -965,6 +1013,27 @@ function Invoke-OpLaunch($opArgs) {
|
|
|
965
1013
|
return @{ processId = [int]$process.Id; executablePath = $path }
|
|
966
1014
|
}
|
|
967
1015
|
|
|
1016
|
+
# ---------------------------------------------------------------------------
|
|
1017
|
+
# Metrics: DPU/DPI diagnostics without touching a window.
|
|
1018
|
+
# ---------------------------------------------------------------------------
|
|
1019
|
+
function Invoke-OpMetrics {
|
|
1020
|
+
# 0 = unaware (legacy bug), 1 = system-aware, 2 = per-monitor.
|
|
1021
|
+
return @{
|
|
1022
|
+
awareness = [int]$script:DpiAwareness
|
|
1023
|
+
screen = @{
|
|
1024
|
+
width = [int][DshClickWin32]::GetSystemMetrics(0) # SM_CXSCREEN
|
|
1025
|
+
height = [int][DshClickWin32]::GetSystemMetrics(1) # SM_CYSCREEN
|
|
1026
|
+
}
|
|
1027
|
+
virtualScreen = @{
|
|
1028
|
+
x = [int][DshClickWin32]::GetSystemMetrics(76) # SM_XVIRTUALSCREEN
|
|
1029
|
+
y = [int][DshClickWin32]::GetSystemMetrics(77) # SM_YVIRTUALSCREEN
|
|
1030
|
+
width = [int][DshClickWin32]::GetSystemMetrics(78) # SM_CXVIRTUALSCREEN
|
|
1031
|
+
height = [int][DshClickWin32]::GetSystemMetrics(79) # SM_CYVIRTUALSCREEN
|
|
1032
|
+
}
|
|
1033
|
+
monitors = [int][DshClickWin32]::GetSystemMetrics(80) # SM_CMONITORS
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
968
1037
|
# ---------------------------------------------------------------------------
|
|
969
1038
|
# Entry point.
|
|
970
1039
|
# ---------------------------------------------------------------------------
|
|
@@ -978,6 +1047,7 @@ try {
|
|
|
978
1047
|
$script:focusFallbackDetail = $null
|
|
979
1048
|
switch ([string]$request.op) {
|
|
980
1049
|
'windows' { $result = Invoke-OpWindows }
|
|
1050
|
+
'metrics' { $result = Invoke-OpMetrics }
|
|
981
1051
|
'apps' { $result = Invoke-OpApps }
|
|
982
1052
|
'snapshot' { $result = Invoke-OpSnapshot $opArgs }
|
|
983
1053
|
'shot' { $result = Invoke-OpShot $opArgs }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-click",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.28",
|
|
4
4
|
"description": "Cross-platform native desktop control tools for DeepSeek Harness (Windows first): screen_shot, screen_read (accessibility tree + pixel description for text-only models), click/type/scroll/key, and app_list/app_launch — every mutating action gated by approval, never stealing foreground focus, with stale-observation rejection and process-identity checks",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|