@andespindola/crow-skills 0.7.1 → 0.8.0
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/README.md +6 -5
- package/crow_skills/__init__.py +1 -1
- package/crow_skills/autoupdate.py +398 -0
- package/crow_skills/cli.py +89 -3
- package/crow_skills/events.py +111 -0
- package/crow_skills/guide.py +7 -1
- package/crow_skills/hook.py +560 -0
- package/crow_skills/integrations.py +427 -63
- package/crow_skills/progress.py +106 -14
- package/crow_skills/source.py +40 -0
- package/crow_skills/storage.py +5 -4
- package/docs/cli.md +96 -17
- package/package.json +1 -1
- package/release.json +30 -15
- package/skills/crow-behaviour/SKILL.md +3 -3
- package/skills/crow-behaviour/references/progress-ledger.md +17 -3
- package/skills/crow-behaviour/scripts/crow_ledger.py +45 -2
|
@@ -11,7 +11,7 @@ Transforme o agente principal em responsável pelo resultado completo: ele defin
|
|
|
11
11
|
|
|
12
12
|
Pedido atual, alvo e revisão, critérios de sucesso, restrições, artefatos já válidos e ferramentas efetivamente expostas pelo runtime. Reutilize o contexto disponível; pergunte apenas por uma decisão material que não possa resolver com evidência.
|
|
13
13
|
|
|
14
|
-
Instalação torna a skill disponível, não garante que o host a carregue em todo turno. Quando selecionada/invocada, aplique este comportamento ao pedido em curso. Mantenha-o nos turnos relacionados enquanto a skill permanecer no contexto e o usuário não o substituir. Se o usuário ou o host declarar um modo de orquestração permanente na sessão, trate-o como vigente para toda tarefa substantiva até ser desligado explicitamente, inclusive após compactação de contexto. Não edite prompts globais, hooks ou configurações para forçar ativação.
|
|
14
|
+
Instalação torna a skill disponível, não garante que o host a carregue em todo turno. Quando selecionada/invocada, aplique este comportamento ao pedido em curso. Mantenha-o nos turnos relacionados enquanto a skill permanecer no contexto e o usuário não o substituir. Se o usuário ou o host declarar um modo de orquestração permanente na sessão, trate-o como vigente para toda tarefa substantiva até ser desligado explicitamente, inclusive após compactação de contexto. O interruptor do usuário é o modo crow (`crow-skills mode on|off`, `/crow on|off`), informado pelo host a cada prompt como `[crow-skills] modo crow: ON` ou `OFF`; vale o anúncio mais recente. ON é essa declaração de modo permanente. OFF desliga esta skill: não a aplique, salvo se o usuário a invocar explicitamente no pedido em curso. Não edite prompts globais, hooks ou configurações para forçar ativação nem altere o modo por iniciativa própria; só o usuário liga ou desliga.
|
|
15
15
|
|
|
16
16
|
## Trabalho
|
|
17
17
|
|
|
@@ -40,7 +40,7 @@ Leia [padrões e critérios de conclusão](references/quality-patterns.md) quand
|
|
|
40
40
|
- Um responsável por arquivo ou recurso mutável em cada momento. Antes de escrita concorrente, use isolamento suportado e autorizado ou ownership disjunto. Não crie clones/worktrees por suposição. Sem isolamento seguro, serialize.
|
|
41
41
|
- O principal pode avançar uma unidade independente enquanto aguarda, mas não refazer em paralelo a mesma unidade atribuída ao worker. Reatribua explicitamente se o executor falhar ou ficar indisponível.
|
|
42
42
|
- Não deixe trabalhadores dispararem novas equipes sem escopo e limite atribuídos. Cancele trabalho obsoleto e aguarde processos relevantes antes de reiniciar ou declarar conclusão.
|
|
43
|
-
- Mantenha o ledger de progresso: o coordenador é o único que grava; registre cada unidade ao iniciar e ao terminar, mostre o progresso na própria conversa (plano no início,
|
|
43
|
+
- Mantenha o ledger de progresso: o coordenador é o único que grava; registre cada unidade ao iniciar e ao terminar, mostre o progresso na própria conversa (plano no início, bloco de processos a cada transição de fase, linha curta quando algo muda) e, se o host tiver uma ferramenta nativa de plano/tarefas, espelhe nela as mesmas unidades. O bloco de processos usa sempre o formato da lista de agentes do host, uma linha por processo em andamento: `● main <o que o coordenador faz>`, depois `○ <dono> <atividade>` para cada unidade em andamento de outro dono (subagente, workflow), e uma linha de contagem (`✓ 3 concluída(s) · ✗ 1 falha(s) · 2 pendente(s)`); `crow_ledger.py show` o imprime a partir do ledger. Nunca abra janela, painel ou outro processo para exibir progresso; veja [ledger de progresso](references/progress-ledger.md).
|
|
44
44
|
|
|
45
45
|
### 4. Verifique antes de sintetizar
|
|
46
46
|
|
|
@@ -66,7 +66,7 @@ Quando o usuário pedir para configurar o comportamento padrão de um agente de
|
|
|
66
66
|
|
|
67
67
|
## Saída e aceite
|
|
68
68
|
|
|
69
|
-
Entregue o resultado pedido, apoiado pelo **execution-ledger**: cobertura de requisitos, evidências da revisão final, contradições resolvidas e pendências com continuação concreta. A resposta ao usuário deve ser proporcional e natural, não uma transcrição de coordenação; o
|
|
69
|
+
Entregue o resultado pedido, apoiado pelo **execution-ledger**: cobertura de requisitos, evidências da revisão final, contradições resolvidas e pendências com continuação concreta. A resposta ao usuário deve ser proporcional e natural, não uma transcrição de coordenação; o bloco de processos entra nas transições de fase e no fim.
|
|
70
70
|
|
|
71
71
|
- Distinga planejado, tentado, produzido e verificado. Registre testes não executados.
|
|
72
72
|
- Relate o modo real quando relevante: workflow, subagentes ou sequencial. Não atribua trabalho a agentes que não existiram.
|
|
@@ -56,7 +56,8 @@ python3 <pasta-da-skill>/scripts/crow_ledger.py start --title "Paridade" --host
|
|
|
56
56
|
# imprime "<run-id> <caminho>"; guarde o run-id e passe-o em toda chamada seguinte
|
|
57
57
|
python3 <pasta-da-skill>/scripts/crow_ledger.py unit u1 --run <run-id> --phase d --title "Mapear CLI" --owner subagent:leitor --status running
|
|
58
58
|
python3 <pasta-da-skill>/scripts/crow_ledger.py unit u1 --run <run-id> --status done --summary "3 pontos de extensão"
|
|
59
|
-
python3 <pasta-da-skill>/scripts/crow_ledger.py show --run <run-id>
|
|
59
|
+
python3 <pasta-da-skill>/scripts/crow_ledger.py show --run <run-id> # bloco de processos para o chat
|
|
60
|
+
python3 <pasta-da-skill>/scripts/crow_ledger.py show --tree --run <run-id> # árvore de fases, se o usuário pedir detalhe
|
|
60
61
|
python3 <pasta-da-skill>/scripts/crow_ledger.py finish --run <run-id> --status done
|
|
61
62
|
```
|
|
62
63
|
|
|
@@ -70,11 +71,24 @@ O progresso aparece na própria conversa, exibido pelo agente que está trabalha
|
|
|
70
71
|
|
|
71
72
|
- **Início:** ao começar uma tarefa substantiva, mostre o plano em poucas linhas: fases, unidades e o que será entregue.
|
|
72
73
|
- **Plano nativo do host:** se o host tiver ferramenta de plano ou tarefas (lista de tarefas, plano de etapas), espelhe nela as mesmas unidades e mantenha os estados em dia: uma unidade em andamento por responsável, concluída assim que tiver evidência. É o jeito preferido de mostrar progresso contínuo, porque a interface do próprio host o exibe sem outra janela.
|
|
73
|
-
- **
|
|
74
|
+
- **Bloco de processos:** a cada transição de fase e no fim, inclua no chat o bloco impresso por `crow_ledger.py show`, no mesmo formato da lista de agentes do host. Uma linha por processo em andamento; `main` é sempre a primeira; o dono vem sem o prefixo `subagent:`; a última linha conta as unidades:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
● main Integrar resultados
|
|
78
|
+
○ revisor Revisar o diff
|
|
79
|
+
○ workflow:testes Rodar a suíte
|
|
80
|
+
✓ 3 concluída(s) · ✗ 1 falha(s) · 2 pendente(s)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Escreva o bloco à mão nesse formato quando o script não estiver disponível; em terminal sem Unicode, `show --ascii` troca `●`/`○` por `*`/`o`. A árvore de fases com barras (`show --tree`) só entra se o usuário pedir detalhe. Não repita o bloco a cada unidade.
|
|
74
84
|
- **Entre transições:** uma linha curta quando uma unidade demorada começa ou termina, ou quando algo muda o plano (falha, achado, decisão pendente). Em espera longa (job em segundo plano, workflow, CI), diga o que está rodando e quando vai checar de novo.
|
|
75
85
|
- **Proporção:** o progresso informa, não substitui a resposta. Sem transcrição de coordenação, sem resumo repetido e sem barra inventada.
|
|
76
86
|
|
|
77
|
-
Não instale nada para exibir progresso.
|
|
87
|
+
Não instale nada para exibir progresso. Se o usuário instalou as integrações do crow-skills, a status line do Claude Code e do Antigravity já mostra o mesmo bloco e o indicador `▸▸ crow on`; isso não substitui o bloco no chat, que funciona em qualquer CLI.
|
|
88
|
+
|
|
89
|
+
## Modo crow
|
|
90
|
+
|
|
91
|
+
O usuário liga ou desliga esta skill para todas as sessões e CLIs com `crow-skills mode on|off` (ou `/crow on|off`). O host informa o modo a cada prompt (`[crow-skills] modo crow: ON|OFF`). Com OFF, não abra ledger nem aplique a skill, salvo invocação explícita. Nunca mude o modo por conta própria.
|
|
78
92
|
|
|
79
93
|
## Limites
|
|
80
94
|
|
|
@@ -9,7 +9,8 @@ coordinator records the transition.
|
|
|
9
9
|
crow_ledger.py phase ID --run RUN [--title T] [--status running|done|...]
|
|
10
10
|
crow_ledger.py unit ID --run RUN [--title T] [--phase P] [--owner O] [--status S] [--progress 0..1] [--summary TXT]
|
|
11
11
|
crow_ledger.py finish --run RUN [--status done|failed|cancelled]
|
|
12
|
-
crow_ledger.py show [--run RUN] #
|
|
12
|
+
crow_ledger.py show [--run RUN] # process list for the chat (● main / ○ owner activity)
|
|
13
|
+
crow_ledger.py show --tree [--run RUN] # phase tree with ASCII bars, when the user asks for detail
|
|
13
14
|
crow_ledger.py path [--run RUN] # where the ledger lives
|
|
14
15
|
|
|
15
16
|
start prints "<run-id> <path>"; pass that run id as --run (or $CROW_RUN) on
|
|
@@ -155,6 +156,45 @@ def clean(text, limit=120):
|
|
|
155
156
|
return text if len(text) <= limit else text[: limit - 3] + "..."
|
|
156
157
|
|
|
157
158
|
|
|
159
|
+
def owner_label(owner):
|
|
160
|
+
owner = clean(owner, 40) or "main"
|
|
161
|
+
return owner.split(":", 1)[1] if owner.startswith("subagent:") and owner[9:] else owner
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def processes(data, ascii_only=False):
|
|
165
|
+
"""The progress block shown in the conversation, in the layout of the host's agent list:
|
|
166
|
+
|
|
167
|
+
● main <what the coordinator is doing>
|
|
168
|
+
○ <owner> <running unit>
|
|
169
|
+
✓ 3 concluída(s) · ✗ 1 falha(s) · 2 pendente(s)
|
|
170
|
+
"""
|
|
171
|
+
dot, ring, check, cross, sep = ("*", "o", "ok", "x", " - ") if ascii_only else ("●", "○", "✓", "✗", " · ")
|
|
172
|
+
units = data.get("units", []) or []
|
|
173
|
+
running = [u for u in units if u.get("status") == "running"]
|
|
174
|
+
mine = [u for u in running if owner_label(u.get("owner")) in ("main", "sequential")]
|
|
175
|
+
others = [u for u in running if u not in mine]
|
|
176
|
+
head = dot + " main"
|
|
177
|
+
if mine:
|
|
178
|
+
head += " " + clean(mine[0].get("title") or mine[0].get("id"), 70) + (" (+" + str(len(mine) - 1) + ")" if len(mine) > 1 else "")
|
|
179
|
+
elif data.get("status", "running") == "running":
|
|
180
|
+
head += " " + clean(data.get("title"), 70)
|
|
181
|
+
else:
|
|
182
|
+
head += " " + clean(data.get("title"), 70) + " [" + clean(data.get("status")) + "]"
|
|
183
|
+
lines = [head]
|
|
184
|
+
for unit in others:
|
|
185
|
+
lines.append(ring + " " + owner_label(unit.get("owner")) + " " + clean(unit.get("title") or unit.get("id"), 70))
|
|
186
|
+
done = sum(u.get("status") == "done" for u in units)
|
|
187
|
+
failed = sum(u.get("status") == "failed" for u in units)
|
|
188
|
+
pending = sum(u.get("status") == "pending" for u in units)
|
|
189
|
+
parts = [check + " " + str(done) + " concluída(s)"]
|
|
190
|
+
if failed:
|
|
191
|
+
parts.append(cross + " " + str(failed) + " falha(s)")
|
|
192
|
+
if pending:
|
|
193
|
+
parts.append(str(pending) + " pendente(s)")
|
|
194
|
+
lines.append(sep.join(parts))
|
|
195
|
+
return "\n".join(lines)
|
|
196
|
+
|
|
197
|
+
|
|
158
198
|
def render(data):
|
|
159
199
|
units = data.get("units", [])
|
|
160
200
|
counted = [u for u in units if u.get("status") != "skipped"]
|
|
@@ -210,6 +250,9 @@ def main(argv=None):
|
|
|
210
250
|
for name in ("show", "path"):
|
|
211
251
|
child = sub.add_parser(name)
|
|
212
252
|
child.add_argument("--run")
|
|
253
|
+
if name == "show":
|
|
254
|
+
child.add_argument("--tree", action="store_true", help="árvore de fases com barras, em vez da lista de processos")
|
|
255
|
+
child.add_argument("--ascii", action="store_true", help="lista de processos só com ASCII")
|
|
213
256
|
for child in (phase, unit, finish):
|
|
214
257
|
child.add_argument("--run")
|
|
215
258
|
args = p.parse_args(argv)
|
|
@@ -234,7 +277,7 @@ def main(argv=None):
|
|
|
234
277
|
print(path)
|
|
235
278
|
return 0
|
|
236
279
|
if args.command == "show":
|
|
237
|
-
print(render(data))
|
|
280
|
+
print(render(data) if args.tree else processes(data, args.ascii))
|
|
238
281
|
return 0
|
|
239
282
|
if args.command == "phase":
|
|
240
283
|
phases = data.setdefault("phases", [])
|