dd-harness 0.32.0 → 0.32.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/dist/sessao.js CHANGED
@@ -61,6 +61,10 @@ export async function abreSessao(host, entrada) {
61
61
  skills.map(s => `- ${s.slug}${s.so_por_comando ? " (só por pedido explícito)" : ""}: ${s.descricao}`).join("\n");
62
62
  if (sync.conflitos.length)
63
63
  contexto += `\n\n${sync.conflitos.length} ponteiro(s) preservado(s) por conflito local; consulte listar_skills.`;
64
+ if (sync.ignoradas.length)
65
+ contexto += `\n\nO serviço não devolveu skill alguma, mas ${sync.ignoradas.length} ponteiro(s) ` +
66
+ `continuam em disco (${sync.ignoradas.join(", ")}); eles não foram apagados porque lista vazia costuma ser falha de leitura. ` +
67
+ `Confirme em listar_skills antes de tratar essas skills como removidas.`;
64
68
  }
65
69
  catch {
66
70
  contexto += "\n\nNão foi possível atualizar as skills; consulte listar_skills quando o serviço voltar.";
package/dist/skill.d.ts CHANGED
@@ -42,11 +42,20 @@ export declare function ponteiroDaSkill(skill: Skill, formato?: "claude" | "padr
42
42
  /**
43
43
  * Atualiza/remove somente ponteiros registrados e intactos. Preserva arquivos manuais,
44
44
  * edições locais e recursos adicionais nos diretórios de skills.
45
+ *
46
+ * **Lista vazia nunca remove.** "O serviço não tem skills" e "a leitura falhou" chegam aqui
47
+ * com a mesma cara — lista sem itens —, mas erram em direções muito diferentes: preservar
48
+ * um ponteiro obsoleto custa uma skill desatualizada até o próximo boot; apagar todos custa
49
+ * as skills inteiras, em silêncio, no projeto de quem só abriu o editor. Remoção real vem
50
+ * uma de cada vez, e nesse caso sobra alguma skill na lista. O acervo inteiro sumindo de uma
51
+ * vez é sinal de problema, não de intenção — então os ponteiros ficam e voltam em
52
+ * `ignoradas`, para o chamador poder dizer o que houve.
45
53
  */
46
54
  export declare function escrevePonteirosDeSkills(raiz: string, skills: Skill[], destinos?: (".claude" | ".agents")[]): Promise<{
47
55
  escritos: number;
48
56
  removidos: number;
49
57
  conflitos: string[];
58
+ ignoradas: string[];
50
59
  }>;
51
60
  /** O minimo para criar uma skill: o resto tem default no banco. */
52
61
  export type NovaSkillInicial = {
package/dist/skill.js CHANGED
@@ -92,10 +92,19 @@ usuário em vez de improvisar um procedimento.
92
92
  /**
93
93
  * Atualiza/remove somente ponteiros registrados e intactos. Preserva arquivos manuais,
94
94
  * edições locais e recursos adicionais nos diretórios de skills.
95
+ *
96
+ * **Lista vazia nunca remove.** "O serviço não tem skills" e "a leitura falhou" chegam aqui
97
+ * com a mesma cara — lista sem itens —, mas erram em direções muito diferentes: preservar
98
+ * um ponteiro obsoleto custa uma skill desatualizada até o próximo boot; apagar todos custa
99
+ * as skills inteiras, em silêncio, no projeto de quem só abriu o editor. Remoção real vem
100
+ * uma de cada vez, e nesse caso sobra alguma skill na lista. O acervo inteiro sumindo de uma
101
+ * vez é sinal de problema, não de intenção — então os ponteiros ficam e voltam em
102
+ * `ignoradas`, para o chamador poder dizer o que houve.
95
103
  */
96
104
  export async function escrevePonteirosDeSkills(raiz, skills, destinos = [".claude"]) {
97
105
  let escritos = 0, removidos = 0;
98
106
  const conflitos = [];
107
+ const ignoradas = [];
99
108
  const hash = (s) => createHash("sha256").update(s).digest("hex");
100
109
  async function temLink(destino, slug) {
101
110
  for (const caminho of [join(raiz, destino), join(raiz, destino, "skills"),
@@ -157,6 +166,12 @@ export async function escrevePonteirosDeSkills(raiz, skills, destinos = [".claud
157
166
  continue;
158
167
  if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug))
159
168
  continue;
169
+ // O manifesto fica como está: no próximo boot com lista boa, o ponteiro é conferido
170
+ // e removido normalmente. Esquecê-lo aqui tornaria o arquivo órfão e intocável.
171
+ if (skills.length === 0) {
172
+ ignoradas.push(slug);
173
+ continue;
174
+ }
160
175
  const caminho = join(raiz, destino, "skills", slug, "SKILL.md");
161
176
  if (await temLink(destino, slug)) {
162
177
  conflitos.push(caminho);
@@ -179,7 +194,7 @@ export async function escrevePonteirosDeSkills(raiz, skills, destinos = [".claud
179
194
  }
180
195
  await escreveAtomico(manifesto, JSON.stringify(proximo));
181
196
  }
182
- return { escritos, removidos, conflitos };
197
+ return { escritos, removidos, conflitos, ignoradas };
183
198
  }
184
199
  /**
185
200
  * Semeia as skills iniciais — so num projeto que ainda nao tem nenhuma.
package/package.json CHANGED
@@ -1,44 +1,44 @@
1
- {
2
- "name": "dd-harness",
3
- "version": "0.32.0",
4
- "type": "module",
1
+ {
2
+ "name": "dd-harness",
3
+ "version": "0.32.1",
4
+ "type": "module",
5
5
  "description": "Política, memória e integrações de Claude Code, Codex e Antigravity. CLI sem dependências de runtime.",
6
- "license": "UNLICENSED",
7
- "author": "Diego Dias",
8
- "keywords": [
9
- "claude-code",
10
- "ai-agents",
11
- "memory",
12
- "brain",
13
- "cli"
14
- ],
15
- "homepage": "https://dd-harness.vercel.app",
16
- "repository": {
17
- "type": "git",
18
- "url": "git+https://github.com/diegodias93/dd-harness-online.git",
19
- "directory": "packages/cli"
20
- },
21
- "bin": {
22
- "dd-harness": "dist/index.js"
23
- },
24
- "//exports": "Aponta para `dist` porque quem IMPORTA isto em tempo de execucao e o Node, que nao executa TypeScript. Nao aponte para `src`: o Node segue os imports relativos de dentro do arquivo e tenta abrir `./api.js` ao lado do `.ts`, que nao existe. Quem consome no workspace e o `packages/mcp`, e ele compila o fonte do CLI junto (ver o tsconfig.build.json dele) em vez de depender deste campo — assim o build funciona num checkout limpo, sem `dist` previo.",
25
- "exports": {
26
- "./api": "./dist/api.js",
27
- "./buscar": "./dist/buscar.js",
28
- "./curar": "./dist/curar.js",
29
- "./gravar": "./dist/gravar.js",
30
- "./pasta": "./dist/pasta.js",
31
- "./projeto": "./dist/projeto.js"
32
- },
33
- "files": [
34
- "dist"
35
- ],
36
- "engines": {
6
+ "license": "UNLICENSED",
7
+ "author": "Diego Dias",
8
+ "keywords": [
9
+ "claude-code",
10
+ "ai-agents",
11
+ "memory",
12
+ "brain",
13
+ "cli"
14
+ ],
15
+ "homepage": "https://dd-harness.vercel.app",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/diegodias93/dd-harness-online.git",
19
+ "directory": "packages/cli"
20
+ },
21
+ "bin": {
22
+ "dd-harness": "dist/index.js"
23
+ },
24
+ "//exports": "Aponta para `dist` porque quem IMPORTA isto em tempo de execucao e o Node, que nao executa TypeScript. Nao aponte para `src`: o Node segue os imports relativos de dentro do arquivo e tenta abrir `./api.js` ao lado do `.ts`, que nao existe. Quem consome no workspace e o `packages/mcp`, e ele compila o fonte do CLI junto (ver o tsconfig.build.json dele) em vez de depender deste campo — assim o build funciona num checkout limpo, sem `dist` previo.",
25
+ "exports": {
26
+ "./api": "./dist/api.js",
27
+ "./buscar": "./dist/buscar.js",
28
+ "./curar": "./dist/curar.js",
29
+ "./gravar": "./dist/gravar.js",
30
+ "./pasta": "./dist/pasta.js",
31
+ "./projeto": "./dist/projeto.js"
32
+ },
33
+ "files": [
34
+ "dist"
35
+ ],
36
+ "engines": {
37
37
  "node": ">=20.3.0"
38
- },
39
- "scripts": {
40
- "typecheck": "tsc -p . --noEmit",
41
- "build": "tsc -p tsconfig.build.json",
42
- "prepublishOnly": "npm run build"
43
- }
44
- }
38
+ },
39
+ "scripts": {
40
+ "typecheck": "tsc -p . --noEmit",
41
+ "build": "tsc -p tsconfig.build.json",
42
+ "prepublishOnly": "npm run build"
43
+ }
44
+ }