@fazer-ai/agents 1.0.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/LICENSE +21 -0
- package/README.md +112 -0
- package/dist/agents/claude.js +152 -0
- package/dist/agents/codex.js +155 -0
- package/dist/agents/detect.js +15 -0
- package/dist/agents/handoff.js +22 -0
- package/dist/agents/hermes-skills.js +177 -0
- package/dist/agents/hermes.js +474 -0
- package/dist/agents/index.js +57 -0
- package/dist/agents/manual.js +22 -0
- package/dist/agents/other.js +39 -0
- package/dist/agents/shell.js +15 -0
- package/dist/agents/types.js +2 -0
- package/dist/config.js +48 -0
- package/dist/exec.js +279 -0
- package/dist/hostinger.js +75 -0
- package/dist/hub-command.js +144 -0
- package/dist/index.js +726 -0
- package/dist/licenses.js +93 -0
- package/dist/mcp.js +100 -0
- package/dist/oauth.js +578 -0
- package/dist/onboarding-marker.js +48 -0
- package/dist/preferences.js +40 -0
- package/dist/skills/agents-dev/SKILL.md +37 -0
- package/dist/skills/agents-dev/gotchas.md +6 -0
- package/dist/skills/agents-dev/guardrails.md +6 -0
- package/dist/skills/agents-dev/references/00-get-the-code.md +28 -0
- package/dist/skills/agents-dev/references/01-layout-and-bun-check.md +29 -0
- package/dist/skills/agents-dev/references/02-free-full-and-invariants.md +7 -0
- package/dist/skills/agents-dev/references/03-implement.md +9 -0
- package/dist/skills/agents-dev/references/04-own-image-and-deploy.md +13 -0
- package/dist/skills/agents-onboarding/SKILL.md +80 -0
- package/dist/skills/agents-onboarding/gotchas.md +157 -0
- package/dist/skills/agents-onboarding/guardrails.md +65 -0
- package/dist/skills/agents-onboarding/references/00-prereqs-and-access.md +37 -0
- package/dist/skills/agents-onboarding/references/01-vps-dns-ssh.md +67 -0
- package/dist/skills/agents-onboarding/references/01b-brownfield.md +70 -0
- package/dist/skills/agents-onboarding/references/01c-pick-tier.md +61 -0
- package/dist/skills/agents-onboarding/references/02-coolify.md +109 -0
- package/dist/skills/agents-onboarding/references/03-chatwoot-pro.md +61 -0
- package/dist/skills/agents-onboarding/references/04-agents-image.md +46 -0
- package/dist/skills/agents-onboarding/references/05-langfuse.md +45 -0
- package/dist/skills/agents-onboarding/references/06-setup-and-mcp.md +47 -0
- package/dist/skills/agents-onboarding/references/08-agent-import.md +55 -0
- package/dist/skills/agents-onboarding/references/09-chatwoot-bind.md +41 -0
- package/dist/skills/agents-onboarding/references/10-validate-e2e.md +34 -0
- package/dist/skills/agents-onboarding/references/agent-features.md +61 -0
- package/dist/skills/agents-onboarding/references/chatwoot-hub-register.md +69 -0
- package/dist/skills/agents-onboarding/references/deploy-b-portainer.md +138 -0
- package/dist/skills/agents-onboarding/references/deploy-c-compose.md +64 -0
- package/dist/skills/agents-onboarding/samples/agents/README.md +23 -0
- package/dist/skills/agents-onboarding/samples/agents/maria-clinica-moreira.json +313 -0
- package/dist/skills/agents-onboarding/scripts/chatwoot-admin.py +248 -0
- package/dist/skills/agents-onboarding/scripts/coolify.py +552 -0
- package/dist/skills/agents-onboarding/scripts/docker-status.py +129 -0
- package/dist/skills/agents-onboarding/scripts/gen-onboarding-env.ts +187 -0
- package/dist/skills/agents-onboarding/scripts/harbor-login.py +118 -0
- package/dist/skills/agents-onboarding/scripts/langfuse-verify.py +118 -0
- package/dist/skills/agents-onboarding/scripts/portainer-brownfield.py +115 -0
- package/dist/skills/agents-onboarding/scripts/remote.py +198 -0
- package/dist/skills/agents-onboarding/scripts/sshkey.py +140 -0
- package/dist/skills/agents-onboarding/templates/chatwoot/.env.example +30 -0
- package/dist/skills/agents-onboarding/templates/chatwoot/README.md +65 -0
- package/dist/skills/agents-onboarding/templates/chatwoot/docker-compose.coolify.yml +136 -0
- package/dist/skills/agents-onboarding/templates/chatwoot/docker-compose.yml +139 -0
- package/dist/skills/agents-onboarding/templates/docker-compose.coolify.yml +73 -0
- package/dist/skills/agents-onboarding/templates/docker-compose.portainer.yml +132 -0
- package/dist/skills/agents-onboarding/templates/docker-compose.prod.yml +85 -0
- package/dist/skills/agents-onboarding/templates/langfuse/.env.example +59 -0
- package/dist/skills/agents-onboarding/templates/langfuse/README.md +132 -0
- package/dist/skills/agents-onboarding/templates/langfuse/docker-compose.coolify.yml +189 -0
- package/dist/skills/agents-onboarding/templates/langfuse/docker-compose.yml +185 -0
- package/dist/skills/agents-operation/SKILL.md +42 -0
- package/dist/skills/agents-operation/gotchas.md +61 -0
- package/dist/skills/agents-operation/guardrails.md +26 -0
- package/dist/skills/agents-operation/references/00-production-safety.md +24 -0
- package/dist/skills/agents-operation/references/01-diagnose.md +34 -0
- package/dist/skills/agents-operation/references/02-reproduce.md +22 -0
- package/dist/skills/agents-operation/references/03-adjust.md +36 -0
- package/dist/skills/agents-operation/references/04-validate-and-apply.md +31 -0
- package/dist/ui-select.js +279 -0
- package/dist/ui.js +167 -0
- package/package.json +53 -0
package/dist/licenses.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isUsable = isUsable;
|
|
4
|
+
exports.isAvailable = isAvailable;
|
|
5
|
+
exports.kanbanLicenses = kanbanLicenses;
|
|
6
|
+
exports.hasCommunityAccess = hasCommunityAccess;
|
|
7
|
+
exports.licenseLabel = licenseLabel;
|
|
8
|
+
exports.instanceLabel = instanceLabel;
|
|
9
|
+
exports.parseLicenseChoice = parseLicenseChoice;
|
|
10
|
+
exports.buildLicenseMenu = buildLicenseMenu;
|
|
11
|
+
// Status que tornam a licença utilizável pra ligar o Pro (os demais: past_due,
|
|
12
|
+
// canceled, unpaid, paused, incomplete, não habilitam).
|
|
13
|
+
const USABLE_STATUS = new Set(["ACTIVE", "TRIALING"]);
|
|
14
|
+
function isUsable(l) {
|
|
15
|
+
return USABLE_STATUS.has(l.status.toUpperCase());
|
|
16
|
+
}
|
|
17
|
+
// Disponível = utilizável E ainda não atachada a uma instância.
|
|
18
|
+
function isAvailable(l) {
|
|
19
|
+
return isUsable(l) && l.instance === null;
|
|
20
|
+
}
|
|
21
|
+
// Filtra as licenças Kanban/Chatwoot do conjunto cru do `list_licenses`.
|
|
22
|
+
function kanbanLicenses(all) {
|
|
23
|
+
return all.filter((l) => l.feature?.toUpperCase() === "KANBAN" &&
|
|
24
|
+
l.instanceType?.toUpperCase() === "CHATWOOT");
|
|
25
|
+
}
|
|
26
|
+
// Acesso à edição Pro da fazer.ai agents = membership da comunidade (`isCommunityGrant`)
|
|
27
|
+
// com status utilizável. Difere do Kanban avulso: o projeto `agents` no Harbor é
|
|
28
|
+
// liberado só pra membros da comunidade (robot per-user, gating no hub). Uma licença
|
|
29
|
+
// Chatwoot Pro avulsa (isCommunityGrant=false) NÃO desbloqueia o fazer.ai agents Pro.
|
|
30
|
+
function hasCommunityAccess(all) {
|
|
31
|
+
return all.some((l) => l.isCommunityGrant && isUsable(l));
|
|
32
|
+
}
|
|
33
|
+
// Rótulo curto e estável de uma licença pro seletor.
|
|
34
|
+
function licenseLabel(l) {
|
|
35
|
+
const grant = l.isCommunityGrant ? " · comunidade" : "";
|
|
36
|
+
return `Licença #${l.number}${grant}`;
|
|
37
|
+
}
|
|
38
|
+
// Rótulo legível da instância atachada: nome amigável → host → UUID de instalação.
|
|
39
|
+
// O `identifier` cru é um UUID, ilegível como "em uso por"; é o último recurso.
|
|
40
|
+
function instanceLabel(instance) {
|
|
41
|
+
if (!instance)
|
|
42
|
+
return "outra instância";
|
|
43
|
+
return instance.name?.trim() || instance.host?.trim() || instance.identifier;
|
|
44
|
+
}
|
|
45
|
+
// Decodifica o value escolhido no seletor (`lic:<id>` / `attached:<id>` / ação).
|
|
46
|
+
function parseLicenseChoice(value) {
|
|
47
|
+
if (value.startsWith("lic:"))
|
|
48
|
+
return { kind: "available", id: value.slice(4) };
|
|
49
|
+
if (value.startsWith("attached:")) {
|
|
50
|
+
return { kind: "attached", id: value.slice("attached:".length) };
|
|
51
|
+
}
|
|
52
|
+
return { kind: "action", action: value };
|
|
53
|
+
}
|
|
54
|
+
// Monta o menu de licença, ciente do estado:
|
|
55
|
+
// - **empty** (0 licenças): "Atualizar lista" + "Ainda não tenho licença" (única
|
|
56
|
+
// porta pro fluxo da comunidade, só faz sentido quando não há NENHUMA).
|
|
57
|
+
// - **none-available** (só consumidas) / **has-available**: as licenças primeiro
|
|
58
|
+
// (disponíveis selecionáveis = `lic:`, consumidas selecionáveis = `attached:`
|
|
59
|
+
// pra desvincular), depois "Adquirir nova licença" + "Seguir sem o Chatwoot
|
|
60
|
+
// Pro". `defaultIndex` cai na última usada se ainda disponível, senão na 1ª opção.
|
|
61
|
+
function buildLicenseMenu(kanban, lastUsedId) {
|
|
62
|
+
const available = kanban.filter(isAvailable);
|
|
63
|
+
const consumed = kanban.filter((l) => isUsable(l) && l.instance !== null);
|
|
64
|
+
const options = [];
|
|
65
|
+
for (const l of available) {
|
|
66
|
+
options.push({ value: `lic:${l.id}`, label: licenseLabel(l) });
|
|
67
|
+
}
|
|
68
|
+
for (const l of consumed) {
|
|
69
|
+
options.push({
|
|
70
|
+
value: `attached:${l.id}`,
|
|
71
|
+
label: licenseLabel(l),
|
|
72
|
+
hint: `em uso por ${instanceLabel(l.instance)}`,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
let state;
|
|
76
|
+
if (available.length + consumed.length === 0) {
|
|
77
|
+
state = "empty";
|
|
78
|
+
options.push({ value: "refresh", label: "Atualizar lista" });
|
|
79
|
+
options.push({ value: "community", label: "Ainda não tenho licença" });
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
state = available.length > 0 ? "has-available" : "none-available";
|
|
83
|
+
options.push({ value: "acquire", label: "Adquirir nova licença" });
|
|
84
|
+
options.push({
|
|
85
|
+
value: "skip",
|
|
86
|
+
label: "Seguir sem o Chatwoot Pro (OSS, sem Kanban)",
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const lastIdx = lastUsedId
|
|
90
|
+
? available.findIndex((l) => l.id === lastUsedId)
|
|
91
|
+
: -1;
|
|
92
|
+
return { options, defaultIndex: lastIdx >= 0 ? lastIdx : 0, state };
|
|
93
|
+
}
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hostingerEntryPath = hostingerEntryPath;
|
|
4
|
+
exports.installHostingerMcp = installHostingerMcp;
|
|
5
|
+
exports.hasHostingerSpecs = hasHostingerSpecs;
|
|
6
|
+
exports.bootstrapMcpSpecs = bootstrapMcpSpecs;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_os_1 = require("node:os");
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
|
+
const exec_1 = require("./exec");
|
|
11
|
+
// NOTE: Pacote único oficial (hostinger-api-mcp) que expõe 3 servidores por módulo
|
|
12
|
+
// (DNS, VPS, domains). Instalamos LOCAL (~/.fazer-ai/mcp) e apontamos o MCP pro
|
|
13
|
+
// entry .js via o runtime atual (`process.execPath`), em vez de `npx … @latest`: o npx tem startup
|
|
14
|
+
// variável (resolução + checagem de registro do @latest) que estoura os timeouts
|
|
15
|
+
// de conexão do agente (Hermes ~10s) → "Connection closed". O entry via runtime sobe
|
|
16
|
+
// em <1s, conecta de forma confiável nos 3 agentes e é cross-platform (o shim do
|
|
17
|
+
// `.bin/` viraria `.cmd`/`.ps1` no Windows). Token: no execute gravamos o LITERAL (vindo do
|
|
18
|
+
// ~/.fazer-ai/hostinger.json que já mantemos) no config de MCP do agente, pra o
|
|
19
|
+
// conector funcionar também ao REABRIR o agente fora do handoff, sem depender do
|
|
20
|
+
// env vivo nem da expansão de ${VAR} (que só confirmamos no Hermes). No preview do
|
|
21
|
+
// plan usamos a REFERÊNCIA ${HOSTINGER_API_TOKEN} e a marca como segredo, então o
|
|
22
|
+
// literal nunca aparece em saída/preview.
|
|
23
|
+
const HOSTINGER_PACKAGE = "hostinger-api-mcp@latest";
|
|
24
|
+
const HOSTINGER_MODULES = ["dns", "vps", "domains"];
|
|
25
|
+
const HOSTINGER_MCP_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), ".fazer-ai", "mcp");
|
|
26
|
+
// Caminho do ENTRY .js do servidor MCP de um módulo (o `bin` do pacote aponta
|
|
27
|
+
// pra src/servers/<mod>.js). Lançamos via o runtime atual (`process.execPath`) em vez do shim do
|
|
28
|
+
// `.bin/`: no Windows o shim vira `.cmd`/`.ps1` (que o agente não consegue lançar
|
|
29
|
+
// como stdio sem shell), enquanto o runtime é um caminho absoluto sempre resolvível. É o que o
|
|
30
|
+
// shim faz por baixo, só que cross-platform.
|
|
31
|
+
function hostingerEntryPath(mod) {
|
|
32
|
+
return (0, node_path_1.join)(HOSTINGER_MCP_DIR, "node_modules", "hostinger-api-mcp", "src", "servers", `${mod}.js`);
|
|
33
|
+
}
|
|
34
|
+
// Instala o pacote localmente (idempotente: pula se o binário já existe). Robusto a PATH mínimo, na
|
|
35
|
+
// ordem: bun → npm → heal+retry. O instalador instala o bun pra rodar o CLI, então o bun é garantido;
|
|
36
|
+
// sob `bunx` o próprio process.execPath JÁ é o bun (caminho absoluto, sem depender do PATH), o que cobre
|
|
37
|
+
// até o caso bun-only (sem node/npm). O heal do PATH (registro) só entra como último recurso, antes de
|
|
38
|
+
// retentar o npm.
|
|
39
|
+
async function installHostingerMcp(log) {
|
|
40
|
+
if ((0, node_fs_1.existsSync)(hostingerEntryPath("dns")))
|
|
41
|
+
return;
|
|
42
|
+
log?.("Instalando o conector da Hostinger...");
|
|
43
|
+
(0, node_fs_1.mkdirSync)(HOSTINGER_MCP_DIR, { recursive: true });
|
|
44
|
+
const bun = process.versions.bun
|
|
45
|
+
? process.execPath
|
|
46
|
+
: (await (0, exec_1.capture)("bun", ["--version"])).code === 0
|
|
47
|
+
? "bun"
|
|
48
|
+
: undefined;
|
|
49
|
+
if (bun) {
|
|
50
|
+
await (0, exec_1.run)(bun, ["add", `--cwd=${HOSTINGER_MCP_DIR}`, HOSTINGER_PACKAGE], {
|
|
51
|
+
quiet: true,
|
|
52
|
+
});
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const npmArgs = [
|
|
56
|
+
"install",
|
|
57
|
+
"--no-fund",
|
|
58
|
+
"--no-audit",
|
|
59
|
+
"--prefix",
|
|
60
|
+
HOSTINGER_MCP_DIR,
|
|
61
|
+
HOSTINGER_PACKAGE,
|
|
62
|
+
];
|
|
63
|
+
try {
|
|
64
|
+
await (0, exec_1.run)("npm", npmArgs, { quiet: true });
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
await (0, exec_1.healPath)();
|
|
68
|
+
await (0, exec_1.run)("npm", npmArgs, { quiet: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Algum spec é dos MCPs da Hostinger? (gateia o install no execute do agente.)
|
|
72
|
+
function hasHostingerSpecs(specs) {
|
|
73
|
+
return specs.some((s) => s.name.startsWith("hostinger-"));
|
|
74
|
+
}
|
|
75
|
+
function bootstrapMcpSpecs(opts) {
|
|
76
|
+
// Provider "other": sem MCP de provisionamento. O agente instrui DNS/VPS com
|
|
77
|
+
// base no conhecimento do provider que o usuário indicar (ver o skill).
|
|
78
|
+
// Hostinger só entra com token (index.ts captura/seta antes); sem token,
|
|
79
|
+
// conectar falharia, então pula em vez de injetar MCPs quebrados.
|
|
80
|
+
const literalToken = typeof opts.hostingerToken === "string" && opts.hostingerToken.length > 0
|
|
81
|
+
? opts.hostingerToken
|
|
82
|
+
: undefined;
|
|
83
|
+
const specs = opts.provider === "hostinger" && opts.hostingerTokenProvided
|
|
84
|
+
? HOSTINGER_MODULES.map((mod) => ({
|
|
85
|
+
name: `hostinger-${mod}`,
|
|
86
|
+
transport: "stdio",
|
|
87
|
+
command: process.execPath,
|
|
88
|
+
args: [hostingerEntryPath(mod)],
|
|
89
|
+
env: { HOSTINGER_API_TOKEN: literalToken ?? "${HOSTINGER_API_TOKEN}" },
|
|
90
|
+
// Só marca como segredo quando é o token literal (execute): o preview
|
|
91
|
+
// redige. A referência de env (plan) não é segredo e pode aparecer.
|
|
92
|
+
...(literalToken ? { secretEnvKeys: ["HOSTINGER_API_TOKEN"] } : {}),
|
|
93
|
+
note: `Hostinger ${mod}.`,
|
|
94
|
+
}))
|
|
95
|
+
: [];
|
|
96
|
+
// NOTE: o hub NÃO é injetado como MCP no agente. As ops do hub que o onboarding precisa saem pelo
|
|
97
|
+
// proxy `agents hub <op>` (hub-command.ts): menos privilégio (sem token mcp:admin na sessão do
|
|
98
|
+
// agente) e resolve o timing (o agente chama attach-license quando já sabe o host da instância).
|
|
99
|
+
return specs;
|
|
100
|
+
}
|