@kabran-tecnologia/kabran-config 1.9.0 → 1.12.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/package.json +7 -1
- package/src/cli/commands/build.mjs +54 -0
- package/src/cli/commands/check.mjs +107 -0
- package/src/cli/commands/ci.mjs +109 -0
- package/src/cli/commands/test.mjs +130 -0
- package/src/cli/kabran.mjs +144 -0
- package/src/core/config-loader.mjs +154 -0
- package/src/schemas/ci-result.v2.schema.json +1 -1
- package/src/scripts/ci/ci-core.sh +274 -1
- package/src/scripts/ci/ci-runner.sh +9 -0
- package/src/scripts/ci-result-history.mjs +2 -2
- package/src/scripts/ci-result-utils.mjs +1 -1
- package/src/scripts/deploy/deploy-core.sh +1 -1
- package/src/scripts/env-validator.mjs +12 -11
- package/src/scripts/generate-ci-result.mjs +3 -3
- package/src/scripts/quality-standard-validator.mjs +24 -13
- package/src/scripts/readme-validator.mjs +35 -19
- package/src/scripts/traceability/coverage-report.sh +1 -1
- package/src/scripts/traceability/traceability-core.sh +1 -1
- package/src/scripts/traceability/validate-traceability.sh +1 -1
- package/src/telemetry/README.md +11 -11
- package/src/telemetry/config/defaults.mjs +5 -7
- package/src/telemetry/shared/types.d.ts +1 -1
- package/templates/config/kabran.config.mjs +53 -0
- package/CI-CD-MIGRATION.md +0 -388
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
|
|
17
17
|
import {existsSync, readFileSync} from 'node:fs';
|
|
18
18
|
import {join} from 'node:path';
|
|
19
|
+
import {loadConfig, DEFAULTS} from '../core/config-loader.mjs';
|
|
20
|
+
|
|
21
|
+
// Default path for backwards compatibility
|
|
22
|
+
export const DEFAULT_STANDARD_PATH = DEFAULTS.quality.standardPath;
|
|
19
23
|
|
|
20
24
|
/**
|
|
21
25
|
* Required sections that must be present in quality-standard.md
|
|
@@ -33,10 +37,11 @@ export const REQUIRED_FRONTMATTER = ['title', 'type', 'status'];
|
|
|
33
37
|
/**
|
|
34
38
|
* Find quality-standard.md file in the project
|
|
35
39
|
* @param {string} cwd - Current working directory
|
|
40
|
+
* @param {string} [standardPath] - Path to quality standard file (relative to cwd)
|
|
36
41
|
* @returns {{exists: boolean, path?: string} | null} File info or null
|
|
37
42
|
*/
|
|
38
|
-
export function findQualityStandard(cwd = process.cwd()) {
|
|
39
|
-
const expectedPath = join(cwd,
|
|
43
|
+
export function findQualityStandard(cwd = process.cwd(), standardPath = DEFAULT_STANDARD_PATH) {
|
|
44
|
+
const expectedPath = join(cwd, standardPath);
|
|
40
45
|
|
|
41
46
|
if (existsSync(expectedPath)) {
|
|
42
47
|
return {
|
|
@@ -183,26 +188,30 @@ export function compareOverrides(documented, code) {
|
|
|
183
188
|
* Validate quality-standard.md
|
|
184
189
|
* @param {string} cwd - Current working directory
|
|
185
190
|
* @param {boolean} silent - Suppress console output (for testing)
|
|
186
|
-
* @returns {{valid: boolean, errors: string[], warnings: string[]}} Validation result
|
|
191
|
+
* @returns {Promise<{valid: boolean, errors: string[], warnings: string[]}>} Validation result
|
|
187
192
|
*/
|
|
188
|
-
export function validate(cwd = process.cwd(), silent = false) {
|
|
193
|
+
export async function validate(cwd = process.cwd(), silent = false) {
|
|
189
194
|
const log = silent ? () => {} : console.log.bind(console);
|
|
190
195
|
const error = silent ? () => {} : console.error.bind(console);
|
|
191
196
|
|
|
192
197
|
const errors = [];
|
|
193
198
|
const warnings = [];
|
|
194
199
|
|
|
200
|
+
// Load project config
|
|
201
|
+
const config = await loadConfig(cwd);
|
|
202
|
+
const standardPath = config.quality.standardPath;
|
|
203
|
+
|
|
195
204
|
log('');
|
|
196
205
|
log('Validating Quality Standard...');
|
|
197
206
|
log('='.repeat(50));
|
|
198
207
|
|
|
199
208
|
// 1. Check file exists
|
|
200
|
-
const fileInfo = findQualityStandard(cwd);
|
|
209
|
+
const fileInfo = findQualityStandard(cwd, standardPath);
|
|
201
210
|
|
|
202
211
|
if (!fileInfo) {
|
|
203
|
-
errors.push(
|
|
212
|
+
errors.push(`Missing required file: ${standardPath}`);
|
|
204
213
|
error('');
|
|
205
|
-
error(
|
|
214
|
+
error(`ERROR: Missing required file: ${standardPath}`);
|
|
206
215
|
error('');
|
|
207
216
|
error('Run "npx kabran-setup" to create it, or create manually.');
|
|
208
217
|
log('='.repeat(50));
|
|
@@ -210,7 +219,7 @@ export function validate(cwd = process.cwd(), silent = false) {
|
|
|
210
219
|
}
|
|
211
220
|
|
|
212
221
|
log('');
|
|
213
|
-
log(
|
|
222
|
+
log(`File: ${standardPath}`);
|
|
214
223
|
log(' Status: Found');
|
|
215
224
|
|
|
216
225
|
// 2. Read and parse content
|
|
@@ -317,10 +326,12 @@ export function validate(cwd = process.cwd(), silent = false) {
|
|
|
317
326
|
/**
|
|
318
327
|
* Get quality standard validation result in ci-result.json format
|
|
319
328
|
* @param {string} [cwd] - Directory to validate (defaults to process.cwd())
|
|
320
|
-
* @returns {Object} Check result for ci-result.json
|
|
329
|
+
* @returns {Promise<Object>} Check result for ci-result.json
|
|
321
330
|
*/
|
|
322
|
-
export function getQualityStandardCheckResult(cwd = process.cwd()) {
|
|
323
|
-
const
|
|
331
|
+
export async function getQualityStandardCheckResult(cwd = process.cwd()) {
|
|
332
|
+
const config = await loadConfig(cwd);
|
|
333
|
+
const standardPath = config.quality.standardPath;
|
|
334
|
+
const fileInfo = findQualityStandard(cwd, standardPath);
|
|
324
335
|
|
|
325
336
|
if (!fileInfo) {
|
|
326
337
|
return {
|
|
@@ -372,11 +383,11 @@ if (isMainModule) {
|
|
|
372
383
|
const cwd = args.find(a => !a.startsWith('--')) || process.cwd();
|
|
373
384
|
|
|
374
385
|
if (jsonOutput) {
|
|
375
|
-
const result = getQualityStandardCheckResult(cwd);
|
|
386
|
+
const result = await getQualityStandardCheckResult(cwd);
|
|
376
387
|
console.log(JSON.stringify(result, null, 2));
|
|
377
388
|
process.exit(result.status === 'fail' ? 1 : 0);
|
|
378
389
|
} else {
|
|
379
|
-
const result = validate(cwd);
|
|
390
|
+
const result = await validate(cwd);
|
|
380
391
|
process.exit(result.valid ? 0 : 1);
|
|
381
392
|
}
|
|
382
393
|
} catch (err) {
|
|
@@ -16,21 +16,27 @@
|
|
|
16
16
|
|
|
17
17
|
import fs from 'node:fs';
|
|
18
18
|
import path from 'node:path';
|
|
19
|
+
import {loadConfig, DEFAULTS} from '../core/config-loader.mjs';
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Build section patterns from config array.
|
|
23
|
+
* @param {string[]} sections - Section names
|
|
24
|
+
* @returns {Array<{pattern: RegExp, name: string}>}
|
|
25
|
+
*/
|
|
26
|
+
function buildSectionPatterns(sections) {
|
|
27
|
+
return sections.map(name => ({
|
|
28
|
+
pattern: new RegExp(`^##\\s+${name}`, 'mi'),
|
|
29
|
+
name,
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Default sections for backwards compatibility (used when importing directly)
|
|
21
34
|
export const REQUIRED_SECTIONS = [
|
|
22
35
|
{pattern: /^#\s+.+/m, name: 'Project Title (# Heading)'},
|
|
23
|
-
|
|
24
|
-
{pattern: /^##\s+Usage/mi, name: 'Usage'},
|
|
25
|
-
{pattern: /^##\s+License/mi, name: 'License'},
|
|
36
|
+
...buildSectionPatterns(DEFAULTS.readme.required),
|
|
26
37
|
];
|
|
27
38
|
|
|
28
|
-
|
|
29
|
-
export const RECOMMENDED_SECTIONS = [
|
|
30
|
-
{pattern: /^##\s+Development/mi, name: 'Development'},
|
|
31
|
-
{pattern: /^##\s+Contributing/mi, name: 'Contributing'},
|
|
32
|
-
{pattern: /^##\s+Testing/mi, name: 'Testing'},
|
|
33
|
-
];
|
|
39
|
+
export const RECOMMENDED_SECTIONS = buildSectionPatterns(DEFAULTS.readme.recommended);
|
|
34
40
|
|
|
35
41
|
/**
|
|
36
42
|
* Find README.md in directory
|
|
@@ -64,9 +70,9 @@ export function checkSection(content, section) {
|
|
|
64
70
|
* Main validation function
|
|
65
71
|
* @param {string} [cwd] - Directory to validate (defaults to process.cwd())
|
|
66
72
|
* @param {boolean} [silent] - Suppress console output
|
|
67
|
-
* @returns {{valid: boolean, errors: string[], warnings: string[]}}
|
|
73
|
+
* @returns {Promise<{valid: boolean, errors: string[], warnings: string[]}>}
|
|
68
74
|
*/
|
|
69
|
-
export function validateReadme(cwd = process.cwd(), silent = false) {
|
|
75
|
+
export async function validateReadme(cwd = process.cwd(), silent = false) {
|
|
70
76
|
const log = silent ? () => {} : console.log.bind(console);
|
|
71
77
|
const error = silent ? () => {} : console.error.bind(console);
|
|
72
78
|
|
|
@@ -75,6 +81,16 @@ export function validateReadme(cwd = process.cwd(), silent = false) {
|
|
|
75
81
|
const errors = [];
|
|
76
82
|
const warnings = [];
|
|
77
83
|
|
|
84
|
+
// Load project config
|
|
85
|
+
const config = await loadConfig(cwd);
|
|
86
|
+
|
|
87
|
+
// Build section patterns from config
|
|
88
|
+
const requiredSections = [
|
|
89
|
+
{pattern: /^#\s+.+/m, name: 'Project Title (# Heading)'},
|
|
90
|
+
...buildSectionPatterns(config.readme.required),
|
|
91
|
+
];
|
|
92
|
+
const recommendedSections = buildSectionPatterns(config.readme.recommended);
|
|
93
|
+
|
|
78
94
|
// Check if README exists
|
|
79
95
|
const readme = findReadme(cwd);
|
|
80
96
|
if (!readme) {
|
|
@@ -90,7 +106,7 @@ export function validateReadme(cwd = process.cwd(), silent = false) {
|
|
|
90
106
|
|
|
91
107
|
// Check required sections
|
|
92
108
|
log('Checking required sections:');
|
|
93
|
-
for (const section of
|
|
109
|
+
for (const section of requiredSections) {
|
|
94
110
|
const exists = checkSection(content, section);
|
|
95
111
|
if (exists) {
|
|
96
112
|
log(` OK ${section.name}`);
|
|
@@ -102,7 +118,7 @@ export function validateReadme(cwd = process.cwd(), silent = false) {
|
|
|
102
118
|
|
|
103
119
|
// Check recommended sections
|
|
104
120
|
log('\nChecking recommended sections:');
|
|
105
|
-
for (const section of
|
|
121
|
+
for (const section of recommendedSections) {
|
|
106
122
|
const exists = checkSection(content, section);
|
|
107
123
|
if (exists) {
|
|
108
124
|
log(` OK ${section.name}`);
|
|
@@ -134,10 +150,10 @@ export function validateReadme(cwd = process.cwd(), silent = false) {
|
|
|
134
150
|
/**
|
|
135
151
|
* Get README validation result in ci-result.json format
|
|
136
152
|
* @param {string} [cwd] - Directory to validate (defaults to process.cwd())
|
|
137
|
-
* @returns {Object} Check result for ci-result.json
|
|
153
|
+
* @returns {Promise<Object>} Check result for ci-result.json
|
|
138
154
|
*/
|
|
139
|
-
export function getReadmeCheckResult(cwd = process.cwd()) {
|
|
140
|
-
const result = validateReadme(cwd, true);
|
|
155
|
+
export async function getReadmeCheckResult(cwd = process.cwd()) {
|
|
156
|
+
const result = await validateReadme(cwd, true);
|
|
141
157
|
|
|
142
158
|
// Determine status
|
|
143
159
|
let status = 'pass';
|
|
@@ -169,11 +185,11 @@ if (isMainModule) {
|
|
|
169
185
|
const cwd = args.find(a => !a.startsWith('--')) || process.cwd();
|
|
170
186
|
|
|
171
187
|
if (jsonOutput) {
|
|
172
|
-
const result = getReadmeCheckResult(cwd);
|
|
188
|
+
const result = await getReadmeCheckResult(cwd);
|
|
173
189
|
console.log(JSON.stringify(result, null, 2));
|
|
174
190
|
process.exit(result.status === 'fail' ? 1 : 0);
|
|
175
191
|
} else {
|
|
176
|
-
const result = validateReadme(cwd);
|
|
192
|
+
const result = await validateReadme(cwd);
|
|
177
193
|
process.exit(result.valid ? 0 : 1);
|
|
178
194
|
}
|
|
179
195
|
} catch (err) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# ==============================================================================
|
|
3
3
|
# Kabran Traceability Coverage Report
|
|
4
|
-
# Part of @kabran-
|
|
4
|
+
# Part of @kabran-tecnologia/kabran-config
|
|
5
5
|
# Implements PROP-006: JSDoc Traceability Tags
|
|
6
6
|
#
|
|
7
7
|
# Generates a report of spec coverage in the codebase.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# ==============================================================================
|
|
3
3
|
# Kabran Traceability Core - Shared Functions
|
|
4
|
-
# Part of @kabran-
|
|
4
|
+
# Part of @kabran-tecnologia/kabran-config
|
|
5
5
|
# Implements PROP-006: JSDoc Traceability Tags
|
|
6
6
|
# ==============================================================================
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# ==============================================================================
|
|
3
3
|
# Kabran Traceability Validator
|
|
4
|
-
# Part of @kabran-
|
|
4
|
+
# Part of @kabran-tecnologia/kabran-config
|
|
5
5
|
# Implements PROP-006: JSDoc Traceability Tags
|
|
6
6
|
#
|
|
7
7
|
# Validates FORMAT of traceability tags (not presence).
|
package/src/telemetry/README.md
CHANGED
|
@@ -161,8 +161,8 @@ SERVICE_VERSION=1.0.0 # Service version (default: 1.0.0)
|
|
|
161
161
|
ENVIRONMENT=production # Environment name (default: from NODE_ENV)
|
|
162
162
|
OTEL_NAMESPACE=kabran # Service namespace (default: kabran)
|
|
163
163
|
|
|
164
|
-
# OTLP Exporter
|
|
165
|
-
OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.
|
|
164
|
+
# OTLP Exporter (REQUIRED)
|
|
165
|
+
OTEL_EXPORTER_OTLP_ENDPOINT=https://your-otel-collector.example.com # Your collector endpoint
|
|
166
166
|
OTEL_EXPORTER_OTLP_TIMEOUT=10000 # Export timeout in ms (default: 10000)
|
|
167
167
|
|
|
168
168
|
# Sampling
|
|
@@ -188,7 +188,7 @@ initTelemetry({
|
|
|
188
188
|
// Optional (all have sensible defaults)
|
|
189
189
|
serviceVersion: '1.0.0',
|
|
190
190
|
environment: 'production',
|
|
191
|
-
endpoint:
|
|
191
|
+
endpoint: process.env.OTEL_ENDPOINT, // Required - set via env var
|
|
192
192
|
sampleRate: 0.1,
|
|
193
193
|
enabled: true,
|
|
194
194
|
|
|
@@ -292,20 +292,20 @@ import {
|
|
|
292
292
|
} from '@kabran-tecnologia/kabran-config/telemetry/shared'
|
|
293
293
|
```
|
|
294
294
|
|
|
295
|
-
## Integration with
|
|
295
|
+
## Integration with Observability Stack
|
|
296
296
|
|
|
297
|
-
This package is designed to work with
|
|
297
|
+
This package is designed to work with standard observability stacks:
|
|
298
298
|
|
|
299
|
-
- **Traces** → Grafana Tempo
|
|
299
|
+
- **Traces** → Grafana Tempo, Jaeger, or any OTLP-compatible backend
|
|
300
300
|
- **Logs** → Grafana Loki (via stdout/Promtail or direct export)
|
|
301
|
-
- **Metrics** → Prometheus (planned
|
|
301
|
+
- **Metrics** → Prometheus (planned)
|
|
302
302
|
|
|
303
|
-
|
|
303
|
+
**Note:** You must configure `OTEL_ENDPOINT` to point to your OTLP collector.
|
|
304
304
|
|
|
305
305
|
### Viewing Traces
|
|
306
306
|
|
|
307
|
-
1. Open
|
|
308
|
-
2. Go to Explore → Select Tempo
|
|
307
|
+
1. Open your observability dashboard (e.g., Grafana)
|
|
308
|
+
2. Go to Explore → Select your trace backend (Tempo, Jaeger, etc.)
|
|
309
309
|
3. Search by service name or trace ID
|
|
310
310
|
|
|
311
311
|
## Best Practices
|
|
@@ -404,4 +404,4 @@ initTelemetry({
|
|
|
404
404
|
|
|
405
405
|
- [OpenTelemetry JavaScript](https://opentelemetry.io/docs/languages/js/)
|
|
406
406
|
- [W3C Trace Context](https://www.w3.org/TR/trace-context/)
|
|
407
|
-
- [
|
|
407
|
+
- [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/)
|
|
@@ -76,9 +76,10 @@ function parseIgnorePaths(value) {
|
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
78
|
* Default OTLP endpoint
|
|
79
|
-
*
|
|
79
|
+
* REQUIRED: Set via OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_ENDPOINT
|
|
80
|
+
* No default is provided - users must configure their own collector endpoint
|
|
80
81
|
*/
|
|
81
|
-
export const DEFAULT_ENDPOINT =
|
|
82
|
+
export const DEFAULT_ENDPOINT = null
|
|
82
83
|
|
|
83
84
|
/**
|
|
84
85
|
* Default OTLP traces path
|
|
@@ -107,12 +108,9 @@ export const DEFAULT_NAMESPACE = 'kabran'
|
|
|
107
108
|
/**
|
|
108
109
|
* Default CORS URLs for trace header propagation
|
|
109
110
|
* Override: OTEL_PROPAGATE_TRACE_HEADER_CORS_URLS (comma-separated regex patterns)
|
|
111
|
+
* Only localhost is included by default - configure additional domains via env var
|
|
110
112
|
*/
|
|
111
|
-
export const DEFAULT_CORS_URLS = [
|
|
112
|
-
/.*\.supabase\.co/,
|
|
113
|
-
/.*\.kabran\.com\.br/,
|
|
114
|
-
/localhost/,
|
|
115
|
-
]
|
|
113
|
+
export const DEFAULT_CORS_URLS = [/localhost/]
|
|
116
114
|
|
|
117
115
|
/**
|
|
118
116
|
* Default instrumentation options
|
|
@@ -21,7 +21,7 @@ export interface TelemetryConfig {
|
|
|
21
21
|
/** Deployment environment (default: from NODE_ENV or 'development') */
|
|
22
22
|
environment?: string
|
|
23
23
|
|
|
24
|
-
/** OTLP endpoint URL (
|
|
24
|
+
/** OTLP endpoint URL (required - set via OTEL_ENDPOINT env var) */
|
|
25
25
|
endpoint?: string
|
|
26
26
|
|
|
27
27
|
/** Sampling rate 0.0-1.0 (default: 0.1) */
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kabran Configuration File
|
|
3
|
+
*
|
|
4
|
+
* This file customizes the behavior of kabran-config validators and tools.
|
|
5
|
+
* All settings are optional - defaults are applied for any missing values.
|
|
6
|
+
*
|
|
7
|
+
* @see https://github.com/kabran-owner/kabran-config
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** @type {import('@kabran-tecnologia/kabran-config/core/config-loader').KabranConfig} */
|
|
11
|
+
export default {
|
|
12
|
+
/**
|
|
13
|
+
* README Validator Configuration
|
|
14
|
+
*
|
|
15
|
+
* Customize which sections are required and recommended in your README.md
|
|
16
|
+
*/
|
|
17
|
+
readme: {
|
|
18
|
+
// Sections that MUST be present (validation fails if missing)
|
|
19
|
+
required: ['Installation', 'Usage', 'License'],
|
|
20
|
+
|
|
21
|
+
// Sections that SHOULD be present (warning if missing)
|
|
22
|
+
recommended: ['Development', 'Testing', 'Contributing'],
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Environment Validator Configuration
|
|
27
|
+
*
|
|
28
|
+
* Customize how environment variable usage is detected
|
|
29
|
+
*/
|
|
30
|
+
env: {
|
|
31
|
+
// Require .env.example file if env vars are detected
|
|
32
|
+
requireExample: true,
|
|
33
|
+
|
|
34
|
+
// Patterns to search for when detecting env var usage
|
|
35
|
+
detectPatterns: [
|
|
36
|
+
'process.env', // Node.js
|
|
37
|
+
'import.meta.env', // Vite/ESM
|
|
38
|
+
'Deno.env', // Deno
|
|
39
|
+
'os.getenv', // Python
|
|
40
|
+
'$_ENV', // PHP
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Quality Standard Validator Configuration
|
|
46
|
+
*
|
|
47
|
+
* Customize the location of your quality standard documentation
|
|
48
|
+
*/
|
|
49
|
+
quality: {
|
|
50
|
+
// Path to quality standard file (relative to project root)
|
|
51
|
+
standardPath: 'docs/quality/001-quality-standard.md',
|
|
52
|
+
},
|
|
53
|
+
};
|