@guilhermefsousa/open-spec-kit 0.0.1 → 0.0.2
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/package.json
CHANGED
package/src/commands/update.js
CHANGED
|
@@ -130,8 +130,12 @@ export async function updateCommand() {
|
|
|
130
130
|
} else {
|
|
131
131
|
skillsSpinner.succeed('Skills Copilot já estão sincronizados');
|
|
132
132
|
}
|
|
133
|
-
} catch {
|
|
134
|
-
|
|
133
|
+
} catch (err) {
|
|
134
|
+
if (err.code === 'ENOENT') {
|
|
135
|
+
skillsSpinner.warn('Diretório .agents/skills/ não encontrado — skills não sincronizados');
|
|
136
|
+
} else {
|
|
137
|
+
skillsSpinner.warn(`Erro ao sincronizar skills: ${err.message}`);
|
|
138
|
+
}
|
|
135
139
|
}
|
|
136
140
|
}
|
|
137
141
|
|
package/src/commands/validate.js
CHANGED
|
@@ -13,7 +13,6 @@ import { execSync } from 'child_process';
|
|
|
13
13
|
import {
|
|
14
14
|
parseSections, findSection, findAllSections,
|
|
15
15
|
parseTable, extractUniqueMatches, getSectionFullContent,
|
|
16
|
-
buildCodeFenceMask,
|
|
17
16
|
} from '../parsers/markdown-sections.js';
|
|
18
17
|
import { parseAndValidateProjects } from '../schemas/projects.schema.js';
|
|
19
18
|
import * as rules from '../schemas/spec.schema.js';
|
|
@@ -496,7 +495,7 @@ export async function validateCommand(options = {}) {
|
|
|
496
495
|
// Rules 34-37: Semantic linting
|
|
497
496
|
const semanticContents = [briefRaw, scenariosRaw].filter(Boolean);
|
|
498
497
|
if (semanticContents.length > 0) {
|
|
499
|
-
results.push(rules.rule34_noVagueTerms(semanticContents
|
|
498
|
+
results.push(rules.rule34_noVagueTerms(semanticContents));
|
|
500
499
|
}
|
|
501
500
|
if (scenarios) {
|
|
502
501
|
results.push(rules.rule35_thenHasMetric(scenarios, scenariosRaw));
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Parses markdown into a hierarchical section tree with heading hierarchy,
|
|
5
5
|
* code fence awareness, and table extraction.
|
|
6
6
|
*
|
|
7
|
-
* This is the foundation for all
|
|
7
|
+
* This is the foundation for all 37 validation rules in osk validate.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
// --- Code Fence Mask ---
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { buildCodeFenceMask } from '../parsers/markdown-sections.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Zod schemas + 37 validation rules for spec artifacts.
|
|
3
5
|
*
|
|
@@ -646,9 +648,8 @@ const VAGUE_TERMS_RE = /\b(rápido|rápida|lento|lenta|grande|pequeno|pequena|mu
|
|
|
646
648
|
* Rule 34: No vague terms in brief/scenarios.
|
|
647
649
|
* Detects adjectives that should be replaced by quantifiable metrics.
|
|
648
650
|
* @param {string[]} contents - raw content of brief and scenarios
|
|
649
|
-
* @param {function} buildCodeFenceMask - from markdown-sections.js, marks lines inside fences
|
|
650
651
|
*/
|
|
651
|
-
export function rule34_noVagueTerms(contents
|
|
652
|
+
export function rule34_noVagueTerms(contents) {
|
|
652
653
|
const allFound = [];
|
|
653
654
|
for (const content of contents) {
|
|
654
655
|
const lines = content.split('\n');
|
|
@@ -695,6 +696,12 @@ export function rule35_thenHasMetric(parsed, rawContent) {
|
|
|
695
696
|
);
|
|
696
697
|
}
|
|
697
698
|
|
|
699
|
+
// Matches PascalCase domain terms (entity/concept names) in Portuguese text.
|
|
700
|
+
// Uses lookbehind/lookahead instead of \b — JS \b is ASCII-only and would
|
|
701
|
+
// truncate words with accented chars (e.g., Café→"Caf", Índice skipped entirely).
|
|
702
|
+
const LETTER = '[a-zA-ZáéíóúãõçêàâôûüÁÉÍÓÚÃÕÇÊÀÂÔÛÜ]';
|
|
703
|
+
const DOMAIN_TERM_RE = new RegExp(`(?<!${LETTER})([A-ZÁÉÍÓÚÃÕÇÊÀÂÔÛÜ]${LETTER}+)(?!${LETTER})`, 'g');
|
|
704
|
+
|
|
698
705
|
const NOISE_TERMS = new Set([
|
|
699
706
|
'given', 'when', 'then', 'and', 'but', 'dado', 'quando', 'então', 'entao',
|
|
700
707
|
'post', 'get', 'put', 'patch', 'delete', 'head', 'options',
|
|
@@ -716,9 +723,8 @@ export function rule36_ubiquitousLanguage(scenariosRaw, briefRaw) {
|
|
|
716
723
|
return result(36, true, 'WARNING', 'Missing brief or scenarios — rule not applicable');
|
|
717
724
|
}
|
|
718
725
|
|
|
719
|
-
// Extract PascalCase terms from scenarios (at least 3 chars, starts uppercase)
|
|
720
726
|
const scenarioTerms = new Set(
|
|
721
|
-
[...scenariosRaw.matchAll(
|
|
727
|
+
[...scenariosRaw.matchAll(DOMAIN_TERM_RE)]
|
|
722
728
|
.map(m => m[1])
|
|
723
729
|
.filter(t => !NOISE_TERMS.has(t.toLowerCase()) && t.length > 2),
|
|
724
730
|
);
|