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.
Files changed (240) hide show
  1. package/AGENTS.md +416 -0
  2. package/LICENSE +21 -0
  3. package/README.md +190 -0
  4. package/agents/AGENTS.md +234 -0
  5. package/agents/README.md +309 -0
  6. package/agents/engineering/data/eng.data-engineer.agent.md +309 -0
  7. package/agents/engineering/eng.agent.md +303 -0
  8. package/agents/engineering/eng.bug-hunter.md +386 -0
  9. package/agents/engineering/eng.cybersecurity.agent.md +503 -0
  10. package/agents/engineering/eng.dev-code-reviewer.md +148 -0
  11. package/agents/engineering/eng.docs-writer.md +152 -0
  12. package/agents/engineering/eng.frontend.agent.md +117 -0
  13. package/agents/engineering/eng.rpa.agent.md +215 -0
  14. package/agents/engineering/eng.tech-analyst.agent.md +102 -0
  15. package/agents/engineering/eng.ux-designer.agent.md +193 -0
  16. package/agents/engineering/qa/eng.qa.cypress-specialist.md +109 -0
  17. package/agents/engineering/qa/eng.qa.quality-champion-task-agent.md +85 -0
  18. package/agents/engineering/qa/eng.qa.quality-strategist.md +111 -0
  19. package/agents/engineering/qa/eng.qa.test-architect.md +400 -0
  20. package/agents/engineering/qa/eng.qa.test-planner.md +477 -0
  21. package/agents/engineering/qa/eng.qa.testing-engineer.md +339 -0
  22. package/agents/product/prod.pm-checker.md +52 -0
  23. package/bin/commands/docs-publish.js +184 -0
  24. package/bin/commands/docs-sync.js +139 -0
  25. package/bin/commands/info.js +87 -0
  26. package/bin/commands/init.js +237 -0
  27. package/bin/commands/install-rtk.js +90 -0
  28. package/bin/commands/list.js +48 -0
  29. package/bin/commands/qa-signoff.js +112 -0
  30. package/bin/commands/whoami.js +43 -0
  31. package/bin/jarvis.js +159 -0
  32. package/bin/lib/auth/session.js +56 -0
  33. package/bin/lib/config/constants.js +123 -0
  34. package/bin/lib/config/ide-config.js +233 -0
  35. package/bin/lib/core/scanner.js +124 -0
  36. package/bin/lib/core/sync-engine.js +551 -0
  37. package/bin/lib/docs/fetch-file.sh +41 -0
  38. package/bin/lib/docs/publish-file.sh +284 -0
  39. package/bin/lib/docs/validate-frontmatter.js +157 -0
  40. package/bin/lib/env-loader.js +198 -0
  41. package/bin/lib/tasks/comment.js +131 -0
  42. package/bin/lib/utils/git-parser.js +145 -0
  43. package/bin/lib/utils/logger.js +104 -0
  44. package/bin/lib/utils/npmrc-parser.js +106 -0
  45. package/bin/lib/utils/paths.js +55 -0
  46. package/bin/lib/utils/ui.js +59 -0
  47. package/bin/lib/vcs/api.js +312 -0
  48. package/bin/lib/vcs/create-issue.js +43 -0
  49. package/bin/lib/vcs/create-merge.js +43 -0
  50. package/bin/lib/vcs/fetch-raw.js +30 -0
  51. package/bin/postinstall.js +41 -0
  52. package/members.md +25 -0
  53. package/package.json +55 -0
  54. package/rules/AGENTS.md +205 -0
  55. package/rules/engineering/data/data-rules.md +200 -0
  56. package/rules/engineering/eng-rules.md +243 -0
  57. package/rules/engineering/eng-security-rules.md +186 -0
  58. package/rules/engineering/eng.breakdown-subtasks-rules.md +585 -0
  59. package/rules/engineering/eng.bump-rules.md +27 -0
  60. package/rules/engineering/eng.docs-scraping-rules.md +64 -0
  61. package/rules/engineering/eng.downstream-flow-rules.md +297 -0
  62. package/rules/engineering/eng.integrations-rules.md +73 -0
  63. package/rules/engineering/eng.plan-rules.md +333 -0
  64. package/rules/engineering/eng.pr-rules.md +359 -0
  65. package/rules/engineering/eng.pre-pr-rules.md +103 -0
  66. package/rules/engineering/eng.start-rules.md +246 -0
  67. package/rules/engineering/eng.tech-spec-rules.md +968 -0
  68. package/rules/engineering/eng.work-rules.md +312 -0
  69. package/rules/engineering/frontend/eng.frontend-rules.md +147 -0
  70. package/rules/engineering/qa/eng.qa.cypress-standards-rules.md +259 -0
  71. package/rules/engineering/qa/eng.qa.exploratory-session-rules.md +137 -0
  72. package/rules/engineering/qa/eng.qa.quality-gate-scoring-rules.md +181 -0
  73. package/rules/engineering/qa/eng.qa.tech-spec-validation-criteria-rules.md +120 -0
  74. package/rules/engineering/rpa/eng.rpa-rules.md +230 -0
  75. package/rules/product/README.md +24 -0
  76. package/rules/product/prod-rules.md +151 -0
  77. package/rules/rtk-rules.md +68 -0
  78. package/skills/AGENTS.md +290 -0
  79. package/skills/SKILLS-ROADMAP.md +333 -0
  80. package/skills/churn-audit/SKILL.md +385 -0
  81. package/skills/context-detect/SKILL.md +399 -0
  82. package/skills/context-detect/assets/context-profile-template.md +127 -0
  83. package/skills/docs-central/README.md +310 -0
  84. package/skills/docs-central/SKILL.md +423 -0
  85. package/skills/docs-index/SKILL.md +377 -0
  86. package/skills/eng-ai-engineer/SKILL.md +296 -0
  87. package/skills/eng-arch-c4/SKILL.md +358 -0
  88. package/skills/eng-arch-c4/assets/example-code.md +189 -0
  89. package/skills/eng-arch-c4/assets/example-component.md +105 -0
  90. package/skills/eng-arch-c4/assets/example-container.md +104 -0
  91. package/skills/eng-arch-c4/assets/example-context.md +81 -0
  92. package/skills/eng-backend/SKILL.md +776 -0
  93. package/skills/eng-browser-extension-builder/SKILL.md +385 -0
  94. package/skills/eng-cybersecurity/SKILL.md +645 -0
  95. package/skills/eng-data-bi/SKILL.md +199 -0
  96. package/skills/eng-data-debug/SKILL.md +307 -0
  97. package/skills/eng-data-engineer/SKILL.md +256 -0
  98. package/skills/eng-data-onboard/SKILL.md +310 -0
  99. package/skills/eng-data-orchestrator/SKILL.md +426 -0
  100. package/skills/eng-design-system/SKILL.md +619 -0
  101. package/skills/eng-docs-write/SKILL.md +312 -0
  102. package/skills/eng-frontend/SKILL.md +913 -0
  103. package/skills/eng-jira-comment/SKILL.md +17 -0
  104. package/skills/eng-microfrontend/SKILL.md +602 -0
  105. package/skills/eng-ms-trace/SKILL.md +469 -0
  106. package/skills/eng-nestjs/SKILL.md +791 -0
  107. package/skills/eng-performance-engineer/SKILL.md +312 -0
  108. package/skills/eng-pr/SKILL.md +339 -0
  109. package/skills/eng-qa-a11y-audit/SKILL.md +269 -0
  110. package/skills/eng-qa-bug-report/SKILL.md +1088 -0
  111. package/skills/eng-qa-bug-report/TASK_MANAGERS.md +138 -0
  112. package/skills/eng-qa-cypress-e2e/SKILL.md +177 -0
  113. package/skills/eng-qa-dev-guide/SKILL.md +164 -0
  114. package/skills/eng-qa-e2e/SKILL.md +400 -0
  115. package/skills/eng-qa-e2e-spec-writer/SKILL.md +322 -0
  116. package/skills/eng-qa-exploratory/SKILL.md +188 -0
  117. package/skills/eng-qa-gate/SKILL.md +370 -0
  118. package/skills/eng-qa-gate/assets/checklist-validacao.md +291 -0
  119. package/skills/eng-qa-graphql-contract/SKILL.md +256 -0
  120. package/skills/eng-qa-quality-report/SKILL.md +412 -0
  121. package/skills/eng-qa-test-plan/SKILL.md +466 -0
  122. package/skills/eng-qa-test-plan/assets/test-coverage-template.md +92 -0
  123. package/skills/eng-qa-test-plan/assets/test-patterns.md +178 -0
  124. package/skills/eng-qa-testsprite/SKILL.md +325 -0
  125. package/skills/eng-qa-testsprite/references/testsprite-mcp.md +224 -0
  126. package/skills/eng-qa-unit-test/SKILL.md +471 -0
  127. package/skills/eng-rabbitmq/SKILL.md +661 -0
  128. package/skills/eng-scraper/SKILL.md +683 -0
  129. package/skills/eng-scraper-robot-builder/SKILL.md +370 -0
  130. package/skills/eng-security-patch/SKILL.md +378 -0
  131. package/skills/eng-security-triage/SKILL.md +266 -0
  132. package/skills/eng-task-comment/SKILL.md +60 -0
  133. package/skills/eng-tech-analyst/SKILL.md +529 -0
  134. package/skills/eng-threat-model/SKILL.md +161 -0
  135. package/skills/init-jarvis/SKILL.md +1304 -0
  136. package/skills/init-jarvis/assets/mcp-configs.md +389 -0
  137. package/skills/init-jarvis/assets/onboarding-checklist.md +104 -0
  138. package/skills/init-jarvis/assets/setup-guide.md +360 -0
  139. package/skills/lovable-prompt-generator/SKILL.md +304 -0
  140. package/skills/prod-roadmap-report/README.md +303 -0
  141. package/skills/prod-roadmap-report/SKILL.md +198 -0
  142. package/skills/prod-roadmap-report/commands/status.compiled.single.team.md +23 -0
  143. package/skills/prod-roadmap-report/commands/status.list.projects.md +17 -0
  144. package/skills/prod-roadmap-report/commands/status.memory.md +192 -0
  145. package/skills/prod-roadmap-report/commands/status.roadmap.preview.md +94 -0
  146. package/skills/prod-roadmap-report/references/detailed-guide.md +236 -0
  147. package/skills/prod-roadmap-report/rules/detailed-guide.md +237 -0
  148. package/skills/prod-roadmap-report/rules/status-report-rules.md +44 -0
  149. package/skills/prod-roadmap-report/templates/template-multiple-teams-compiled-status.md +53 -0
  150. package/skills/prod-roadmap-report/templates/template-projects-list.md +23 -0
  151. package/skills/prod-roadmap-report/templates/template-single-team-compiled-status.md +60 -0
  152. package/skills/prod-roadmap-report/templates/template-single-team-status.md +49 -0
  153. package/skills/prod-specs/SKILL.md +108 -0
  154. package/skills/prod-specs/references/prod.spec.clarify.md +176 -0
  155. package/skills/prod-specs/references/prod.spec.epic.md +107 -0
  156. package/skills/prod-specs/references/prod.spec.frd.md +135 -0
  157. package/skills/prod-specs/references/prod.spec.issue.md +145 -0
  158. package/skills/prod-specs/references/prod.spec.prd.md +118 -0
  159. package/skills/prod-specs/rules/prod-spec-rules.md +186 -0
  160. package/skills/prod-specs/templates/prod-breakdown-template.md +136 -0
  161. package/skills/prod-specs/templates/prod-epic-template.md +76 -0
  162. package/skills/prod-specs/templates/prod-frd-template.md +172 -0
  163. package/skills/prod-specs/templates/prod-issue-template.md +68 -0
  164. package/skills/prod-specs/templates/prod-prd-full-template.md +159 -0
  165. package/skills/prod-specs/templates/prod-prd-template.md +173 -0
  166. package/skills/prod-specs-update/SKILL.md +272 -0
  167. package/skills/report-issue/SKILL.md +156 -0
  168. package/taxonomy.md +270 -0
  169. package/templates/AGENTS.md +189 -0
  170. package/templates/CDD aplicado a Prompts.md +182 -0
  171. package/templates/ENV-template.md +187 -0
  172. package/templates/engineering/AGENTS-template.md +71 -0
  173. package/templates/engineering/ARD-template.md +193 -0
  174. package/templates/engineering/CONTACTS-template.md +135 -0
  175. package/templates/engineering/PR-template.md +40 -0
  176. package/templates/engineering/RFC-Playbook.md +325 -0
  177. package/templates/engineering/RFC-template.md +199 -0
  178. package/templates/engineering/architecture-template.md +277 -0
  179. package/templates/engineering/breakdown-subtasks-template.md +582 -0
  180. package/templates/engineering/c4-model-template.md +516 -0
  181. package/templates/engineering/data-contract-template.md +135 -0
  182. package/templates/engineering/data-pipeline-template.md +163 -0
  183. package/templates/engineering/plan-template.md +255 -0
  184. package/templates/engineering/qa/eng.qa.quality-gate-examples-template.md +311 -0
  185. package/templates/engineering/qa/eng.qa.quality-gate-report-template.md +249 -0
  186. package/templates/engineering/qa/qa.cypress-test-template.md +172 -0
  187. package/templates/engineering/qa/qa.exploratory-session-template.md +148 -0
  188. package/templates/engineering/qa/qa.quality-report-template.md +130 -0
  189. package/templates/engineering/qa/qa.release-signoff-template.md +54 -0
  190. package/templates/engineering/qa/qa.sprint-plan-template.md +49 -0
  191. package/templates/engineering/swagger-template.md +145 -0
  192. package/templates/engineering/tech-spec-template.md +497 -0
  193. package/templates/engineering/work-progress-template.md +155 -0
  194. package/workflows/AGENTS.md +240 -0
  195. package/workflows/README.md +160 -0
  196. package/workflows/all-tools.md +11 -0
  197. package/workflows/engineering/data/data.contract.md +202 -0
  198. package/workflows/engineering/data/data.new-pipeline.md +234 -0
  199. package/workflows/engineering/eng.breakdown-subtasks.md +420 -0
  200. package/workflows/engineering/eng.bug-audit.md +591 -0
  201. package/workflows/engineering/eng.build-tech-spec.md +1116 -0
  202. package/workflows/engineering/eng.create-ard-from-code.md +259 -0
  203. package/workflows/engineering/eng.create-ard.md +382 -0
  204. package/workflows/engineering/eng.create-rfc.md +245 -0
  205. package/workflows/engineering/eng.debug.md +479 -0
  206. package/workflows/engineering/eng.docs.md +40 -0
  207. package/workflows/engineering/eng.light-arch.md +84 -0
  208. package/workflows/engineering/eng.plan.md +213 -0
  209. package/workflows/engineering/eng.pr.md +466 -0
  210. package/workflows/engineering/eng.pre-pr.md +167 -0
  211. package/workflows/engineering/eng.review.md +185 -0
  212. package/workflows/engineering/eng.rpa.robot.md +342 -0
  213. package/workflows/engineering/eng.security-audit.md +312 -0
  214. package/workflows/engineering/eng.security-incident.md +275 -0
  215. package/workflows/engineering/eng.security-pipeline.md +210 -0
  216. package/workflows/engineering/eng.security-review.md +235 -0
  217. package/workflows/engineering/eng.start.md +494 -0
  218. package/workflows/engineering/eng.work.md +558 -0
  219. package/workflows/engineering/frontend/eng.frontend-component.md +190 -0
  220. package/workflows/engineering/frontend/eng.frontend-perf-audit.md +375 -0
  221. package/workflows/engineering/frontend/eng.frontend-review.md +185 -0
  222. package/workflows/engineering/qa/eng.qa-dev-quality-guide.md +51 -0
  223. package/workflows/engineering/qa/eng.qa-e2e-test-generation.md +51 -0
  224. package/workflows/engineering/qa/eng.qa-exploratory-session.md +60 -0
  225. package/workflows/engineering/qa/eng.qa-quality-gate-validation.md +202 -0
  226. package/workflows/engineering/qa/eng.qa-quality-report.md +83 -0
  227. package/workflows/engineering/qa/eng.qa-refinement-entry.md +83 -0
  228. package/workflows/engineering/qa/eng.qa-release-signoff.md +170 -0
  229. package/workflows/engineering/qa/eng.qa-sprint-planning.md +100 -0
  230. package/workflows/engineering/ta/eng.ta.atendimento.md +93 -0
  231. package/workflows/product/prod.roadmap.preview.md +110 -0
  232. package/workflows/product/prod.spec.breakdown.md +163 -0
  233. package/workflows/product/prod.spec.clarify.md +178 -0
  234. package/workflows/product/prod.spec.epic.md +154 -0
  235. package/workflows/product/prod.spec.frd.md +96 -0
  236. package/workflows/product/prod.spec.issue.md +145 -0
  237. package/workflows/product/prod.spec.md +60 -0
  238. package/workflows/product/prod.spec.prd.md +100 -0
  239. package/workflows/taxonomy.md +92 -0
  240. 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
+ }