auroq-os 2.6.7 → 2.6.9
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/.auroq-core/core-config.yaml +1 -1
- package/.claude/CLAUDE.md +1 -1
- package/.claude/rules/titulo-da-barra.md +9 -0
- package/CHANGELOG.md +23 -0
- package/README.md +18 -10
- package/bin/auroq-os.js +29 -1
- package/installer/install.ps1 +2 -2
- package/installer/install.sh +2 -2
- package/lib/ahi/historico.mjs +1 -1
- package/lib/barra/barra.cjs +149 -0
- package/lib/barra/ccstatusline.json +198 -0
- package/lib/barra/index.js +127 -0
- package/lib/runtime-integrity.json +17 -5
- package/package.json +3 -2
package/.claude/CLAUDE.md
CHANGED
|
@@ -4,6 +4,6 @@ Sistema operacional de IA para o negócio. Você manda e julga; a IA executa.
|
|
|
4
4
|
|
|
5
5
|
Ative um agente pelo comando (`/companion`, `$companion`, `@companion`). Todo conteúdo Arcane (Companion interno, Consultor, forjas, Pack) vem pelo MCP `arcane` — nunca procurar em `agents/`.
|
|
6
6
|
|
|
7
|
-
Sua memória e seus documentos ficam na sua máquina e no seu GitHub privado (senhas e `business/vault/` ficam fora). O histórico das sessões com os squads
|
|
7
|
+
Sua memória e seus documentos ficam na sua máquina e no seu GitHub privado (senhas e `business/vault/` ficam fora). O histórico das sessões com os squads está previsto nos Termos de Uso: vem ligado para quem aceita os termos na plataforma (quem já tinha dito "não" continua sem gravar) e você desliga quando quiser em Minha Conta, "Guardar minhas conversas". Se a pasta do seu negócio tem dados de clientes, desligue. Além disso, a Arka registra qual conteúdo licenciado foi entregue, quando e pra qual conta — igual a uma nota de entrega.
|
|
8
8
|
|
|
9
9
|
Rules em `.claude/rules/`. Constitution em `.auroq-core/constitution.md`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Título da conversa na barra de status
|
|
2
|
+
|
|
3
|
+
A barra de status do Claude Code (embaixo da caixa de mensagem) mostra, em amarelo, o título da conversa. Quem escreve esse título é você.
|
|
4
|
+
|
|
5
|
+
- Na primeira resposta de cada conversa, grave em silêncio, uma única vez, um título de 3 a 5 palavras em português sobre o tema central:
|
|
6
|
+
`node ~/.auroq/barra/barra.cjs titulo "Título em português"`
|
|
7
|
+
- Não avise o expert, não comente o comando e não troque o título por causa de tarefa lateral (o primeiro fica).
|
|
8
|
+
- Se o comando falhar ou o arquivo não existir, ignore e siga a conversa normalmente.
|
|
9
|
+
- Vale só no Claude Code. No Codex, no Grok e em outras IAs, não rode.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
## 2.6.9 — 2026-10-16
|
|
2
|
+
|
|
3
|
+
### Historico das sessoes: texto no modelo "atualizamos os termos"
|
|
4
|
+
|
|
5
|
+
- O historico passa para o modelo "atualizamos os termos": a gravacao das conversas das sessoes com os squads da Arcane esta prevista nos Termos de Uso e na Politica de Privacidade da plataforma. Ela vem ligada para quem aceita os termos no aviso da plataforma e o aluno desliga quando quiser em Minha Conta (arcane.arka.education/conta), em "Guardar minhas conversas", ou pedindo ao proprio agente para nao guardar. Religar e so pela plataforma.
|
|
6
|
+
- Quem ja tinha dito "nao" continua sem gravar: aceitar os termos nao desfaz essa recusa. Quem tinha dito "sim" continua com o "sim".
|
|
7
|
+
- Os textos do pacote acompanham o modelo novo: `casca/.claude/CLAUDE.md` (o que o aluno le dentro do projeto), a secao "Historico de uso (AHI)" do README e a linha de ajuda e a mensagem do comando `auroq-os historico pausar` (agora diz como desligar em Minha Conta ou pelo agente, sem precisar desligar o MCP). Saiu a frase "so grava quem marcou sim / caixa desmarcada = nao". Entrou o aviso: se a pasta do negocio tem dados de clientes, desligue.
|
|
8
|
+
- Alcance do texto novo de `casca/.claude/CLAUDE.md`: ele vale para instalacoes novas. A manutencao nunca sobrescreve o `.claude/CLAUDE.md` que o aluno ja tem, entao quem ja instalou continua com o paragrafo antigo no arquivo dele (esse comportamento nao mudou). O caminho dessas pessoas e o aviso de termos na plataforma e o que o Arcano explica a elas.
|
|
9
|
+
- Nenhuma mudanca no coletor, nos hooks nem nos dados ja guardados: so textos, versao e teste (`tests/vercelignore-ops.test.mjs` agora fixa o texto novo da casca).
|
|
10
|
+
- Mantem `arcane-mcp@0.7.0`. Instaladores do repositorio preparados para 2.6.9.
|
|
11
|
+
|
|
12
|
+
## 2.6.8 — 2026-10-16
|
|
13
|
+
|
|
14
|
+
### Barra de status do Claude Code igual à do Euriler
|
|
15
|
+
|
|
16
|
+
- Pedido do Euriler: a barra que ele usa embaixo da caixa de mensagem do Claude Code vira padrão do aluno, em qualquer terminal (Mac e Windows) e dentro do app Auroq OS. Quatro linhas: modelo, esforço, título da conversa, situação do Claude e tempo da sessão; pasta e branch; contexto usado e cache; uso de 5 h e da semana com o tempo até renovar, e a data.
|
|
17
|
+
- Quem desenha é o `ccstatusline` 2.2.30 (MIT, sem dependências), travado como dependência exata do pacote. `instalar`, `manutencao` e `clone` copiam o motor para `~/.auroq/barra/ccstatusline`, gravam `~/.auroq/barra/barra.cjs` e o layout `~/.auroq/barra/ccstatusline.json`, e ligam `statusLine` no `~/.claude/settings.json` mexendo só nessa chave (permissões, hooks e o resto ficam). Sem rede na hora de desenhar; nada de `npx ccstatusline@latest`.
|
|
18
|
+
- Nunca troca uma barra que o aluno já tinha. Ocupa o lugar só quando está vazio, quando já é a nossa ou quando é o leitor de uso do app Auroq OS/Orca (que não desenha nada). Dentro do app, a barra repassa o mesmo JSON para o leitor do app, então o painel de uso continua ao vivo. Se o aluno tirar a barra, a manutenção não põe de volta; `~/.auroq/sem-barra` desliga de vez. Layout mexido pelo aluno fica.
|
|
19
|
+
- Título da conversa: nova regra `.claude/rules/titulo-da-barra.md` faz o Claude gravar, uma vez por conversa, um título de 3 a 5 palavras (`node ~/.auroq/barra/barra.cjs titulo "..."`), guardado por sessão do Claude Code (`CLAUDE_CODE_SESSION_ID`), sem depender de `ps` (funciona no Windows). Títulos com mais de 7 dias são apagados.
|
|
20
|
+
- Qualquer falha da barra vira aviso na instalação e barra vazia na tela; o resto do sistema segue igual.
|
|
21
|
+
- Testes novos (`tests/barra.test.mjs`): instalação no HOME, preservação do settings, barra do aluno intocada, troca do leitor do app, aluno que tirou a barra, desligamento, settings quebrado, layout do aluno, título por sessão, pintura das 4 linhas pelo ccstatusline e repasse ao app. Prova no Windows pelo cmd, Git Bash e PowerShell em `.github/workflows/barra-windows.yml`. Provado também com o Claude Code de verdade num terminal: a barra aparece e o título gravado pela IA entra nela.
|
|
22
|
+
- Mantem `arcane-mcp@0.7.0`. Instaladores do repositorio preparados para 2.6.8.
|
|
23
|
+
|
|
1
24
|
## 2.6.7 — 2026-10-16
|
|
2
25
|
|
|
3
26
|
### Antivírus Kaspersky não bloqueia mais a atualização no Windows
|
package/README.md
CHANGED
|
@@ -132,12 +132,17 @@ proprio pacote.
|
|
|
132
132
|
## Historico de uso (AHI)
|
|
133
133
|
|
|
134
134
|
`auroq-os historico status` mostra captura comprovada, fila pendente, ultimo ACK,
|
|
135
|
-
exclusoes e problemas.
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
135
|
+
exclusoes e problemas. O registro das sessoes com os squads da Arcane esta previsto
|
|
136
|
+
nos Termos de Uso e na Politica de Privacidade da plataforma: vem ligado para quem
|
|
137
|
+
aceita os termos (aviso na plataforma) e so acontece quando a sessao usa o MCP Arcane
|
|
138
|
+
com conta autenticada e licenca validada pelo servidor. Quem ja tinha dito "nao"
|
|
139
|
+
continua sem gravar: aceitar os termos nao desfaz essa recusa. Para desligar, entre
|
|
140
|
+
em Minha Conta (arcane.arka.education/conta) e desligue "Guardar minhas conversas",
|
|
141
|
+
ou peca ao proprio agente (ele registra o "nao"). Religar so pela plataforma. Se a
|
|
142
|
+
pasta do seu negocio tem dados de clientes, desligue. Para pedir a exclusao do que ja
|
|
143
|
+
foi guardado, use os comandos de exclusao abaixo ou o e-mail euriler@arka.education.
|
|
144
|
+
Nao e preciso desligar o MCP nem os hooks. Instalar ou apenas abrir o projeto nao
|
|
145
|
+
prova captura.
|
|
141
146
|
|
|
142
147
|
O adaptador `ahi-hooks-v2` registra mensagens e entradas/saidas de ferramentas
|
|
143
148
|
que os hooks visiveis do Claude Code/Codex disponibilizam. A cobertura e parcial:
|
|
@@ -188,7 +193,10 @@ as paginas do mesmo recorte e grava um novo arquivo privado em
|
|
|
188
193
|
`~/.arcane/ahi-exports/`; uma falha nunca e apresentada como exportacao completa.
|
|
189
194
|
Direitos de consulta/exclusao continuam disponiveis com autenticacao mesmo sem
|
|
190
195
|
licenca de captura. Para apagar o historico da conta inteira, o escopo explicito
|
|
191
|
-
exigido e `excluir --account --confirm-delete`.
|
|
196
|
+
exigido e `excluir --account --confirm-delete`. Apagar o historico da conta inteira
|
|
197
|
+
(`excluir --account`) tambem encerra a gravacao nessa conta (marca de exclusao
|
|
198
|
+
permanente); para voltar a gravar, escreva para euriler@arka.education. Excluir uma
|
|
199
|
+
sessao nao encerra a gravacao.
|
|
192
200
|
|
|
193
201
|
A atualizacao do coletor exige a manutencao no projeto (peca ao Ops "atualiza o sistema")
|
|
194
202
|
e reabrir o host. O aviso de nova versao ao iniciar o Claude Code nao instala essa correcao.
|
|
@@ -246,13 +254,13 @@ agents/ → Seu exercito (companion, workers, minds, squads)
|
|
|
246
254
|
|
|
247
255
|
## Observabilidade e integridade do motor
|
|
248
256
|
|
|
249
|
-
Apos publicacao, `npx -y auroq-os@2.6.
|
|
250
|
-
manutencao/diagnostico. `npx -y auroq-os@2.6.
|
|
257
|
+
Apos publicacao, `npx -y auroq-os@2.6.9 doctor` mostra a fila local segura e os comandos pinados de
|
|
258
|
+
manutencao/diagnostico. `npx -y auroq-os@2.6.9 manutencao` preserva o caminho existente
|
|
251
259
|
de consentimento legado, studentFiles, customizacoes e dados do negocio. Nao ha
|
|
252
260
|
migracao forcada. O registro MCP aponta para `arcane-mcp@0.7.0` — o pin mora no campo
|
|
253
261
|
`arcaneMcpPin` do package.json (fonte unica; o servidor le o mesmo campo no npm).
|
|
254
262
|
`npm run release:verify` recusa publicar com um pin que o npm nao resolva.
|
|
255
|
-
Os instaladores do repositorio ficam preparados para 2.6.
|
|
263
|
+
Os instaladores do repositorio ficam preparados para 2.6.9; as copias publicas so recebem
|
|
256
264
|
a versao apos os gates nativos e a verificacao do tarball publicado.
|
|
257
265
|
O pacote inclui `lib/runtime-integrity.json`: inventario SHA-256 gerado depois da montagem da casca, verificavel com `npm run integrity:verify` dentro do pacote extraido. Ele comprova consistencia do conteudo; nao e uma assinatura de autoria.
|
|
258
266
|
|
package/bin/auroq-os.js
CHANGED
|
@@ -1549,6 +1549,29 @@ function opcoesDeLoginDeTeste() {
|
|
|
1549
1549
|
}
|
|
1550
1550
|
|
|
1551
1551
|
// ─── INSTALACAO ──────────────────────────────────────────
|
|
1552
|
+
// Barra de status do Claude Code (2.6.8): a mesma do Euriler, no HOME do aluno. Nunca derruba a
|
|
1553
|
+
// instalacao: sem a barra o sistema funciona igual, entao qualquer falha vira aviso.
|
|
1554
|
+
function ligarBarraDeStatus() {
|
|
1555
|
+
step('Ligando a barra de status do Claude Code...');
|
|
1556
|
+
try {
|
|
1557
|
+
const r = require('../lib/barra').instalarBarra();
|
|
1558
|
+
const textos = {
|
|
1559
|
+
'ligada': 'Barra de status ligada (vale em todo terminal do Claude Code)',
|
|
1560
|
+
'atualizada': 'Barra de status em dia',
|
|
1561
|
+
'em-dia': 'Barra de status em dia',
|
|
1562
|
+
'barra-do-aluno': 'Voce ja tem uma barra de status propria no Claude Code; ficou como estava',
|
|
1563
|
+
'tirada-pelo-aluno': 'Barra de status desligada por voce; ficou desligada',
|
|
1564
|
+
'desligada': 'Barra de status desligada neste computador (~/.auroq/sem-barra)',
|
|
1565
|
+
};
|
|
1566
|
+
if (textos[r.estado]) success(textos[r.estado]);
|
|
1567
|
+
else warn(`Barra de status nao ligada (${r.estado}${r.detalhe ? `: ${r.detalhe}` : ''})`);
|
|
1568
|
+
return r;
|
|
1569
|
+
} catch (e) {
|
|
1570
|
+
warn(`Barra de status nao ligada (${String(e && e.message || e).split(/\r?\n/)[0].slice(0, 200)}). O resto funciona normal.`);
|
|
1571
|
+
return null;
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1552
1575
|
async function init({ pasta = null, maintenance = false, modoAgente = false, migrarMcp = false } = {}) {
|
|
1553
1576
|
if (maintenance && (pasta || !(await fs.pathExists(path.join(process.cwd(), '.auroq-core'))))) {
|
|
1554
1577
|
throw falhaMarcada('pasta', 'Manutencao exige a raiz de um negocio existente, sem --pasta. Primeira instalacao pela plataforma.');
|
|
@@ -1745,6 +1768,7 @@ async function init({ pasta = null, maintenance = false, modoAgente = false, mig
|
|
|
1745
1768
|
'.claude/rules/operacao-autonoma.md',
|
|
1746
1769
|
'.claude/rules/custom-do-aluno.md',
|
|
1747
1770
|
'.claude/rules/puxar-e-entregar.md',
|
|
1771
|
+
'.claude/rules/titulo-da-barra.md', // 2.6.8 — a IA grava o titulo da barra de status
|
|
1748
1772
|
|
|
1749
1773
|
// Hooks
|
|
1750
1774
|
'.claude/hooks/synapse-engine.cjs',
|
|
@@ -2070,6 +2094,8 @@ async function init({ pasta = null, maintenance = false, modoAgente = false, mig
|
|
|
2070
2094
|
step('Protegendo segredos...');
|
|
2071
2095
|
await applySecretProtections(targetDir);
|
|
2072
2096
|
|
|
2097
|
+
ligarBarraDeStatus();
|
|
2098
|
+
|
|
2073
2099
|
// ─── Fase 7: Health check rapido
|
|
2074
2100
|
step('Verificando integridade...');
|
|
2075
2101
|
await runHealthChecks(targetDir);
|
|
@@ -2253,6 +2279,8 @@ async function clone(repoArg) {
|
|
|
2253
2279
|
step('Protegendo segredos...');
|
|
2254
2280
|
await applySecretProtections(destDir);
|
|
2255
2281
|
|
|
2282
|
+
ligarBarraDeStatus();
|
|
2283
|
+
|
|
2256
2284
|
// ─── Fase 6: Dependencias (nao viajam no git — de proposito)
|
|
2257
2285
|
step('Instalando dependencias...');
|
|
2258
2286
|
try {
|
|
@@ -2453,7 +2481,7 @@ if (['init', 'install', 'update'].includes(command)) {
|
|
|
2453
2481
|
log(` ${CYAN}doctor${RESET} Diagnostico: arquivos, Node, MCP arcane, login e servidor`);
|
|
2454
2482
|
log(` ${CYAN}register-mcp${RESET} Reescrever o registro do conteudo ao vivo (MCP arcane) no projeto`);
|
|
2455
2483
|
log(` ${CYAN}sync-codex${RESET} Gerar e verificar as skills locais do Codex CLI ($nome)`);
|
|
2456
|
-
log(` ${CYAN}historico${RESET} Estado da captura do trabalho (
|
|
2484
|
+
log(` ${CYAN}historico${RESET} Estado da captura do trabalho (prevista nos Termos de Uso; desliga em Minha Conta)`);
|
|
2457
2485
|
log(` ${CYAN}conectar-1password${RESET} Conectar o 1Password CLI (token lido do Ctrl+C, nunca digitado)`);
|
|
2458
2486
|
log('');
|
|
2459
2487
|
log(`${DIM}Primeira instalacao: https://arcane.arka.education/auroq${RESET}`);
|
package/installer/install.ps1
CHANGED
|
@@ -589,7 +589,7 @@ function Invoke-AuroqLogin {
|
|
|
589
589
|
# sucesso. Usado como pergunta de sim/nao, ele dizia "voce ja estava logado"
|
|
590
590
|
# pra quem nunca logou, pulava o portao e deixava a conta sem acesso chegar ate
|
|
591
591
|
# a criacao da pasta.
|
|
592
|
-
& (Get-AuroqNpx) -y auroq-os@2.6.
|
|
592
|
+
& (Get-AuroqNpx) -y auroq-os@2.6.9 check-access
|
|
593
593
|
if ($LASTEXITCODE -ne 0) {
|
|
594
594
|
Write-AuroqLog 'login' 'recusado'
|
|
595
595
|
Write-Host ''
|
|
@@ -677,7 +677,7 @@ function Invoke-AuroqInit {
|
|
|
677
677
|
if ($env:AUROQ_INSTALL_DRY_RUN) { Write-AuroqOk 'Sistema - seria montado aqui'; return }
|
|
678
678
|
|
|
679
679
|
Set-Location $script:AuroqPastaAlvo
|
|
680
|
-
& (Get-AuroqNpx) -y auroq-os@2.6.
|
|
680
|
+
& (Get-AuroqNpx) -y auroq-os@2.6.9 instalar
|
|
681
681
|
if ($LASTEXITCODE -ne 0) {
|
|
682
682
|
Write-AuroqLog 'init' 'falhou'
|
|
683
683
|
Write-AuroqErro 'A montagem do sistema parou no meio.' 'Rode o mesmo comando de novo. Se repetir, mande pro suporte o arquivo install.log da pasta .auroq.'
|
package/installer/install.sh
CHANGED
|
@@ -219,9 +219,9 @@ auroq_tem_terminal() {
|
|
|
219
219
|
# recebem pedaco do script no lugar da resposta dele.
|
|
220
220
|
auroq_npx_aluno() {
|
|
221
221
|
if [ -t 0 ]; then
|
|
222
|
-
npx -y auroq-os@2.6.
|
|
222
|
+
npx -y auroq-os@2.6.9 "$@"
|
|
223
223
|
else
|
|
224
|
-
npx -y auroq-os@2.6.
|
|
224
|
+
npx -y auroq-os@2.6.9 "$@" < /dev/tty
|
|
225
225
|
fi
|
|
226
226
|
}
|
|
227
227
|
|
package/lib/ahi/historico.mjs
CHANGED
|
@@ -5,7 +5,7 @@ const require = createRequire(import.meta.url);
|
|
|
5
5
|
const runtime = require('../../.claude/hooks/ahi/runtime.cjs');
|
|
6
6
|
export function run(argv = [], cwd = process.cwd()) {
|
|
7
7
|
const host = argv.includes('--codex') ? 'codex' : 'claude-code';
|
|
8
|
-
if (['pausar', 'pause'].includes(argv[0])) return { ok: false, code: 'NO_PAUSE', error: '
|
|
8
|
+
if (['pausar', 'pause'].includes(argv[0])) return { ok: false, code: 'NO_PAUSE', error: 'Nao ha pausa por aqui. Para nao guardar suas conversas, desligue "Guardar minhas conversas" em Minha Conta (arcane.arka.education/conta) ou peca ao agente para registrar "nao". Nao e preciso desligar o MCP nem os hooks; direitos de acesso e exclusao continuam disponiveis.' };
|
|
9
9
|
if (['sessoes', 'sessions', 'timeline', 'busca', 'search', 'exportar', 'export', 'excluir', 'delete'].includes(argv[0])) return runRemote(argv, cwd);
|
|
10
10
|
if (argv[0] && !['status', '--codex'].includes(argv[0])) return { ok: false, code: 'UNKNOWN_COMMAND', error: 'Use auroq-os historico status [--codex].' };
|
|
11
11
|
try { return runtime.status(cwd, host); } catch { return { ok: false, capture: 'error', reason: 'DIAGNOSTIC_UNAVAILABLE' }; }
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
// Barra de status do Claude Code do aluno (2.6.8). Mora em ~/.auroq/barra/barra.cjs e e o
|
|
4
|
+
// `statusLine.command` do ~/.claude/settings.json: vale em qualquer terminal e no app Auroq OS.
|
|
5
|
+
//
|
|
6
|
+
// node barra.cjs desenha a barra (o Claude Code manda o JSON da sessao na entrada)
|
|
7
|
+
// node barra.cjs titulo "Texto" grava o titulo da conversa (uma vez por sessao; a IA chama)
|
|
8
|
+
// node barra.cjs topico pedaco da barra: o titulo desta sessao
|
|
9
|
+
// node barra.cjs data pedaco da barra: "sex 16/10 11:39"
|
|
10
|
+
//
|
|
11
|
+
// Quem desenha e o ccstatusline (MIT, versao travada, copiado pelo `auroq-os` para ./ccstatusline).
|
|
12
|
+
// Nada aqui usa rede. Qualquer falha sai em silencio: barra vazia, nunca erro na tela do aluno.
|
|
13
|
+
const fs = require('node:fs');
|
|
14
|
+
const os = require('node:os');
|
|
15
|
+
const path = require('node:path');
|
|
16
|
+
const { spawn } = require('node:child_process');
|
|
17
|
+
|
|
18
|
+
const PASTA = __dirname;
|
|
19
|
+
const TITULOS = path.join(PASTA, 'titulos');
|
|
20
|
+
const MOTOR = path.join(PASTA, 'ccstatusline', 'dist', 'ccstatusline.js');
|
|
21
|
+
const LAYOUT = path.join(PASTA, 'ccstatusline.json');
|
|
22
|
+
const SESSAO_VALIDA = /^[A-Za-z0-9._-]{1,128}$/;
|
|
23
|
+
const SETE_DIAS_MS = 7 * 24 * 60 * 60 * 1000;
|
|
24
|
+
|
|
25
|
+
function lerEntrada() {
|
|
26
|
+
return new Promise(resolve => {
|
|
27
|
+
if (process.stdin.isTTY) return resolve('');
|
|
28
|
+
const partes = [];
|
|
29
|
+
process.stdin.on('data', p => partes.push(p));
|
|
30
|
+
process.stdin.on('end', () => resolve(Buffer.concat(partes).toString('utf8')));
|
|
31
|
+
process.stdin.on('error', () => resolve(''));
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function sessaoDoJson(texto) {
|
|
36
|
+
try {
|
|
37
|
+
const id = JSON.parse(texto).session_id;
|
|
38
|
+
return typeof id === 'string' && SESSAO_VALIDA.test(id) ? id : null;
|
|
39
|
+
} catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function arquivoDoTitulo(sessao) {
|
|
45
|
+
return path.join(TITULOS, `${sessao}.txt`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function gravarTitulo(texto) {
|
|
49
|
+
const sessao = process.env.CLAUDE_CODE_SESSION_ID;
|
|
50
|
+
const titulo = String(texto || '').replace(/[\r\n\t]+/g, ' ').replace(/[\u0000-\u001f\u007f]/g, '').trim().slice(0, 60);
|
|
51
|
+
if (!titulo || !sessao || !SESSAO_VALIDA.test(sessao)) return;
|
|
52
|
+
fs.mkdirSync(TITULOS, { recursive: true });
|
|
53
|
+
const alvo = arquivoDoTitulo(sessao);
|
|
54
|
+
// Uma vez por sessao: o primeiro titulo fica, como o do Euriler.
|
|
55
|
+
try {
|
|
56
|
+
fs.writeFileSync(alvo, `${titulo}\n`, { flag: 'wx' });
|
|
57
|
+
} catch (e) {
|
|
58
|
+
if (e.code !== 'EEXIST') throw e;
|
|
59
|
+
}
|
|
60
|
+
limparTitulosVelhos();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function limparTitulosVelhos() {
|
|
64
|
+
const limite = Date.now() - SETE_DIAS_MS;
|
|
65
|
+
for (const nome of fs.readdirSync(TITULOS)) {
|
|
66
|
+
const arquivo = path.join(TITULOS, nome);
|
|
67
|
+
try {
|
|
68
|
+
if (fs.statSync(arquivo).mtimeMs < limite) fs.unlinkSync(arquivo);
|
|
69
|
+
} catch {}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function mostrarTitulo(entrada) {
|
|
74
|
+
const sessao = sessaoDoJson(entrada);
|
|
75
|
+
if (!sessao) return '';
|
|
76
|
+
try {
|
|
77
|
+
const primeira = fs.readFileSync(arquivoDoTitulo(sessao), 'utf8').split(/\r?\n/)[0] || '';
|
|
78
|
+
return [...primeira].slice(0, 40).join('');
|
|
79
|
+
} catch {
|
|
80
|
+
return '';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const DIAS = ['dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sáb'];
|
|
85
|
+
function dataCurta(agora = new Date()) {
|
|
86
|
+
const dois = n => String(n).padStart(2, '0');
|
|
87
|
+
return `${DIAS[agora.getDay()]} ${dois(agora.getDate())}/${dois(agora.getMonth() + 1)} ${dois(agora.getHours())}:${dois(agora.getMinutes())}`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Dentro do app Auroq OS (ou do Orca), o app usa a statusLine para ler o uso da conta ao vivo.
|
|
91
|
+
// A barra ocupou esse lugar, entao repassa o mesmo JSON para o script do app, sem esperar por ele.
|
|
92
|
+
function scriptDoApp() {
|
|
93
|
+
if (!process.env.ORCA_PANE_KEY || (!process.env.ORCA_AGENT_HOOK_PORT && !process.env.ORCA_AGENT_HOOK_ENDPOINT)) return null;
|
|
94
|
+
const nome = process.platform === 'win32' ? 'claude-statusline.cmd' : 'claude-statusline.sh';
|
|
95
|
+
const pastas = [];
|
|
96
|
+
if (process.env.ORCA_AGENT_HOOK_ENDPOINT) pastas.push(path.dirname(process.env.ORCA_AGENT_HOOK_ENDPOINT));
|
|
97
|
+
pastas.push(path.join(os.homedir(), '.auroq-os', 'agent-hooks'), path.join(os.homedir(), '.orca', 'agent-hooks'));
|
|
98
|
+
for (const pasta of pastas) {
|
|
99
|
+
const alvo = path.join(pasta, nome);
|
|
100
|
+
if (fs.existsSync(alvo)) return alvo;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function repassarAoApp(entrada) {
|
|
106
|
+
const alvo = scriptDoApp();
|
|
107
|
+
if (!alvo || !entrada) return;
|
|
108
|
+
try {
|
|
109
|
+
const filho = process.platform === 'win32'
|
|
110
|
+
? spawn(process.env.ComSpec || 'cmd.exe', ['/d', '/c', alvo], { stdio: ['pipe', 'ignore', 'ignore'], windowsHide: true, detached: true })
|
|
111
|
+
: spawn('/bin/sh', [alvo], { stdio: ['pipe', 'ignore', 'ignore'], detached: true });
|
|
112
|
+
filho.on('error', () => {});
|
|
113
|
+
filho.stdin.on('error', () => {});
|
|
114
|
+
filho.stdin.end(entrada);
|
|
115
|
+
filho.unref();
|
|
116
|
+
} catch {}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function desenhar(entrada) {
|
|
120
|
+
return new Promise(resolve => {
|
|
121
|
+
if (!fs.existsSync(MOTOR)) return resolve();
|
|
122
|
+
let filho;
|
|
123
|
+
try {
|
|
124
|
+
filho = spawn(process.execPath, [MOTOR, '--config', LAYOUT], { stdio: ['pipe', 'inherit', 'ignore'], windowsHide: true });
|
|
125
|
+
} catch {
|
|
126
|
+
return resolve();
|
|
127
|
+
}
|
|
128
|
+
filho.on('error', () => resolve());
|
|
129
|
+
filho.on('close', () => resolve());
|
|
130
|
+
filho.stdin.on('error', () => {});
|
|
131
|
+
filho.stdin.end(entrada);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function principal() {
|
|
136
|
+
const [modo, ...resto] = process.argv.slice(2);
|
|
137
|
+
if (modo === 'titulo') return gravarTitulo(resto.join(' '));
|
|
138
|
+
if (modo === 'data') return process.stdout.write(dataCurta());
|
|
139
|
+
const entrada = await lerEntrada();
|
|
140
|
+
if (modo === 'topico') return process.stdout.write(mostrarTitulo(entrada));
|
|
141
|
+
repassarAoApp(entrada);
|
|
142
|
+
await desenhar(entrada);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (require.main === module) {
|
|
146
|
+
principal().catch(() => {}).finally(() => { process.exitCode = 0; });
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
module.exports = { dataCurta, sessaoDoJson, mostrarTitulo, gravarTitulo, scriptDoApp };
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 4,
|
|
3
|
+
"lines": [
|
|
4
|
+
[
|
|
5
|
+
{
|
|
6
|
+
"id": "l1-model",
|
|
7
|
+
"type": "model",
|
|
8
|
+
"color": "brightCyan",
|
|
9
|
+
"bold": true,
|
|
10
|
+
"rawValue": true
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"id": "l1-effort",
|
|
14
|
+
"type": "thinking-effort",
|
|
15
|
+
"color": "magenta"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "l1-skill",
|
|
19
|
+
"type": "skills",
|
|
20
|
+
"color": "brightBlack",
|
|
21
|
+
"metadata": {
|
|
22
|
+
"hide": "empty"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "l1-topic",
|
|
27
|
+
"type": "custom-command",
|
|
28
|
+
"color": "yellow",
|
|
29
|
+
"commandPath": "{{BARRA}} topico",
|
|
30
|
+
"timeout": 1000
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "l1-flex",
|
|
34
|
+
"type": "flex-separator"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "l1-status",
|
|
38
|
+
"type": "claude-status",
|
|
39
|
+
"color": "brightBlack"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "l1-clock-ico",
|
|
43
|
+
"type": "custom-text",
|
|
44
|
+
"customText": "⏱",
|
|
45
|
+
"color": "brightYellow",
|
|
46
|
+
"merge": "no-padding"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "l1-clock",
|
|
50
|
+
"type": "session-clock",
|
|
51
|
+
"color": "brightYellow",
|
|
52
|
+
"rawValue": true
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
[
|
|
56
|
+
{
|
|
57
|
+
"id": "l2-cwd",
|
|
58
|
+
"type": "current-working-dir",
|
|
59
|
+
"color": "blue",
|
|
60
|
+
"metadata": {
|
|
61
|
+
"abbreviateHome": "true"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "l2-branch",
|
|
66
|
+
"type": "git-branch",
|
|
67
|
+
"color": "green",
|
|
68
|
+
"metadata": {
|
|
69
|
+
"hide": "no-git"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"id": "l2-changes",
|
|
74
|
+
"type": "git-changes",
|
|
75
|
+
"color": "yellow",
|
|
76
|
+
"metadata": {
|
|
77
|
+
"hide": "zero"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
[
|
|
82
|
+
{
|
|
83
|
+
"id": "l3-ctx",
|
|
84
|
+
"type": "context-bar",
|
|
85
|
+
"color": "brightMagenta"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"id": "l3-flex",
|
|
89
|
+
"type": "flex-separator"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "l3-cache",
|
|
93
|
+
"type": "cache-timer",
|
|
94
|
+
"color": "brightBlack",
|
|
95
|
+
"metadata": {
|
|
96
|
+
"ttlSeconds": "3600"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
[
|
|
101
|
+
{
|
|
102
|
+
"id": "l4-5h-lbl",
|
|
103
|
+
"type": "custom-text",
|
|
104
|
+
"customText": "5h ",
|
|
105
|
+
"color": "brightBlack",
|
|
106
|
+
"merge": "no-padding",
|
|
107
|
+
"metadata": {
|
|
108
|
+
"hide": "merge-target-hidden"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"id": "l4-5h",
|
|
113
|
+
"type": "session-usage",
|
|
114
|
+
"color": "brightGreen",
|
|
115
|
+
"rawValue": true,
|
|
116
|
+
"metadata": {
|
|
117
|
+
"hide": "no-data"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "l4-5hr-lbl",
|
|
122
|
+
"type": "custom-text",
|
|
123
|
+
"customText": "↻ ",
|
|
124
|
+
"color": "brightBlack",
|
|
125
|
+
"merge": "no-padding",
|
|
126
|
+
"metadata": {
|
|
127
|
+
"hide": "merge-target-hidden"
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"id": "l4-5hr",
|
|
132
|
+
"type": "reset-timer",
|
|
133
|
+
"color": "brightBlack",
|
|
134
|
+
"rawValue": true,
|
|
135
|
+
"metadata": {
|
|
136
|
+
"hide": "no-data"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"id": "l4-sep1",
|
|
141
|
+
"type": "separator",
|
|
142
|
+
"character": "|"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"id": "l4-wk-lbl",
|
|
146
|
+
"type": "custom-text",
|
|
147
|
+
"customText": "semana ",
|
|
148
|
+
"color": "brightBlack",
|
|
149
|
+
"merge": "no-padding",
|
|
150
|
+
"metadata": {
|
|
151
|
+
"hide": "merge-target-hidden"
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"id": "l4-wk",
|
|
156
|
+
"type": "weekly-usage",
|
|
157
|
+
"color": "brightRed",
|
|
158
|
+
"rawValue": true,
|
|
159
|
+
"metadata": {
|
|
160
|
+
"hide": "no-data"
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"id": "l4-wkr-lbl",
|
|
165
|
+
"type": "custom-text",
|
|
166
|
+
"customText": "↻ ",
|
|
167
|
+
"color": "brightBlack",
|
|
168
|
+
"merge": "no-padding",
|
|
169
|
+
"metadata": {
|
|
170
|
+
"hide": "merge-target-hidden"
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"id": "l4-wkr",
|
|
175
|
+
"type": "weekly-reset-timer",
|
|
176
|
+
"color": "brightBlack",
|
|
177
|
+
"rawValue": true,
|
|
178
|
+
"metadata": {
|
|
179
|
+
"hide": "no-data"
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"id": "l4-flex",
|
|
184
|
+
"type": "flex-separator"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"id": "l4-date",
|
|
188
|
+
"type": "custom-command",
|
|
189
|
+
"color": "brightBlack",
|
|
190
|
+
"commandPath": "{{BARRA}} data",
|
|
191
|
+
"timeout": 1000
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
],
|
|
195
|
+
"flexMode": "full",
|
|
196
|
+
"colorLevel": 3,
|
|
197
|
+
"defaultPadding": " "
|
|
198
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// Barra de status do Claude Code do aluno (2.6.8): a mesma barra do Euriler (modelo, esforco,
|
|
3
|
+
// titulo da conversa, pasta, branch, contexto, cache, uso de 5 h e da semana, data), em qualquer
|
|
4
|
+
// terminal do Mac ou do Windows e dentro do app Auroq OS.
|
|
5
|
+
//
|
|
6
|
+
// O que faz, sempre no HOME do aluno (nunca na pasta do negocio):
|
|
7
|
+
// - copia o ccstatusline travado (MIT, sem dependencias) para ~/.auroq/barra/ccstatusline;
|
|
8
|
+
// - grava ~/.auroq/barra/barra.cjs (quem roda a cada pintura) e o layout ccstatusline.json;
|
|
9
|
+
// - liga `statusLine` no ~/.claude/settings.json, mexendo so nessa chave.
|
|
10
|
+
// Nunca troca uma barra que o aluno ja tinha. Ocupa o lugar so quando ele esta vazio, quando ja e
|
|
11
|
+
// a nossa ou quando e o leitor de uso do app Auroq OS/Orca (que nao desenha nada; a barra repassa
|
|
12
|
+
// o JSON para ele). Se o aluno tirar a barra depois, ela nao volta. `~/.auroq/sem-barra` desliga.
|
|
13
|
+
const fs = require('node:fs');
|
|
14
|
+
const os = require('node:os');
|
|
15
|
+
const path = require('node:path');
|
|
16
|
+
const crypto = require('node:crypto');
|
|
17
|
+
|
|
18
|
+
const VERSAO_CCSTATUSLINE = '2.2.30';
|
|
19
|
+
const AQUI = __dirname;
|
|
20
|
+
|
|
21
|
+
const ehNossa = comando => /[\\/]\.auroq[\\/]barra[\\/]barra\.cjs/.test(comando);
|
|
22
|
+
const ehDoApp = comando => /agent-hooks[\\/]+claude-statusline/.test(comando);
|
|
23
|
+
const sha = texto => crypto.createHash('sha256').update(texto).digest('hex');
|
|
24
|
+
|
|
25
|
+
function gravarAtomico(arquivo, conteudo) {
|
|
26
|
+
const tmp = `${arquivo}.${process.pid}.tmp`;
|
|
27
|
+
fs.writeFileSync(tmp, conteudo);
|
|
28
|
+
fs.renameSync(tmp, arquivo);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function lerJson(arquivo) {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(fs.readFileSync(arquivo, 'utf8').replace(/^/, ''));
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function origemPadrao() {
|
|
40
|
+
return path.dirname(require.resolve('ccstatusline/package.json'));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function copiarMotor(origem, destino) {
|
|
44
|
+
const versao = lerJson(path.join(origem, 'package.json'))?.version;
|
|
45
|
+
if (versao !== VERSAO_CCSTATUSLINE) throw new Error(`ccstatusline ${versao || 'ausente'} no pacote; esperado ${VERSAO_CCSTATUSLINE}`);
|
|
46
|
+
const jaTem = lerJson(path.join(destino, 'package.json'))?.version === VERSAO_CCSTATUSLINE
|
|
47
|
+
&& fs.existsSync(path.join(destino, 'dist', 'ccstatusline.js'));
|
|
48
|
+
if (jaTem) return false;
|
|
49
|
+
// Monta ao lado e troca de uma vez: uma sessao aberta nunca le o motor pela metade.
|
|
50
|
+
const novo = `${destino}.novo-${process.pid}`;
|
|
51
|
+
fs.rmSync(novo, { recursive: true, force: true });
|
|
52
|
+
fs.mkdirSync(path.join(novo, 'dist'), { recursive: true });
|
|
53
|
+
for (const arquivo of ['package.json', 'LICENSE', path.join('dist', 'ccstatusline.js')]) {
|
|
54
|
+
if (fs.existsSync(path.join(origem, arquivo))) fs.copyFileSync(path.join(origem, arquivo), path.join(novo, arquivo));
|
|
55
|
+
}
|
|
56
|
+
const velho = `${destino}.velho-${process.pid}`;
|
|
57
|
+
try {
|
|
58
|
+
if (fs.existsSync(destino)) fs.renameSync(destino, velho);
|
|
59
|
+
fs.renameSync(novo, destino);
|
|
60
|
+
} catch {
|
|
61
|
+
// Windows com o motor aberto por outra sessao: copia por cima.
|
|
62
|
+
if (fs.existsSync(velho) && !fs.existsSync(destino)) fs.renameSync(velho, destino);
|
|
63
|
+
fs.cpSync(novo, destino, { recursive: true, force: true });
|
|
64
|
+
}
|
|
65
|
+
fs.rmSync(novo, { recursive: true, force: true });
|
|
66
|
+
fs.rmSync(velho, { recursive: true, force: true });
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function instalarBarra({
|
|
71
|
+
home = os.homedir(),
|
|
72
|
+
claudeDir = process.env.CLAUDE_CONFIG_DIR || path.join(home, '.claude'),
|
|
73
|
+
origem = null,
|
|
74
|
+
} = {}) {
|
|
75
|
+
if (fs.existsSync(path.join(home, '.auroq', 'sem-barra'))) return { estado: 'desligada' };
|
|
76
|
+
|
|
77
|
+
const pasta = path.join(home, '.auroq', 'barra');
|
|
78
|
+
const script = path.join(pasta, 'barra.cjs').split(path.sep).join('/');
|
|
79
|
+
// Aspas servem ao cmd.exe e aos shells POSIX; caminho com aspas, $, crase ou quebra de linha fica de fora.
|
|
80
|
+
if (/["\r\n`$%]/.test(script)) return { estado: 'caminho-nao-suportado', detalhe: script };
|
|
81
|
+
const comando = `node "${script}"`;
|
|
82
|
+
|
|
83
|
+
fs.mkdirSync(pasta, { recursive: true });
|
|
84
|
+
const motorNovo = copiarMotor(origem || origemPadrao(), path.join(pasta, 'ccstatusline'));
|
|
85
|
+
gravarAtomico(path.join(pasta, 'barra.cjs'), fs.readFileSync(path.join(AQUI, 'barra.cjs')));
|
|
86
|
+
|
|
87
|
+
// Layout: o nosso, a menos que o aluno tenha mexido no que gravamos da ultima vez.
|
|
88
|
+
const registroPath = path.join(pasta, 'instalacao.json');
|
|
89
|
+
const registro = lerJson(registroPath) || {};
|
|
90
|
+
const layoutPath = path.join(pasta, 'ccstatusline.json');
|
|
91
|
+
const layout = fs.readFileSync(path.join(AQUI, 'ccstatusline.json'), 'utf8').split('{{BARRA}}').join(comando.replace(/"/g, '\\"'));
|
|
92
|
+
const layoutAtual = fs.existsSync(layoutPath) ? fs.readFileSync(layoutPath, 'utf8') : null;
|
|
93
|
+
const layoutDoAluno = layoutAtual !== null && registro.layoutSha && sha(layoutAtual) !== registro.layoutSha && sha(layoutAtual) !== sha(layout);
|
|
94
|
+
if (!layoutDoAluno && layoutAtual !== layout) gravarAtomico(layoutPath, layout);
|
|
95
|
+
|
|
96
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
97
|
+
let settings = {};
|
|
98
|
+
if (fs.existsSync(settingsPath)) {
|
|
99
|
+
settings = lerJson(settingsPath);
|
|
100
|
+
if (!settings || typeof settings !== 'object' || Array.isArray(settings)) {
|
|
101
|
+
return { estado: 'settings-ilegivel', detalhe: settingsPath };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const atual = settings.statusLine && typeof settings.statusLine.command === 'string' ? settings.statusLine.command : '';
|
|
105
|
+
let estado;
|
|
106
|
+
if (!atual) estado = registro.ligadaEm ? 'tirada-pelo-aluno' : 'ligada';
|
|
107
|
+
else if (ehNossa(atual)) estado = 'em-dia';
|
|
108
|
+
else if (ehDoApp(atual)) estado = 'ligada';
|
|
109
|
+
else estado = 'barra-do-aluno';
|
|
110
|
+
|
|
111
|
+
const desejada = { type: 'command', command: comando, padding: 0, refreshInterval: 10 };
|
|
112
|
+
if (estado === 'ligada' || (estado === 'em-dia' && JSON.stringify(settings.statusLine) !== JSON.stringify({ ...settings.statusLine, ...desejada }))) {
|
|
113
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
114
|
+
gravarAtomico(settingsPath, `${JSON.stringify({ ...settings, statusLine: { ...(estado === 'em-dia' ? settings.statusLine : {}), ...desejada } }, null, 2)}\n`);
|
|
115
|
+
if (estado === 'em-dia') estado = 'atualizada';
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const novoRegistro = {
|
|
119
|
+
versaoCcstatusline: VERSAO_CCSTATUSLINE,
|
|
120
|
+
layoutSha: layoutDoAluno ? registro.layoutSha : sha(layout),
|
|
121
|
+
ligadaEm: registro.ligadaEm || (estado === 'ligada' ? new Date().toISOString() : undefined),
|
|
122
|
+
};
|
|
123
|
+
gravarAtomico(registroPath, `${JSON.stringify(novoRegistro, null, 2)}\n`);
|
|
124
|
+
return { estado, comando, motorNovo, layoutDoAluno: Boolean(layoutDoAluno) };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
module.exports = { instalarBarra, ehNossa, ehDoApp, VERSAO_CCSTATUSLINE };
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schema": 1,
|
|
3
3
|
"algorithm": "sha256",
|
|
4
4
|
"scope": "packaged-runtime-and-cascas",
|
|
5
|
-
"version": "2.6.
|
|
5
|
+
"version": "2.6.9",
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"path": ".auroq-core/constitution.md",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"path": ".auroq-core/core-config.yaml",
|
|
13
|
-
"sha256": "
|
|
13
|
+
"sha256": "619e43f8d9e495c48269650e1e96b52f70d455d277fd3251d2c5f17a81ef7a69"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"path": ".auroq-core/core/synapse/context/context-builder.js",
|
|
@@ -210,7 +210,7 @@
|
|
|
210
210
|
},
|
|
211
211
|
{
|
|
212
212
|
"path": "bin/auroq-os.js",
|
|
213
|
-
"sha256": "
|
|
213
|
+
"sha256": "ed26b60a9309f55f5175cc8469c71e28f3bd58bcb60da05fae8dccbe92ac5892"
|
|
214
214
|
},
|
|
215
215
|
{
|
|
216
216
|
"path": "lib/ahi/client.mjs",
|
|
@@ -218,7 +218,7 @@
|
|
|
218
218
|
},
|
|
219
219
|
{
|
|
220
220
|
"path": "lib/ahi/historico.mjs",
|
|
221
|
-
"sha256": "
|
|
221
|
+
"sha256": "909c0d0b5f6c19a75d1c278b639e107d8f29efb015aac91464b3168d23388556"
|
|
222
222
|
},
|
|
223
223
|
{
|
|
224
224
|
"path": "lib/ahi/install.cjs",
|
|
@@ -228,6 +228,18 @@
|
|
|
228
228
|
"path": "lib/auth.js",
|
|
229
229
|
"sha256": "5f1ddefbf2d4b9005e562380b40525e5bf823641e05a7bdb71568e15a5179869"
|
|
230
230
|
},
|
|
231
|
+
{
|
|
232
|
+
"path": "lib/barra/barra.cjs",
|
|
233
|
+
"sha256": "30fa51fd3561b8da7e17dd9b35fd55739d0a33d358dbbd99583f6b0eec1b576e"
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
"path": "lib/barra/ccstatusline.json",
|
|
237
|
+
"sha256": "590573ff67c95cac2294f987789a4646cca6ccf0e85bc558fa6af22d0608296e"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"path": "lib/barra/index.js",
|
|
241
|
+
"sha256": "a72edfd62af60bfb5b314300a618cbb3fc8e7e30b9092ecb83ff366a776fee90"
|
|
242
|
+
},
|
|
231
243
|
{
|
|
232
244
|
"path": "lib/codex-windows.cjs",
|
|
233
245
|
"sha256": "d6307d0106bad3e69142052d6450cef3f6252544049d3f3340aec55fc99005d1"
|
|
@@ -262,7 +274,7 @@
|
|
|
262
274
|
},
|
|
263
275
|
{
|
|
264
276
|
"path": "package.json",
|
|
265
|
-
"sha256": "
|
|
277
|
+
"sha256": "ffc469c06ce3d8b5ac8c1353e3cbf412169dd420b8de3341ee4e648effc96768"
|
|
266
278
|
},
|
|
267
279
|
{
|
|
268
280
|
"path": "scripts/build-pack.mjs",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auroq-os",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.9",
|
|
4
4
|
"arcaneMcpPin": "0.7.0",
|
|
5
5
|
"description": "Auroq OS — Sistema Operacional de IA para Experts",
|
|
6
6
|
"bin": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"auroq:sync:codex:check": "npm run sync:codex:check",
|
|
20
20
|
"auroq:validate": "npm run validate:hybrid",
|
|
21
21
|
"validate:hybrid": "node scripts/validate-hybrid.mjs",
|
|
22
|
-
"lint": "node --check bin/auroq-os.js && node --check lib/auth.js && node --check lib/diagnostico.js && node --check lib/credentials.js && node --check lib/onepassword.js && node --check lib/supabase.js && node --check scripts/sync-codex-skills.mjs && node --check scripts/validate-hybrid.mjs && node --check scripts/prepack-casca.mjs && node --check scripts/postpack-casca.mjs && node --check scripts/assert-mcp-pin.mjs && node --check lib/telemetry.mjs && node --check scripts/synapse-hashes.mjs && node --check lib/ahi/historico.mjs && node --check .claude/hooks/ahi-capture.cjs && node --check .claude/hooks/ahi/security.cjs && node --check .claude/hooks/ahi/runtime.cjs && node --check .claude/hooks/ahi/worker.cjs && node --check lib/ahi/install.cjs && node --check lib/codex-windows.cjs && node --check .claude/hooks/ahi/auth-config.cjs && node --check lib/ahi/client.mjs && node --check scripts/build-pack.mjs && node --check scripts/assert-native-release.mjs && node --check scripts/runtime-integrity.mjs && node --check scripts/pack-state.mjs",
|
|
22
|
+
"lint": "node --check bin/auroq-os.js && node --check lib/barra/index.js && node --check lib/barra/barra.cjs && node --check lib/auth.js && node --check lib/diagnostico.js && node --check lib/credentials.js && node --check lib/onepassword.js && node --check lib/supabase.js && node --check scripts/sync-codex-skills.mjs && node --check scripts/validate-hybrid.mjs && node --check scripts/prepack-casca.mjs && node --check scripts/postpack-casca.mjs && node --check scripts/assert-mcp-pin.mjs && node --check lib/telemetry.mjs && node --check scripts/synapse-hashes.mjs && node --check lib/ahi/historico.mjs && node --check .claude/hooks/ahi-capture.cjs && node --check .claude/hooks/ahi/security.cjs && node --check .claude/hooks/ahi/runtime.cjs && node --check .claude/hooks/ahi/worker.cjs && node --check lib/ahi/install.cjs && node --check lib/codex-windows.cjs && node --check .claude/hooks/ahi/auth-config.cjs && node --check lib/ahi/client.mjs && node --check scripts/build-pack.mjs && node --check scripts/assert-native-release.mjs && node --check scripts/runtime-integrity.mjs && node --check scripts/pack-state.mjs",
|
|
23
23
|
"typecheck": "npm run validate:hybrid",
|
|
24
24
|
"test": "node --test tests/*.test.mjs",
|
|
25
25
|
"release:verify": "node scripts/assert-mcp-pin.mjs && node scripts/assert-native-release.mjs",
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
],
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@supabase/supabase-js": "^2.103.0",
|
|
60
|
+
"ccstatusline": "2.2.30",
|
|
60
61
|
"fs-extra": "^11.3.0",
|
|
61
62
|
"js-yaml": "^4.3.2",
|
|
62
63
|
"prompts": "^2.4.2"
|