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,312 @@
|
|
|
1
|
+
import { parseRepoUrl, mergeRequestPath } from "../utils/git-parser.js";
|
|
2
|
+
import { getVcsToken } from "../utils/npmrc-parser.js";
|
|
3
|
+
|
|
4
|
+
function authHeaders(vendor, token) {
|
|
5
|
+
if (vendor === "gitlab") {
|
|
6
|
+
return { "PRIVATE-TOKEN": token };
|
|
7
|
+
}
|
|
8
|
+
if (vendor === "github") {
|
|
9
|
+
return {
|
|
10
|
+
Authorization: `Bearer ${token}`,
|
|
11
|
+
Accept: "application/vnd.github+json",
|
|
12
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
Authorization: `Bearer ${token}`,
|
|
17
|
+
Accept: "application/json",
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function request(url, { method = "GET", headers = {}, body } = {}) {
|
|
22
|
+
const res = await fetch(url, {
|
|
23
|
+
method,
|
|
24
|
+
headers: {
|
|
25
|
+
"Content-Type": "application/json",
|
|
26
|
+
...headers,
|
|
27
|
+
},
|
|
28
|
+
body: body != null ? JSON.stringify(body) : undefined,
|
|
29
|
+
});
|
|
30
|
+
const text = await res.text();
|
|
31
|
+
let json = null;
|
|
32
|
+
try {
|
|
33
|
+
json = text ? JSON.parse(text) : null;
|
|
34
|
+
} catch {
|
|
35
|
+
json = { raw: text };
|
|
36
|
+
}
|
|
37
|
+
return { ok: res.ok, status: res.status, json, text };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function fetchRawFile(repoUrl, filePath, ref = "main") {
|
|
41
|
+
const repo = parseRepoUrl(repoUrl);
|
|
42
|
+
const token = getVcsToken(repo.vendor);
|
|
43
|
+
const headers = authHeaders(repo.vendor, token);
|
|
44
|
+
const encodedPath = encodeURIComponent(filePath);
|
|
45
|
+
|
|
46
|
+
let url;
|
|
47
|
+
if (repo.vendor === "gitlab") {
|
|
48
|
+
url = `${repo.apiBase}/projects/${repo.projectPathEncoded}/repository/files/${encodedPath}/raw?ref=${encodeURIComponent(ref)}`;
|
|
49
|
+
} else if (repo.vendor === "github") {
|
|
50
|
+
url = `${repo.apiBase}/repos/${repo.owner}/${repo.repo}/contents/${filePath}?ref=${encodeURIComponent(ref)}`;
|
|
51
|
+
headers.Accept = "application/vnd.github.raw";
|
|
52
|
+
} else {
|
|
53
|
+
url = `${repo.apiBase}/repositories/${repo.owner}/${repo.repo}/src/${encodeURIComponent(ref)}/${filePath}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const res = await fetch(url, { headers });
|
|
57
|
+
if (res.status === 404) {
|
|
58
|
+
const err = new Error(`not_found:${filePath}`);
|
|
59
|
+
err.code = 404;
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
if (res.status === 401 || res.status === 403) {
|
|
63
|
+
const err = new Error(`unauthorized:${repo.vendor}`);
|
|
64
|
+
err.code = res.status;
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
if (!res.ok) {
|
|
68
|
+
throw new Error(`fetch failed ${res.status}: ${await res.text()}`);
|
|
69
|
+
}
|
|
70
|
+
return await res.text();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function createMergeRequest(repoUrl, opts) {
|
|
74
|
+
const { source, target, title, description = "" } = opts;
|
|
75
|
+
const repo = parseRepoUrl(repoUrl);
|
|
76
|
+
const token = getVcsToken(repo.vendor);
|
|
77
|
+
const headers = authHeaders(repo.vendor, token);
|
|
78
|
+
|
|
79
|
+
if (repo.vendor === "gitlab") {
|
|
80
|
+
const { ok, status, json } = await request(
|
|
81
|
+
`${repo.apiBase}/projects/${repo.projectPathEncoded}/merge_requests`,
|
|
82
|
+
{
|
|
83
|
+
method: "POST",
|
|
84
|
+
headers,
|
|
85
|
+
body: {
|
|
86
|
+
source_branch: source,
|
|
87
|
+
target_branch: target,
|
|
88
|
+
title,
|
|
89
|
+
description,
|
|
90
|
+
remove_source_branch: true,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
if (!ok || !json?.web_url) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Falha ao criar MR GitLab (${status}): ${JSON.stringify(json)}`,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
return { vendor: "gitlab", iid: json.iid, url: json.web_url };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (repo.vendor === "github") {
|
|
103
|
+
const { ok, status, json } = await request(
|
|
104
|
+
`${repo.apiBase}/repos/${repo.owner}/${repo.repo}/pulls`,
|
|
105
|
+
{
|
|
106
|
+
method: "POST",
|
|
107
|
+
headers,
|
|
108
|
+
body: {
|
|
109
|
+
title,
|
|
110
|
+
head: source,
|
|
111
|
+
base: target,
|
|
112
|
+
body: description,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
);
|
|
116
|
+
if (!ok || !json?.html_url) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
`Falha ao criar PR GitHub (${status}): ${JSON.stringify(json)}`,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
return { vendor: "github", iid: json.number, url: json.html_url };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const { ok, status, json } = await request(
|
|
125
|
+
`${repo.apiBase}/repositories/${repo.owner}/${repo.repo}/pullrequests`,
|
|
126
|
+
{
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers,
|
|
129
|
+
body: {
|
|
130
|
+
title,
|
|
131
|
+
description,
|
|
132
|
+
source: { branch: { name: source } },
|
|
133
|
+
destination: { branch: { name: target } },
|
|
134
|
+
close_source_branch: true,
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
);
|
|
138
|
+
if (!ok || !json?.links?.html?.href) {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`Falha ao criar PR Bitbucket (${status}): ${JSON.stringify(json)}`,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
vendor: "bitbucket",
|
|
145
|
+
iid: json.id,
|
|
146
|
+
url: json.links.html.href,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Commit de um ou mais arquivos numa branch nova (docs publish).
|
|
152
|
+
* files: [{ path, contentBase64, action: 'create'|'update' }]
|
|
153
|
+
*/
|
|
154
|
+
export async function commitFiles(repoUrl, opts) {
|
|
155
|
+
const { branch, startBranch, message, files } = opts;
|
|
156
|
+
const repo = parseRepoUrl(repoUrl);
|
|
157
|
+
const token = getVcsToken(repo.vendor);
|
|
158
|
+
const headers = authHeaders(repo.vendor, token);
|
|
159
|
+
|
|
160
|
+
if (repo.vendor === "gitlab") {
|
|
161
|
+
const { ok, status, json } = await request(
|
|
162
|
+
`${repo.apiBase}/projects/${repo.projectPathEncoded}/repository/commits`,
|
|
163
|
+
{
|
|
164
|
+
method: "POST",
|
|
165
|
+
headers,
|
|
166
|
+
body: {
|
|
167
|
+
branch,
|
|
168
|
+
start_branch: startBranch,
|
|
169
|
+
commit_message: message,
|
|
170
|
+
actions: files.map((f) => ({
|
|
171
|
+
action: f.action || "create",
|
|
172
|
+
file_path: f.path,
|
|
173
|
+
content: f.contentBase64,
|
|
174
|
+
encoding: "base64",
|
|
175
|
+
})),
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
);
|
|
179
|
+
if (!ok || !json?.id) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`Falha no commit GitLab (${status}): ${JSON.stringify(json)}`,
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
return { sha: json.id };
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (repo.vendor === "github") {
|
|
188
|
+
const refRes = await request(
|
|
189
|
+
`${repo.apiBase}/repos/${repo.owner}/${repo.repo}/git/ref/heads/${startBranch}`,
|
|
190
|
+
{ headers },
|
|
191
|
+
);
|
|
192
|
+
if (!refRes.ok) {
|
|
193
|
+
throw new Error(
|
|
194
|
+
`Branch ${startBranch} não encontrada no GitHub (${refRes.status})`,
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
const sha = refRes.json.object.sha;
|
|
198
|
+
await request(
|
|
199
|
+
`${repo.apiBase}/repos/${repo.owner}/${repo.repo}/git/refs`,
|
|
200
|
+
{
|
|
201
|
+
method: "POST",
|
|
202
|
+
headers,
|
|
203
|
+
body: { ref: `refs/heads/${branch}`, sha },
|
|
204
|
+
},
|
|
205
|
+
);
|
|
206
|
+
let lastSha = sha;
|
|
207
|
+
for (const file of files) {
|
|
208
|
+
const put = await request(
|
|
209
|
+
`${repo.apiBase}/repos/${repo.owner}/${repo.repo}/contents/${file.path}`,
|
|
210
|
+
{
|
|
211
|
+
method: "PUT",
|
|
212
|
+
headers,
|
|
213
|
+
body: {
|
|
214
|
+
message,
|
|
215
|
+
content: file.contentBase64,
|
|
216
|
+
branch,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
);
|
|
220
|
+
if (!put.ok) {
|
|
221
|
+
throw new Error(
|
|
222
|
+
`Falha ao escrever ${file.path} no GitHub (${put.status}): ${JSON.stringify(put.json)}`,
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
lastSha = put.json.commit?.sha || lastSha;
|
|
226
|
+
}
|
|
227
|
+
return { sha: lastSha };
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const form = new FormData();
|
|
231
|
+
form.set("branch", branch);
|
|
232
|
+
form.set("parents", startBranch);
|
|
233
|
+
form.set("message", message);
|
|
234
|
+
for (const file of files) {
|
|
235
|
+
const buf = Buffer.from(file.contentBase64, "base64");
|
|
236
|
+
form.set(file.path, new Blob([buf]));
|
|
237
|
+
}
|
|
238
|
+
const res = await fetch(
|
|
239
|
+
`${repo.apiBase}/repositories/${repo.owner}/${repo.repo}/src`,
|
|
240
|
+
{
|
|
241
|
+
method: "POST",
|
|
242
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
243
|
+
body: form,
|
|
244
|
+
},
|
|
245
|
+
);
|
|
246
|
+
if (!res.ok) {
|
|
247
|
+
throw new Error(`Falha no commit Bitbucket (${res.status}): ${await res.text()}`);
|
|
248
|
+
}
|
|
249
|
+
return { sha: "ok" };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export async function createIssue(repoUrl, opts) {
|
|
253
|
+
const { title, body, labels = ["bug"] } = opts;
|
|
254
|
+
const repo = parseRepoUrl(repoUrl);
|
|
255
|
+
const token = getVcsToken(repo.vendor);
|
|
256
|
+
const headers = authHeaders(repo.vendor, token);
|
|
257
|
+
|
|
258
|
+
if (repo.vendor === "gitlab") {
|
|
259
|
+
const { ok, status, json } = await request(
|
|
260
|
+
`${repo.apiBase}/projects/${repo.projectPathEncoded}/issues`,
|
|
261
|
+
{
|
|
262
|
+
method: "POST",
|
|
263
|
+
headers,
|
|
264
|
+
body: { title, description: body, labels: labels.join(",") },
|
|
265
|
+
},
|
|
266
|
+
);
|
|
267
|
+
if (!ok || !json?.web_url) {
|
|
268
|
+
throw new Error(`Issue GitLab (${status}): ${JSON.stringify(json)}`);
|
|
269
|
+
}
|
|
270
|
+
return { vendor: "gitlab", iid: json.iid, url: json.web_url };
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (repo.vendor === "github") {
|
|
274
|
+
const { ok, status, json } = await request(
|
|
275
|
+
`${repo.apiBase}/repos/${repo.owner}/${repo.repo}/issues`,
|
|
276
|
+
{
|
|
277
|
+
method: "POST",
|
|
278
|
+
headers,
|
|
279
|
+
body: { title, body, labels },
|
|
280
|
+
},
|
|
281
|
+
);
|
|
282
|
+
if (!ok || !json?.html_url) {
|
|
283
|
+
throw new Error(`Issue GitHub (${status}): ${JSON.stringify(json)}`);
|
|
284
|
+
}
|
|
285
|
+
return { vendor: "github", iid: json.number, url: json.html_url };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const { ok, status, json } = await request(
|
|
289
|
+
`${repo.apiBase}/repositories/${repo.owner}/${repo.repo}/issues`,
|
|
290
|
+
{
|
|
291
|
+
method: "POST",
|
|
292
|
+
headers,
|
|
293
|
+
body: { title, content: { raw: body } },
|
|
294
|
+
},
|
|
295
|
+
);
|
|
296
|
+
if (!ok || !json?.links?.html?.href) {
|
|
297
|
+
throw new Error(`Issue Bitbucket (${status}): ${JSON.stringify(json)}`);
|
|
298
|
+
}
|
|
299
|
+
return { vendor: "bitbucket", iid: json.id, url: json.links.html.href };
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export function cardUrl(taskManager, baseUrl, cardKey) {
|
|
303
|
+
const tm = String(taskManager || "jira").toLowerCase();
|
|
304
|
+
const base = String(baseUrl || "").replace(/\/$/, "");
|
|
305
|
+
if (!base) return cardKey;
|
|
306
|
+
if (tm === "linear") return `${base}/issue/${cardKey}`;
|
|
307
|
+
if (tm === "github") return `${base}/issues/${cardKey.replace(/^#/, "")}`;
|
|
308
|
+
if (tm === "asana") return `${base}/0/0/${cardKey}`;
|
|
309
|
+
return `${base}/browse/${cardKey}`;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export { parseRepoUrl, mergeRequestPath, getVcsToken };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { createIssue, parseRepoUrl } from "./api.js";
|
|
3
|
+
|
|
4
|
+
function arg(name, fallback = "") {
|
|
5
|
+
const idx = process.argv.indexOf(`--${name}`);
|
|
6
|
+
if (idx === -1) return fallback;
|
|
7
|
+
return process.argv[idx + 1] || fallback;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const title = arg("title");
|
|
11
|
+
const bodyFile = arg("body-file");
|
|
12
|
+
const repo = arg("repo");
|
|
13
|
+
|
|
14
|
+
if (!title || !bodyFile || !repo) {
|
|
15
|
+
console.error(
|
|
16
|
+
"Uso: create-issue.js --repo <url-ou-path> --title <titulo> --body-file <path>",
|
|
17
|
+
);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let repoUrl = repo.trim();
|
|
22
|
+
if (!/^https?:\/\//.test(repoUrl) && !repoUrl.includes("@")) {
|
|
23
|
+
const hostGuess = (process.env.VERSION_CONTROL || "gitlab").toLowerCase();
|
|
24
|
+
const host =
|
|
25
|
+
hostGuess === "github"
|
|
26
|
+
? "github.com"
|
|
27
|
+
: hostGuess === "bitbucket"
|
|
28
|
+
? "bitbucket.org"
|
|
29
|
+
: "gitlab.com";
|
|
30
|
+
repoUrl = `https://${host}/${repoUrl.replace(/^\/+/, "")}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const body = existsSync(bodyFile) ? readFileSync(bodyFile, "utf-8") : "";
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const result = await createIssue(repoUrl, { title, body });
|
|
37
|
+
parseRepoUrl(repoUrl);
|
|
38
|
+
console.log(`✅ Issue aberto: ${result.url}`);
|
|
39
|
+
console.log(JSON.stringify(result));
|
|
40
|
+
} catch (err) {
|
|
41
|
+
console.error(err.message);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { createMergeRequest, parseRepoUrl } from "./api.js";
|
|
4
|
+
|
|
5
|
+
function arg(name, fallback = "") {
|
|
6
|
+
const idx = process.argv.indexOf(`--${name}`);
|
|
7
|
+
if (idx === -1) return fallback;
|
|
8
|
+
return process.argv[idx + 1] || fallback;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const source = arg("source");
|
|
12
|
+
const target = arg("target");
|
|
13
|
+
const title = arg("title");
|
|
14
|
+
const bodyFile = arg("body-file");
|
|
15
|
+
const repoArg = arg("repo");
|
|
16
|
+
|
|
17
|
+
if (!source || !target || !title) {
|
|
18
|
+
console.error(
|
|
19
|
+
"Uso: create-merge.js --source <branch> --target <branch> --title <titulo> [--body-file path] [--repo url]",
|
|
20
|
+
);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const repoUrl =
|
|
25
|
+
repoArg ||
|
|
26
|
+
execSync("git remote get-url origin", { encoding: "utf-8" }).trim();
|
|
27
|
+
const description = bodyFile ? readFileSync(bodyFile, "utf-8") : "";
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const result = await createMergeRequest(repoUrl, {
|
|
31
|
+
source,
|
|
32
|
+
target,
|
|
33
|
+
title,
|
|
34
|
+
description,
|
|
35
|
+
});
|
|
36
|
+
const parsed = parseRepoUrl(repoUrl);
|
|
37
|
+
const noun = parsed.vendor === "gitlab" ? "MR" : "PR";
|
|
38
|
+
console.log(`✅ ${noun} criado: ${result.url}`);
|
|
39
|
+
console.log(JSON.stringify(result));
|
|
40
|
+
} catch (err) {
|
|
41
|
+
console.error(err.message);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { fetchRawFile } from "./api.js";
|
|
2
|
+
|
|
3
|
+
const filePath = process.argv[2];
|
|
4
|
+
const ref = process.argv[3] || "main";
|
|
5
|
+
const repo = process.env.CENTRAL_DOCS_REPO;
|
|
6
|
+
|
|
7
|
+
if (!filePath) {
|
|
8
|
+
console.error("Uso: fetch-raw.js <file-path> [ref]");
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
if (!repo) {
|
|
12
|
+
console.error("CENTRAL_DOCS_REPO não definido");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const content = await fetchRawFile(repo, filePath, ref);
|
|
18
|
+
process.stdout.write(content);
|
|
19
|
+
} catch (err) {
|
|
20
|
+
if (err.code === 404) {
|
|
21
|
+
console.error(`⚠️ Arquivo não encontrado no central-docs: ${filePath}`);
|
|
22
|
+
process.exit(2);
|
|
23
|
+
}
|
|
24
|
+
if (err.code === 401 || err.code === 403) {
|
|
25
|
+
console.error("❌ Token sem permissão para acessar o repositório");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
console.error(err.message);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { execSync } from "node:child_process";
|
|
3
|
+
import { join, dirname } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = dirname(__filename);
|
|
8
|
+
|
|
9
|
+
const cwd = process.env.INIT_CWD || process.cwd();
|
|
10
|
+
const lockPath = join(cwd, "jarvis-lock.json");
|
|
11
|
+
|
|
12
|
+
// ── Sincronizar assets para projetos com jarvis-lock.json ───────────────────
|
|
13
|
+
if (existsSync(lockPath)) {
|
|
14
|
+
try {
|
|
15
|
+
const lock = JSON.parse(readFileSync(lockPath, "utf-8"));
|
|
16
|
+
const { syncAssets } = await import("./lib/core/sync-engine.js");
|
|
17
|
+
const { getWorkflowsFolder } = await import("./lib/config/ide-config.js");
|
|
18
|
+
const { logger } = await import("./lib/utils/logger.js");
|
|
19
|
+
logger.info(`\n jarvis-framework — syncing to .${lock.ide}/\n`);
|
|
20
|
+
const result = syncAssets(cwd, lock.ide, {
|
|
21
|
+
force: true,
|
|
22
|
+
workflowsFolder: getWorkflowsFolder(lock.ide),
|
|
23
|
+
});
|
|
24
|
+
logger.info(` ${result.copied.length} items synced.\n`);
|
|
25
|
+
} catch {}
|
|
26
|
+
} else {
|
|
27
|
+
const { logger } = await import("./lib/utils/logger.js");
|
|
28
|
+
logger.info(`
|
|
29
|
+
jarvis-framework installed.
|
|
30
|
+
Run: npx jarvis init --ide windsurf
|
|
31
|
+
`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ── Sugestão RTK (sempre, se rtk não estiver instalado) ─────────────────────
|
|
35
|
+
try {
|
|
36
|
+
execSync("which rtk 2>/dev/null", { stdio: "pipe" });
|
|
37
|
+
} catch {
|
|
38
|
+
const { logger } = await import("./lib/utils/logger.js");
|
|
39
|
+
logger.info(` 💡 Dica: instale o RTK para economizar 60-90% dos tokens de shell.`);
|
|
40
|
+
logger.info(` npx jarvis install-rtk\n`);
|
|
41
|
+
}
|
package/members.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Members
|
|
2
|
+
|
|
3
|
+
Lista de membros da organização com suas posições, squads e identificadores.
|
|
4
|
+
|
|
5
|
+
> **Formato**: `Nome Completo | email | posição | slack_user_id`
|
|
6
|
+
> **Squads válidos**: definidos em `taxonomy.md`
|
|
7
|
+
> Preencha via `/members-manager` ou edite esta tabela.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## C-LEVEL
|
|
12
|
+
|
|
13
|
+
Membros sem squad específico ou com atuação transversal.
|
|
14
|
+
|
|
15
|
+
| Nome | Email | Posição | Slack ID |
|
|
16
|
+
|------|-------|---------|----------|
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## HEADS
|
|
21
|
+
|
|
22
|
+
Membros sem squad específico ou com atuação transversal.
|
|
23
|
+
|
|
24
|
+
| Nome | Email | Posição | Slack ID |
|
|
25
|
+
|------|-------|---------|----------|
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jarvis-ai-framework",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Jarvis framework",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"jarvis": "./bin/jarvis.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"postinstall": "node bin/postinstall.js",
|
|
11
|
+
"prepublishOnly": "echo 'Publishing jarvis-framework...'",
|
|
12
|
+
"publish:gitlab": "npm publish",
|
|
13
|
+
"test": "node test/e2e-docs-central.js",
|
|
14
|
+
"test:utils": "node test/test-phase1-utils.js",
|
|
15
|
+
"test:all": "npm run test:utils && npm run test"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"bin/",
|
|
19
|
+
"agents/",
|
|
20
|
+
"skills/",
|
|
21
|
+
"workflows/",
|
|
22
|
+
"templates/",
|
|
23
|
+
"rules/",
|
|
24
|
+
"taxonomy.md",
|
|
25
|
+
"members.md",
|
|
26
|
+
"AGENTS.md",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
29
|
+
"keywords": [
|
|
30
|
+
"ai-prompts",
|
|
31
|
+
"agents",
|
|
32
|
+
"workflows",
|
|
33
|
+
"claude",
|
|
34
|
+
"windsurf",
|
|
35
|
+
"cursor",
|
|
36
|
+
"mcp"
|
|
37
|
+
],
|
|
38
|
+
"author": "Felipe Ribeiro de Andrade",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/phelipperibeiro/jarvis-framework.git"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/phelipperibeiro/jarvis-framework",
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/phelipperibeiro/jarvis-framework/issues"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18.0.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"sharp": "^0.34.5"
|
|
54
|
+
}
|
|
55
|
+
}
|