ganbatte-os 0.2.41 → 0.2.42
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/.gos/README.md +2 -6
- package/.gos/agents/profiles/ganbatte-os-master.md +91 -58
- package/.gos/agents/profiles/index.json +3 -1
- package/.gos/agents/profiles/perf-optimizer.md +10 -0
- package/.gos/agents/profiles/po.md +1 -1
- package/.gos/agents/profiles/security-auditor.md +11 -0
- package/.gos/agents/profiles/sm.md +4 -4
- package/.gos/agents/profiles/squad-creator.md +2 -2
- package/.gos/config.json +23 -2
- package/.gos/docs/curation.md +8 -6
- package/.gos/docs/gos_installation_guide.md +1 -1
- package/.gos/docs/plan-distribuicao-publica.md +2 -3
- package/.gos/docs/toolchain-map.md +2 -2
- package/.gos/libraries/doc-sync-policy.md +31 -0
- package/.gos/libraries/lazy-dev-policy.md +38 -0
- package/.gos/libraries/lucide-icons-policy.md +1 -1
- package/.gos/libraries/performance-audit-playbook.md +54 -0
- package/.gos/libraries/security-audit-playbook.md +63 -0
- package/.gos/manifests/g-os-runtime-manifest.json +29 -8
- package/.gos/playbooks/plan-creation-playbook.md +3 -5
- package/.gos/prompts/01-search.md +2 -2
- package/.gos/prompts/03-tasks.md +4 -4
- package/.gos/prompts/05-reviews.md +1 -1
- package/.gos/scripts/cli/gos-cli.js +16 -0
- package/.gos/scripts/hooks/claude-stop-summary.js +0 -16
- package/.gos/scripts/integrations/check-plan.js +15 -5
- package/.gos/scripts/integrations/setup-ide-adapters.js +72 -75
- package/.gos/scripts/tools/model-router.js +122 -0
- package/.gos/skills/execute-plan/SKILL.md +37 -23
- package/.gos/skills/perf-review/SKILL.md +58 -0
- package/.gos/skills/plan-blueprint/SKILL.md +26 -26
- package/.gos/skills/plan-to-tasks/SKILL.md +4 -1
- package/.gos/skills/progress-tracker/SKILL.md +3 -3
- package/.gos/skills/registry.json +3 -4
- package/.gos/skills/security-review/SKILL.md +59 -0
- package/.gos/skills/simplify-review/SKILL.md +59 -0
- package/.gos/skills/validate-plan/SKILL.md +29 -30
- package/.gos/squads/code-quality/README.md +20 -0
- package/.gos/squads/code-quality/squad.yaml +32 -0
- package/.gos/squads/code-quality/workflows/wf-code-quality.yaml +19 -0
- package/.gos/squads/design-delivery/README.md +1 -1
- package/.gos/squads/design-delivery/squad.yaml +4 -3
- package/.gos/squads/design-delivery/workflows/wf-design-delivery.yaml +6 -6
- package/.gos/templates/planTemplate.md +14 -5
- package/.gos/templates/specTemplate.md +68 -0
- package/.gos/templates/taskTemplate.md +8 -5
- package/AGENTS.md +0 -2
- package/CLAUDE.md +25 -9
- package/GEMINI.md +3 -3
- package/LICENSE +1 -1
- package/README.md +6 -8
- package/package.json +2 -3
- package/.gos/docs/slack-notifications.md +0 -219
- package/.gos/playbooks/sprint-planner-playbook.md +0 -127
- package/.gos/scripts/hooks/post-commit-notify.js +0 -175
- package/.gos/scripts/tools/clickup-preprocess.js +0 -218
- package/.gos/scripts/tools/clickup.js +0 -1058
- package/.gos/scripts/tools/slack-notify.js +0 -271
- package/.gos/skills/clickup/SKILL.md +0 -151
- package/.gos/skills/slack-review/SKILL.md +0 -91
- package/.gos/skills/sprint-planner/SKILL.md +0 -434
- package/.gos/skills/weekly-update/CHANGELOG.md +0 -165
- package/.gos/skills/weekly-update/SKILL.md +0 -361
- package/.gos/squads/sprint-planning/agents/sprint-chief.md +0 -47
- package/.gos/squads/sprint-planning/agents/sprint-planner-agent.md +0 -43
- package/.gos/squads/sprint-planning/agents/sprint-tracker.md +0 -43
- package/.gos/squads/sprint-planning/agents/task-importer.md +0 -44
- package/.gos/squads/sprint-planning/checklists/sprint-readiness.md +0 -27
- package/.gos/squads/sprint-planning/config/config.yaml +0 -65
- package/.gos/squads/sprint-planning/data/clickup-field-mapping.yaml +0 -94
- package/.gos/squads/sprint-planning/squad.yaml +0 -52
- package/.gos/squads/sprint-planning/tasks/close-sprint.md +0 -43
- package/.gos/squads/sprint-planning/tasks/create-sprint.md +0 -42
- package/.gos/squads/sprint-planning/tasks/import-tasks.md +0 -39
- package/.gos/squads/sprint-planning/tasks/sync-status.md +0 -31
- package/.gos/squads/sprint-planning/workflows/wf-sprint-creation.yaml +0 -59
- package/.gos/squads/sprint-planning/workflows/wf-sprint-sync.yaml +0 -35
- package/.gos/templates/sprint-clickup.template.md +0 -80
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
'use strict'
|
|
4
|
-
|
|
5
|
-
const ACCENT_FIXES = {
|
|
6
|
-
'nao': 'não', 'entao': 'então', 'tambem': 'também', 'codigo': 'código',
|
|
7
|
-
'pagina': 'página', 'unico': 'único', 'analise': 'análise', 'modulo': 'módulo',
|
|
8
|
-
'numero': 'número', 'especifico': 'específico', 'diretorio': 'diretório',
|
|
9
|
-
'padrao': 'padrão', 'configuracao': 'configuração', 'validacao': 'validação',
|
|
10
|
-
'implementacao': 'implementação', 'descricao': 'descrição', 'opcao': 'opção',
|
|
11
|
-
'sessao': 'sessão', 'secao': 'seção', 'funcao': 'função', 'acao': 'ação',
|
|
12
|
-
'informacao': 'informação', 'versao': 'versão', 'conexao': 'conexão',
|
|
13
|
-
'excecao': 'exceção', 'condicao': 'condição', 'operacao': 'operação',
|
|
14
|
-
'autenticacao': 'autenticação', 'migracao': 'migração', 'integracao': 'integração',
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const AI_PATTERNS = [
|
|
18
|
-
/\bvale ressaltar\b/gi, /\be importante destacar\b/gi,
|
|
19
|
-
/\bnesse sentido\b/gi, /\bdiante disso\b/gi,
|
|
20
|
-
/\bem suma\b/gi, /\bpor fim\b/gi,
|
|
21
|
-
/\brobusto\b/gi, /\babrangente\b/gi,
|
|
22
|
-
/\binovador\b/gi, /\bestrategico\b/gi,
|
|
23
|
-
/\bholistic[oa]\b/gi, /\balem disso\b/gi,
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
function fixAccents(text) {
|
|
27
|
-
if (typeof text !== 'string' || !text) return text
|
|
28
|
-
let output = text
|
|
29
|
-
for (const [wrong, right] of Object.entries(ACCENT_FIXES)) {
|
|
30
|
-
output = output.replace(new RegExp(`\\b${wrong}\\b`, 'gi'), (match) => {
|
|
31
|
-
if (match === match.toUpperCase()) return right.toUpperCase()
|
|
32
|
-
if (match[0] === match[0].toUpperCase()) return right[0].toUpperCase() + right.slice(1)
|
|
33
|
-
return right
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
return output
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function detectAIPatterns(text) {
|
|
40
|
-
if (!text) return { count: 0, matches: [] }
|
|
41
|
-
const haystack = Array.isArray(text) ? text.join('\n') : String(text)
|
|
42
|
-
const matches = []
|
|
43
|
-
let count = 0
|
|
44
|
-
for (const pattern of AI_PATTERNS) {
|
|
45
|
-
const found = haystack.match(pattern)
|
|
46
|
-
if (found) {
|
|
47
|
-
count += found.length
|
|
48
|
-
matches.push({ pattern: pattern.source, count: found.length })
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return { count, matches }
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function buildTaskDescription(task) {
|
|
55
|
-
const sections = []
|
|
56
|
-
|
|
57
|
-
// Descrição principal (texto livre, sem header)
|
|
58
|
-
if (task.description) sections.push(task.description)
|
|
59
|
-
|
|
60
|
-
// Seções estruturadas — headers H3, sem emojis, português com acentos
|
|
61
|
-
if (task.context) sections.push(`### Contexto\n${task.context}`)
|
|
62
|
-
if (task.steps?.length) sections.push(`### Como fazer\n${task.steps.map((s, i) => `${i + 1}. ${s}`).join('\n')}`)
|
|
63
|
-
if (task.businessRules?.length) sections.push(`### Regras de Negócio\n${task.businessRules.map((r) => `\`${r}\``).join(' · ')}`)
|
|
64
|
-
if (task.files?.length) sections.push(`### Arquivos\n${task.files.map((f) => `- \`${f}\``).join('\n')}`)
|
|
65
|
-
if (task.dependencies?.length) sections.push(`### Dependências\n${task.dependencies.map((d) => `- ${d}`).join('\n')}`)
|
|
66
|
-
if (task.acceptanceCriteria?.length) sections.push(`### Critérios de Aceite\n${task.acceptanceCriteria.map((a) => `- [ ] ${a}`).join('\n')}`)
|
|
67
|
-
if (task.ref) sections.push(`### Referência\n${task.ref}`)
|
|
68
|
-
if (task.technicalNotes) sections.push(`### Notas Técnicas\n${task.technicalNotes}`)
|
|
69
|
-
if (task.dod) sections.push(`### Definition of Done\n${task.dod}`)
|
|
70
|
-
|
|
71
|
-
// Primeira seção (descrição) separada das demais por ---
|
|
72
|
-
if (sections.length > 1) {
|
|
73
|
-
return sections[0] + '\n\n---\n\n' + sections.slice(1).join('\n\n')
|
|
74
|
-
}
|
|
75
|
-
return sections.join('\n\n')
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
function scoreCompleteness(task) {
|
|
80
|
-
let score = 0
|
|
81
|
-
const suggestions = []
|
|
82
|
-
|
|
83
|
-
if (task.description && task.description.length > 50) {
|
|
84
|
-
score += 20
|
|
85
|
-
} else if (task.description) {
|
|
86
|
-
score += 5
|
|
87
|
-
suggestions.push(`Descricao muito curta (${task.description.length} chars).`)
|
|
88
|
-
} else {
|
|
89
|
-
suggestions.push('Sem descricao.')
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (task.acceptanceCriteria?.length >= 2 && task.acceptanceCriteria.every((a) => a.length > 20)) {
|
|
93
|
-
score += 25
|
|
94
|
-
} else if (task.acceptanceCriteria?.length) {
|
|
95
|
-
score += 10
|
|
96
|
-
suggestions.push(`ACs insuficientes (${task.acceptanceCriteria.length} item(ns)).`)
|
|
97
|
-
} else {
|
|
98
|
-
suggestions.push('Sem criterios de aceite.')
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (task.steps?.length || task.subtasks?.length) score += 15
|
|
102
|
-
else suggestions.push('Sem steps de implementacao.')
|
|
103
|
-
|
|
104
|
-
if (task.files?.length) score += 10
|
|
105
|
-
else suggestions.push('Sem arquivos listados.')
|
|
106
|
-
|
|
107
|
-
if (task.points && task.points >= 1 && task.points <= 13) score += 10
|
|
108
|
-
else suggestions.push('Sem story points validos.')
|
|
109
|
-
|
|
110
|
-
if (task.dependencies?.length >= 0) score += 5
|
|
111
|
-
|
|
112
|
-
if (task.context || task.businessRules?.length) score += 10
|
|
113
|
-
else suggestions.push('Sem contexto de negocio.')
|
|
114
|
-
|
|
115
|
-
if (task.dod || task.acceptanceCriteria?.some((a) => /\b(dado|quando|entao|given|when|then)\b/i.test(a))) score += 5
|
|
116
|
-
else suggestions.push('Sem Definition of Done explicito.')
|
|
117
|
-
|
|
118
|
-
return { score, suggestions }
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function sanitizeTaskTexts(task) {
|
|
122
|
-
const copy = { ...task }
|
|
123
|
-
let aiPatternCount = 0
|
|
124
|
-
const textFields = ['description', 'context', 'technicalNotes', 'dod', 'title', 'name', 'ref']
|
|
125
|
-
const arrayFields = ['acceptanceCriteria', 'steps', 'businessRules', 'dependencies', 'files']
|
|
126
|
-
|
|
127
|
-
for (const field of textFields) {
|
|
128
|
-
if (typeof copy[field] === 'string') {
|
|
129
|
-
copy[field] = fixAccents(copy[field])
|
|
130
|
-
aiPatternCount += detectAIPatterns(copy[field]).count
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
for (const field of arrayFields) {
|
|
135
|
-
if (Array.isArray(copy[field])) {
|
|
136
|
-
copy[field] = copy[field].map((item) => {
|
|
137
|
-
if (typeof item !== 'string') return item
|
|
138
|
-
const fixed = fixAccents(item)
|
|
139
|
-
aiPatternCount += detectAIPatterns(fixed).count
|
|
140
|
-
return fixed
|
|
141
|
-
})
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const completeness = scoreCompleteness(copy)
|
|
146
|
-
const description = buildTaskDescription(copy)
|
|
147
|
-
return {
|
|
148
|
-
task: {
|
|
149
|
-
...copy,
|
|
150
|
-
completenessScore: completeness.score,
|
|
151
|
-
completenessSuggestions: completeness.suggestions,
|
|
152
|
-
aiPatternCount,
|
|
153
|
-
description,
|
|
154
|
-
},
|
|
155
|
-
aiPatternCount,
|
|
156
|
-
completenessScore: completeness.score,
|
|
157
|
-
completenessSuggestions: completeness.suggestions,
|
|
158
|
-
description,
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function processPayload(payload) {
|
|
163
|
-
if (Array.isArray(payload)) {
|
|
164
|
-
return { tasks: payload.map((task) => sanitizeTaskTexts(task).task) }
|
|
165
|
-
}
|
|
166
|
-
if (payload && Array.isArray(payload.tasks)) {
|
|
167
|
-
return { ...payload, tasks: payload.tasks.map((task) => sanitizeTaskTexts(task).task) }
|
|
168
|
-
}
|
|
169
|
-
if (payload && typeof payload === 'object') {
|
|
170
|
-
return sanitizeTaskTexts(payload).task
|
|
171
|
-
}
|
|
172
|
-
return payload
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function readStdin() {
|
|
176
|
-
return new Promise((resolve, reject) => {
|
|
177
|
-
let data = ''
|
|
178
|
-
process.stdin.setEncoding('utf8')
|
|
179
|
-
process.stdin.on('data', (chunk) => { data += chunk })
|
|
180
|
-
process.stdin.on('end', () => resolve(data))
|
|
181
|
-
process.stdin.on('error', reject)
|
|
182
|
-
})
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
async function main() {
|
|
186
|
-
if (!process.argv.includes('--json')) {
|
|
187
|
-
console.error(JSON.stringify({ error: 'Use --json and provide JSON via stdin' }))
|
|
188
|
-
process.exit(1)
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const input = await readStdin()
|
|
192
|
-
let parsed
|
|
193
|
-
try {
|
|
194
|
-
parsed = input.trim() ? JSON.parse(input) : {}
|
|
195
|
-
} catch (error) {
|
|
196
|
-
console.error(JSON.stringify({ error: `Invalid JSON input: ${error.message}` }))
|
|
197
|
-
process.exit(1)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const output = processPayload(parsed)
|
|
201
|
-
process.stdout.write(JSON.stringify(output, null, 2) + '\n')
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (require.main === module) {
|
|
205
|
-
main().catch((error) => {
|
|
206
|
-
console.error(JSON.stringify({ error: error.message }))
|
|
207
|
-
process.exit(1)
|
|
208
|
-
})
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
module.exports = {
|
|
212
|
-
fixAccents,
|
|
213
|
-
detectAIPatterns,
|
|
214
|
-
scoreCompleteness,
|
|
215
|
-
buildTaskDescription,
|
|
216
|
-
sanitizeTaskTexts,
|
|
217
|
-
processPayload,
|
|
218
|
-
}
|