@nio-cli/cli 0.3.0 → 0.3.4
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/.env.example +35 -0
- package/Dockerfile.gateway +12 -0
- package/README.md +3 -2
- package/dist/adapters/ide/ide-gateway.js +8 -15
- package/dist/adapters/ide/ide-gateway.js.map +1 -1
- package/dist/adapters/lang/scaffold-gateway.js +2 -2
- package/dist/adapters/lang/scaffold-gateway.js.map +1 -1
- package/dist/adapters/pkg/toolchain-gateway.js +2 -2
- package/dist/adapters/pkg/toolchain-gateway.js.map +1 -1
- package/dist/app/ai-client.js +24 -9
- package/dist/app/ai-client.js.map +1 -1
- package/dist/cli/commands/docker.js +75 -7
- package/dist/cli/commands/docker.js.map +1 -1
- package/dist/cli/commands/sync.js +2 -2
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/flows/clients.js +2 -2
- package/dist/cli/flows/clients.js.map +1 -1
- package/dist/lib/auth/gateway-process.js +25 -2
- package/dist/lib/auth/gateway-process.js.map +1 -1
- package/dist/lib/clients/client-install.js +2 -2
- package/dist/lib/clients/client-install.js.map +1 -1
- package/dist/lib/deps/dependency-install-project.js +2 -2
- package/dist/lib/deps/dependency-install-project.js.map +1 -1
- package/dist/lib/deps/dependency-install.js +4 -4
- package/dist/lib/deps/dependency-install.js.map +1 -1
- package/dist/lib/headroom.js +5 -13
- package/dist/lib/headroom.js.map +1 -1
- package/dist/lib/proc.js +21 -0
- package/dist/lib/proc.js.map +1 -0
- package/dist/tui/app.js +49 -10
- package/dist/tui/app.js.map +1 -1
- package/dist/tui/components.js +0 -0
- package/dist/tui/components.js.map +1 -1
- package/dist/tui/opencode.js +14 -9
- package/dist/tui/opencode.js.map +1 -1
- package/dist/tui/palette.js +1 -43
- package/dist/tui/palette.js.map +1 -1
- package/dist/tui/state.js +52 -25
- package/dist/tui/state.js.map +1 -1
- package/docker/docker-compose.yml +73 -33
- package/docker/kong.yml +45 -0
- package/package.json +6 -6
- package/headroom/docker-compose.yml +0 -27
package/dist/tui/state.js
CHANGED
|
@@ -33,30 +33,29 @@ function reconcilePending(state, realId) {
|
|
|
33
33
|
state.messages.splice(i, 1);
|
|
34
34
|
}
|
|
35
35
|
function applyPart(state, raw) {
|
|
36
|
-
const
|
|
37
|
-
if (!
|
|
36
|
+
const messageID = raw.messageID;
|
|
37
|
+
if (!messageID || !raw.id)
|
|
38
38
|
return;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return;
|
|
42
|
-
reconcilePending(state, part.messageID);
|
|
43
|
-
const msg = upsertMessage(state, part.messageID, 'assistant');
|
|
44
|
-
if (type === 'tool') {
|
|
45
|
-
const cp = upsertPart(msg, part.id, 'tool');
|
|
46
|
-
cp.text = part.state?.title ?? part.tool ?? 'tool';
|
|
47
|
-
cp.tool = {
|
|
48
|
-
status: part.state?.status ?? 'running',
|
|
49
|
-
output: String(part.state?.output ?? part.state?.error ?? ''),
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
else if (typeof part.text === 'string') {
|
|
53
|
-
upsertPart(msg, part.id, type === 'reasoning' ? 'reasoning' : 'text').text = part.text;
|
|
54
|
-
}
|
|
39
|
+
reconcilePending(state, messageID);
|
|
40
|
+
applyPartInto(upsertMessage(state, messageID, 'assistant'), raw);
|
|
55
41
|
}
|
|
56
42
|
export function applyEvent(prev, evt) {
|
|
57
43
|
const state = clone(prev);
|
|
58
44
|
const p = evt.properties ?? {};
|
|
59
45
|
tlog('event', evt.type, JSON.stringify(p).slice(0, 200));
|
|
46
|
+
const etype = evt.type;
|
|
47
|
+
if (etype === 'permission.asked' || etype === 'permission.updated') {
|
|
48
|
+
const perm = p;
|
|
49
|
+
if (perm.id && perm.sessionID) {
|
|
50
|
+
const what = perm.patterns?.length ? ` ${perm.patterns.join(', ')}` : '';
|
|
51
|
+
state.permission = {
|
|
52
|
+
id: perm.id,
|
|
53
|
+
sessionId: perm.sessionID,
|
|
54
|
+
title: perm.title ?? `${perm.permission ?? perm.tool?.name ?? 'ação'}${what}`,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return state;
|
|
58
|
+
}
|
|
60
59
|
switch (evt.type) {
|
|
61
60
|
case 'message.updated': {
|
|
62
61
|
const info = (p.info ?? p);
|
|
@@ -69,13 +68,6 @@ export function applyEvent(prev, evt) {
|
|
|
69
68
|
case 'message.part.updated':
|
|
70
69
|
applyPart(state, (p.part ?? p));
|
|
71
70
|
break;
|
|
72
|
-
case 'permission.updated': {
|
|
73
|
-
const perm = p;
|
|
74
|
-
if (perm.id && perm.sessionID) {
|
|
75
|
-
state.permission = { id: perm.id, sessionId: perm.sessionID, title: perm.title ?? 'permissão' };
|
|
76
|
-
}
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
71
|
case 'permission.replied':
|
|
80
72
|
state.permission = null;
|
|
81
73
|
break;
|
|
@@ -92,6 +84,41 @@ export function applyEvent(prev, evt) {
|
|
|
92
84
|
}
|
|
93
85
|
return state;
|
|
94
86
|
}
|
|
87
|
+
export function syncMessages(prev, raw, busy) {
|
|
88
|
+
const state = { messages: [], busy, permission: prev.permission };
|
|
89
|
+
for (const m of raw) {
|
|
90
|
+
if (!m.info?.id)
|
|
91
|
+
continue;
|
|
92
|
+
const msg = upsertMessage(state, m.info.id, m.info.role === 'user' ? 'user' : 'assistant');
|
|
93
|
+
for (const raw of m.parts ?? [])
|
|
94
|
+
applyPartInto(msg, raw);
|
|
95
|
+
}
|
|
96
|
+
const pending = prev.messages.find((x) => x.id === PENDING_USER);
|
|
97
|
+
if (pending && !state.messages.some((x) => x.role === 'user' && sameText(x, pending))) {
|
|
98
|
+
state.messages.push(pending);
|
|
99
|
+
}
|
|
100
|
+
return state;
|
|
101
|
+
}
|
|
102
|
+
function sameText(a, b) {
|
|
103
|
+
const t = (m) => m.parts.map((p) => p.text).join('').trim();
|
|
104
|
+
return t(a) === t(b);
|
|
105
|
+
}
|
|
106
|
+
function applyPartInto(msg, raw) {
|
|
107
|
+
const part = raw;
|
|
108
|
+
if (!part.id)
|
|
109
|
+
return;
|
|
110
|
+
const type = part.type ?? 'text';
|
|
111
|
+
if (type === 'step-start' || type === 'step-finish')
|
|
112
|
+
return;
|
|
113
|
+
if (type === 'tool') {
|
|
114
|
+
const cp = upsertPart(msg, part.id, 'tool');
|
|
115
|
+
cp.text = part.state?.title ?? part.tool ?? 'tool';
|
|
116
|
+
cp.tool = { status: part.state?.status ?? 'running', output: String(part.state?.output ?? part.state?.error ?? '') };
|
|
117
|
+
}
|
|
118
|
+
else if (typeof part.text === 'string') {
|
|
119
|
+
upsertPart(msg, part.id, type === 'reasoning' ? 'reasoning' : 'text').text = part.text;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
95
122
|
export function pushUserMessage(prev, text) {
|
|
96
123
|
return {
|
|
97
124
|
messages: [
|
package/dist/tui/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/tui/state.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAuBlC,MAAM,CAAC,MAAM,SAAS,GAAc,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AACpF,MAAM,YAAY,GAAG,cAAc,CAAC;AAEpC,SAAS,KAAK,CAAC,IAAe;IAC5B,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACrF,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,UAAU,EAAE,IAAI,CAAC,UAAU;KAC5B,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAgB,EAAE,EAAU,EAAE,IAAyB;IAC5E,IAAI,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC9B,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CAAC,GAAgB,EAAE,EAAU,EAAE,IAAsB;IACtE,IAAI,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAC9B,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACjB,OAAO,IAAI,CAAC;AACd,CAAC;AAGD,SAAS,gBAAgB,CAAC,KAAgB,EAAE,MAAc;IACxD,IAAI,MAAM,KAAK,YAAY;QAAE,OAAO;IACpC,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC,CAAC;IACjE,IAAI,CAAC,IAAI,CAAC;QAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,SAAS,CAAC,KAAgB,EAAE,GAA4B;IAC/D,MAAM,
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/tui/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,44 +1,84 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
# Stack NIO unificado — 1 compose, 1 rede (`nio-net`), 1 stack no Portainer.
|
|
2
|
+
# Substitui os 3 composes antigos (docker/ + kong/ + headroom/). O gateway agora
|
|
3
|
+
# é container (Dockerfile.gateway) e o Kong o alcança por NOME na rede, sem
|
|
4
|
+
# host.docker.internal. Ver docs/container-architecture.md.
|
|
5
|
+
name: nio
|
|
6
|
+
|
|
7
|
+
networks:
|
|
8
|
+
nio-net:
|
|
9
|
+
name: nio-net
|
|
10
|
+
driver: bridge
|
|
11
|
+
|
|
12
|
+
volumes:
|
|
13
|
+
nio_portainer_data: { name: nio_portainer_data }
|
|
14
|
+
nio_headroom_cache: { name: nio_headroom_cache }
|
|
12
15
|
|
|
13
|
-
# `restart: unless-stopped`, `extra_hosts` p/ Linux. Roda em qualquer Docker
|
|
14
|
-
# Engine — não exige Docker Desktop.
|
|
15
16
|
services:
|
|
17
|
+
nio-gateway:
|
|
18
|
+
build:
|
|
19
|
+
context: .. # raiz do repo (onde estão dist/ e package.json)
|
|
20
|
+
dockerfile: Dockerfile.gateway # relativo ao context (raiz)
|
|
21
|
+
image: nio-gateway:local
|
|
22
|
+
container_name: nio-gateway
|
|
23
|
+
restart: unless-stopped
|
|
24
|
+
env_file: [ ../.env ] # NIO_DATABASE_URL, JWT_SECRET (gitignored)
|
|
25
|
+
environment:
|
|
26
|
+
# o gateway lê env via env() que PREFIXA NIO_ → a var é NIO_GATEWAY_HOST
|
|
27
|
+
# (não GATEWAY_HOST). 0.0.0.0 = ouvir na interface da rede, não só loopback.
|
|
28
|
+
NIO_GATEWAY_HOST: "0.0.0.0"
|
|
29
|
+
ports: [ "127.0.0.1:3000:3000" ] # acesso direto da CLI (padrão)
|
|
30
|
+
healthcheck:
|
|
31
|
+
test: ["CMD-SHELL", "curl -fsS http://localhost:3000/health || exit 1"]
|
|
32
|
+
interval: 10s
|
|
33
|
+
timeout: 3s
|
|
34
|
+
retries: 5
|
|
35
|
+
start_period: 15s
|
|
36
|
+
networks: [ nio-net ]
|
|
37
|
+
|
|
38
|
+
headroom:
|
|
39
|
+
image: ghcr.io/headroomlabs-ai/headroom@sha256:35b799e94eef4644cb15a2e695b4b99698fe7668614623e9338cb10c10ececf9 # headroom:latest, pinado 2026-09-03
|
|
40
|
+
container_name: nio-headroom
|
|
41
|
+
restart: unless-stopped
|
|
42
|
+
command: ["--host", "0.0.0.0", "--port", "8787"]
|
|
43
|
+
environment:
|
|
44
|
+
OPENAI_TARGET_API_URL: "${NIO_HEADROOM_OPENAI_TARGET:-https://opencode.ai/zen/v1}"
|
|
45
|
+
HEADROOM_UPDATE_CHECK: "off"
|
|
46
|
+
ports: [ "127.0.0.1:8787:8787" ]
|
|
47
|
+
volumes: [ "nio_headroom_cache:/root/.headroom" ]
|
|
48
|
+
networks: [ nio-net ]
|
|
49
|
+
|
|
16
50
|
mcp-gateway:
|
|
17
|
-
image: docker/mcp-gateway:latest
|
|
51
|
+
image: docker/mcp-gateway@sha256:f5a679a05fc39022a046167bef92aeeb01bcd59485ad27843ae5227db7950688 # docker/mcp-gateway:latest, pinado 2026-09-03
|
|
18
52
|
container_name: nio-mcp-gateway
|
|
19
53
|
restart: unless-stopped
|
|
20
|
-
command:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
volumes:
|
|
25
|
-
- /var/run/docker.sock:/var/run/docker.sock
|
|
26
|
-
ports:
|
|
27
|
-
- "127.0.0.1:8811:8811"
|
|
28
|
-
extra_hosts:
|
|
29
|
-
- "host.docker.internal:host-gateway"
|
|
54
|
+
command: ["--transport=streaming", "--port=8811", "--servers=docker"]
|
|
55
|
+
ports: [ "127.0.0.1:8811:8811" ]
|
|
56
|
+
volumes: [ "/var/run/docker.sock:/var/run/docker.sock" ]
|
|
57
|
+
networks: [ nio-net ]
|
|
30
58
|
|
|
31
59
|
portainer:
|
|
32
|
-
image: portainer/portainer-ce:lts
|
|
60
|
+
image: portainer/portainer-ce@sha256:511f3f06c96fe3b993ebeaafde311c1959cae73a7ef825dba6397d51b450dffa # portainer-ce:lts, pinado 2026-09-03
|
|
33
61
|
container_name: nio-portainer
|
|
34
62
|
restart: unless-stopped
|
|
63
|
+
ports: [ "127.0.0.1:9443:9443" ] # UI (edge :8000 REMOVIDO — libera p/ Kong)
|
|
35
64
|
volumes:
|
|
36
|
-
- /var/run/docker.sock:/var/run/docker.sock
|
|
37
|
-
- nio_portainer_data:/data
|
|
38
|
-
|
|
39
|
-
- "127.0.0.1:9443:9443"
|
|
40
|
-
- "127.0.0.1:8000:8000"
|
|
65
|
+
- "/var/run/docker.sock:/var/run/docker.sock"
|
|
66
|
+
- "nio_portainer_data:/data"
|
|
67
|
+
networks: [ nio-net ]
|
|
41
68
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
69
|
+
kong:
|
|
70
|
+
image: kong@sha256:2a8cf3b110cdaba1cb00adc665b8635ed1fc75c907f7a4298613c68e4976de0a # kong:3.9, pinado 2026-09-03
|
|
71
|
+
container_name: nio-kong
|
|
72
|
+
restart: unless-stopped
|
|
73
|
+
environment:
|
|
74
|
+
KONG_DATABASE: "off"
|
|
75
|
+
KONG_DECLARATIVE_CONFIG: /kong/kong.yml
|
|
76
|
+
KONG_PROXY_LISTEN: "0.0.0.0:8000"
|
|
77
|
+
KONG_ADMIN_LISTEN: "0.0.0.0:8001"
|
|
78
|
+
volumes: [ "./kong.yml:/kong/kong.yml:ro" ] # docker/kong.yml (T3)
|
|
79
|
+
ports:
|
|
80
|
+
- "127.0.0.1:${NIO_KONG_PROXY_PORT:-8000}:8000" # sem colisão: Portainer largou :8000
|
|
81
|
+
- "127.0.0.1:${NIO_KONG_ADMIN_PORT:-8001}:8001"
|
|
82
|
+
depends_on:
|
|
83
|
+
nio-gateway: { condition: service_healthy }
|
|
84
|
+
networks: [ nio-net ]
|
package/docker/kong.yml
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Config declarativa do Kong (DB-less). Kong entra na frente do `nio-gateway` e aplica as regras de roteamento e plugins (rate-limitng)
|
|
2
|
+
_format_version: "3.0"
|
|
3
|
+
|
|
4
|
+
services:
|
|
5
|
+
- name: nio-gateway
|
|
6
|
+
url: http://nio-gateway:3000
|
|
7
|
+
routes:
|
|
8
|
+
# /login — alvo de brute-force; rate-limit apertado.
|
|
9
|
+
- name: nio-gateway-login
|
|
10
|
+
paths:
|
|
11
|
+
- /login
|
|
12
|
+
strip_path: false
|
|
13
|
+
plugins:
|
|
14
|
+
- name: rate-limiting
|
|
15
|
+
config:
|
|
16
|
+
minute: 20
|
|
17
|
+
policy: local
|
|
18
|
+
- name: nio-gateway-logout
|
|
19
|
+
paths:
|
|
20
|
+
- /logout
|
|
21
|
+
strip_path: false
|
|
22
|
+
# /verify-2fa e /security/* — OTP + gerência do 2º fator (spec 0004).
|
|
23
|
+
# cada SMS custa; brute-force de OTP de 6 dígitos → limite mais baixo.
|
|
24
|
+
- name: nio-gateway-verify-2fa
|
|
25
|
+
paths:
|
|
26
|
+
- /verify-2fa
|
|
27
|
+
strip_path: false
|
|
28
|
+
plugins:
|
|
29
|
+
- name: rate-limiting
|
|
30
|
+
config:
|
|
31
|
+
minute: 10
|
|
32
|
+
policy: local
|
|
33
|
+
- name: nio-gateway-security
|
|
34
|
+
paths:
|
|
35
|
+
- /security
|
|
36
|
+
strip_path: false
|
|
37
|
+
plugins:
|
|
38
|
+
- name: rate-limiting
|
|
39
|
+
config:
|
|
40
|
+
minute: 10
|
|
41
|
+
policy: local
|
|
42
|
+
- name: nio-gateway-health
|
|
43
|
+
paths:
|
|
44
|
+
- /health
|
|
45
|
+
strip_path: false
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nio-cli/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Orquestrador de ambientes de desenvolvimento: escolhe um perfil, responde um wizard e a CLI (com auxílio de IA via MCP) materializa toolchains, linguagens, frameworks, dotfiles e IDE.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
"files": [
|
|
14
14
|
"dist",
|
|
15
15
|
"docker/docker-compose.yml",
|
|
16
|
-
"
|
|
16
|
+
"docker/kong.yml",
|
|
17
|
+
"Dockerfile.gateway",
|
|
18
|
+
".env.example",
|
|
17
19
|
"README.md"
|
|
18
20
|
],
|
|
19
21
|
"engines": {
|
|
@@ -45,7 +47,7 @@
|
|
|
45
47
|
"nio"
|
|
46
48
|
],
|
|
47
49
|
"scripts": {
|
|
48
|
-
"build": "rm -rf dist && tsc && node --input-type=commonjs -e \"require('fs').cpSync('src/cli/copy','dist/cli/copy',{recursive:true})
|
|
50
|
+
"build": "rm -rf dist && tsc && node --input-type=commonjs -e \"const fs=require('fs');fs.cpSync('src/cli/copy','dist/cli/copy',{recursive:true});for(const f of ['cli.js','mcp-server.js','gateway/index.js','mcp-server-lang.js'])fs.chmodSync('dist/'+f,0o755)\"",
|
|
49
51
|
"gen:docs": "bun run scripts/gen-reference.ts",
|
|
50
52
|
"db:ping": "bun run scripts/db-ping.ts",
|
|
51
53
|
"dev:sms-echo": "bun run scripts/sms-echo.ts",
|
|
@@ -53,9 +55,7 @@
|
|
|
53
55
|
"dev:mcp": "bun run src/mcp-server.ts",
|
|
54
56
|
"dev:gateway": "bun run src/gateway/index.ts",
|
|
55
57
|
"dev:lang": "bun run src/mcp-server-lang.ts",
|
|
56
|
-
"dev:
|
|
57
|
-
"dev:docker": "docker compose -f docker/docker-compose.yml up",
|
|
58
|
-
"dev:headroom": "docker compose -f headroom/docker-compose.yml up",
|
|
58
|
+
"dev:docker": "docker compose -f docker/docker-compose.yml up --build",
|
|
59
59
|
"prepublishOnly": "npm run build"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Headroom — proxy de compressão de contexto entre o client de IA e o LLM.
|
|
2
|
-
# Obrigatório pro `nio ai` (ADR 0007). Mesmo padrão do `docker/docker-compose.yml`:
|
|
3
|
-
# porta pinada em 127.0.0.1, `restart: unless-stopped`, `extra_hosts` p/ Linux.
|
|
4
|
-
#
|
|
5
|
-
# O entrypoint da imagem já é `headroom proxy` — `command` passa só flags.
|
|
6
|
-
# `OPENAI_TARGET_API_URL` roteia as chamadas OpenAI-compatíveis (o operador usa
|
|
7
|
-
# OpenCode Zen) pro Zen; o header Authorization do OpenCode passa transparente,
|
|
8
|
-
# então o Headroom não precisa de API key própria.
|
|
9
|
-
services:
|
|
10
|
-
headroom:
|
|
11
|
-
image: ghcr.io/headroomlabs-ai/headroom:latest
|
|
12
|
-
container_name: nio-headroom
|
|
13
|
-
restart: unless-stopped
|
|
14
|
-
command: ["--host", "0.0.0.0", "--port", "8787"]
|
|
15
|
-
environment:
|
|
16
|
-
OPENAI_TARGET_API_URL: "${NIO_HEADROOM_OPENAI_TARGET:-https://opencode.ai/zen/v1}"
|
|
17
|
-
HEADROOM_UPDATE_CHECK: "off"
|
|
18
|
-
ports:
|
|
19
|
-
- "127.0.0.1:${NIO_HEADROOM_PORT:-8787}:8787"
|
|
20
|
-
extra_hosts:
|
|
21
|
-
- "host.docker.internal:host-gateway"
|
|
22
|
-
volumes:
|
|
23
|
-
- nio_headroom_cache:/root/.headroom
|
|
24
|
-
|
|
25
|
-
volumes:
|
|
26
|
-
nio_headroom_cache:
|
|
27
|
-
name: nio_headroom_cache
|