funifier-mcp 0.2.27 → 0.3.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/.cursor/rules/funifier.mdc +7 -7
- package/.github/copilot-instructions.md +10 -8
- package/AGENTS.md +8 -4
- package/README.md +6 -12
- package/datasource-funifier-docs/.coverage.json +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +13 -9
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/init.test.js +28 -9
- package/dist/cli/init.test.js.map +1 -1
- package/dist/cli/prompts.d.ts +1 -0
- package/dist/cli/prompts.d.ts.map +1 -1
- package/dist/cli/prompts.js +8 -0
- package/dist/cli/prompts.js.map +1 -1
- package/dist/cli/search.js +3 -3
- package/dist/cli/search.js.map +1 -1
- package/dist/cli/search.test.js +9 -9
- package/dist/cli/search.test.js.map +1 -1
- package/dist/mcp/bundle.js +84 -84
- package/dist/mcp/check-update.d.ts +5 -0
- package/dist/mcp/check-update.d.ts.map +1 -1
- package/dist/mcp/check-update.js +21 -10
- package/dist/mcp/check-update.js.map +1 -1
- package/dist/mcp/check-update.test.d.ts +2 -0
- package/dist/mcp/check-update.test.d.ts.map +1 -0
- package/dist/mcp/check-update.test.js +33 -0
- package/dist/mcp/check-update.test.js.map +1 -0
- package/dist/mcp/prompts/templates.d.ts.map +1 -1
- package/dist/mcp/prompts/templates.js +35 -0
- package/dist/mcp/prompts/templates.js.map +1 -1
- package/dist/mcp/resources/documentation.d.ts.map +1 -1
- package/dist/mcp/resources/documentation.js +2 -1
- package/dist/mcp/resources/documentation.js.map +1 -1
- package/dist/mcp/tools/docs-flow.test.d.ts +2 -0
- package/dist/mcp/tools/docs-flow.test.d.ts.map +1 -0
- package/dist/mcp/tools/docs-flow.test.js +91 -0
- package/dist/mcp/tools/docs-flow.test.js.map +1 -0
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js +27 -0
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/read-doc.d.ts +3 -0
- package/dist/mcp/tools/read-doc.d.ts.map +1 -0
- package/dist/mcp/tools/read-doc.js +97 -0
- package/dist/mcp/tools/read-doc.js.map +1 -0
- package/dist/mcp/tools/read-doc.test.d.ts +2 -0
- package/dist/mcp/tools/read-doc.test.d.ts.map +1 -0
- package/dist/mcp/tools/read-doc.test.js +92 -0
- package/dist/mcp/tools/read-doc.test.js.map +1 -0
- package/dist/mcp/tools/search-docs.js +3 -3
- package/dist/mcp/tools/search-docs.js.map +1 -1
- package/dist/mcp/tools/search-docs.test.d.ts +2 -0
- package/dist/mcp/tools/search-docs.test.d.ts.map +1 -0
- package/dist/mcp/tools/search-docs.test.js +100 -0
- package/dist/mcp/tools/search-docs.test.js.map +1 -0
- package/package.json +1 -1
- package/skills/acquire-funifier-knowledge/SKILL.md +25 -2
- package/skills/acquire-funifier-knowledge/assets/templates/OVERVIEW.md +39 -0
- package/skills/funifier/SKILL.md +5 -3
- package/skills/funifier/references/configure-security.md +7 -7
- package/skills/funifier/references/create-action.md +7 -7
- package/skills/funifier/references/create-aggregate.md +8 -8
- package/skills/funifier/references/create-challenge.md +8 -8
- package/skills/funifier/references/create-competition.md +6 -6
- package/skills/funifier/references/create-crossword.md +1 -1
- package/skills/funifier/references/create-custom-object.md +7 -7
- package/skills/funifier/references/create-custom-page.md +8 -8
- package/skills/funifier/references/create-folder.md +6 -6
- package/skills/funifier/references/create-lastmile.md +1 -1
- package/skills/funifier/references/create-leaderboard.md +8 -8
- package/skills/funifier/references/create-level.md +7 -7
- package/skills/funifier/references/create-notification.md +7 -7
- package/skills/funifier/references/create-point.md +7 -7
- package/skills/funifier/references/create-quiz.md +7 -7
- package/skills/funifier/references/create-scheduler.md +10 -10
- package/skills/funifier/references/create-story.md +1 -1
- package/skills/funifier/references/create-swap.md +6 -6
- package/skills/funifier/references/create-trigger.md +14 -14
- package/skills/funifier/references/create-virtual-good.md +7 -7
- package/skills/funifier/references/create-webhook.md +7 -7
- package/skills/funifier/references/create-websocket.md +8 -8
- package/skills/funifier/references/create-widget.md +7 -7
- package/skills/funifier/references/debug.md +16 -16
- package/skills/funifier/references/help.md +8 -8
- package/skills/funifier/references/implement-frontend.md +15 -15
- package/skills/funifier/references/import-csv.md +7 -7
- package/skills/funifier/references/manage-player.md +6 -6
- package/skills/funifier/references/manage-team.md +6 -6
- package/skills/funifier/references/upload-file.md +6 -6
|
@@ -88,13 +88,13 @@ function registerSearchDocsTool(server, docsPath) {
|
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
const lines = results.map((r, i) => {
|
|
91
|
-
const
|
|
92
|
-
return `${i + 1}.
|
|
91
|
+
const docPath = r.file.replace(/^knowledge\//, "").replace(/\.md$/, "");
|
|
92
|
+
return `${i + 1}. ${docPath} [score: ${r.score.toFixed(2)}]`;
|
|
93
93
|
});
|
|
94
94
|
return {
|
|
95
95
|
content: [{
|
|
96
96
|
type: "text",
|
|
97
|
-
text: `Documentation search results for "${query}":\n\n${lines.join("\n")}\n\
|
|
97
|
+
text: `Documentation search results for "${query}":\n\n${lines.join("\n")}\n\nRead the full content with funifier_read_doc path=<path> (e.g. funifier_read_doc path=${results[0].file.replace(/^knowledge\//, "").replace(/\.md$/, "")}).`,
|
|
98
98
|
}],
|
|
99
99
|
};
|
|
100
100
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-docs.js","sourceRoot":"","sources":["../../../src/mcp/tools/search-docs.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,wDAqEC;AA3ED,uCAAyB;AACzB,2CAA6B;AAC7B,6BAAwB;AAExB,gDAAkE;AAElE,SAAgB,sBAAsB,CAAC,MAAiB,EAAE,QAAgB;IACxE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,oBAAoB,CAAC,CAAC;IAClE,IAAI,WAAW,GAAuB,IAAI,CAAC;IAE3C,SAAS,SAAS;QAChB,IAAI,WAAW;YAAE,OAAO,WAAW,CAAC;QACpC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3C,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAgB,CAAC;QAC7E,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,+BAA+B;QACtC,WAAW,EACT,6FAA6F;YAC7F,yGAAyG;YACzG,oEAAoE;QACtE,WAAW,EAAE;YACX,KAAK,EAAE,OAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,CAAC,4GAA4G,CAAC;YACzH,GAAG,EAAE,OAAC;iBACH,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,kDAAkD,CAAC;YAC/D,SAAS,EAAE,OAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,4DAA4D,CAAC;SAC1E;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE;QAC5B,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kFAAkF,EAAE,CAAC;gBACrH,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,IAAA,oBAAU,EAAC,KAAK,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAExF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,oCAAoC,KAAK,uBAAuB,EAAE,CAAC;aACpG,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACjC,MAAM,
|
|
1
|
+
{"version":3,"file":"search-docs.js","sourceRoot":"","sources":["../../../src/mcp/tools/search-docs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-docs.test.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/search-docs.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const vitest_1 = require("vitest");
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const os = __importStar(require("os"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const search_docs_1 = require("./search-docs");
|
|
41
|
+
const lexical_1 = require("../../core/lexical");
|
|
42
|
+
// Package-style layout: docsPath is the knowledge/ dir; the index sits one level up,
|
|
43
|
+
// exactly where the tool resolves it (path.join(docsPath, "..", ".search-index.json")).
|
|
44
|
+
let root;
|
|
45
|
+
let docsPath;
|
|
46
|
+
function invokeWith(dp) {
|
|
47
|
+
const handlers = {};
|
|
48
|
+
const server = {
|
|
49
|
+
registerTool: (name, _config, handler) => {
|
|
50
|
+
handlers[name] = handler;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
(0, search_docs_1.registerSearchDocsTool)(server, dp);
|
|
54
|
+
return (args) => handlers["funifier_search_docs"](args);
|
|
55
|
+
}
|
|
56
|
+
(0, vitest_1.beforeAll)(() => {
|
|
57
|
+
root = fs.mkdtempSync(path.join(os.tmpdir(), "funifier-searchdocs-"));
|
|
58
|
+
docsPath = path.join(root, "knowledge");
|
|
59
|
+
fs.mkdirSync(docsPath, { recursive: true });
|
|
60
|
+
// Index keys carry the knowledge/ prefix, like the real build output, so the
|
|
61
|
+
// tool's strip of `^knowledge/` and `.md` is exercised.
|
|
62
|
+
const files = new Map([
|
|
63
|
+
[
|
|
64
|
+
"knowledge/modules/trigger.md",
|
|
65
|
+
"# Trigger\n\n## Groovy event\n\nTrigger fires on before_win events with a groovy script.",
|
|
66
|
+
],
|
|
67
|
+
["knowledge/modules/quiz.md", "# Quiz\n\nQuestions and answers for players."],
|
|
68
|
+
]);
|
|
69
|
+
fs.writeFileSync(path.join(root, ".search-index.json"), JSON.stringify((0, lexical_1.buildIndex)(files)));
|
|
70
|
+
});
|
|
71
|
+
(0, vitest_1.afterAll)(() => {
|
|
72
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
73
|
+
});
|
|
74
|
+
(0, vitest_1.describe)("funifier_search_docs", () => {
|
|
75
|
+
(0, vitest_1.it)("loads the index next to docsPath and ranks matching docs", () => {
|
|
76
|
+
const result = invokeWith(docsPath)({ query: "trigger groovy event before_win" });
|
|
77
|
+
(0, vitest_1.expect)(result.isError).toBeUndefined();
|
|
78
|
+
(0, vitest_1.expect)(result.content[0].text).toContain("modules/trigger");
|
|
79
|
+
});
|
|
80
|
+
(0, vitest_1.it)("returns paths stripped of knowledge/ and .md, pointing at funifier_read_doc (not a resource URI)", () => {
|
|
81
|
+
const text = invokeWith(docsPath)({ query: "trigger groovy event before_win" }).content[0].text;
|
|
82
|
+
(0, vitest_1.expect)(text).toContain("funifier_read_doc path=");
|
|
83
|
+
(0, vitest_1.expect)(text).not.toContain("funifier://docs/");
|
|
84
|
+
(0, vitest_1.expect)(text).not.toContain("knowledge/");
|
|
85
|
+
(0, vitest_1.expect)(text).not.toContain(".md");
|
|
86
|
+
});
|
|
87
|
+
(0, vitest_1.it)("returns isError when the search index is missing", () => {
|
|
88
|
+
const emptyRoot = fs.mkdtempSync(path.join(os.tmpdir(), "funifier-noindex-"));
|
|
89
|
+
const result = invokeWith(path.join(emptyRoot, "knowledge"))({ query: "trigger" });
|
|
90
|
+
(0, vitest_1.expect)(result.isError).toBe(true);
|
|
91
|
+
(0, vitest_1.expect)(result.content[0].text).toContain("index not found");
|
|
92
|
+
fs.rmSync(emptyRoot, { recursive: true, force: true });
|
|
93
|
+
});
|
|
94
|
+
(0, vitest_1.it)("reports no matches for an unrelated query", () => {
|
|
95
|
+
const result = invokeWith(docsPath)({ query: "zzzznonexistentterm" });
|
|
96
|
+
(0, vitest_1.expect)(result.isError).toBeUndefined();
|
|
97
|
+
(0, vitest_1.expect)(result.content[0].text).toContain("No documentation found");
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
//# sourceMappingURL=search-docs.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-docs.test.js","sourceRoot":"","sources":["../../../src/mcp/tools/search-docs.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -27,7 +27,7 @@ Produza esta estrutura em `docs/funifier/`. **Nenhum arquivo pode ficar vazio**
|
|
|
27
27
|
|
|
28
28
|
| Arquivo | Conteúdo |
|
|
29
29
|
|---------|----------|
|
|
30
|
-
| `OVERVIEW.md` | Identificação da instância, contagens agregadas por categoria, data do snapshot, escopo do mapeamento |
|
|
30
|
+
| `OVERVIEW.md` | Identificação da instância, contagens agregadas por categoria, data do snapshot, escopo do mapeamento e o **mapa de arquitetura em Mermaid** (o que dispara/premia/alimenta/chama o quê) |
|
|
31
31
|
| `GAME_MECHANICS.md` | Pontos, níveis, achievements/badges, challenges, missions, quizzes, virtual goods — com IDs, regras de atribuição e condições |
|
|
32
32
|
| `TRIGGERS.md` | Todos os triggers: nome, ID, entidade/evento de origem, condições, ações, status |
|
|
33
33
|
| `SCHEDULERS.md` | Cron jobs: nome, expressão cron, ação, próxima/última execução conhecida, status |
|
|
@@ -82,7 +82,7 @@ Avance pelas fases em ordem. As fases 1 e 6 são sempre completas (mesmo em Modo
|
|
|
82
82
|
1. **Validar conexão e identificar a instância.** Confirme que o MCP responde (uma chamada `funifier_database action=collections` ou um `funifier_list type=trigger limit=1` serve). Registre serverUrl/nome da conexão e a data do snapshot para o `OVERVIEW.md`.
|
|
83
83
|
2. **Inventário bruto.** Para cada um dos 18 tipos, rode `funifier_list` e registre os IDs e nomes. Rode `funifier_database action=collections` para descobrir coleções que revelam elementos fora do enum (webhooks, notifications, competitions, custom `__c`, player, team). Consulte `references/funifier-inventory-checklist.md` para a lista de perguntas por categoria.
|
|
84
84
|
3. **Detalhamento.** Para cada objeto que precisa de detalhe, rode `funifier_get mode=read` e extraia as regras, condições e ações. Amostre coleções relevantes com `funifier_database action=query` (limit pequeno) para entender o modelo de player/team.
|
|
85
|
-
4. **Análise cruzada.** Relacione objetos: qual `trigger` alimenta qual `point`/`challenge`; qual `scheduler` chama qual `public-endpoint`; quais `action`s satisfazem as regras de cada `challenge`; quais `leaderboard`s usam quais `point`s. Anote as relações para `CONCERNS.md` e `TECHNIQUES_AND_PATTERNS.md`.
|
|
85
|
+
4. **Análise cruzada e diagrama de arquitetura.** Relacione objetos: qual `trigger` alimenta qual `point`/`challenge`; qual `scheduler` chama qual `public-endpoint`; quais `action`s satisfazem as regras de cada `challenge`; quais `leaderboard`s usam quais `point`s. Anote as relações para `CONCERNS.md` e `TECHNIQUES_AND_PATTERNS.md`. Com essas relações já mapeadas (e **somente** com elas), monte o **mapa de arquitetura em Mermaid** e escreva-o na seção própria do `OVERVIEW.md` — siga as convenções em "Diagrama de arquitetura (Mermaid)" abaixo.
|
|
86
86
|
5. **Inferência de técnicas de jogos.** Classifique as técnicas observadas usando `references/game-techniques-taxonomy.md`. Cada técnica DEVE ser ligada aos IDs concretos que a implementam. Sem objeto que a sustente, não afirme a técnica.
|
|
87
87
|
6. **Validação.** Verifique: (a) cada claim aponta para um ID/objeto; (b) nenhuma seção obrigatória está vazia; (c) todo nome de ferramenta usado existe; (d) nenhum tipo inventado. Veja a checklist no fim deste arquivo.
|
|
88
88
|
7. **Apresentar.** Mostre um sumário (contagens + onde está cada doc) e uma lista numerada de itens `[ASK USER]` e divergências encontradas, para o usuário resolver.
|
|
@@ -95,6 +95,26 @@ Avance pelas fases em ordem. As fases 1 e 6 são sempre completas (mesmo em Modo
|
|
|
95
95
|
- **Nunca infira comportamento sem um objeto que o sustente.** "Provavelmente dispara X" é proibido; cite a config do trigger e o evento exato.
|
|
96
96
|
- **Toda seção termina com um bloco `## Evidence`** listando os IDs consultados e as chamadas MCP que produziram o conteúdo (ex.: `funifier_list type=trigger`, `funifier_get type=challenge id=...`).
|
|
97
97
|
|
|
98
|
+
## Diagrama de arquitetura (Mermaid)
|
|
99
|
+
|
|
100
|
+
O `OVERVIEW.md` carrega um **mapa de arquitetura** em Mermaid: a visão macro de "o que dispara, premia, alimenta e chama o quê". Ele é a *visualização* das relações já levantadas na Fase 4 — nunca uma fonte nova de verdade.
|
|
101
|
+
|
|
102
|
+
**Regras duras:**
|
|
103
|
+
|
|
104
|
+
1. **Toda aresta corresponde a um campo configurado num objeto real.** A origem é o `entity`/`event` de um `trigger`, a recompensa de um `challenge`, a métrica de um `leaderboard`, o preço de um `virtual-good-item`, etc. Sem campo que a sustente, a aresta não existe.
|
|
105
|
+
2. **Toda aresta é rastreável no doc da categoria.** Cada relação desenhada DEVE também aparecer como fato no doc correspondente (`TRIGGERS.md`, `GAME_MECHANICS.md`, `LEADERBOARDS.md`, ...). O diagrama não afirma nada que os docs não afirmem.
|
|
106
|
+
3. **Relação incerta = aresta tracejada `-.->` rotulada `[ASK USER]`.** Nunca desenhe uma aresta sólida "provável" (mesmo princípio do anti-padrão "provavelmente dispara X").
|
|
107
|
+
4. **Legibilidade > completude.** Se uma categoria tem **mais de 8 objetos**, não desenhe um nó por objeto: colapse a categoria num único nó anotado com a contagem (ex.: `challenges["challenges (×24)"]`) e desenhe só os fluxos principais. O mapa do `OVERVIEW.md` é macro; diagramas detalhados por área só quando o usuário pedir.
|
|
108
|
+
|
|
109
|
+
**Convenções de sintaxe (para o Mermaid não quebrar):**
|
|
110
|
+
|
|
111
|
+
- Use `flowchart LR`. Agrupe os nós em `subgraph`s por camada: `Ações & Eventos`, `Automação` (`trigger`/`scheduler`), `Mecânicas` (`challenge`/`quiz`/`level`/trilhas), `Recompensas` (`point`/`virtual-good`), `Visualização` (`leaderboard`/`aggregate`/`custom-page`/`widget`), `Integrações` (`public-endpoint`/`webhook`/`websocket`/`auth-module`).
|
|
112
|
+
- **IDs de nó**: apenas `[A-Za-z0-9_]`. Derive do nome substituindo qualquer outro caractere por `_`. Rótulo sempre entre aspas duplas, com nome + tipo: `tr_login["login_trigger · trigger"]`.
|
|
113
|
+
- **Verbos das arestas** (use só estes, sempre rotulados): `dispara` (trigger/scheduler → ação/endpoint), `premia` (challenge/quiz → point/virtual-good), `alimenta` (point → leaderboard; action → challenge), `exige` (level → point; item → preço), `lê` (aggregate → coleção; page/widget → aggregate/leaderboard), `chama` (frontend/page → public-endpoint; trigger → webhook externo).
|
|
114
|
+
- Uma instrução por linha; nunca use parênteses em rótulos sem aspas.
|
|
115
|
+
|
|
116
|
+
O esqueleto pronto para preencher está em `assets/templates/OVERVIEW.md` — substitua os `{{...}}` pelos objetos reais e remova as arestas que não tiverem relação comprovada.
|
|
117
|
+
|
|
98
118
|
## Modo Foco (Focus Area Mode)
|
|
99
119
|
|
|
100
120
|
Se o usuário pedir foco ("só triggers", "mecânicas e técnicas apenas"):
|
|
@@ -102,6 +122,7 @@ Se o usuário pedir foco ("só triggers", "mecânicas e técnicas apenas"):
|
|
|
102
122
|
- A **Fase 1** (validar/identificar) roda sempre, completa.
|
|
103
123
|
- Os documentos do foco são preenchidos **completos**.
|
|
104
124
|
- Os demais documentos obrigatórios **existem**, com suas seções presentes mas marcadas `[TODO]` (e uma nota indicando que ficaram fora do escopo desta execução).
|
|
125
|
+
- O **mapa de arquitetura** no `OVERVIEW.md` é sempre gerado; seu escopo reflete o foco — categorias fora do foco aparecem colapsadas num único nó com a contagem.
|
|
105
126
|
- A **Fase 6** (validação) roda em **todos** os documentos.
|
|
106
127
|
|
|
107
128
|
## Anti-padrões
|
|
@@ -114,6 +135,7 @@ Se o usuário pedir foco ("só triggers", "mecânicas e técnicas apenas"):
|
|
|
114
135
|
| Confundir achievement com challenge ou mission | Respeitar a tipagem do Funifier; cada categoria no seu doc |
|
|
115
136
|
| Inventar um tipo (ex.: tratar "webhook" como `funifier_list type=webhook`) | Usar só os 18 tipos reais; inferir o resto de coleções e ações |
|
|
116
137
|
| Modificar a instância para "testar" um comportamento | Apenas ler; nunca `save`/`delete`/`execute`/`insert`/`update` |
|
|
138
|
+
| Desenhar uma aresta "provável" no diagrama Mermaid | Só desenhar arestas com um campo de objeto que as sustente; incertezas viram `-.->` `[ASK USER]` |
|
|
117
139
|
|
|
118
140
|
## Quando ler cada arquivo de referência
|
|
119
141
|
|
|
@@ -128,5 +150,6 @@ Se o usuário pedir foco ("só triggers", "mecânicas e técnicas apenas"):
|
|
|
128
150
|
- [ ] Todo objeto com status conhecido tem o status registrado.
|
|
129
151
|
- [ ] Nenhum tipo inventado — só os 18 tipos reais + coleções via `funifier_database`.
|
|
130
152
|
- [ ] Cada documento termina com um bloco `## Evidence`.
|
|
153
|
+
- [ ] O `OVERVIEW.md` contém o mapa de arquitetura em Mermaid; cada aresta tem um campo de objeto que a sustenta e o mesmo fato aparece no doc da categoria. Incertezas são `-.->` `[ASK USER]`, não arestas sólidas.
|
|
131
154
|
- [ ] Itens dependentes de intenção estão marcados `[ASK USER]`, não adivinhados.
|
|
132
155
|
- [ ] Nenhuma ferramenta de escrita foi usada (`save`/`delete`/`execute`/`insert`/`update`/`bulk`/`folder progress`).
|
|
@@ -38,6 +38,44 @@ Contagem por tipo listável (preencha 0 quando não houver — não omita):
|
|
|
38
38
|
|----------|---------|-------------|
|
|
39
39
|
| {{webhook/notification/competition/...}} | {{collection}} | {{n}} |
|
|
40
40
|
|
|
41
|
+
### Mapa de Arquitetura
|
|
42
|
+
|
|
43
|
+
Visão macro de "o que dispara/premia/alimenta/chama o quê". **Regras:** toda aresta vem de um campo real (trigger `entity`/`event`, recompensa de challenge, métrica de leaderboard, preço de virtual-good...) e o mesmo fato aparece no doc da categoria; relação incerta = `-.->` `[ASK USER]`; categoria com >8 objetos = um único nó com a contagem (`challenges["challenges (×24)"]`). Verbos permitidos: `dispara`, `premia`, `alimenta`, `exige`, `lê`, `chama`. Substitua os `{{...}}` por IDs de nó saneados (`[A-Za-z0-9_]`) e remova as arestas sem relação comprovada.
|
|
44
|
+
|
|
45
|
+
```mermaid
|
|
46
|
+
flowchart LR
|
|
47
|
+
subgraph Acoes["Ações & Eventos"]
|
|
48
|
+
{{act_id}}["{{nome}} · action"]
|
|
49
|
+
end
|
|
50
|
+
subgraph Automacao["Automação"]
|
|
51
|
+
{{trigger_id}}["{{nome}} · trigger"]
|
|
52
|
+
{{scheduler_id}}["{{nome}} · scheduler"]
|
|
53
|
+
end
|
|
54
|
+
subgraph Mecanicas["Mecânicas"]
|
|
55
|
+
{{challenge_id}}["{{nome}} · challenge"]
|
|
56
|
+
{{level_id}}["{{nome}} · level"]
|
|
57
|
+
end
|
|
58
|
+
subgraph Recompensas["Recompensas"]
|
|
59
|
+
{{point_id}}["{{nome}} · point"]
|
|
60
|
+
{{vg_id}}["{{nome}} · virtual-good"]
|
|
61
|
+
end
|
|
62
|
+
subgraph Visualizacao["Visualização"]
|
|
63
|
+
{{leaderboard_id}}["{{nome}} · leaderboard"]
|
|
64
|
+
{{aggregate_id}}["{{nome}} · aggregate"]
|
|
65
|
+
end
|
|
66
|
+
subgraph Integracoes["Integrações"]
|
|
67
|
+
{{endpoint_id}}["{{nome}} · public-endpoint"]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
{{act_id}} -->|alimenta| {{challenge_id}}
|
|
71
|
+
{{trigger_id}} -->|premia| {{point_id}}
|
|
72
|
+
{{challenge_id}} -->|premia| {{vg_id}}
|
|
73
|
+
{{point_id}} -->|alimenta| {{leaderboard_id}}
|
|
74
|
+
{{level_id}} -->|exige| {{point_id}}
|
|
75
|
+
{{aggregate_id}} -->|lê| {{point_id}}
|
|
76
|
+
{{scheduler_id}} -.->|chama [ASK USER]| {{endpoint_id}}
|
|
77
|
+
```
|
|
78
|
+
|
|
41
79
|
## Extended (Opcional)
|
|
42
80
|
- Versão/plano da instância, se conhecido.
|
|
43
81
|
- Principais áreas funcionais identificadas (resumo de 2-3 linhas).
|
|
@@ -45,3 +83,4 @@ Contagem por tipo listável (preencha 0 quando não houver — não omita):
|
|
|
45
83
|
## Evidence
|
|
46
84
|
- `funifier_list type=<cada um dos 18 tipos>`
|
|
47
85
|
- `funifier_database action=collections`
|
|
86
|
+
- Mapa de arquitetura: cada aresta é evidenciada pelo objeto/campo que a sustenta, documentado no doc da categoria correspondente ({{ex.: TRIGGERS.md #id, GAME_MECHANICS.md #id}}).
|
package/skills/funifier/SKILL.md
CHANGED
|
@@ -21,11 +21,13 @@ Only proceed directly with MCP tools when no row matches.
|
|
|
21
21
|
3. Read the file listed in the Reference column
|
|
22
22
|
4. Follow the workflow in that file
|
|
23
23
|
|
|
24
|
-
For general questions with no matching task,
|
|
24
|
+
For general questions with no matching task, search the docs with the MCP tool:
|
|
25
25
|
|
|
26
|
-
```bash
|
|
27
|
-
npx funifier-mcp search "<user question>"
|
|
28
26
|
```
|
|
27
|
+
funifier_search_docs "<user question>"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Then read a result with `funifier_read_doc path=<path>`.
|
|
29
31
|
|
|
30
32
|
## Routing Table
|
|
31
33
|
|
|
@@ -6,19 +6,19 @@ Configure Funifier security settings — roles, scopes, app tokens, and auth par
|
|
|
6
6
|
|
|
7
7
|
## Before starting — find relevant docs
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use the `funifier_search_docs` MCP tool to load only what you need:
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
11
|
+
```
|
|
12
|
+
funifier_search_docs "security role scope token auth app permission basic bearer access-control"
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Then read the most relevant results with `funifier_read_doc path=<path>`.
|
|
16
16
|
|
|
17
17
|
## Primary docs for this skill
|
|
18
18
|
|
|
19
|
-
If search returns insufficient results, read directly:
|
|
19
|
+
If search returns insufficient results, read these directly:
|
|
20
20
|
|
|
21
|
-
- `
|
|
21
|
+
- `funifier_read_doc path=modules/security`
|
|
22
22
|
|
|
23
23
|
## Steps
|
|
24
24
|
|
|
@@ -54,7 +54,7 @@ Authorization: Bearer <studio_token>
|
|
|
54
54
|
### 2. Ler a documentação do módulo
|
|
55
55
|
|
|
56
56
|
```
|
|
57
|
-
|
|
57
|
+
funifier_read_doc path=modules/security
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
### 3. Definir roles e apps
|
|
@@ -6,20 +6,20 @@ Create a Funifier action — define trackable player behaviors with attributes
|
|
|
6
6
|
|
|
7
7
|
## Before starting — find relevant docs
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use the `funifier_search_docs` MCP tool to load only what you need:
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
11
|
+
```
|
|
12
|
+
funifier_search_docs "action track player behavior attributes log event"
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Then read the most relevant results with `funifier_read_doc path=<path>`.
|
|
16
16
|
|
|
17
17
|
## Primary docs for this skill
|
|
18
18
|
|
|
19
|
-
If search returns insufficient results, read directly:
|
|
19
|
+
If search returns insufficient results, read these directly:
|
|
20
20
|
|
|
21
|
-
- `
|
|
22
|
-
- `
|
|
21
|
+
- `funifier_read_doc path=modules/action`
|
|
22
|
+
- `funifier_read_doc path=modules/action-log`
|
|
23
23
|
|
|
24
24
|
## Steps
|
|
25
25
|
|
|
@@ -45,21 +45,21 @@ Note que `aggregate` é uma **string** contendo JSON serializado (com `\n` e `\"
|
|
|
45
45
|
|
|
46
46
|
## Before starting — find relevant docs
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
Use the `funifier_search_docs` MCP tool to load only what you need:
|
|
49
49
|
|
|
50
|
-
```
|
|
51
|
-
|
|
50
|
+
```
|
|
51
|
+
funifier_search_docs "aggregate mongodb pipeline report dashboard query prepared"
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
Then read the most relevant results with `funifier_read_doc path=<path>`.
|
|
55
55
|
|
|
56
56
|
## Primary docs for this skill
|
|
57
57
|
|
|
58
|
-
If search returns insufficient results, read directly:
|
|
58
|
+
If search returns insufficient results, read these directly:
|
|
59
59
|
|
|
60
|
-
- `
|
|
61
|
-
- `
|
|
62
|
-
- `
|
|
60
|
+
- `funifier_read_doc path=guides/aggregates`
|
|
61
|
+
- `funifier_read_doc path=guides/database-access`
|
|
62
|
+
- `funifier_read_doc path=modules/database`
|
|
63
63
|
|
|
64
64
|
## Steps
|
|
65
65
|
|
|
@@ -6,21 +6,21 @@ Create a Funifier challenge — missions with action rules and point rewards
|
|
|
6
6
|
|
|
7
7
|
## Before starting — find relevant docs
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use the `funifier_search_docs` MCP tool to load only what you need:
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
11
|
+
```
|
|
12
|
+
funifier_search_docs "challenge mission reward rules action points gamification"
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Then read the most relevant results with `funifier_read_doc path=<path>`.
|
|
16
16
|
|
|
17
17
|
## Primary docs for this skill
|
|
18
18
|
|
|
19
|
-
If search returns insufficient results, read directly:
|
|
19
|
+
If search returns insufficient results, read these directly:
|
|
20
20
|
|
|
21
|
-
- `
|
|
22
|
-
- `
|
|
23
|
-
- `
|
|
21
|
+
- `funifier_read_doc path=modules/challenge`
|
|
22
|
+
- `funifier_read_doc path=modules/action`
|
|
23
|
+
- `funifier_read_doc path=modules/point`
|
|
24
24
|
|
|
25
25
|
## Steps
|
|
26
26
|
|
|
@@ -6,19 +6,19 @@ Create a Funifier competition — timed ranking contests with player enrollment,
|
|
|
6
6
|
|
|
7
7
|
## Before starting — find relevant docs
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use the `funifier_search_docs` MCP tool to load only what you need:
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
11
|
+
```
|
|
12
|
+
funifier_search_docs "competition contest ranking tournament enrollment rewards position gt26"
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Then read the most relevant results with `funifier_read_doc path=<path>`.
|
|
16
16
|
|
|
17
17
|
## Primary docs for this skill
|
|
18
18
|
|
|
19
|
-
If search returns insufficient results, read directly:
|
|
19
|
+
If search returns insufficient results, read these directly:
|
|
20
20
|
|
|
21
|
-
- `
|
|
21
|
+
- `funifier_read_doc path=modules/competition`
|
|
22
22
|
|
|
23
23
|
## Steps
|
|
24
24
|
|
|
@@ -6,20 +6,20 @@ Create and manage Funifier custom objects — domain-specific collections with t
|
|
|
6
6
|
|
|
7
7
|
## Before starting — find relevant docs
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use the `funifier_search_docs` MCP tool to load only what you need:
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
11
|
+
```
|
|
12
|
+
funifier_search_docs "custom object collection database crud __c domain entity business"
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Then read the most relevant results with `funifier_read_doc path=<path>`.
|
|
16
16
|
|
|
17
17
|
## Primary docs for this skill
|
|
18
18
|
|
|
19
|
-
If search returns insufficient results, read directly:
|
|
19
|
+
If search returns insufficient results, read these directly:
|
|
20
20
|
|
|
21
|
-
- `
|
|
22
|
-
- `
|
|
21
|
+
- `funifier_read_doc path=modules/custom-object`
|
|
22
|
+
- `funifier_read_doc path=modules/database`
|
|
23
23
|
|
|
24
24
|
## Steps
|
|
25
25
|
|
|
@@ -45,21 +45,21 @@ Note que `aggregate` é uma **string** contendo JSON serializado (com `\n` e `\"
|
|
|
45
45
|
|
|
46
46
|
## Before starting — find relevant docs
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
Use the `funifier_search_docs` MCP tool to load only what you need:
|
|
49
49
|
|
|
50
|
-
```
|
|
51
|
-
|
|
50
|
+
```
|
|
51
|
+
funifier_search_docs "custom page studio dashboard angularjs bootstrap admin crud kpi"
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
Then read the most relevant results with `funifier_read_doc path=<path>`.
|
|
55
55
|
|
|
56
56
|
## Primary docs for this skill
|
|
57
57
|
|
|
58
|
-
If search returns insufficient results, read directly:
|
|
58
|
+
If search returns insufficient results, read these directly:
|
|
59
59
|
|
|
60
|
-
- `
|
|
61
|
-
- `
|
|
62
|
-
- `
|
|
60
|
+
- `funifier_read_doc path=modules/studio-page`
|
|
61
|
+
- `funifier_read_doc path=guides/aggregates`
|
|
62
|
+
- `funifier_read_doc path=modules/auth`
|
|
63
63
|
|
|
64
64
|
## Steps
|
|
65
65
|
|
|
@@ -6,19 +6,19 @@ Create a Funifier learning trail (folder) — hierarchical courses with content
|
|
|
6
6
|
|
|
7
7
|
## Before starting — find relevant docs
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use the `funifier_search_docs` MCP tool to load only what you need:
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
11
|
+
```
|
|
12
|
+
funifier_search_docs "folder trail course learning progress content hierarchy unlock training lms"
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Then read the most relevant results with `funifier_read_doc path=<path>`.
|
|
16
16
|
|
|
17
17
|
## Primary docs for this skill
|
|
18
18
|
|
|
19
|
-
If search returns insufficient results, read directly:
|
|
19
|
+
If search returns insufficient results, read these directly:
|
|
20
20
|
|
|
21
|
-
- `
|
|
21
|
+
- `funifier_read_doc path=modules/folder`
|
|
22
22
|
|
|
23
23
|
## Steps
|
|
24
24
|
|
|
@@ -6,21 +6,21 @@ Create a Funifier leaderboard — rankings by points, actions, or attributes
|
|
|
6
6
|
|
|
7
7
|
## Before starting — find relevant docs
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use the `funifier_search_docs` MCP tool to load only what you need:
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
11
|
+
```
|
|
12
|
+
funifier_search_docs "leaderboard ranking score top players classification board"
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Then read the most relevant results with `funifier_read_doc path=<path>`.
|
|
16
16
|
|
|
17
17
|
## Primary docs for this skill
|
|
18
18
|
|
|
19
|
-
If search returns insufficient results, read directly:
|
|
19
|
+
If search returns insufficient results, read these directly:
|
|
20
20
|
|
|
21
|
-
- `
|
|
22
|
-
- `
|
|
23
|
-
- `
|
|
21
|
+
- `funifier_read_doc path=modules/leaderboard`
|
|
22
|
+
- `funifier_read_doc path=modules/point`
|
|
23
|
+
- `funifier_read_doc path=modules/action`
|
|
24
24
|
|
|
25
25
|
## Steps
|
|
26
26
|
|
|
@@ -6,20 +6,20 @@ Create Funifier levels — progression system based on accumulated points
|
|
|
6
6
|
|
|
7
7
|
## Before starting — find relevant docs
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use the `funifier_search_docs` MCP tool to load only what you need:
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
11
|
+
```
|
|
12
|
+
funifier_search_docs "level progression rank tier xp points unlock"
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Then read the most relevant results with `funifier_read_doc path=<path>`.
|
|
16
16
|
|
|
17
17
|
## Primary docs for this skill
|
|
18
18
|
|
|
19
|
-
If search returns insufficient results, read directly:
|
|
19
|
+
If search returns insufficient results, read these directly:
|
|
20
20
|
|
|
21
|
-
- `
|
|
22
|
-
- `
|
|
21
|
+
- `funifier_read_doc path=modules/level`
|
|
22
|
+
- `funifier_read_doc path=modules/point`
|
|
23
23
|
|
|
24
24
|
## Steps
|
|
25
25
|
|