jarvis-ai-framework 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/AGENTS.md +416 -0
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/agents/AGENTS.md +234 -0
- package/agents/README.md +309 -0
- package/agents/engineering/data/eng.data-engineer.agent.md +309 -0
- package/agents/engineering/eng.agent.md +303 -0
- package/agents/engineering/eng.bug-hunter.md +386 -0
- package/agents/engineering/eng.cybersecurity.agent.md +503 -0
- package/agents/engineering/eng.dev-code-reviewer.md +148 -0
- package/agents/engineering/eng.docs-writer.md +152 -0
- package/agents/engineering/eng.frontend.agent.md +117 -0
- package/agents/engineering/eng.rpa.agent.md +215 -0
- package/agents/engineering/eng.tech-analyst.agent.md +102 -0
- package/agents/engineering/eng.ux-designer.agent.md +193 -0
- package/agents/engineering/qa/eng.qa.cypress-specialist.md +109 -0
- package/agents/engineering/qa/eng.qa.quality-champion-task-agent.md +85 -0
- package/agents/engineering/qa/eng.qa.quality-strategist.md +111 -0
- package/agents/engineering/qa/eng.qa.test-architect.md +400 -0
- package/agents/engineering/qa/eng.qa.test-planner.md +477 -0
- package/agents/engineering/qa/eng.qa.testing-engineer.md +339 -0
- package/agents/product/prod.pm-checker.md +52 -0
- package/bin/commands/docs-publish.js +184 -0
- package/bin/commands/docs-sync.js +139 -0
- package/bin/commands/info.js +87 -0
- package/bin/commands/init.js +237 -0
- package/bin/commands/install-rtk.js +90 -0
- package/bin/commands/list.js +48 -0
- package/bin/commands/qa-signoff.js +112 -0
- package/bin/commands/whoami.js +43 -0
- package/bin/jarvis.js +159 -0
- package/bin/lib/auth/session.js +56 -0
- package/bin/lib/config/constants.js +123 -0
- package/bin/lib/config/ide-config.js +233 -0
- package/bin/lib/core/scanner.js +124 -0
- package/bin/lib/core/sync-engine.js +551 -0
- package/bin/lib/docs/fetch-file.sh +41 -0
- package/bin/lib/docs/publish-file.sh +284 -0
- package/bin/lib/docs/validate-frontmatter.js +157 -0
- package/bin/lib/env-loader.js +198 -0
- package/bin/lib/tasks/comment.js +131 -0
- package/bin/lib/utils/git-parser.js +145 -0
- package/bin/lib/utils/logger.js +104 -0
- package/bin/lib/utils/npmrc-parser.js +106 -0
- package/bin/lib/utils/paths.js +55 -0
- package/bin/lib/utils/ui.js +59 -0
- package/bin/lib/vcs/api.js +312 -0
- package/bin/lib/vcs/create-issue.js +43 -0
- package/bin/lib/vcs/create-merge.js +43 -0
- package/bin/lib/vcs/fetch-raw.js +30 -0
- package/bin/postinstall.js +41 -0
- package/members.md +25 -0
- package/package.json +55 -0
- package/rules/AGENTS.md +205 -0
- package/rules/engineering/data/data-rules.md +200 -0
- package/rules/engineering/eng-rules.md +243 -0
- package/rules/engineering/eng-security-rules.md +186 -0
- package/rules/engineering/eng.breakdown-subtasks-rules.md +585 -0
- package/rules/engineering/eng.bump-rules.md +27 -0
- package/rules/engineering/eng.docs-scraping-rules.md +64 -0
- package/rules/engineering/eng.downstream-flow-rules.md +297 -0
- package/rules/engineering/eng.integrations-rules.md +73 -0
- package/rules/engineering/eng.plan-rules.md +333 -0
- package/rules/engineering/eng.pr-rules.md +359 -0
- package/rules/engineering/eng.pre-pr-rules.md +103 -0
- package/rules/engineering/eng.start-rules.md +246 -0
- package/rules/engineering/eng.tech-spec-rules.md +968 -0
- package/rules/engineering/eng.work-rules.md +312 -0
- package/rules/engineering/frontend/eng.frontend-rules.md +147 -0
- package/rules/engineering/qa/eng.qa.cypress-standards-rules.md +259 -0
- package/rules/engineering/qa/eng.qa.exploratory-session-rules.md +137 -0
- package/rules/engineering/qa/eng.qa.quality-gate-scoring-rules.md +181 -0
- package/rules/engineering/qa/eng.qa.tech-spec-validation-criteria-rules.md +120 -0
- package/rules/engineering/rpa/eng.rpa-rules.md +230 -0
- package/rules/product/README.md +24 -0
- package/rules/product/prod-rules.md +151 -0
- package/rules/rtk-rules.md +68 -0
- package/skills/AGENTS.md +290 -0
- package/skills/SKILLS-ROADMAP.md +333 -0
- package/skills/churn-audit/SKILL.md +385 -0
- package/skills/context-detect/SKILL.md +399 -0
- package/skills/context-detect/assets/context-profile-template.md +127 -0
- package/skills/docs-central/README.md +310 -0
- package/skills/docs-central/SKILL.md +423 -0
- package/skills/docs-index/SKILL.md +377 -0
- package/skills/eng-ai-engineer/SKILL.md +296 -0
- package/skills/eng-arch-c4/SKILL.md +358 -0
- package/skills/eng-arch-c4/assets/example-code.md +189 -0
- package/skills/eng-arch-c4/assets/example-component.md +105 -0
- package/skills/eng-arch-c4/assets/example-container.md +104 -0
- package/skills/eng-arch-c4/assets/example-context.md +81 -0
- package/skills/eng-backend/SKILL.md +776 -0
- package/skills/eng-browser-extension-builder/SKILL.md +385 -0
- package/skills/eng-cybersecurity/SKILL.md +645 -0
- package/skills/eng-data-bi/SKILL.md +199 -0
- package/skills/eng-data-debug/SKILL.md +307 -0
- package/skills/eng-data-engineer/SKILL.md +256 -0
- package/skills/eng-data-onboard/SKILL.md +310 -0
- package/skills/eng-data-orchestrator/SKILL.md +426 -0
- package/skills/eng-design-system/SKILL.md +619 -0
- package/skills/eng-docs-write/SKILL.md +312 -0
- package/skills/eng-frontend/SKILL.md +913 -0
- package/skills/eng-jira-comment/SKILL.md +17 -0
- package/skills/eng-microfrontend/SKILL.md +602 -0
- package/skills/eng-ms-trace/SKILL.md +469 -0
- package/skills/eng-nestjs/SKILL.md +791 -0
- package/skills/eng-performance-engineer/SKILL.md +312 -0
- package/skills/eng-pr/SKILL.md +339 -0
- package/skills/eng-qa-a11y-audit/SKILL.md +269 -0
- package/skills/eng-qa-bug-report/SKILL.md +1088 -0
- package/skills/eng-qa-bug-report/TASK_MANAGERS.md +138 -0
- package/skills/eng-qa-cypress-e2e/SKILL.md +177 -0
- package/skills/eng-qa-dev-guide/SKILL.md +164 -0
- package/skills/eng-qa-e2e/SKILL.md +400 -0
- package/skills/eng-qa-e2e-spec-writer/SKILL.md +322 -0
- package/skills/eng-qa-exploratory/SKILL.md +188 -0
- package/skills/eng-qa-gate/SKILL.md +370 -0
- package/skills/eng-qa-gate/assets/checklist-validacao.md +291 -0
- package/skills/eng-qa-graphql-contract/SKILL.md +256 -0
- package/skills/eng-qa-quality-report/SKILL.md +412 -0
- package/skills/eng-qa-test-plan/SKILL.md +466 -0
- package/skills/eng-qa-test-plan/assets/test-coverage-template.md +92 -0
- package/skills/eng-qa-test-plan/assets/test-patterns.md +178 -0
- package/skills/eng-qa-testsprite/SKILL.md +325 -0
- package/skills/eng-qa-testsprite/references/testsprite-mcp.md +224 -0
- package/skills/eng-qa-unit-test/SKILL.md +471 -0
- package/skills/eng-rabbitmq/SKILL.md +661 -0
- package/skills/eng-scraper/SKILL.md +683 -0
- package/skills/eng-scraper-robot-builder/SKILL.md +370 -0
- package/skills/eng-security-patch/SKILL.md +378 -0
- package/skills/eng-security-triage/SKILL.md +266 -0
- package/skills/eng-task-comment/SKILL.md +60 -0
- package/skills/eng-tech-analyst/SKILL.md +529 -0
- package/skills/eng-threat-model/SKILL.md +161 -0
- package/skills/init-jarvis/SKILL.md +1304 -0
- package/skills/init-jarvis/assets/mcp-configs.md +389 -0
- package/skills/init-jarvis/assets/onboarding-checklist.md +104 -0
- package/skills/init-jarvis/assets/setup-guide.md +360 -0
- package/skills/lovable-prompt-generator/SKILL.md +304 -0
- package/skills/prod-roadmap-report/README.md +303 -0
- package/skills/prod-roadmap-report/SKILL.md +198 -0
- package/skills/prod-roadmap-report/commands/status.compiled.single.team.md +23 -0
- package/skills/prod-roadmap-report/commands/status.list.projects.md +17 -0
- package/skills/prod-roadmap-report/commands/status.memory.md +192 -0
- package/skills/prod-roadmap-report/commands/status.roadmap.preview.md +94 -0
- package/skills/prod-roadmap-report/references/detailed-guide.md +236 -0
- package/skills/prod-roadmap-report/rules/detailed-guide.md +237 -0
- package/skills/prod-roadmap-report/rules/status-report-rules.md +44 -0
- package/skills/prod-roadmap-report/templates/template-multiple-teams-compiled-status.md +53 -0
- package/skills/prod-roadmap-report/templates/template-projects-list.md +23 -0
- package/skills/prod-roadmap-report/templates/template-single-team-compiled-status.md +60 -0
- package/skills/prod-roadmap-report/templates/template-single-team-status.md +49 -0
- package/skills/prod-specs/SKILL.md +108 -0
- package/skills/prod-specs/references/prod.spec.clarify.md +176 -0
- package/skills/prod-specs/references/prod.spec.epic.md +107 -0
- package/skills/prod-specs/references/prod.spec.frd.md +135 -0
- package/skills/prod-specs/references/prod.spec.issue.md +145 -0
- package/skills/prod-specs/references/prod.spec.prd.md +118 -0
- package/skills/prod-specs/rules/prod-spec-rules.md +186 -0
- package/skills/prod-specs/templates/prod-breakdown-template.md +136 -0
- package/skills/prod-specs/templates/prod-epic-template.md +76 -0
- package/skills/prod-specs/templates/prod-frd-template.md +172 -0
- package/skills/prod-specs/templates/prod-issue-template.md +68 -0
- package/skills/prod-specs/templates/prod-prd-full-template.md +159 -0
- package/skills/prod-specs/templates/prod-prd-template.md +173 -0
- package/skills/prod-specs-update/SKILL.md +272 -0
- package/skills/report-issue/SKILL.md +156 -0
- package/taxonomy.md +270 -0
- package/templates/AGENTS.md +189 -0
- package/templates/CDD aplicado a Prompts.md +182 -0
- package/templates/ENV-template.md +187 -0
- package/templates/engineering/AGENTS-template.md +71 -0
- package/templates/engineering/ARD-template.md +193 -0
- package/templates/engineering/CONTACTS-template.md +135 -0
- package/templates/engineering/PR-template.md +40 -0
- package/templates/engineering/RFC-Playbook.md +325 -0
- package/templates/engineering/RFC-template.md +199 -0
- package/templates/engineering/architecture-template.md +277 -0
- package/templates/engineering/breakdown-subtasks-template.md +582 -0
- package/templates/engineering/c4-model-template.md +516 -0
- package/templates/engineering/data-contract-template.md +135 -0
- package/templates/engineering/data-pipeline-template.md +163 -0
- package/templates/engineering/plan-template.md +255 -0
- package/templates/engineering/qa/eng.qa.quality-gate-examples-template.md +311 -0
- package/templates/engineering/qa/eng.qa.quality-gate-report-template.md +249 -0
- package/templates/engineering/qa/qa.cypress-test-template.md +172 -0
- package/templates/engineering/qa/qa.exploratory-session-template.md +148 -0
- package/templates/engineering/qa/qa.quality-report-template.md +130 -0
- package/templates/engineering/qa/qa.release-signoff-template.md +54 -0
- package/templates/engineering/qa/qa.sprint-plan-template.md +49 -0
- package/templates/engineering/swagger-template.md +145 -0
- package/templates/engineering/tech-spec-template.md +497 -0
- package/templates/engineering/work-progress-template.md +155 -0
- package/workflows/AGENTS.md +240 -0
- package/workflows/README.md +160 -0
- package/workflows/all-tools.md +11 -0
- package/workflows/engineering/data/data.contract.md +202 -0
- package/workflows/engineering/data/data.new-pipeline.md +234 -0
- package/workflows/engineering/eng.breakdown-subtasks.md +420 -0
- package/workflows/engineering/eng.bug-audit.md +591 -0
- package/workflows/engineering/eng.build-tech-spec.md +1116 -0
- package/workflows/engineering/eng.create-ard-from-code.md +259 -0
- package/workflows/engineering/eng.create-ard.md +382 -0
- package/workflows/engineering/eng.create-rfc.md +245 -0
- package/workflows/engineering/eng.debug.md +479 -0
- package/workflows/engineering/eng.docs.md +40 -0
- package/workflows/engineering/eng.light-arch.md +84 -0
- package/workflows/engineering/eng.plan.md +213 -0
- package/workflows/engineering/eng.pr.md +466 -0
- package/workflows/engineering/eng.pre-pr.md +167 -0
- package/workflows/engineering/eng.review.md +185 -0
- package/workflows/engineering/eng.rpa.robot.md +342 -0
- package/workflows/engineering/eng.security-audit.md +312 -0
- package/workflows/engineering/eng.security-incident.md +275 -0
- package/workflows/engineering/eng.security-pipeline.md +210 -0
- package/workflows/engineering/eng.security-review.md +235 -0
- package/workflows/engineering/eng.start.md +494 -0
- package/workflows/engineering/eng.work.md +558 -0
- package/workflows/engineering/frontend/eng.frontend-component.md +190 -0
- package/workflows/engineering/frontend/eng.frontend-perf-audit.md +375 -0
- package/workflows/engineering/frontend/eng.frontend-review.md +185 -0
- package/workflows/engineering/qa/eng.qa-dev-quality-guide.md +51 -0
- package/workflows/engineering/qa/eng.qa-e2e-test-generation.md +51 -0
- package/workflows/engineering/qa/eng.qa-exploratory-session.md +60 -0
- package/workflows/engineering/qa/eng.qa-quality-gate-validation.md +202 -0
- package/workflows/engineering/qa/eng.qa-quality-report.md +83 -0
- package/workflows/engineering/qa/eng.qa-refinement-entry.md +83 -0
- package/workflows/engineering/qa/eng.qa-release-signoff.md +170 -0
- package/workflows/engineering/qa/eng.qa-sprint-planning.md +100 -0
- package/workflows/engineering/ta/eng.ta.atendimento.md +93 -0
- package/workflows/product/prod.roadmap.preview.md +110 -0
- package/workflows/product/prod.spec.breakdown.md +163 -0
- package/workflows/product/prod.spec.clarify.md +178 -0
- package/workflows/product/prod.spec.epic.md +154 -0
- package/workflows/product/prod.spec.frd.md +96 -0
- package/workflows/product/prod.spec.issue.md +145 -0
- package/workflows/product/prod.spec.md +60 -0
- package/workflows/product/prod.spec.prd.md +100 -0
- package/workflows/taxonomy.md +92 -0
- package/workflows/warm-up.md +574 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Configuração centralizada de IDEs suportadas
|
|
3
|
+
* @module config/ide-config
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { logger } from "../utils/logger.js";
|
|
7
|
+
|
|
8
|
+
/** @constant {string} Pasta padrão para workflows */
|
|
9
|
+
export const DEFAULT_WORKFLOWS_FOLDER = "workflows";
|
|
10
|
+
|
|
11
|
+
/** @constant {string} Pasta alternativa para comandos */
|
|
12
|
+
export const COMMANDS_FOLDER = "commands";
|
|
13
|
+
|
|
14
|
+
/** @constant {string} Pasta de steering files (Kiro) */
|
|
15
|
+
export const STEERING_FOLDER = "steering";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {Object} IDEConfig
|
|
19
|
+
* @property {string} name - Nome completo da IDE
|
|
20
|
+
* @property {string} value - Identificador único (slug)
|
|
21
|
+
* @property {boolean} supported - Se a IDE é suportada
|
|
22
|
+
* @property {string} workflowsFolder - Nome da pasta para workflows/commands
|
|
23
|
+
* @property {string} [folderName] - Nome real da pasta no filesystem (sem o ponto). Defaults para value.
|
|
24
|
+
* @property {string} [icon] - Emoji/ícone da IDE (opcional)
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Lista de IDEs suportadas (source of truth)
|
|
29
|
+
* @type {ReadonlyArray<Readonly<IDEConfig>>}
|
|
30
|
+
*/
|
|
31
|
+
export const IDES = Object.freeze([
|
|
32
|
+
{
|
|
33
|
+
name: "Windsurf",
|
|
34
|
+
value: "windsurf",
|
|
35
|
+
supported: true,
|
|
36
|
+
workflowsFolder: DEFAULT_WORKFLOWS_FOLDER,
|
|
37
|
+
icon: "🤖",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "Claude Code",
|
|
41
|
+
value: "claude",
|
|
42
|
+
supported: true,
|
|
43
|
+
workflowsFolder: COMMANDS_FOLDER,
|
|
44
|
+
icon: "🔌",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "Cursor",
|
|
48
|
+
value: "cursor",
|
|
49
|
+
supported: true,
|
|
50
|
+
workflowsFolder: COMMANDS_FOLDER,
|
|
51
|
+
icon: "💻",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "Codex (OpenAI)",
|
|
55
|
+
value: "codex",
|
|
56
|
+
supported: true,
|
|
57
|
+
workflowsFolder: DEFAULT_WORKFLOWS_FOLDER,
|
|
58
|
+
icon: "🔮",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "OpenCode",
|
|
62
|
+
value: "opencode",
|
|
63
|
+
supported: true,
|
|
64
|
+
workflowsFolder: COMMANDS_FOLDER,
|
|
65
|
+
icon: "⚡",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "Gemini CLI / Antigravity (Google)",
|
|
69
|
+
value: "gemini",
|
|
70
|
+
folderName: "agents",
|
|
71
|
+
supported: true,
|
|
72
|
+
workflowsFolder: DEFAULT_WORKFLOWS_FOLDER,
|
|
73
|
+
icon: "🌐",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: "Kiro (AWS)",
|
|
77
|
+
value: "kiro",
|
|
78
|
+
supported: true,
|
|
79
|
+
workflowsFolder: STEERING_FOLDER,
|
|
80
|
+
icon: "☁️",
|
|
81
|
+
},
|
|
82
|
+
]);
|
|
83
|
+
|
|
84
|
+
/** @type {Map<string, IDEConfig> | null} */
|
|
85
|
+
let _ideConfigCache = null;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Inicializa o cache de configurações (O(n) uma vez, depois O(1))
|
|
89
|
+
* @private
|
|
90
|
+
* @returns {Map<string, IDEConfig>}
|
|
91
|
+
*/
|
|
92
|
+
function _initCache() {
|
|
93
|
+
if (_ideConfigCache === null) {
|
|
94
|
+
_ideConfigCache = new Map();
|
|
95
|
+
for (const ide of IDES) {
|
|
96
|
+
_validateIDEConfig(ide);
|
|
97
|
+
_ideConfigCache.set(ide.value, ide);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return _ideConfigCache;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Valida schema de configuração de IDE
|
|
105
|
+
* @private
|
|
106
|
+
* @param {IDEConfig} config
|
|
107
|
+
* @throws {Error} Se a configuração for inválida
|
|
108
|
+
*/
|
|
109
|
+
function _validateIDEConfig(config) {
|
|
110
|
+
if (!config.name || typeof config.name !== "string") {
|
|
111
|
+
throw new Error(`IDE config inválida: 'name' é obrigatório (string)`);
|
|
112
|
+
}
|
|
113
|
+
if (!config.value || typeof config.value !== "string") {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`IDE config inválida: 'value' é obrigatório (string) para ${config.name}`,
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
if (typeof config.supported !== "boolean") {
|
|
119
|
+
throw new Error(
|
|
120
|
+
`IDE config inválida: 'supported' é obrigatório (boolean) para ${config.name}`,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
if (!config.workflowsFolder || typeof config.workflowsFolder !== "string") {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`IDE config inválida: 'workflowsFolder' é obrigatório (string) para ${config.name}`,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
// Validar valores conhecidos
|
|
129
|
+
const knownFolders = [DEFAULT_WORKFLOWS_FOLDER, COMMANDS_FOLDER, STEERING_FOLDER];
|
|
130
|
+
if (!knownFolders.includes(config.workflowsFolder)) {
|
|
131
|
+
logger.warn(
|
|
132
|
+
`⚠️ Atenção: IDE '${config.name}' usa workflowsFolder customizado: '${config.workflowsFolder}'`,
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Busca configuração de IDE por slug (O(1) com cache)
|
|
139
|
+
* @param {string} ideValue - Slug da IDE (ex: "windsurf", "claude")
|
|
140
|
+
* @returns {IDEConfig | undefined} Configuração da IDE ou undefined
|
|
141
|
+
* @example
|
|
142
|
+
* const config = getIDEConfig("windsurf");
|
|
143
|
+
* // config.workflowsFolder === "workflows"
|
|
144
|
+
*/
|
|
145
|
+
export function getIDEConfig(ideValue) {
|
|
146
|
+
if (!ideValue || typeof ideValue !== "string") {
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
const cache = _initCache();
|
|
150
|
+
return cache.get(ideValue);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Retorna todas as IDEs suportadas
|
|
155
|
+
* @returns {ReadonlyArray<Readonly<IDEConfig>>}
|
|
156
|
+
*/
|
|
157
|
+
export function getSupportedIDEs() {
|
|
158
|
+
return IDES.filter((ide) => ide.supported);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Retorna lista de slugs de IDEs suportadas
|
|
163
|
+
* @returns {string[]}
|
|
164
|
+
* @example
|
|
165
|
+
* getIDEValues() // ["windsurf", "claude", "cursor", ...]
|
|
166
|
+
*/
|
|
167
|
+
export function getIDEValues() {
|
|
168
|
+
return getSupportedIDEs().map((ide) => ide.value);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Valida se uma IDE é suportada
|
|
173
|
+
* @param {string} ideValue - Slug da IDE
|
|
174
|
+
* @returns {boolean}
|
|
175
|
+
* @example
|
|
176
|
+
* isIDESupported("windsurf") // true
|
|
177
|
+
* isIDESupported("vscode") // false
|
|
178
|
+
*/
|
|
179
|
+
export function isIDESupported(ideValue) {
|
|
180
|
+
const config = getIDEConfig(ideValue);
|
|
181
|
+
return config !== undefined && config.supported === true;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Formata lista de IDEs para exibição no CLI
|
|
186
|
+
* @param {string} [separator=" | "] - Separador entre IDEs
|
|
187
|
+
* @returns {string}
|
|
188
|
+
* @example
|
|
189
|
+
* formatIDEsList() // "🤖 Windsurf | 🔌 Claude Code | ..."
|
|
190
|
+
*/
|
|
191
|
+
export function formatIDEsList(separator = " | ") {
|
|
192
|
+
return getSupportedIDEs()
|
|
193
|
+
.map((ide) => `${ide.icon || "•"} ${ide.name}`)
|
|
194
|
+
.join(separator);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Retorna o nome da pasta no filesystem para uma IDE (sem o ponto)
|
|
199
|
+
* Usa folderName se definido, senão usa value.
|
|
200
|
+
* @param {string} ideValue - Slug da IDE
|
|
201
|
+
* @returns {string} Nome da pasta (ex: "windsurf", "agents" para gemini)
|
|
202
|
+
* @example
|
|
203
|
+
* getIDEFolder("windsurf") // "windsurf"
|
|
204
|
+
* getIDEFolder("gemini") // "agents"
|
|
205
|
+
* getIDEFolder("unknown") // "unknown" (fallback)
|
|
206
|
+
*/
|
|
207
|
+
export function getIDEFolder(ideValue) {
|
|
208
|
+
const config = getIDEConfig(ideValue);
|
|
209
|
+
return config?.folderName || ideValue;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Retorna a pasta de workflows para uma IDE (com fallback)
|
|
214
|
+
* @param {string} ideValue - Slug da IDE
|
|
215
|
+
* @returns {string} Nome da pasta (ex: "workflows", "commands")
|
|
216
|
+
* @example
|
|
217
|
+
* getWorkflowsFolder("windsurf") // "workflows"
|
|
218
|
+
* getWorkflowsFolder("claude") // "commands"
|
|
219
|
+
* getWorkflowsFolder("gemini") // "workflows"
|
|
220
|
+
* getWorkflowsFolder("unknown") // "workflows" (fallback)
|
|
221
|
+
*/
|
|
222
|
+
export function getWorkflowsFolder(ideValue) {
|
|
223
|
+
const config = getIDEConfig(ideValue);
|
|
224
|
+
return config?.workflowsFolder || DEFAULT_WORKFLOWS_FOLDER;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Limpa o cache (útil para testes)
|
|
229
|
+
* @private
|
|
230
|
+
*/
|
|
231
|
+
export function _clearCache() {
|
|
232
|
+
_ideConfigCache = null;
|
|
233
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { getFrameworkRoot } from "../utils/paths.js";
|
|
4
|
+
|
|
5
|
+
function parseFrontmatter(content) {
|
|
6
|
+
const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
7
|
+
if (!match) return {};
|
|
8
|
+
|
|
9
|
+
const fm = {};
|
|
10
|
+
for (const line of match[1].split("\n")) {
|
|
11
|
+
const kv = line.match(/^(\w[\w-]*):\s*(.+)$/);
|
|
12
|
+
if (kv) {
|
|
13
|
+
let val = kv[2].trim();
|
|
14
|
+
if (
|
|
15
|
+
(val.startsWith('"') && val.endsWith('"')) ||
|
|
16
|
+
(val.startsWith("'") && val.endsWith("'"))
|
|
17
|
+
) {
|
|
18
|
+
val = val.slice(1, -1);
|
|
19
|
+
}
|
|
20
|
+
fm[kv[1]] = val;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return fm;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function extractDeps(content) {
|
|
27
|
+
const deps = { rules: [], templates: [], skills: [], agents: [] };
|
|
28
|
+
|
|
29
|
+
const ruleFile = content.match(/rules_file:\s*"?\$IDE\/rules\/(.+?)\.md"?/);
|
|
30
|
+
if (ruleFile) deps.rules.push(ruleFile[1]);
|
|
31
|
+
|
|
32
|
+
for (const m of content.matchAll(/rules\/([\w./-]+)\.md/g)) {
|
|
33
|
+
if (!deps.rules.includes(m[1])) deps.rules.push(m[1]);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const tplFile = content.match(
|
|
37
|
+
/template_file:\s*"?\$IDE\/templates\/(.+?)\.md"?/,
|
|
38
|
+
);
|
|
39
|
+
if (tplFile) deps.templates.push(tplFile[1]);
|
|
40
|
+
|
|
41
|
+
const agentFile = content.match(/agent:\s*"?\$IDE\/agents\/(.+?)\.md"?/);
|
|
42
|
+
if (agentFile) deps.agents.push(agentFile[1]);
|
|
43
|
+
|
|
44
|
+
return deps;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function scanDir(dir, type) {
|
|
48
|
+
if (!existsSync(dir)) return [];
|
|
49
|
+
|
|
50
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
51
|
+
const results = [];
|
|
52
|
+
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
const fullPath = join(dir, entry.name);
|
|
55
|
+
|
|
56
|
+
if (entry.isDirectory()) {
|
|
57
|
+
if (type === "skill") {
|
|
58
|
+
const skillFile = join(fullPath, "SKILL.md");
|
|
59
|
+
if (existsSync(skillFile)) {
|
|
60
|
+
const content = readFileSync(skillFile, "utf-8");
|
|
61
|
+
const fm = parseFrontmatter(content);
|
|
62
|
+
results.push({
|
|
63
|
+
id: fm.name || entry.name,
|
|
64
|
+
type,
|
|
65
|
+
name: fm.name || entry.name,
|
|
66
|
+
description: fm.description || "",
|
|
67
|
+
version: fm.version || "1.0.0",
|
|
68
|
+
deps: extractDeps(content),
|
|
69
|
+
path: skillFile,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
results.push(...scanDir(fullPath, type));
|
|
74
|
+
}
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (
|
|
79
|
+
!entry.name.endsWith(".md") ||
|
|
80
|
+
entry.name === "README.md" ||
|
|
81
|
+
entry.name === "AGENTS.md"
|
|
82
|
+
) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const content = readFileSync(fullPath, "utf-8");
|
|
87
|
+
const fm = parseFrontmatter(content);
|
|
88
|
+
const id = entry.name.replace(".md", "");
|
|
89
|
+
|
|
90
|
+
results.push({
|
|
91
|
+
id,
|
|
92
|
+
type,
|
|
93
|
+
name: fm.description || id,
|
|
94
|
+
description: fm.description || "",
|
|
95
|
+
model: fm.model || fm.recommended_model || "",
|
|
96
|
+
version: fm.version || "1.0.0",
|
|
97
|
+
deps: extractDeps(content),
|
|
98
|
+
path: fullPath,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return results;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function discoverAll() {
|
|
106
|
+
const root = getFrameworkRoot();
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
agents: scanDir(join(root, "agents"), "agent"),
|
|
110
|
+
skills: scanDir(join(root, "skills"), "skill"),
|
|
111
|
+
workflows: scanDir(join(root, "workflows"), "workflow"),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function findPrompt(typeAndName) {
|
|
116
|
+
const [type, name] = typeAndName.split("/");
|
|
117
|
+
if (!type || !name) return null;
|
|
118
|
+
|
|
119
|
+
const all = discoverAll();
|
|
120
|
+
const collection = all[type + "s"];
|
|
121
|
+
if (!collection) return null;
|
|
122
|
+
|
|
123
|
+
return collection.find((p) => p.id === name) || null;
|
|
124
|
+
}
|