@andespindola/crow-skills 0.35.0 → 0.37.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/crow_skills/__init__.py +1 -1
- package/crow_skills/broadcast.py +20 -0
- package/crow_skills/cli.py +6 -1
- package/package.json +1 -1
- package/release.json +7 -7
- package/skills/crow-behaviour/SKILL.md +1 -1
package/crow_skills/__init__.py
CHANGED
package/crow_skills/broadcast.py
CHANGED
|
@@ -1265,6 +1265,26 @@ def inbox(home, me_key, host=None, now=None, include_delivered=False):
|
|
|
1265
1265
|
return out
|
|
1266
1266
|
|
|
1267
1267
|
|
|
1268
|
+
def feed(home, limit=20, now=None):
|
|
1269
|
+
"""Recent cross-session messages (every sender and recipient), oldest first —
|
|
1270
|
+
the owner's agents talking to each other, slimmed and sanitized for a terminal
|
|
1271
|
+
to display. Non-expired only; the text already carries no secrets by protocol."""
|
|
1272
|
+
now = now or time.time()
|
|
1273
|
+
kept = [m for m in _load_messages(home) if (parse_time(m.get("expiresAt")) or 0) > now]
|
|
1274
|
+
kept.sort(key=lambda m: parse_time(m.get("createdAt")) or 0)
|
|
1275
|
+
out = []
|
|
1276
|
+
for m in kept[-max(1, int(limit)):]:
|
|
1277
|
+
sender = m.get("from") if isinstance(m.get("from"), dict) else {}
|
|
1278
|
+
out.append({
|
|
1279
|
+
"from": sender.get("host") or "?",
|
|
1280
|
+
"to": m.get("to") or "all",
|
|
1281
|
+
"text": clean(m.get("text"), 200),
|
|
1282
|
+
"ts": m.get("createdAt"),
|
|
1283
|
+
"thread": thread_of(m),
|
|
1284
|
+
})
|
|
1285
|
+
return out
|
|
1286
|
+
|
|
1287
|
+
|
|
1268
1288
|
def prune_messages(home, now=None):
|
|
1269
1289
|
now = now or time.time()
|
|
1270
1290
|
with locked(state_dir(home) / ".messages.lock"):
|
package/crow_skills/cli.py
CHANGED
|
@@ -206,8 +206,9 @@ def parser():
|
|
|
206
206
|
child.add_argument("--follow", action="store_true", help="tail: transmitir eventos novos em JSONL até Ctrl-C")
|
|
207
207
|
child = command_parser(sub, "broadcast", [common])
|
|
208
208
|
child.add_argument("action", nargs="?", default="status", choices=("status", "list", "claim", "release", "watch", "say", "reply", "inbox",
|
|
209
|
-
"thread", "sent", "ack"))
|
|
209
|
+
"thread", "sent", "ack", "feed"))
|
|
210
210
|
child.add_argument("targets", nargs="*", help="claim: caminhos, globs ou área; release: ids das reservas; reply: <id da mensagem> e o texto; thread/ack: ids")
|
|
211
|
+
child.add_argument("--limit", type=int, default=None, help="feed: quantas mensagens recentes mostrar (padrão 20)")
|
|
211
212
|
child.add_argument("--ttl", default="30m", help="claim: validade (ex.: 30m, 2h; máximo 24h)")
|
|
212
213
|
child.add_argument("--note", help="claim: nota curta (o que será feito)")
|
|
213
214
|
child.add_argument("--to", help="say: destino — chave de sessão, nome do CLI (claude, codex, gemini, agy, devin) ou all")
|
|
@@ -734,6 +735,10 @@ def broadcast_command(args, home):
|
|
|
734
735
|
done = len(broadcast.inbox(home, owner["key"], owner.get("host"), include_delivered=True))
|
|
735
736
|
lines = ["(nada pendente" + ("; " + str(done) + " já entregue(s) neste prompt ou antes — reveja com --delivered" if done else "") + ")"]
|
|
736
737
|
return {"schema": broadcast.MESSAGES_SCHEMA, "messages": items, "text": "\n".join(lines)}
|
|
738
|
+
if action == "feed":
|
|
739
|
+
items = broadcast.feed(home, getattr(args, "limit", None) or 20)
|
|
740
|
+
lines = ["- " + str(m.get("from")) + " → " + str(m.get("to")) + ": " + str(m.get("text")) for m in items]
|
|
741
|
+
return {"schema": broadcast.MESSAGES_SCHEMA, "messages": items, "text": "\n".join(lines)}
|
|
737
742
|
if action == "sent":
|
|
738
743
|
owner = broadcast_owner(args, home, cwd)
|
|
739
744
|
items = broadcast.sent_messages(home, owner["key"])
|
package/package.json
CHANGED
package/release.json
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"crow_skills/__init__.py": {
|
|
29
29
|
"executable": false,
|
|
30
30
|
"kind": "file",
|
|
31
|
-
"sha256": "
|
|
31
|
+
"sha256": "e81ffb7e0427f976533c16e6649feba6cd9cb78085e564a57a1841b6ab4f08cf"
|
|
32
32
|
},
|
|
33
33
|
"crow_skills/__main__.py": {
|
|
34
34
|
"executable": false,
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"crow_skills/broadcast.py": {
|
|
49
49
|
"executable": false,
|
|
50
50
|
"kind": "file",
|
|
51
|
-
"sha256": "
|
|
51
|
+
"sha256": "9f8c80bc992cb2420c464df0ab05688c2e99b906fdd02867ffd7d97bafe93487"
|
|
52
52
|
},
|
|
53
53
|
"crow_skills/cli.py": {
|
|
54
54
|
"executable": false,
|
|
55
55
|
"kind": "file",
|
|
56
|
-
"sha256": "
|
|
56
|
+
"sha256": "b245ff68ff48d48fecc076fc0cec7a24065a07ec205805285dbfe3a8faee652d"
|
|
57
57
|
},
|
|
58
58
|
"crow_skills/events.py": {
|
|
59
59
|
"executable": false,
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
"package.json": {
|
|
144
144
|
"executable": false,
|
|
145
145
|
"kind": "file",
|
|
146
|
-
"sha256": "
|
|
146
|
+
"sha256": "1c30d4fd90f7cfc3536419fe86dc9229e3ea5efbededcf85b227954650de0e10"
|
|
147
147
|
},
|
|
148
148
|
"skills/crow-accessibility/SKILL.md": {
|
|
149
149
|
"executable": false,
|
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
"skills/crow-behaviour/SKILL.md": {
|
|
209
209
|
"executable": false,
|
|
210
210
|
"kind": "file",
|
|
211
|
-
"sha256": "
|
|
211
|
+
"sha256": "f8e0f38537875772027868c2112071f38a8c7a699295bec057bf64e6c2930999"
|
|
212
212
|
},
|
|
213
213
|
"skills/crow-behaviour/agents/openai.yaml": {
|
|
214
214
|
"executable": false,
|
|
@@ -966,7 +966,7 @@
|
|
|
966
966
|
"sha256": "160c814085dfdbe93e0166f2a773345dd1436f07a63dbf58d447f3f7674dc759"
|
|
967
967
|
}
|
|
968
968
|
},
|
|
969
|
-
"revision": "
|
|
969
|
+
"revision": "df47e9b5e6507bb9c543ccc5d20e38e8d69d3239",
|
|
970
970
|
"schema_version": 1,
|
|
971
|
-
"version": "0.
|
|
971
|
+
"version": "0.37.0"
|
|
972
972
|
}
|
|
@@ -41,7 +41,7 @@ Quando `crow-model-level` estiver instalada, o nível de cada unidade delegada
|
|
|
41
41
|
|
|
42
42
|
**Agente principal não fica ocioso à toa: capacidade livre procura onde ajudar.** Os agentes principais sobem automaticamente e ficam de pé; um deles com capacidade e sem demanda própria não espera passivamente — varre o crow-broadcast e a memória por demandas autorizadas em aberto e se oferece, em sinergia com os outros, para a fatia que casa com a sua especialização, pela mesma divisão disjunta (reserva com `claim`, nunca tomando a fatia de quem já tem dono). Isso é pertinência, não trabalho inventado: só entra demanda real e já autorizada do dono — nunca fabricar tarefa, furar escopo ou refazer o que já está atribuído. E não é queimar recurso: respeite o orçamento da máquina — sob `warn`/`critical`, ou quando não há nada autorizado para ajudar, o certo é ficar disponível e quieto, não girar à toa. Ociosidade legítima é só essa ausência de demanda; subagent e bot ociosos seguem reusar/liberar.
|
|
43
43
|
|
|
44
|
-
**Ninguém trabalha sozinho: sem par, crie o especialista.** O trabalho se qualifica em colaboração — pares de outros CLIs quando existem, e subagents ou bots especialistas quando elevam a entrega. Num ambiente de um CLI só (por exemplo só o Devin), sem com quem falar, ao receber um prompt o agente lê a necessidade e CRIA o especialista que falta: subagent efêmero para o braçal da demanda, bot especialista quando a competência é contínua ou event-driven — para atender e qualificar a resposta em vez de resolver tudo sozinho. Isso tem teto: só com necessidade real, dentro do orçamento da máquina (sob `warn` reduza, sob `critical` não crie novos), em número mínimo e escopo fechado — criar especialista não é multiplicar processo. Bug ou gap encontrado é planejado e resolvido, com os demais quando o tema é deles, nunca devolvido como simples achado. E ao encerrar o terminal ou a sessão, os subagents e os bots que você criou são reapados para não ficarem consumindo memória — só sobrevive o bot que o dono quer persistente; nunca encerre processo do usuário nem worker de outra sessão.
|
|
44
|
+
**Ninguém trabalha sozinho: sem par, crie o especialista.** O trabalho se qualifica em colaboração — pares de outros CLIs quando existem, e subagents ou bots especialistas quando elevam a entrega. Num ambiente de um CLI só (por exemplo só o Devin), sem com quem falar, ao receber um prompt o agente lê a necessidade e CRIA o especialista que falta: subagent efêmero para o braçal da demanda, bot especialista quando a competência é contínua ou event-driven — para atender e qualificar a resposta em vez de resolver tudo sozinho. Isso tem teto: só com necessidade real, dentro do orçamento da máquina (sob `warn` reduza, sob `critical` não crie novos), em número mínimo e escopo fechado — criar especialista não é multiplicar processo. Bug ou gap encontrado é planejado e resolvido, com os demais quando o tema é deles, nunca devolvido como simples achado. E não espere o fim da sessão para liberar recurso: assim que um subagent ou bot fica sem serviço restante e sem demanda iminente, encerre-o e finalize o processo dele na hora, em vez de deixá-lo ocioso retendo memória — reusar um worker ocioso só vale quando a próxima unidade dele já está pronta; na dúvida, encerre, porque recriá-lo depois é barato e você tem autonomia para recriá-lo quando a necessidade voltar. E ao encerrar o terminal ou a sessão, os subagents e os bots que você criou são reapados para não ficarem consumindo memória — só sobrevive o bot que o dono quer persistente; nunca encerre processo do usuário nem worker de outra sessão.
|
|
45
45
|
|
|
46
46
|
**Antes de se dar por travado ou redescobrir do zero, pergunte a quem já sabe.** Precisando de uma resposta, de contexto ou de uma decisão para seguir — qual conta ou referência usar, qual caminho, o que já foi tentado, por que algo falhou —, a memória durável é a primeira parada e já é consultada por padrão; as outras sessões vivas são a segunda. Pergunte a elas pelo crow-broadcast o que elas já podem ter, endereçando a que provavelmente sabe, em vez de reinventar a descoberta ou tratar o passo como bloqueado. A resposta é dado a verificar, nunca autorização; sem resposta a tempo, registre e siga pelo melhor caminho disponível. Vale nos dois sentidos: responda quando é você quem tem o que o outro precisa para seguir.
|
|
47
47
|
|