DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

frederico-kluser /

frederico-kluser/dsh-goal-pause-guard

Verified

Plugin do DeepSeek Harness (DSH): modal de confirmação antes de pausar uma atividade rodando — pausar interrompe a rodada atual e as subtarefas na hora.

★ 1 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@da751ec5

dsh-goal-pause-guard

Plugin para o DeepSeek Harness: modal de confirmação antes de pausar uma atividade rodando.

license node dsh ci topic: dsh-plugin

Pausar uma goal não é um gesto pequeno: ela interrompe a rodada atual e todas as subtarefas em execução na hora. O plugin pede confirmação antes.

Modal de confirmação antes de pausar a goal


Porquê

No harness, pausar uma goal armada dispara uma cascata (motorizada no goal-round-driver, goal/changed → agent.cancel, keepInbox):

  1. a rodada em andamento é abortada — o agente para de executar no meio do que estava fazendo;
  2. as subtarefas em execução param junto (tools, comandos, subagentes);
  3. a continuação automática fica desarmada — nada de novas rodadas até um resume humano.

É exatamente esse efeito que o plugin coloca atrás de um portão: um clique acidental no botão de pause não pode desligar uma atividade que está rodando.

O que o plugin faz

clique em "Pause goal" (clique humano, trusted)
        │
        ▼
  ┌──────────────┐   captura no document (capture phase, antes do React)
  │ GUARD        │   isPauseButton? ── não ──► o clique passa (fail-open)
  └──────┬───────┘
         ▼ sim
  MODAL DE CONFIRMAÇÃO  (pt-BR / en / zh, tema claro-escuro do host)
     ├── Cancelar / Esc / fundo ──► nada acontece
     └── Confirmar ──► re-clique UNTRUSTED no botão de pause ATUAL
                          │  (passa pelo guard sem re-gate)
                          ▼
                    GoalBar → goals.pause (Remote RPC)
                          ▼
                    host: goal paused + rodada abortada + subtasks param
  • Detecção por dois canais — o botão é reconhecido pelo aria-label localizado (Pause goal / 暂停目标, os dois dicionários da barra de goal) ou pelo path SVG do ícone de pause (IconPauseOutline16), sempre dentro de [data-goal-bar] (o marcador que o próprio e2e oficial usa).
  • Fail-open por projeto — se o botão não for identificável, o clique passa e o pause se comporta exatamente como sem o plugin. Um portão de confirmação nunca pode quebrar a ação que protege.
  • Sem loop, sem referência velha — o confirm re-localiza o botão de pause atual antes de re-clicar (um re-render entre abrir e confirmar nunca transforma "confirmar" em "clicar outra coisa"); botão desabilitado ou removido nesse meio-tempo = nada acontece.
  • Um modal por vez — Esc, fundo e Cancelar fecham; o foco vai ao botão de confirmar e volta ao botão de pause no fechar.
  • Determinismo — sem timers, sem rede, sem storage. A metade host é um apply vazio (mesmo padrão do @deepseek-ai/dsh-client-ui-goal): nenhum estado do harness é tocado.

Instalação

Como bundle do profile web — o dsh.bundle.patch do pacote ativa a camada sozinho (insert próprio, sem colidir com nenhum outro id):

dsh plugin --profile web add /caminho/para/dsh-goal-pause-guard
dsh web   # reinicie a instância; plugins entram no boot

Desinstalar: remova a linha do bundle do ~/.dsh/profiles/web/package.json (dsh plugin --profile web remove dsh-goal-pause-guard) e reinicie.

Verificação

Toda a verificação roda isolada — nenhum teste toca uma instância real do DSH (nem a porta 3080, nem o $DSH_HOME):

pnpm install
pnpm run typecheck   # tsc estrito
pnpm run build       # dist/ (host) + lib/client.js (browser, closure-factory)
pnpm test            # 23 testes: detector + comportamento + e2e do artefato
Camada Prova
Detector (unit, jsdom) os dois canais de identificação; rejeição de todo o resto (resume/edit/clear, botões fora da barra, ícones estrangeiros, prefixos parecidos)
Comportamento (jsdom) clique humano abre o modal e nunca chega ao app; confirmar re-clica UMA vez como untrusted; cancelar/Esc/fundo não pausam; segundo clique engolido; botão removido/desabilitado no confirm não dispara; disposer remove tudo
E2E do artefato o lib/client.js enviado é carregado como o harness carrega (window.__ModuleLoader__.load({id, factory})) e o fluxo inteiro é dirigido sobre ele

O screenshot acima é real: capturado num boot isolado ( $DSH_HOME temporária + porta própria) com Chromium headless, clicando no botão de pause de verdade (evento trusted via CDP) — o guard abriu o modal e o cancelamento não enviou pausa nenhuma.

Estrutura

dsh-goal-pause-guard/
├── package.json             # dsh.bundle.patch + dsh.client (platform web) + exports["./client"]
├── cordis.patch.yml         # camada 1 (bundle): insert próprio, sem !!js, sem config
├── src/index.ts             # host half: apply vazio (entrada do Loader)
├── client/
│   ├── guard-core.ts        # TODA a lógica: detector, textos, modal, install (0 imports)
│   ├── index.ts             # plugin body: inject [] + apply(ctx) via ctx.effect
│   ├── guard.css            # modal com tokens --dsw-* (claro/escuro), classes gpg-
│   └── client.d.ts          # declaração do subpath ./client
├── scripts/build-client.mjs # esbuild → lib/client.js (closure-factory, CSS embutido)
├── test/                    # jsdom + node:test, offline por projeto
└── dist/, lib/              # produtos do build (host half / browser bundle)

Compatibilidade

Verificado contra DSH 0.1.5-alpha.2 (a linha viva instalada, bootada do source). O detector ancora em dois fatos estáveis da superfície — data-goal-bar e o aria-label do action.pause do dicionário goal. Se o harness mudar os dois ao mesmo tempo, o guard fica fail-open (pause sem modal) — nunca quebrado.

Licença

MIT © Frederico Kluser

—/ 5

No ratings yet

Verified DSH bundle

Commit da751ec533cb

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout