@mestreyoda/fabrica 0.1.4 → 0.1.6
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/configs/interview-templates.json +12 -20
- package/dist/index.js +26 -18
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
|
@@ -1,43 +1,35 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
3
|
-
"max_rounds":
|
|
2
|
+
"version": "1.1",
|
|
3
|
+
"max_rounds": 1,
|
|
4
4
|
"types": {
|
|
5
5
|
"feature": {
|
|
6
6
|
"round1": [
|
|
7
|
-
{ "id": "f1", "question": "Qual
|
|
8
|
-
{ "id": "f2", "question": "
|
|
9
|
-
{ "id": "f3", "question": "Qual é o fluxo principal? O que o usuário faz passo a passo?", "required": true, "follow_up_if_vague": "Tente descrever: 'O usuário clica em X, preenche Y, vê Z'." },
|
|
10
|
-
{ "id": "f4", "question": "Existe alguma restrição de tecnologia, prazo ou compatibilidade?", "required": false, "follow_up_if_vague": null },
|
|
11
|
-
{ "id": "f5", "question": "Esse fluxo exige login? Se sim, quais perfis existem e quais permissões cada perfil deve ter?", "required": false, "follow_up_if_vague": "Descreva pelo menos um exemplo de ação permitida e uma ação bloqueada por perfil." }
|
|
7
|
+
{ "id": "f1", "question": "Qual o fluxo principal? O que o usuario faz e o que recebe de volta?", "required": true, "follow_up_if_vague": "Descreva o uso mais basico: entrada → saida." },
|
|
8
|
+
{ "id": "f2", "question": "Alguma restricao de tecnologia ou compatibilidade?", "required": false, "follow_up_if_vague": null }
|
|
12
9
|
]
|
|
13
10
|
},
|
|
14
11
|
"bugfix": {
|
|
15
12
|
"round1": [
|
|
16
|
-
{ "id": "b1", "question": "O que
|
|
17
|
-
{ "id": "b2", "question": "
|
|
18
|
-
{ "id": "b3", "question": "Como reproduzir o bug? Passos exatos.", "required": true, "follow_up_if_vague": "Em qual página/tela? Com qual tipo de dado?" },
|
|
19
|
-
{ "id": "b4", "question": "Com que frequência acontece? Sempre, às vezes, em condições específicas?", "required": false, "follow_up_if_vague": null }
|
|
13
|
+
{ "id": "b1", "question": "O que esta acontecendo vs. o que deveria acontecer?", "required": true, "follow_up_if_vague": "Voce ve alguma mensagem de erro?" },
|
|
14
|
+
{ "id": "b2", "question": "Como reproduzir?", "required": true, "follow_up_if_vague": null }
|
|
20
15
|
]
|
|
21
16
|
},
|
|
22
17
|
"refactor": {
|
|
23
18
|
"round1": [
|
|
24
|
-
{ "id": "r1", "question": "Qual parte do
|
|
25
|
-
{ "id": "r2", "question": "Qual o
|
|
26
|
-
{ "id": "r3", "question": "Qual o resultado esperado da refatoração?", "required": true, "follow_up_if_vague": "Quer que fique mais legível, mais rápido, ou mais testável?" }
|
|
19
|
+
{ "id": "r1", "question": "Qual parte do codigo e qual o problema atual?", "required": true, "follow_up_if_vague": null },
|
|
20
|
+
{ "id": "r2", "question": "Qual o resultado esperado da refatoracao?", "required": true, "follow_up_if_vague": null }
|
|
27
21
|
]
|
|
28
22
|
},
|
|
29
23
|
"research": {
|
|
30
24
|
"round1": [
|
|
31
|
-
{ "id": "s1", "question": "O que precisa ser investigado
|
|
32
|
-
{ "id": "s2", "question": "Qual
|
|
33
|
-
{ "id": "s3", "question": "Quais critérios definem sucesso da pesquisa?", "required": true, "follow_up_if_vague": "Qual entregável esperado? Documento, PoC, comparativo?" }
|
|
25
|
+
{ "id": "s1", "question": "O que precisa ser investigado e qual decisao isso informa?", "required": true, "follow_up_if_vague": null },
|
|
26
|
+
{ "id": "s2", "question": "Qual o entregavel? Documento, PoC, comparativo?", "required": true, "follow_up_if_vague": null }
|
|
34
27
|
]
|
|
35
28
|
},
|
|
36
29
|
"infra": {
|
|
37
30
|
"round1": [
|
|
38
|
-
{ "id": "i1", "question": "O que precisa ser configurado
|
|
39
|
-
{ "id": "i2", "question": "
|
|
40
|
-
{ "id": "i3", "question": "Há requisitos de downtime, rollback ou compatibilidade?", "required": false, "follow_up_if_vague": null }
|
|
31
|
+
{ "id": "i1", "question": "O que precisa ser configurado e em qual ambiente?", "required": true, "follow_up_if_vague": null },
|
|
32
|
+
{ "id": "i2", "question": "Ha requisitos de downtime ou rollback?", "required": false, "follow_up_if_vague": null }
|
|
41
33
|
]
|
|
42
34
|
}
|
|
43
35
|
}
|
package/dist/index.js
CHANGED
|
@@ -111329,8 +111329,8 @@ import fsSync from "node:fs";
|
|
|
111329
111329
|
import path5 from "node:path";
|
|
111330
111330
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
111331
111331
|
function getCurrentVersion() {
|
|
111332
|
-
if ("0.1.
|
|
111333
|
-
return "0.1.
|
|
111332
|
+
if ("0.1.6") {
|
|
111333
|
+
return "0.1.6";
|
|
111334
111334
|
}
|
|
111335
111335
|
try {
|
|
111336
111336
|
const pkgPath = path5.join(THIS_DIR, "..", "..", "package.json");
|
|
@@ -116084,30 +116084,34 @@ var init_conduct_interview = __esm({
|
|
|
116084
116084
|
try {
|
|
116085
116085
|
const questionsText = (payload.interview?.questions ?? []).map((q, i2) => `${i2 + 1}. ${q.question}`).join("\n");
|
|
116086
116086
|
const answersText = Object.entries(payload.answers ?? {}).map(([key, value]) => `- ${key}: ${value}`).join("\n");
|
|
116087
|
-
const prompt = `You are a
|
|
116087
|
+
const prompt = `You are a pragmatic senior engineer scoping a small project from a brief user request. Your job is to derive a tight, actionable specification \u2014 NOT to ask more questions.
|
|
116088
116088
|
|
|
116089
|
-
|
|
116090
|
-
|
|
116089
|
+
User request: "${payload.raw_idea}"
|
|
116090
|
+
Type: ${type}
|
|
116091
116091
|
|
|
116092
|
-
|
|
116093
|
-
${
|
|
116092
|
+
Context from earlier steps:
|
|
116093
|
+
${answersText || "(none)"}
|
|
116094
116094
|
|
|
116095
|
-
|
|
116096
|
-
${answersText || "(none provided yet)"}
|
|
116095
|
+
Produce a concise JSON spec. The title should be a SHORT name (3-5 words, suitable as a repo name). Keep scope minimal \u2014 only what the user explicitly asked for.
|
|
116097
116096
|
|
|
116098
116097
|
Return ONLY valid JSON (no markdown fences):
|
|
116099
116098
|
{
|
|
116100
|
-
"
|
|
116101
|
-
"
|
|
116102
|
-
"
|
|
116099
|
+
"project_slug": "<kebab-case repo name, 2-4 words, e.g. email-validator-cli>",
|
|
116100
|
+
"title": "<short project name, 3-5 words, max 60 chars>",
|
|
116101
|
+
"objective": "<1-2 sentence objective>",
|
|
116102
|
+
"scope_v1": ["<concrete deliverable 1>", "<concrete deliverable 2>"],
|
|
116103
116103
|
"out_of_scope": ["<item>"],
|
|
116104
|
-
"acceptance_criteria": ["<specific,
|
|
116104
|
+
"acceptance_criteria": ["<specific, testable AC 1>", "<AC 2>"],
|
|
116105
116105
|
"definition_of_done": ["Code reviewed and merged", "Tests pass", "QA contract passes"],
|
|
116106
116106
|
"constraints": "<constraints or 'None specified'>",
|
|
116107
116107
|
"risks": ["<risk 1>"]
|
|
116108
116108
|
}
|
|
116109
116109
|
|
|
116110
|
-
|
|
116110
|
+
Rules:
|
|
116111
|
+
- Title must be a short name like "email-validator-cli" or "task-tracker-api", NOT a full sentence.
|
|
116112
|
+
- Acceptance criteria must be domain-specific and testable.
|
|
116113
|
+
- Do NOT invent features the user didn't ask for.
|
|
116114
|
+
- Keep it lean \u2014 a CLI that validates emails doesn't need auth, profiles, or config files.`;
|
|
116111
116115
|
const result = await withLlmRetry(() => ctx.runCommand(resolveOpenClawCli({
|
|
116112
116116
|
homeDir: ctx.homeDir,
|
|
116113
116117
|
workspaceDir: ctx.workspaceDir
|
|
@@ -117982,7 +117986,7 @@ function normalizeIntakeText(value) {
|
|
|
117982
117986
|
return trimmed || null;
|
|
117983
117987
|
}
|
|
117984
117988
|
function sanitizeRepoName(raw) {
|
|
117985
|
-
return raw.normalize("NFKD").replace(/[^\x00-\x7F]/g, "").toLowerCase().replace(/[\s_]+/g, "-").replace(/[^a-z0-9._-]+/g, "-").replace(/[._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0,
|
|
117989
|
+
return raw.normalize("NFKD").replace(/[^\x00-\x7F]/g, "").toLowerCase().replace(/[\s_]+/g, "-").replace(/[^a-z0-9._-]+/g, "-").replace(/[._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40).replace(/-+$/g, "");
|
|
117986
117990
|
}
|
|
117987
117991
|
function isValidRepoName(name) {
|
|
117988
117992
|
return name.length >= 3 && !REPO_NAME_BLOCKLIST.has(name);
|
|
@@ -118014,6 +118018,7 @@ function deriveRepoName(payload, explicitRepoName) {
|
|
|
118014
118018
|
return deriveRepoNameFromCandidates([
|
|
118015
118019
|
{ value: explicitRepoName, source: "metadata.repo_url" },
|
|
118016
118020
|
{ value: payload.metadata.project_name, source: "metadata.project_name" },
|
|
118021
|
+
{ value: payload.spec_data?.project_slug, source: "spec_data.project_slug" },
|
|
118017
118022
|
{ value: payload.project_map?.project_slug, source: "project_map.project_slug" },
|
|
118018
118023
|
{ value: payload.project_map?.project, source: "project_map.project" },
|
|
118019
118024
|
{ value: payload.spec?.title, source: "spec.title" },
|
|
@@ -142071,7 +142076,7 @@ init_migrate_layout();
|
|
|
142071
142076
|
import { createHash as createHash6 } from "node:crypto";
|
|
142072
142077
|
import fs38 from "node:fs/promises";
|
|
142073
142078
|
import path39 from "node:path";
|
|
142074
|
-
var SESSION_TTL_MS =
|
|
142079
|
+
var SESSION_TTL_MS = 10 * 6e4;
|
|
142075
142080
|
function sessionsDir(workspaceDir) {
|
|
142076
142081
|
return path39.join(workspaceDir, DATA_DIR, "bootstrap-sessions");
|
|
142077
142082
|
}
|
|
@@ -142261,9 +142266,12 @@ function parseClarificationResponse(text, session) {
|
|
|
142261
142266
|
}
|
|
142262
142267
|
function buildClarificationMessage(parsed, pendingClarification) {
|
|
142263
142268
|
if (pendingClarification === "stack_and_name" || !parsed.stackHint && !parsed.projectName) {
|
|
142264
|
-
return `
|
|
142269
|
+
return `Beleza! S\xF3 preciso de duas coisas pra criar:
|
|
142270
|
+
|
|
142271
|
+
1. Qual stack? (Python, Node.js, Go, Java...)
|
|
142272
|
+
2. Quer dar um nome pro projeto? Se n\xE3o, eu invento um.`;
|
|
142265
142273
|
}
|
|
142266
|
-
return `Qual stack voc\xEA quer usar
|
|
142274
|
+
return `Qual stack voc\xEA quer usar? (Python, Node.js, Go, Java...)`;
|
|
142267
142275
|
}
|
|
142268
142276
|
function buildFollowUpClarification(session) {
|
|
142269
142277
|
if (!session.stackHint) {
|