dsh-locator 0.7.5 → 0.7.7
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 +17 -0
- package/README-es.md +328 -106
- package/README-hi.md +328 -104
- package/README-pt.md +329 -103
- package/README.en.md +247 -123
- package/README.md +223 -84
- package/lib/content.d.ts +14 -0
- package/lib/content.d.ts.map +1 -1
- package/lib/content.js +62 -1
- package/lib/content.js.map +1 -1
- package/package.json +1 -1
- package/src/content.ts +57 -1
package/README-pt.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# 🔎 dsh-locator
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Busque por nome quando lembra do nome e por conteúdo quando lembra da frase; depois abra o arquivo ou volte para a conversa.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Busca de arquivos em todo o disco para o [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) com **índice próprio**: sem instalar o Everything, sem `es.exe`, com as mesmas ferramentas e o mesmo painel no Windows, macOS e Linux.
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/dsh-locator)
|
|
10
10
|
[](https://www.npmjs.com/package/dsh-locator)
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
[](https://github.com/PerryLink/dsh-locator/releases)
|
|
13
13
|
[](LICENSE)
|
|
14
14
|
[](https://github.com/topics/dsh-plugin)
|
|
15
|
-
[](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin)
|
|
16
|
+
[](#versão-e-compatibilidade)
|
|
16
17
|
[](https://gitee.com/perrylink/dsh-locator)
|
|
17
18
|
[](https://gitcode.com/PerryLink/dsh-locator)
|
|
18
19
|
|
|
@@ -24,15 +25,62 @@ dsh plugin --profile web add dsh-locator
|
|
|
24
25
|
|
|
25
26
|
</div>
|
|
26
27
|
|
|
27
|
-
> **Repositório oficial:** [GitHub `PerryLink/dsh-locator`](https://github.com/PerryLink/dsh-locator)
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
> **Repositório oficial:** [GitHub `PerryLink/dsh-locator`](https://github.com/PerryLink/dsh-locator); Gitee e GitCode são espelhos sincronizados automaticamente, e o GitHub é a fonte da verdade. Faz parte da [família de plugins do DSH](https://github.com/PerryLink) (Apache-2.0) e está listado no [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin). Uma ⭐ ajuda a próxima pessoa a encontrá-lo; nada fica bloqueado atrás dela.
|
|
29
|
+
|
|
30
|
+
## Índice
|
|
31
|
+
|
|
32
|
+
- [De relance](#de-relance)
|
|
33
|
+
- [Como difere de Everything / Spotlight / grep](#como-difere-de-everything--spotlight--grep)
|
|
34
|
+
- [Instalação](#instalação)
|
|
35
|
+
- [Primeira execução](#primeira-execução)
|
|
36
|
+
- [Duas buscas](#duas-buscas)
|
|
37
|
+
- [Painel web](#painel-web)
|
|
38
|
+
- [Ferramentas](#ferramentas)
|
|
39
|
+
- [Linguagem de consulta](#linguagem-de-consulta)
|
|
40
|
+
- [Configuração](#configuração)
|
|
41
|
+
- [Desempenho e recursos](#desempenho-e-recursos)
|
|
42
|
+
- [Suporte de plataformas](#suporte-de-plataformas)
|
|
43
|
+
- [Solução de problemas](#solução-de-problemas)
|
|
44
|
+
- [Compilar a partir do código-fonte](#compilar-a-partir-do-código-fonte)
|
|
45
|
+
- [Design](#design)
|
|
46
|
+
- [Limitações](#limitações)
|
|
47
|
+
- [Memória](#memória)
|
|
48
|
+
- [Segurança e privacidade](#segurança-e-privacidade)
|
|
49
|
+
- [Versão e compatibilidade](#versão-e-compatibilidade)
|
|
50
|
+
- [Roteiro](#roteiro)
|
|
51
|
+
- [Licença](#licença)
|
|
52
|
+
|
|
53
|
+
## De relance
|
|
54
|
+
|
|
55
|
+
Buscar arquivos tem duas formas:
|
|
56
|
+
|
|
57
|
+
- **Você lembra do nome mas não do local.** `glob`/`grep` percorrem o workspace a cada chamada: ótimo quando você conhece o diretório, doloroso quando lembra só de metade do nome.
|
|
58
|
+
- **Você lembra de uma frase, de uma decisão ou de um trecho, não do arquivo nem da conversa.** Um índice de nomes não ajuda, e os logs de sessão do DSH também são dados de primeira classe.
|
|
59
|
+
|
|
60
|
+
O `dsh-locator` junta os dois em um único plugin:
|
|
61
|
+
|
|
62
|
+
| Recurso | Como usar |
|
|
63
|
+
|---|---|
|
|
64
|
+
| Busca por nome / caminho | `locator_search`, ou o modo padrão do painel |
|
|
65
|
+
| Busca no corpo dos arquivos | `locator_find`, ou o modo **Buscar conteúdo** do painel |
|
|
66
|
+
| Busca em sessões do DSH | As mesmas ferramentas; os resultados trazem `sessionId` / `messageId` e o painel pode voltar à conversa |
|
|
67
|
+
| Abrir / revelar | As ferramentas devolvem caminhos; o painel revela com duplo clique, `Ctrl+O` abre e `Ctrl+Enter` insere `@"caminho"` no compositor |
|
|
68
|
+
| Consumo externo | `locator_export` grava um espelho SQLite somente leitura |
|
|
69
|
+
|
|
70
|
+
O índice é local: sem chamadas de rede, sem telemetria, sem uploads; o plugin nunca modifica, move ou apaga os arquivos indexados.
|
|
30
71
|
|
|
31
|
-
|
|
72
|
+
## Como difere de Everything / Spotlight / grep
|
|
32
73
|
|
|
33
|
-
|
|
74
|
+
| | dsh-locator | Everything | Spotlight | `glob` / `grep` |
|
|
75
|
+
|---|---|---|---|---|
|
|
76
|
+
| Plataformas | Windows / macOS / Linux / WSL | Windows | macOS | Multiplataforma |
|
|
77
|
+
| Índice | Persistente, próprio | Persistente (USN do NTFS) | Índice do sistema (metadados/conteúdo) | Percorre a cada chamada |
|
|
78
|
+
| Busca no conteúdo | Arquivos de texto + mensagens de sessão do DSH | Só nomes por padrão | Sim, varia por sistema | Sim, sem índice |
|
|
79
|
+
| Salto para sessão | Resultados trazem `sessionId` / `messageId` | Não | Não | Não |
|
|
80
|
+
| Ferramentas para agentes | Seis ferramentas, uma linguagem de consulta | Precisa de CLI/serviço | Precisa de scripts próprios | Nativas, sem índice persistente |
|
|
81
|
+
| Velocidade no Windows | Perto do Everything (USN opcional) | Mais rápido e leve | Não se aplica | Mais lento que um índice |
|
|
34
82
|
|
|
35
|
-
|
|
83
|
+
Resumindo: a **ideia** do Everything (índice persistente + consultas estruturadas) foi implementada de forma independente e multiplataforma, com as sessões do DSH por cima. Não é um invólucro do Everything.
|
|
36
84
|
|
|
37
85
|
## Instalação
|
|
38
86
|
|
|
@@ -40,150 +88,328 @@ dsh plugin --profile web add dsh-locator
|
|
|
40
88
|
# npm (recomendado)
|
|
41
89
|
dsh plugin --profile web add dsh-locator
|
|
42
90
|
|
|
43
|
-
#
|
|
91
|
+
# fixar uma versão
|
|
92
|
+
dsh plugin --profile web add dsh-locator@0.7.7
|
|
93
|
+
|
|
94
|
+
# branch principal do GitHub
|
|
44
95
|
dsh plugin --profile web add github:PerryLink/dsh-locator
|
|
45
96
|
|
|
46
|
-
#
|
|
97
|
+
# a partir de um checkout
|
|
47
98
|
pnpm install
|
|
48
99
|
pnpm build
|
|
49
|
-
pnpm build:engine
|
|
100
|
+
pnpm build:engine # motor Go da plataforma atual
|
|
50
101
|
dsh plugin --profile web add /caminho/absoluto/dsh-locator
|
|
51
102
|
|
|
52
|
-
# tarball
|
|
103
|
+
# a partir de um tarball (saída do npm pack; troque pela versão real)
|
|
53
104
|
npm pack
|
|
54
|
-
dsh plugin --profile web add /caminho/absoluto/dsh-locator-0.
|
|
105
|
+
dsh plugin --profile web add /caminho/absoluto/dsh-locator-0.7.7.tgz
|
|
55
106
|
```
|
|
56
107
|
|
|
57
|
-
O pacote
|
|
108
|
+
- O pacote inclui motores pré-compilados para `linux-x64`, `linux-arm64`, `win32-x64`, `win32-arm64`, `darwin-x64` e `darwin-arm64`; não é preciso Go local.
|
|
109
|
+
- Se o espelho npm estiver atrasado, adicione `--registry=https://registry.npmjs.org` ao comando.
|
|
110
|
+
- Depois de instalar em um perfil Web **em execução**, **recarregue a página** (`F5`): as ferramentas do host podem montar na hora, mas o painel do navegador é carregado do boot graph ao abrir a página. Perfis headless/TUI só têm as ferramentas.
|
|
111
|
+
- Atualizar: `dsh plugin --profile web add dsh-locator@latest` e depois `F5`. Uma mudança de esquema do conteúdo reconstrói o banco uma vez.
|
|
112
|
+
- Desinstalar: `dsh plugin --profile web remove dsh-locator`; para manter a configuração mas desativar, `enabled: false`.
|
|
113
|
+
|
|
114
|
+
## Primeira execução
|
|
115
|
+
|
|
116
|
+
Na primeira montagem o motor indexa as raízes configuradas (padrão: seu diretório pessoal) e grava o snapshot e o banco de conteúdo no diretório de cache da plataforma:
|
|
117
|
+
|
|
118
|
+
| Plataforma | Diretório de estado padrão |
|
|
119
|
+
|---|---|
|
|
120
|
+
| Windows | `%LOCALAPPDATA%\dsh-locator` |
|
|
121
|
+
| macOS | `~/Library/Application Support/dsh-locator` |
|
|
122
|
+
| Linux | `$XDG_CACHE_HOME/dsh-locator` ou `~/.cache/dsh-locator` |
|
|
123
|
+
|
|
124
|
+
A primeira varredura de um diretório pessoal grande lê o disco; os próximos inícios carregam o snapshot. As requisições são atendidas **durante** essa varredura: a busca devolve o que já foi indexado com `indexing: true`, e o rodapé do painel avisa que o índice ainda está sendo construído.
|
|
125
|
+
|
|
126
|
+
Por padrão, `node_modules`, `.git`, `.hg`, `.svn`, `.cache`, `__pycache__`, `.venv`, `venv` e `.next` são ignorados por nome; `excludes` altera a lista.
|
|
127
|
+
|
|
128
|
+
Experimente:
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
Encontre os PDFs que alterei na semana passada
|
|
132
|
+
Onde "contentRefreshMs" foi discutido?
|
|
133
|
+
Em qual conversa este desenho foi decidido?
|
|
134
|
+
```
|
|
58
135
|
|
|
59
|
-
|
|
136
|
+
## Duas buscas
|
|
137
|
+
|
|
138
|
+
### Por nome: `locator_search`
|
|
139
|
+
|
|
140
|
+
Sintaxe no estilo Everything devolvendo caminho, tamanho, data de modificação, extensão e tipo. Ideal para “o nome contém report”, “PDFs alterados esta semana”, “vídeos com mais de 50 MB”.
|
|
141
|
+
|
|
142
|
+
Ordenação, paginação e `limit`/`offset` são feitos no motor do host; consultas comuns sobre 1,51 M de entradas respondem em dezenas de milissegundos.
|
|
143
|
+
|
|
144
|
+
### Por conteúdo: `locator_find`
|
|
145
|
+
|
|
146
|
+
Pesquisa no **corpo** de arquivos de texto e mensagens de sessão do DSH e devolve trechos com a origem:
|
|
147
|
+
|
|
148
|
+
- resultados de arquivo trazem caminho e podem ser abertos ou revelados;
|
|
149
|
+
- resultados de sessão trazem `sessionId` e `messageId`, então o painel abre a conversa e destaca a mensagem;
|
|
150
|
+
- substrings em chinês e inglês funcionam (tokenizador trigram, sem segmentação de palavras).
|
|
151
|
+
|
|
152
|
+
Como o índice de conteúdo se comporta:
|
|
153
|
+
|
|
154
|
+
- **Preguiçoso por padrão.** Nada é construído na inicialização; a primeira busca de conteúdo (`locator_find` ou o modo conteúdo do painel) inicia a construção em segundo plano, e `contentLazy: false` volta à construção no arranque. A primeira consulta informa `building: true` em vez de devolver vazio sem explicação.
|
|
155
|
+
- **Reinício reaproveitando.** Se o banco existe, ele é atualizado de forma incremental; a construção completa (primeiro logs de sessão, depois corpos de arquivo) só acontece se o banco não existe, tem esquema antigo, ficou incompleto por uma construção interrompida ou não abre.
|
|
156
|
+
- **Atualização incremental** a cada `contentRefreshMs` (5 minutos por padrão), relendo só arquivos e sessões cujo mtime mudou; `0` desativa.
|
|
157
|
+
- **Sessões arquivadas e ativas.** Arquivadas são ignoradas a menos que `contentIncludeArchived: true`; um log que ainda está sendo escrito só é indexado após `contentActiveSessionDelayMs` (2 minutos) de quietude, para não descomprimi-lo a cada atualização. Sessões apagadas saem do índice quando os arquivos desaparecem.
|
|
158
|
+
- **Orçamento e truncamento.** Padrões: 1 MB por arquivo de texto, 200.000 arquivos, 1 GB de corpos e as 100 sessões mais recentes. Ao atingir o orçamento, arquivos que chegam depois na ordem de varredura são ignorados; o `locator_find` informa `content budget reached` e o estado HTTP traz `truncated: true`. Aumente `contentMaxTotalBytes` ou reduza `contentExcludes`.
|
|
159
|
+
- **Árvores de dependências não são lidas.** `node_modules`, `.cargo`, `.bun`, `.pnpm`, `site-packages`, `toolchain`, … são ignorados por padrão via `contentExcludes`; caso contrário, código de bibliotecas esgotaria o orçamento antes dos seus documentos. O índice de nomes continua cobrindo esses caminhos.
|
|
160
|
+
|
|
161
|
+
A construção roda dentro do processo anfitrião do DSH, mas leituras de arquivo e descompressão zstd são assíncronas e os dois laços cedem o controle a cada ~8 ms: em um corpus de 28,6 MB o maior bloqueio do laço de eventos caiu de 968 ms para cerca de 20 ms, então carregar e trocar sessões continua fluido. As **consultas** de conteúdo rodam em uma worker thread com conexão somente leitura: palavras comuns levam cerca de 100 ms e termos raros alguns milissegundos, sem bloquear o host.
|
|
60
162
|
|
|
61
163
|
## Painel web
|
|
62
164
|
|
|
63
|
-

|
|
64
166
|
|
|
65
|
-
Pressione `Ctrl+Shift+F` em qualquer lugar da
|
|
167
|
+
Pressione `Ctrl+Shift+F` em qualquer lugar da GUI web, ou clique na lupa no pé da barra lateral.
|
|
66
168
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
169
|
+
- Consulta vazia lista as entradas modificadas mais recentemente; ao digitar, a mesma sintaxe das ferramentas é usada após 110 ms de debounce.
|
|
170
|
+
- Clique no cabeçalho de uma coluna para ordenar por nome, tamanho, data de modificação ou caminho.
|
|
171
|
+
- Alterne **somente arquivos** / **somente diretórios** para filtrar o tipo.
|
|
172
|
+
- Marque **Buscar conteúdo** para trocar nomes por corpos de arquivo e mensagens de sessão; enquanto o índice é construído o rodapé mostra o estado e o painel consulta de novo.
|
|
173
|
+
- `↑`/`↓` selecionam, `Enter` copia o caminho, `Ctrl+O` abre, `Ctrl+Enter` insere `@"caminho"` no compositor e `Esc` fecha.
|
|
174
|
+
- Duplo clique em um arquivo revela no Explorer/Finder/`xdg-open`; duplo clique em uma sessão abre a conversa na mensagem encontrada.
|
|
175
|
+
- O texto do painel segue `navigator.language` (zh/en/es/pt/hi).
|
|
176
|
+
|
|
177
|
+
O painel usa rotas de mesma origem — `/dsh-locator/search`, `/dsh-locator/content`, `/dsh-locator/content/rebuild`, `/dsh-locator/status`, `/dsh-locator/reveal`, `/dsh-locator/open` — então não precisa de outro servidor nem de outra porta. Perfis sem servidor web não o montam.
|
|
72
178
|
|
|
73
179
|
## Ferramentas
|
|
74
180
|
|
|
75
|
-
| Ferramenta |
|
|
181
|
+
| Ferramenta | O que faz |
|
|
182
|
+
|---|---|
|
|
183
|
+
| `locator_search` | Consulta nomes e caminhos com filtros `ext:`, `size:`, `dm:`, `path:`, ordenação e paginação. |
|
|
184
|
+
| `locator_find` | Busca em corpos de arquivo e mensagens de sessão; devolve trechos, `sessionId`/`messageId` e o estado do índice de conteúdo. |
|
|
185
|
+
| `locator_status` | Raízes, contagens do índice de nomes, estado do watcher, diretório de estado e caminho do motor. (O progresso do conteúdo é informado pelo `locator_find` e pelo painel.) |
|
|
186
|
+
| `locator_rebuild` | Substitui o índice de nomes por uma varredura em segundo plano; as buscas usam o índice antigo até o novo ficar pronto. |
|
|
187
|
+
| `locator_reindex` | Atualiza ou reconstrói o índice de conteúdo: incremental por padrão, `full: true` apaga e reconstrói. |
|
|
188
|
+
| `locator_export` | Grava um espelho SQLite somente leitura do índice de nomes (tabela `entries`) para ferramentas SQL externas. |
|
|
189
|
+
|
|
190
|
+
## Linguagem de consulta
|
|
191
|
+
|
|
192
|
+
Palavras soltas são substrings do nome unidas por AND. Filtros no estilo Everything se combinam com elas:
|
|
193
|
+
|
|
194
|
+
| Exemplo | Significado |
|
|
76
195
|
|---|---|
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
196
|
+
| `report` | o nome contém `report` |
|
|
197
|
+
| `report ext:pdf` | …e a extensão é `pdf` |
|
|
198
|
+
| `ext:ts,js` / `ext:!tmp` | incluir ou excluir extensões |
|
|
199
|
+
| `*.sln` / `?ata` | curingas `*` e `?` |
|
|
200
|
+
| `"annual report"` | frase com espaço |
|
|
201
|
+
| `!archive` | negar um termo |
|
|
202
|
+
| `path:src` | o caminho completo contém `src` |
|
|
203
|
+
| `size:>10mb` / `size:1kb..2mb` | comparações de tamanho |
|
|
204
|
+
| `dm:today` / `dm:thisweek` / `dm:2026-01-01` | data de modificação |
|
|
205
|
+
| `folder:` / `file:` | somente diretórios / somente arquivos |
|
|
206
|
+
| `case:1` / `wholeword:1` | sensível a maiúsculas / limites de palavra |
|
|
207
|
+
|
|
208
|
+
O `locator_search` também aceita `sort` (`name`, `path`, `size`, `mtime`, `ext`), `desc`, `offset`, `limit`, `regex`, `caseSensitive` e `wholeWord`.
|
|
209
|
+
|
|
210
|
+
## Configuração
|
|
211
|
+
|
|
212
|
+
Cada campo é um campo de configuração do Schemastery; sobrescreva a entrada `dsh-locator` no patch do perfil, por exemplo:
|
|
213
|
+
|
|
214
|
+
```yaml
|
|
215
|
+
- id: dsh-locator
|
|
216
|
+
name: dsh-locator
|
|
217
|
+
config:
|
|
218
|
+
roots: ['/home/me/Documents', '/home/me/notes']
|
|
219
|
+
contentMaxTotalBytes: 2000000000
|
|
220
|
+
contentExcludes: ['node_modules', '.git', '.cargo', 'site-packages']
|
|
221
|
+
```
|
|
83
222
|
|
|
84
|
-
|
|
223
|
+
| Chave | Padrão | Significado |
|
|
224
|
+
|---|---|---|
|
|
225
|
+
| `enabled` | `true` | Chave geral; `false` não monta ferramentas nem inicia o motor. |
|
|
226
|
+
| `roots` | diretório pessoal | Diretórios a indexar; pode haver vários. |
|
|
227
|
+
| `excludes` | nomes de desenvolvimento/cache | Globs por nome ignorados pelo índice de nomes. |
|
|
228
|
+
| `watch` | `true` | Aplicar notificações do sistema de arquivos. |
|
|
229
|
+
| `refreshIntervalMs` | `1800000` | Cadência de reconstrução quando não há watcher nativo (kqueue ou falha do watcher); `0` desativa. |
|
|
230
|
+
| `scanWorkers` | `0` | Concorrência de leitura de diretórios; `0` usa o número de CPUs. |
|
|
231
|
+
| `windowsUsn` | `false` | Tentar a enumeração USN/MFT do NTFS antes da varredura (Windows, administrador; com fallback automático). |
|
|
232
|
+
| `memoryLimitMB` | `0` | Limite suave do heap Go do motor em MiB; `0` deixa com `GOMEMLIMIT`/`GOGC`. |
|
|
233
|
+
| `contentIndex` | `true` | Construir o índice de corpos e mensagens de sessão; `false` deixa a busca por nome com custo de conteúdo quase zero. |
|
|
234
|
+
| `contentLazy` | `true` | Construir o índice de conteúdo na primeira busca em vez de no arranque. |
|
|
235
|
+
| `contentMaxFileBytes` | `1000000` | Bytes lidos de um arquivo de texto. |
|
|
236
|
+
| `contentMaxTotalBytes` | `1000000000` | Total de bytes de corpos guardados; `0` = sem limite. |
|
|
237
|
+
| `contentMaxFiles` | `200000` | Arquivos de texto indexados por construção; `0` = sem limite. |
|
|
238
|
+
| `contentMaxSessions` | `100` | Logs de sessão mais recentes indexados; `0` = todos. |
|
|
239
|
+
| `contentRefreshMs` | `300000` | Cadência de atualização incremental do conteúdo; `0` desativa. |
|
|
240
|
+
| `contentIncludeArchived` | `false` | Indexar também sessões arquivadas. |
|
|
241
|
+
| `contentActiveSessionDelayMs` | `120000` | Indexar um log de sessão só após esse tempo de quietude. |
|
|
242
|
+
| `contentSessionDirs` | `[]` | Diretórios de sessão extras; vazio = `$DSH_HOME/sessions`. |
|
|
243
|
+
| `contentExcludes` | nomes de dependências/toolchains | Segmentos ou substrings de caminho ignorados pelo índice de conteúdo; o de nomes continua cobrindo. |
|
|
244
|
+
| `stateDir` | `''` | Diretório do snapshot e do banco de conteúdo; vazio = cache da plataforma. Use um diretório por processo do DSH. |
|
|
245
|
+
|
|
246
|
+
`binaryPath`, `maxResults`, `startupTimeoutMs` e `requestTimeoutMs` também existem para motores personalizados, limites de página e prazos; os padrões atendem a maioria dos casos.
|
|
247
|
+
|
|
248
|
+
## Desempenho e recursos
|
|
249
|
+
|
|
250
|
+
Medido em uma máquina de desenvolvimento WSL2 (Linux, cache de página quente) e um diretório pessoal real; sua máquina varia com disco, número de arquivos, cache e GC.
|
|
251
|
+
|
|
252
|
+
**Índice de nomes**
|
|
253
|
+
|
|
254
|
+
| Métrica | Resultado |
|
|
255
|
+
|---|---|
|
|
256
|
+
| Varredura a frio | ~1,51 M de entradas em 11–12 s |
|
|
257
|
+
| Tamanho do snapshot | ~171 MB para 1,51 M de entradas |
|
|
258
|
+
| Consulta a quente (`locator_search`) | 6–25 ms para consultas comuns; varreduras `path:` ~70 ms |
|
|
259
|
+
| Busca durante uma reconstrução | O índice antigo continua servindo até o novo ficar pronto |
|
|
260
|
+
| Memória de pico na varredura | Centenas de MB; o motor é um processo filho e respeita `memoryLimitMB` / `GOMEMLIMIT` |
|
|
85
261
|
|
|
86
|
-
|
|
262
|
+
**Índice de conteúdo** (diretório pessoal real, orçamento de 1 GB)
|
|
87
263
|
|
|
88
|
-
|
|
264
|
+
| Métrica | Resultado (0.7.x, diretório real) |
|
|
265
|
+
|---|---|
|
|
266
|
+
| Cobertura | ~95,8 k arquivos de texto / 95 sessões / 1.050 mensagens |
|
|
267
|
+
| Reconstrução completa | ~3,5 min em segundo plano; host p95 14 ms / máx 115 ms durante ela |
|
|
268
|
+
| Atualização incremental (sem mudanças) | ~12 s (dominado pelo dump de 1,51 M de entradas do motor) |
|
|
269
|
+
| Latência do host ocioso | p50 2 ms / p95 3 ms / máx 6 ms |
|
|
270
|
+
| Tamanho do banco | ~3,1 GB (cerca de 3× o orçamento de corpos) |
|
|
271
|
+
| Consulta de conteúdo | ~100 ms para palavras comuns, poucos ms para raras (worker thread, host não bloqueia) |
|
|
89
272
|
|
|
90
|
-
|
|
273
|
+
**Configurações mais econômicas**
|
|
91
274
|
|
|
92
|
-
|
|
275
|
+
- Só busca por nome: `contentIndex: false` zera o trabalho de conteúdo.
|
|
276
|
+
- Manter conteúdo usando menos disco: reduza `contentMaxTotalBytes` (ex.: 256000000) ou `contentMaxFileBytes`, ou aumente `contentRefreshMs`.
|
|
277
|
+
- Cobrir mais arquivos: aumente `contentMaxTotalBytes` / `contentMaxFiles` e confira se `contentExcludes` não está excluindo árvores de documentos reais.
|
|
278
|
+
- O banco de conteúdo é cache: apagar `stateDir` reconstrói e nunca toca nos arquivos originais.
|
|
93
279
|
|
|
94
|
-
|
|
280
|
+
## Suporte de plataformas
|
|
95
281
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
282
|
+
| Plataforma | Varredura + snapshot | Atualizações ao vivo | Observações |
|
|
283
|
+
|---|---|---|---|
|
|
284
|
+
| Linux | sim | inotify, recursivo | Descritores de vigilância são por diretório; árvores enormes podem atingir `fs.inotify.max_user_watches`. |
|
|
285
|
+
| Windows | sim | `ReadDirectoryChangesW`, recursivo | Não precisa de administrador nem do Everything. Enumeração USN/MFT opcional com privilégios elevados. Mudanças do WSL em `/mnt/<drive>` podem não gerar notificações; reconstrua essas raízes. |
|
|
286
|
+
| macOS | sim | FSEvents nos binários cgo publicados, recursivo e sem limite | kqueue é o fallback com `CGO_ENABLED=0` (até 4.096 diretórios); mudanças de conteúdo dependem da reconstrução periódica. |
|
|
287
|
+
|
|
288
|
+
### Windows e o diário USN
|
|
289
|
+
|
|
290
|
+
O motor inclui um decodificador USN, um caminho rápido opcional e uma sonda. O caminho fica **desativado por padrão** (`windowsUsn: false`) porque o ioctl do volume exige privilégios de administrador; foi validado de ponta a ponta em um runner Windows do GitHub Actions (administrador, volume NTFS real):
|
|
291
|
+
|
|
292
|
+
- 1.345.546 registros MFT lidos, 1.345.539 caminhos resolvidos
|
|
293
|
+
- 164.209 entradas em `C:\Windows` (122.915 arquivos, 41.294 diretórios)
|
|
294
|
+
- `scan --usn --root C:\Windows` indexou 164.216 entradas em 7,8 s; uma consulta respondeu em 9,6 ms
|
|
295
|
+
- o diário de mudanças foi lido (8.233 registros em uma execução) e um diário inativo em `D:` caiu para a varredura com aviso
|
|
296
|
+
|
|
297
|
+
Teste você mesmo:
|
|
298
|
+
|
|
299
|
+
```powershell
|
|
300
|
+
# PowerShell elevado (ou: Start-Process -Verb RunAs <caminho> ...)
|
|
301
|
+
& ".\bin\win32-x64\indexd.exe" usn-probe --volume C: --root "C:\Windows" --limit 5 --journal 5
|
|
107
302
|
```
|
|
108
303
|
|
|
109
|
-
|
|
304
|
+
Ele imprime o id/USNs do diário, enumera a MFT (registros por segundo, arquivos/diretórios sob a raiz, caminhos de exemplo) e decodifica os últimos registros do diário. Sem elevação falha com `Access is denied`; o parser e a reconstrução de caminhos são cobertos por testes unitários em todas as plataformas.
|
|
110
305
|
|
|
111
|
-
|
|
112
|
-
|---|---|
|
|
113
|
-
| `roots` | Diretórios indexados; vazio = diretório pessoal. |
|
|
114
|
-
| `excludes` | Globs por nome (`node_modules`, `.git`, …). |
|
|
115
|
-
| `watch` | Ativa notificações do sistema. |
|
|
116
|
-
| `refreshIntervalMs` | Reconstrução periódica quando não há watcher nativo. |
|
|
117
|
-
| `windowsUsn` | Caminho rápido USN/MFT (Windows, administrador; padrão `false`). |
|
|
118
|
-
| `scanWorkers` | Leitores de diretório em paralelo; 0 = CPU. |
|
|
119
|
-
| `contentIndex` | Constrói o índice de conteúdo de arquivos e sessões (padrão `true`). |
|
|
120
|
-
| `contentLazy` | Constrói o índice de conteúdo na primeira busca de conteúdo em vez de na inicialização; `false` constrói em segundo plano desde o início (padrão `true`). |
|
|
121
|
-
| `contentMaxFileBytes` | Bytes lidos de cada arquivo de texto (padrão `1000000`). |
|
|
122
|
-
| `contentMaxTotalBytes` | Total de bytes de conteúdo mantido; `0` = sem limite (padrão `1000000000`). |
|
|
123
|
-
| `contentMaxFiles` | Máximo de arquivos de texto indexados a cada execução; `0` = sem limite (padrão `200000`). |
|
|
124
|
-
| `contentMaxSessions` | Sessões mais recentes indexadas; `0` = todas (padrão `100`). |
|
|
125
|
-
| `contentRefreshMs` | Ritmo da atualização incremental de conteúdo; `0` desativa (padrão `300000`). |
|
|
126
|
-
| `contentIncludeArchived` | Indexa também sessões arquivadas; padrão `false`. |
|
|
127
|
-
| `contentActiveSessionDelayMs` | Só indexa um log de sessão depois de ficar quieto esse tempo (padrão `120000`). |
|
|
128
|
-
| `contentSessionDirs` | Diretórios adicionais de sessões; vazio = `$DSH_HOME/sessions`. |
|
|
129
|
-
| `contentExcludes` | Trechos de caminho que a busca por conteúdo ignora (dependências e toolchains); o índice de nomes continua igual. |
|
|
130
|
-
| `stateDir` | Diretório do instantâneo; vazio = cache do sistema. |
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
## Plataformas
|
|
134
|
-
|
|
135
|
-
| Plataforma | Varredura | Atualizações |
|
|
136
|
-
|---|---|---|
|
|
137
|
-
| Linux | varredura paralela | inotify recursivo |
|
|
138
|
-
| Windows | varredura ou USN/MFT (admin) | `ReadDirectoryChangesW`; USN retoma após reinício |
|
|
139
|
-
| macOS | varredura | FSEvents nos binários cgo; kqueue como fallback |
|
|
306
|
+
Com `windowsUsn: true` (ou `indexd scan --usn`) o motor enumera a MFT em vez de percorrer diretórios e monta caminhos a partir do mapa de pais FRN. Uma varredura USN bem-sucedida grava `usn-state.json` (id do diário, próximo USN, raízes) e mantém o FRN em cada registro; no próximo `serve --usn` o motor reproduz o diário a partir desse cursor antes de responder, então arquivos criados enquanto estava parado aparecem sem varredura completa. Um diário envolvido, apagado ou inconsistente cai para o watcher portátil. Ele mantém o handle do volume e consulta o diário a cada dois segundos, aplicando criações, exclusões e renomeações via `usn.ApplyChanges` (o mesmo mapa FRN, atualizado no local). Registros USN **não trazem tamanho nem data de modificação**: os resultados são corretos para nomes e caminhos, o `locator_status` marca esse índice com `USN`, e o daemon faz stat da página devolvida para que as linhas mostrem tamanhos e datas reais; filtros `size:`/`dm:` sobre o índice inteiro continuam aproximados até uma passada de metadados. Qualquer falha (sem elevação, volume não suportado, registros demais) cai para a varredura portátil com aviso; nunca desativa a busca.
|
|
140
307
|
|
|
141
|
-
|
|
308
|
+
O Everything lê a Master File Table do NTFS pelo diário USN, e é por isso que seu primeiro índice é quase instantâneo. O `dsh-locator` mantém a varredura portátil como padrão (sem serviço, sem UAC, qualquer sistema de arquivos) e usa USN/MFT como caminho rápido opcional onde o processo tem `GENERIC_READ` (administrador), com reprodução do diário entre reinícios. O caminho portátil continua sendo o fallback.
|
|
142
309
|
|
|
143
|
-
##
|
|
310
|
+
## Solução de problemas
|
|
144
311
|
|
|
145
|
-
|
|
312
|
+
**O painel não aparece depois de instalar.**
|
|
313
|
+
Recarregue a página (`F5`); confirme que instalou no perfil `web` e que o painel carrega do boot graph. Perfis headless/TUI nunca montam painel.
|
|
146
314
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
- `locator_export` de 1,24 M de linhas: 477 MB, 6,4 s.
|
|
315
|
+
**Um arquivo recém-criado não aparece.**
|
|
316
|
+
A notificação pode não ter chegado (comum com gravações do WSL em `/mnt/c`, compartilhamentos de rede e alguns overlays de contêiner). Espere um instante ou rode `locator_rebuild` para essa raiz. O modo USN reproduz o diário ao reiniciar.
|
|
150
317
|
|
|
151
|
-
|
|
318
|
+
**A busca de conteúdo não devolve nada.**
|
|
319
|
+
Veja `building` no resultado do `locator_find`: a primeira busca dispara a construção preguiçosa e os resultados podem ser parciais até terminar (o painel consulta de novo sozinho). Confirme também que a extensão é de texto, o arquivo não passa de `contentMaxFileBytes`, não é excluído por `contentExcludes` e a sessão não está arquivada (arquivadas são ignoradas por padrão).
|
|
320
|
+
|
|
321
|
+
**O banco de conteúdo está enorme / o disco cresce rápido.**
|
|
322
|
+
Veja [Desempenho e recursos](#desempenho-e-recursos): reduza o orçamento ou use `contentIndex: false`. Apagar `stateDir` dispara uma reconstrução.
|
|
152
323
|
|
|
153
|
-
|
|
324
|
+
**Aparece um aviso de `inotify`.**
|
|
325
|
+
Diretórios demais atingem o limite do kernel; o índice continua utilizável e as mudanças dependem de reconstruções periódicas. Aumente `fs.inotify.max_user_watches` ou reduza `roots`.
|
|
154
326
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
* **Consulta**: termos compilados uma vez, divididos em fragmentos e um heap limitado escolhe `offset+limit`.
|
|
158
|
-
* **Persistência**: arquivo temporário + rename atômico; o instantâneo é a fonte de inicialização.
|
|
159
|
-
* **Protocolo**: NDJSON por stdio; sem porta nem superfície de rede.
|
|
327
|
+
**O comportamento mudou após atualizar.**
|
|
328
|
+
Rode `dsh plugin --profile web add dsh-locator@latest` e `F5`. Uma mudança de esquema do conteúdo reconstrói o banco uma vez. Veja o [CHANGELOG](CHANGELOG.md).
|
|
160
329
|
|
|
161
|
-
## Compilar do código
|
|
330
|
+
## Compilar a partir do código-fonte
|
|
162
331
|
|
|
163
|
-
|
|
332
|
+
Requisitos: Node `^22.19 || >=24.9`, pnpm e Go 1.22+ para o motor.
|
|
164
333
|
|
|
165
334
|
```sh
|
|
166
335
|
pnpm install
|
|
167
336
|
pnpm build
|
|
168
|
-
pnpm build:engine:all
|
|
169
|
-
pnpm check
|
|
337
|
+
pnpm build:engine:all # ou build:engine para a plataforma atual
|
|
338
|
+
pnpm check # typecheck + testes + verificação de empacotamento/instalação
|
|
170
339
|
```
|
|
171
340
|
|
|
172
|
-
O motor Go
|
|
341
|
+
O motor é um módulo Go separado em `engine/`; seus testes rodam com `cd engine && go test ./...`. O backend FSEvents do macOS precisa de cgo e é compilado no CI de macOS. Os testes Node rodam em Linux, Windows e macOS no CI.
|
|
342
|
+
|
|
343
|
+
## Design
|
|
344
|
+
|
|
345
|
+

|
|
173
346
|
|
|
174
|
-
|
|
347
|
+
```
|
|
348
|
+
DeepSeek Harness
|
|
349
|
+
└─ dsh-locator (plugin TypeScript)
|
|
350
|
+
├─ locator_search / locator_find / locator_status / locator_rebuild /
|
|
351
|
+
│ locator_reindex / locator_export
|
|
352
|
+
├─ client.js: overlay Ctrl+Shift+F (slot shell.overlay)
|
|
353
|
+
├─ POST /dsh-locator/{search,content,status,reveal,open} (mesma origem)
|
|
354
|
+
├─ armazenamento de conteúdo: SQLite FTS5 (trigram) no processo anfitrião,
|
|
355
|
+
│ consultas em worker thread
|
|
356
|
+
└─ processo filho: indexd serve (Go, NDJSON por stdio)
|
|
357
|
+
├─ scanner: varredura recursiva, exclusões, progresso
|
|
358
|
+
├─ index: arena de nomes + registros fixos + tabela de caminhos aberta
|
|
359
|
+
├─ query: parser, matcher, seleção top-K, ordenação, paginação
|
|
360
|
+
├─ watcher: inotify (Linux) / ReadDirectoryChangesW (Windows)
|
|
361
|
+
└─ snapshot: arquivo único, mmap-friendly, renomeação atômica
|
|
362
|
+
```
|
|
175
363
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
364
|
+
- **Scanner paralelo.** Leitores de diretório drenam uma fila limitada e gravam um lote por diretório (`AddBatch`), então o registro pai existe antes dos filhos entrarem na fila. A fila não bloqueia: se estiver cheia, aquela subárvore é varrida em linha.
|
|
365
|
+
- **Layout de memória.** Registros guardam deslocamento/comprimento do nome em uma arena de bytes e um id de pai; caminhos completos só são reconstruídos para a página de resultados e filtros `path:`. Isso evita um cabeçalho de string por arquivo.
|
|
366
|
+
- **Tabela de caminhos.** Uma tabela de endereçamento aberto com slots `id+1` mantém busca/atualização perto de 12 bytes por entrada em vez dos ~50 de um `map[string]int32`.
|
|
367
|
+
- **Motor de consulta.** Termos e filtros são compilados uma vez, comparados em blocos paralelos e reduzidos com um max-heap limitado: as `offset+limit` linhas são selecionadas sem ordenar milhões de correspondências.
|
|
368
|
+
- **Índice de conteúdo.** SQLite FTS5 no host com tokenizador trigram (substrings UTF-8, CJK); a lista de arquivos vem da própria varredura do motor e logs de sessão são descomprimidos com zstd do Node.
|
|
369
|
+
- **Consistência do conteúdo.** Um lock de construção por processo serializa escritores que compartilham `stateDir`, uma marca de construção completa força reconstrução após uma interrompida, e um handle obsoleto é detectado por dispositivo+inode para que a reconstrução de outro processo não deixe o host lendo um banco desvinculado.
|
|
370
|
+
- **Persistência.** O snapshot é gravado em arquivo temporário e renomeado; um contador de geração permite ao daemon salvar só quando o índice mudou. Lápides são compactadas quando as exclusões passam de um limite.
|
|
371
|
+
- **Protocolo.** Uma requisição/resposta JSON por linha em stdio, com eventos `scan`, `stats`, `warning`, `error` e `rebuilt`. Sem portas, sem superfície de autenticação, sem listeners de rede.
|
|
372
|
+
- **Somente leitura.** O motor abre arquivos apenas para metadados; nunca escreve nos caminhos indexados.
|
|
373
|
+
|
|
374
|
+
## Limitações
|
|
375
|
+
|
|
376
|
+
- A busca de conteúdo lê apenas arquivos de texto (por extensão) e logs de sessão do DSH; PDF, Office e imagens não têm texto extraído.
|
|
377
|
+
- O orçamento de conteúdo é consumido na ordem de varredura, não por importância do arquivo; arquivos posteriores não são buscáveis ao atingir o limite (`truncated` é true).
|
|
378
|
+
- O índice cobre as raízes configuradas; não é um driver do sistema de arquivos.
|
|
379
|
+
- O inotify do Linux vigia um descritor por diretório; um diretório pessoal com centenas de milhares de diretórios pode exceder o limite do kernel. O plugin avisa e o snapshot continua utilizável; reconstruções se recuperam.
|
|
380
|
+
- Gravações do WSL em `/mnt/c` podem não produzir notificações do Windows (o watcher não vê o fluxo do escritor 9p). Reconstrua essas raízes.
|
|
381
|
+
- Compartilhamentos de rede só são varridos se acessíveis como diretórios comuns; não há feed de mudanças específico de SMB.
|
|
382
|
+
- O conteúdo das sessões vem de logs locais; mensagens ainda não gravadas em disco não são buscáveis.
|
|
383
|
+
- Dois processos do DSH compartilhando um `stateDir` devem ser evitados: o lock de construção serializa escritores, mas não compartilha um handle de banco aberto.
|
|
384
|
+
- O macOS usa FSEvents (recursivo) nos binários publicados; uma compilação com `CGO_ENABLED=0` cai para kqueue, limitado a 4.096 diretórios, com mudanças de conteúdo dependendo da reconstrução periódica.
|
|
385
|
+
- USN/MFT do Windows é opcional e só é usado se o processo puder ler o volume e o diário estiver ativo; caso contrário, usa-se a varredura portátil.
|
|
386
|
+
|
|
387
|
+
## Memória
|
|
388
|
+
|
|
389
|
+
O motor é um único processo Go e respeita as variáveis padrão `GOMEMLIMIT` e `GOGC` (ou `memoryLimitMB` na configuração). Um índice de 1,2–1,5 M de entradas chega a várias centenas de MB de RSS com o GC padrão; use `GOMEMLIMIT=600MiB` (limite suave, o runtime troca CPU por memória) ou `GOGC=50` quando o host estiver apertado de RAM. Nenhum altera o formato do snapshot. Na instalação ao vivo usada para os números acima, o processo anfitrião do DSH (incluindo o cache de páginas do banco de conteúdo) ficava por volta de 700 MB de RSS com o índice construído, e a latência do host ocioso permanecia em p50 2 ms.
|
|
181
390
|
|
|
182
391
|
## Segurança e privacidade
|
|
183
392
|
|
|
184
|
-
O
|
|
393
|
+
- O índice é local: sem chamadas de rede, sem telemetria, sem uploads. O plugin nunca modifica, move ou apaga arquivos indexados.
|
|
394
|
+
- O banco de conteúdo e o lock de construção são criados `0600`, e o diretório de estado `0700`: outros usuários locais não conseguem ler documentos indexados nem o texto de sessões.
|
|
395
|
+
- O snapshot e o banco de conteúdo contêm nomes, caminhos e corpos; trate o diretório de estado como dado privado. Apagá-lo limpa o cache.
|
|
396
|
+
- Dê a cada processo concorrente do DSH um `stateDir` separado.
|
|
397
|
+
|
|
398
|
+
## Versão e compatibilidade
|
|
399
|
+
|
|
400
|
+
- Node `^22.19.0 || >=24.9.0`; DSH `>=0.2.1-rc.2 <0.3.0` (veja `engines` no `package.json`).
|
|
401
|
+
- As versões são publicadas com procedência do GitHub Actions, então a origem do pacote npm é verificável; Gitee / GitCode são sincronizados por um workflow de espelho.
|
|
402
|
+
- Registro de mudanças: [CHANGELOG.md](CHANGELOG.md); dúvidas e relatos: [Issues](https://github.com/PerryLink/dsh-locator/issues).
|
|
403
|
+
|
|
404
|
+
## Roteiro
|
|
405
|
+
|
|
406
|
+
Não é um compromisso, apenas a direção atual:
|
|
185
407
|
|
|
186
|
-
|
|
408
|
+
1. Verificar o runtime desktop Electron em uma instalação real do Windows.
|
|
409
|
+
2. Pré-visualizações e agrupamento de resultados no painel.
|
|
410
|
+
3. Cobertura de runtime em Windows on ARM / Linux ARM.
|
|
411
|
+
4. Arena de nomes em minúsculas e pré-filtro trigram para índices muito grandes.
|
|
412
|
+
5. Compactação incremental do snapshot e diários por raiz.
|
|
187
413
|
|
|
188
414
|
## Licença
|
|
189
415
|
|