@vitortrack777/djinnai 0.0.0-stage → 0.6.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 vitortrack
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,138 @@
1
- # Temporary Holding Version
1
+ <h1 align="center">DjinnAI</h1>
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ <p align="center">
4
+ Uma tela local para conversar com o agente do <strong>Claude Code</strong> dentro do seu projeto.<br>
5
+ O agente pode ser o <strong>Claude</strong> ou um modelo do <strong>Ollama</strong>, e os comandos do ambiente ficam a um <code>/</code> de distância.
6
+ </p>
7
+
8
+ <p align="center">
9
+ <a href="https://www.npmjs.com/package/@vitortrack777/djinnai"><img src="https://img.shields.io/npm/v/@vitortrack777/djinnai.svg" alt="versão no npm"></a>
10
+ <img src="https://img.shields.io/node/v/@vitortrack777/djinnai.svg" alt="node">
11
+ <a href="LICENSE"><img src="https://img.shields.io/npm/l/@vitortrack777/djinnai.svg" alt="licença MIT"></a>
12
+ </p>
13
+
14
+ ```bash
15
+ npm install -g @vitortrack777/djinnai
16
+ cd meu-projeto
17
+ djinn # abre o aplicativo (djinn --navegador abre no navegador)
18
+ djinn restart api # os comandos do ambiente continuam funcionando direto no terminal
19
+ ```
20
+
21
+ ---
22
+
23
+ ## Como funciona
24
+
25
+ `djinn` sobe um servidor em `127.0.0.1`, numa porta livre, e abre a tela num **aplicativo de desktop**
26
+ (Electron, que vem com o pacote), no Linux, no Windows e no macOS, sem depender de navegador.
27
+ **Fechar a janela encerra o DjinnAI.** O endereço também aparece no terminal: dá para abrir no
28
+ navegador ao mesmo tempo, e as duas telas mostram a mesma conversa.
29
+
30
+ | Comando | Abre |
31
+ |---|---|
32
+ | `djinn` (ou `djinnai`) | A janela do aplicativo. Se ela não abrir (sem ambiente gráfico, por exemplo), cai no navegador padrão |
33
+ | `djinn --navegador` | Só o navegador padrão, como numa aba comum |
34
+
35
+ A conversa é
36
+ uma sessão do Claude Code aberta na raiz do projeto, no mesmo protocolo que o Agent SDK usa
37
+ (`stream-json` de entrada e saída). Por isso a tela tem o que o Claude Code tem:
38
+
39
+ - o texto aparece enquanto o agente escreve, com raciocínio, ferramentas, tempo e tokens;
40
+ - o agente **pede permissão** na tela antes de editar ou rodar comando, mostrando o comando ou o diff;
41
+ - o agente **faz perguntas** com opções e **apresenta o plano** para você aprovar no modo Planejar;
42
+ - dá para **mandar mensagem com o agente trabalhando**: ela entra na fila e o agente lê assim que puder;
43
+ - **prints colados** (Ctrl+V) ou arrastados para a tela vão junto com a mensagem;
44
+ - o `/` lista as skills e comandos do Claude Code do projeto, além dos comandos do ambiente;
45
+ - recarregar a página não perde a conversa, que continua até você digitar `/novo` ou fechar o DjinnAI.
46
+
47
+ Quem decide o que fazer é o agente. O DjinnAI não tem templates nem validadores próprios: ele só repassa
48
+ o pedido, o modelo, o esforço e o modo de permissão, mais o contexto do projeto descrito abaixo.
49
+
50
+ ## Requisitos
51
+
52
+ | Requisito | Para quê |
53
+ |---|---|
54
+ | [Node.js](https://nodejs.org) 22.12+ (recomendado: 24 LTS) | Executar o DjinnAI e o Electron |
55
+ | [Claude Code](https://docs.anthropic.com/claude-code) instalado e logado (`claude`) | O agente |
56
+ | [Ollama](https://ollama.com) 0.14+ (opcional) | Usar modelos do Ollama como agente |
57
+ | Script `appDev` ou `app` na raiz (opcional) | Os comandos do ambiente (`/start`, `/logs`…) |
58
+
59
+ ## A tela
60
+
61
+ | Parte | O que faz |
62
+ |---|---|
63
+ | Contexto e **Nova conversa**, no topo | Quantos tokens a conversa já carrega (o agente relê tudo a cada passo). Acima de 100k a tela sugere uma conversa nova; o botão (ou `/novo`) começa uma sessão limpa. Cada `djinn` também começa numa sessão nova |
64
+ | Caixa de pedido | Enter envia, Shift+Enter quebra a linha. Com o agente trabalhando, Enter põe a mensagem na fila e o botão vira **parar** |
65
+ | `/` | Lista `/novo` (conversa nova), os comandos do ambiente (`/start`, `/restart api`, `/logs --tail=100 api`, `/status`…) e as skills do Claude Code. A saída do ambiente aparece na tela, e o botão de parar encerra o comando (útil no `logs -f`) |
66
+ | Seletor de modelo | Os modelos que a sua conta do Claude Code oferece ou qualquer modelo instalado no Ollama. O modelo do Ollama roda **dentro do Claude Code**, com as mesmas ferramentas e os mesmos `CLAUDE.md` |
67
+ | Esforço | Baixo a Máximo, repassado como `--effort` (vale a partir da próxima mensagem com o agente parado) |
68
+ | Modo, no topo | **Planejar** (planeja e pede aprovação do plano; aprovar passa para Editar), **Perguntar** (pede permissão para cada edição e comando), **Editar** (edita sem perguntar; comandos fora das regras do projeto pedem permissão), **Automático** (o Claude Code decide o que é seguro). Muda na hora, mesmo no meio de uma resposta |
69
+
70
+ No cartão de permissão, **Permitir e não perguntar de novo** grava a regra sugerida pelo Claude Code, como no terminal.
71
+
72
+ Os comandos destrutivos do ambiente (`execute`, que recria o banco, e `auto-remove`, que apaga
73
+ volumes) não aparecem na tela. Use pelo terminal: `djinn execute <banco> arquivo.sql`.
74
+
75
+ ## Contexto que o agente recebe
76
+
77
+ O Claude Code já carrega os `CLAUDE.md`, as configurações do projeto (`.claude/`), as skills e o git
78
+ status. O DjinnAI acrescenta ao system prompt (`--append-system-prompt`):
79
+
80
+ - as pastas versionadas do projeto, até 4 níveis e no máximo 150, para o agente não gastar passos procurando;
81
+ - o conteúdo de `.djinn/contexto.md`, se existir, como instrução.
82
+
83
+ Use o `.djinn/contexto.md` para o que vale só para você e não pertence ao repositório: vocabulário do
84
+ domínio, armadilhas conhecidas, onde fica cada coisa, o card em andamento. Ele é lido no começo de
85
+ cada conversa: depois de editar, digite `/novo`.
86
+
87
+ ## Configuração
88
+
89
+ O modelo, o esforço e o modo escolhidos na tela ficam salvos em `.djinn/config.json`:
90
+
91
+ ```json
92
+ {
93
+ "model": "claude:opus",
94
+ "effort": "high",
95
+ "mode": "acceptEdits",
96
+ "ollamaUrl": "http://127.0.0.1:11434"
97
+ }
98
+ ```
99
+
100
+ O retorno bruto da última mensagem ao agente fica em `.djinn/last-turn.ndjson`, para diagnóstico.
101
+
102
+ | Variável de ambiente | Descrição |
103
+ |---|---|
104
+ | `DJINN_PORT` | Porta fixa no lugar de uma porta livre |
105
+ | `DJINN_APP_SCRIPT` | Script de ambiente no lugar de `appDev`/`app` |
106
+
107
+ Projetos que já têm `.detro/` continuam usando essa pasta, e `DETRO_PORT`/`DETRO_APP_SCRIPT` seguem valendo quando a variável `DJINN_` correspondente não está definida.
108
+
109
+ O DjinnAI remove `ANTHROPIC_API_KEY` do ambiente do agente: o uso conta na sua assinatura do Claude Code,
110
+ não na API paga. Com modelo de nuvem do Ollama (`:cloud`), o código lido pelo agente sai da máquina.
111
+
112
+ ## Segurança
113
+
114
+ - O servidor só escuta em `127.0.0.1`.
115
+ - Toda chamada à API exige o token aleatório que vai na URL (`?t=…`), gerado a cada execução. Outro
116
+ site aberto no navegador não consegue disparar o agente.
117
+ - Um comando do ambiente por vez: enquanto um roda, os outros são recusados.
118
+ - A resposta do modelo aparece como Markdown, sem HTML, sem imagens e sem links que não sejam http(s).
119
+
120
+ ## Instalação a partir do código
121
+
122
+ ```bash
123
+ git clone git@github.com:vitortrack/djinnai.git
124
+ cd djinnai
125
+ bash ./djinn.sh install # npm ci + build da tela + npm link + autocompletar do bash
126
+ ```
127
+
128
+ | Comando | O que faz |
129
+ |---|---|
130
+ | `bash ./djinn.sh update` | O mesmo que `install`, depois de um `git pull` |
131
+ | `bash ./djinn.sh uninstall` | Remove o link global e o autocompletar |
132
+ | `npm run build` | Gera `web/dist`, que é o que o pacote publica |
133
+ | `npm test` | Checa o Markdown (sem HTML nem links perigosos) e como a tela monta a conversa a partir dos eventos |
134
+
135
+ A tela é React + Vite e usa componentes do [React Bits](https://reactbits.dev) (PromptBar,
136
+ ThoughtLine, LatticeLoader, StatusMark, RubberSegment), copiados para `web/src/components/`. O
137
+ servidor (`server.js`) usa só a biblioteca padrão do Node; a única dependência do pacote é o Electron,
138
+ que desenha a janela (`window.cjs`).
@@ -0,0 +1,9 @@
1
+ # Autocomplete Bash do DjinnAI.
2
+
3
+ _djinn_completion() {
4
+ if [[ ${COMP_CWORD} -eq 1 ]]; then
5
+ COMPREPLY=($(compgen -W "start restart rebuild logs status stop clean execute hot-reload auto-remove worker help version" -- "${COMP_WORDS[1]}"))
6
+ fi
7
+ }
8
+
9
+ complete -F _djinn_completion djinn djinnai
package/djinn.sh ADDED
@@ -0,0 +1,246 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -Eeuo pipefail
4
+
5
+ readonly CLI_NAME="djinn"
6
+ readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
7
+ readonly PACKAGE_FILE="${SCRIPT_DIR}/package.json"
8
+ readonly PACKAGE_LOCK_FILE="${SCRIPT_DIR}/package-lock.json"
9
+ readonly INDEX_FILE="${SCRIPT_DIR}/index.js"
10
+ readonly COMPLETION_SOURCE="${SCRIPT_DIR}/djinn-completion.bash"
11
+
12
+ readonly COMPLETION_DIR="${HOME}/.local/share/bash-completion/completions"
13
+ readonly COMPLETION_FILE="${COMPLETION_DIR}/${CLI_NAME}"
14
+ readonly BASHRC_FILE="${HOME}/.bashrc"
15
+
16
+ readonly BASHRC_MARKER_START="# >>> DJINNAI >>>"
17
+ readonly BASHRC_MARKER_END="# <<< DJINNAI <<<"
18
+
19
+ info() {
20
+ printf '\033[1;36m%s\033[0m\n' "$1"
21
+ }
22
+
23
+ success() {
24
+ printf '\033[1;32m%s\033[0m\n' "$1"
25
+ }
26
+
27
+ warning() {
28
+ printf '\033[1;33m%s\033[0m\n' "$1"
29
+ }
30
+
31
+ error() {
32
+ printf '\033[1;31mErro: %s\033[0m\n' "$1" >&2
33
+ }
34
+
35
+ die() {
36
+ error "$1"
37
+ exit 1
38
+ }
39
+
40
+ on_error() {
41
+ local exit_code=$?
42
+ local line_number="${1:-desconhecida}"
43
+
44
+ error "A instalação falhou na linha ${line_number}."
45
+ exit "${exit_code}"
46
+ }
47
+
48
+ trap 'on_error "$LINENO"' ERR
49
+
50
+ command_exists() {
51
+ command -v "$1" >/dev/null 2>&1
52
+ }
53
+
54
+ validate_environment() {
55
+ command_exists node || die "Node.js não está instalado."
56
+ command_exists npm || die "npm não está instalado."
57
+
58
+ [[ -f "${PACKAGE_FILE}" ]] ||
59
+ die "Arquivo não encontrado: ${PACKAGE_FILE}"
60
+
61
+ [[ -f "${INDEX_FILE}" ]] ||
62
+ die "Arquivo não encontrado: ${INDEX_FILE}"
63
+
64
+ [[ -f "${COMPLETION_SOURCE}" ]] ||
65
+ die "Arquivo não encontrado: ${COMPLETION_SOURCE}"
66
+ }
67
+
68
+ ensure_permissions() {
69
+ chmod +x "${INDEX_FILE}"
70
+ chmod +x "${SCRIPT_DIR}/djinn.sh"
71
+ }
72
+
73
+ install_dependencies() {
74
+ info "Instalando dependências..."
75
+
76
+ cd "${SCRIPT_DIR}"
77
+
78
+ if [[ -f "${PACKAGE_LOCK_FILE}" ]]; then
79
+ npm ci --no-audit --no-fund
80
+ else
81
+ npm install --no-audit --no-fund
82
+ fi
83
+
84
+ info "Gerando a tela web..."
85
+ npm run build
86
+ }
87
+
88
+ install_cli() {
89
+ info "Registrando comando ${CLI_NAME}..."
90
+ cd "${SCRIPT_DIR}"
91
+ npm link
92
+ }
93
+
94
+ install_completion() {
95
+ info "Instalando autocomplete..."
96
+
97
+ mkdir -p "${COMPLETION_DIR}"
98
+
99
+ install \
100
+ -m 0644 \
101
+ "${COMPLETION_SOURCE}" \
102
+ "${COMPLETION_FILE}"
103
+ }
104
+
105
+ remove_old_bashrc_configuration() {
106
+ [[ -f "${BASHRC_FILE}" ]] || return 0
107
+
108
+ local temporary_file
109
+ temporary_file="$(mktemp)"
110
+
111
+ awk \
112
+ -v start="${BASHRC_MARKER_START}" \
113
+ -v end="${BASHRC_MARKER_END}" \
114
+ '
115
+ $0 == start {
116
+ removing = 1
117
+ next
118
+ }
119
+
120
+ $0 == end {
121
+ removing = 0
122
+ next
123
+ }
124
+
125
+ !removing {
126
+ print
127
+ }
128
+ ' "${BASHRC_FILE}" > "${temporary_file}"
129
+
130
+ mv "${temporary_file}" "${BASHRC_FILE}"
131
+ }
132
+
133
+ configure_bashrc() {
134
+ info "Configurando o Bash..."
135
+
136
+ touch "${BASHRC_FILE}"
137
+
138
+ remove_old_bashrc_configuration
139
+
140
+ cat >> "${BASHRC_FILE}" <<EOF
141
+
142
+ ${BASHRC_MARKER_START}
143
+ if [[ -f "${COMPLETION_FILE}" ]]; then
144
+ source "${COMPLETION_FILE}"
145
+ fi
146
+ ${BASHRC_MARKER_END}
147
+ EOF
148
+ }
149
+
150
+ verify_installation() {
151
+ hash -r
152
+
153
+ local installed_cli
154
+
155
+ installed_cli="$(command -v "${CLI_NAME}" 2>/dev/null || true)"
156
+
157
+ if [[ -z "${installed_cli}" ]]; then
158
+ warning "A CLI foi instalada, mas o comando ainda não apareceu no PATH atual."
159
+ warning "Abra um novo terminal para atualizar o ambiente."
160
+ return 0
161
+ fi
162
+
163
+ success "CLI disponível em: ${installed_cli}"
164
+ }
165
+
166
+ uninstall_cli() {
167
+ info "Removendo DjinnAI..."
168
+
169
+ cd "${SCRIPT_DIR}"
170
+
171
+ npm unlink --global "${CLI_NAME}" >/dev/null 2>&1 ||
172
+ npm unlink --global >/dev/null 2>&1 ||
173
+ true
174
+
175
+ rm -f "${COMPLETION_FILE}"
176
+
177
+ remove_old_bashrc_configuration
178
+
179
+ success "DjinnAI removida."
180
+ warning "Abra um novo terminal para concluir a atualização do ambiente."
181
+ }
182
+
183
+ show_help() {
184
+ cat <<EOF
185
+ Uso:
186
+
187
+ bash ./djinn.sh
188
+ bash ./djinn.sh install
189
+ bash ./djinn.sh update
190
+ bash ./djinn.sh uninstall
191
+ bash ./djinn.sh help
192
+
193
+ Comandos:
194
+
195
+ install Instala a CLI e o autocomplete
196
+ update Atualiza a instalação existente
197
+ uninstall Remove a CLI e o autocomplete
198
+ help Exibe esta ajuda
199
+
200
+ Sem argumentos, o comando executado será "install".
201
+ EOF
202
+ }
203
+
204
+ install_all() {
205
+ validate_environment
206
+ ensure_permissions
207
+ install_dependencies
208
+ install_cli
209
+ install_completion
210
+ configure_bashrc
211
+ verify_installation
212
+
213
+ echo
214
+ success "DjinnAI instalada com sucesso."
215
+ echo
216
+ printf 'Use:\n'
217
+ printf ' %s\n' "${CLI_NAME}"
218
+ printf ' %s restart\n' "${CLI_NAME}"
219
+ printf ' %s logs\n' "${CLI_NAME}"
220
+ echo
221
+ warning "O autocomplete estará disponível automaticamente nos próximos terminais."
222
+ }
223
+
224
+ main() {
225
+ local action="${1:-install}"
226
+
227
+ case "${action}" in
228
+ install|update)
229
+ install_all
230
+ ;;
231
+
232
+ uninstall|remove)
233
+ uninstall_cli
234
+ ;;
235
+
236
+ help|-h|--help)
237
+ show_help
238
+ ;;
239
+
240
+ *)
241
+ die "Comando desconhecido: ${action}. Use: bash ./djinn.sh help"
242
+ ;;
243
+ esac
244
+ }
245
+
246
+ main "$@"
package/index.js ADDED
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn } from 'node:child_process';
4
+ import { existsSync, readFileSync, statSync } from 'node:fs';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ import { startServer } from './server.js';
9
+
10
+ function findProjectRoot(start) {
11
+ for (const marker of ['.djinn', '.detro', '.git', 'package.json']) {
12
+ for (let dir = start; ; dir = path.dirname(dir)) {
13
+ if (existsSync(path.join(dir, marker))) return dir;
14
+ if (path.dirname(dir) === dir) break;
15
+ }
16
+ }
17
+ return start;
18
+ }
19
+
20
+ const projectDir = findProjectRoot(process.cwd());
21
+ const appScript = [process.env.DJINN_APP_SCRIPT ?? process.env.DETRO_APP_SCRIPT, 'appDev', 'app']
22
+ .filter(Boolean)
23
+ .map((name) => path.resolve(projectDir, name))
24
+ .find((file) => existsSync(file)) ?? path.join(projectDir, 'appDev');
25
+
26
+ const HERE = path.dirname(fileURLToPath(import.meta.url));
27
+ const QUICK_EXIT_MS = 3000;
28
+ const { version } = JSON.parse(readFileSync(path.join(HERE, 'package.json'), 'utf8'));
29
+
30
+ function openBrowser(url) {
31
+ const opener = { darwin: ['open'], win32: ['cmd', '/c', 'start', ''] }[process.platform] ?? ['xdg-open'];
32
+ spawn(opener[0], [...opener.slice(1), url], { stdio: 'ignore', detached: true }).on('error', () => {}).unref();
33
+ }
34
+
35
+ function sandboxFlags(electron) {
36
+ if (process.platform !== 'linux') return [];
37
+ try {
38
+ const { uid, mode } = statSync(path.join(path.dirname(electron), 'chrome-sandbox'));
39
+ if (uid === 0 && mode & 0o4000) return [];
40
+ } catch {}
41
+ return ['--no-sandbox'];
42
+ }
43
+
44
+ async function openAppWindow(url, onClose) {
45
+ const electron = await import('electron').then((module) => module.default, () => null);
46
+ let fellBack = false;
47
+ const fallback = () => {
48
+ if (fellBack) return;
49
+ fellBack = true;
50
+ console.log('Não consegui abrir a janela do aplicativo; abrindo no navegador.');
51
+ openBrowser(url);
52
+ };
53
+ if (!electron) return fallback();
54
+ const startedAt = Date.now();
55
+ const { ELECTRON_RUN_AS_NODE, ...env } = process.env;
56
+ const window = spawn(electron, [...sandboxFlags(electron), path.join(HERE, 'window.cjs'), url], { stdio: 'ignore', env });
57
+ window.on('error', fallback);
58
+ window.on('exit', () => (Date.now() - startedAt < QUICK_EXIT_MS ? fallback() : onClose()));
59
+ return window;
60
+ }
61
+
62
+ const args = process.argv.slice(2);
63
+
64
+ if (['version', '--version', '-v'].includes(args[0])) {
65
+ console.log(`DjinnAI ${version}`);
66
+ } else if (args.length > 0 && args[0] !== '--navegador') {
67
+ spawn(appScript, args, { cwd: projectDir, stdio: 'inherit' })
68
+ .on('error', (error) => {
69
+ console.error(`Não foi possível executar ${appScript} (${error.message}). Confira se ele existe e é executável (chmod +x).`);
70
+ process.exit(1);
71
+ })
72
+ .on('close', (code) => process.exit(code ?? 1));
73
+ } else {
74
+ const { url, close } = await startServer({ projectDir, appScript, version, port: Number(process.env.DJINN_PORT ?? process.env.DETRO_PORT) || 0 }).catch((error) => {
75
+ console.error(error.message);
76
+ process.exit(1);
77
+ });
78
+ console.log(`DjinnAI ${version} — ${projectDir}\n\n ${url}\n\nAbra o endereço no navegador se quiser acompanhar por lá também. Feche a janela ou use Ctrl+C para encerrar.`);
79
+ const quit = () => {
80
+ close();
81
+ process.exit(0);
82
+ };
83
+ const window = args[0] === '--navegador' ? openBrowser(url) : await openAppWindow(url, quit);
84
+ process.on('SIGINT', () => {
85
+ window?.kill();
86
+ quit();
87
+ });
88
+ }
package/package.json CHANGED
@@ -1,6 +1,67 @@
1
1
  {
2
2
  "name": "@vitortrack777/djinnai",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.6.1",
4
+ "description": "DjinnAI: aplicativo local para conversar com o agente do Claude Code (Claude ou modelos do Ollama) e rodar os comandos do ambiente do projeto.",
5
+ "type": "module",
6
+ "bin": {
7
+ "djinn": "./index.js",
8
+ "djinnai": "./index.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node index.js",
12
+ "test": "node web/src/lib/markdown.test.js && node web/src/lib/turns.test.js",
13
+ "build": "vite build --config web/vite.config.js",
14
+ "prepublishOnly": "npm run build",
15
+ "setup": "bash ./djinn.sh install",
16
+ "update": "bash ./djinn.sh update",
17
+ "uninstall-cli": "bash ./djinn.sh uninstall"
18
+ },
19
+ "license": "MIT",
20
+ "engines": {
21
+ "node": ">=22.12"
22
+ },
23
+ "files": [
24
+ "index.js",
25
+ "server.js",
26
+ "window.cjs",
27
+ "web/dist/",
28
+ "djinn.sh",
29
+ "djinn-completion.bash",
30
+ "LICENSE"
31
+ ],
32
+ "keywords": [
33
+ "djinnai",
34
+ "djinn",
35
+ "cli",
36
+ "ai",
37
+ "claude",
38
+ "claude-code",
39
+ "ollama",
40
+ "agent"
41
+ ],
42
+ "author": "vitortrack",
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "git+https://github.com/vitortrack/djinnai.git"
46
+ },
47
+ "homepage": "https://github.com/vitortrack/djinnai#readme",
48
+ "bugs": {
49
+ "url": "https://github.com/vitortrack/djinnai/issues"
50
+ },
51
+ "publishConfig": {
52
+ "access": "public"
53
+ },
54
+ "devDependencies": {
55
+ "@hugeicons/core-free-icons": "^4.3.5",
56
+ "@hugeicons/react": "^1.1.10",
57
+ "@vitejs/plugin-react": "^4.7.0",
58
+ "marked": "^15.0.12",
59
+ "motion": "^12.43.0",
60
+ "react": "^19.3.1",
61
+ "react-dom": "^19.3.1",
62
+ "vite": "^6.4.5"
63
+ },
64
+ "dependencies": {
65
+ "electron": "44.7.1"
66
+ }
67
+ }