@esthernandez/vibe-doc 0.1.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/dist/checker/index.d.ts +34 -0
- package/dist/checker/index.d.ts.map +1 -0
- package/dist/checker/index.js +154 -0
- package/dist/checker/staleness.d.ts +26 -0
- package/dist/checker/staleness.d.ts.map +1 -0
- package/dist/checker/staleness.js +56 -0
- package/dist/classifier/index.d.ts +26 -0
- package/dist/classifier/index.d.ts.map +1 -0
- package/dist/classifier/index.js +146 -0
- package/dist/classifier/llm-prompt.d.ts +12 -0
- package/dist/classifier/llm-prompt.d.ts.map +1 -0
- package/dist/classifier/llm-prompt.js +123 -0
- package/dist/classifier/scoring-engine.d.ts +41 -0
- package/dist/classifier/scoring-engine.d.ts.map +1 -0
- package/dist/classifier/scoring-engine.js +197 -0
- package/dist/classifier/signals.d.ts +16 -0
- package/dist/classifier/signals.d.ts.map +1 -0
- package/dist/classifier/signals.js +305 -0
- package/dist/gap-analyzer/breadcrumbs.d.ts +18 -0
- package/dist/gap-analyzer/breadcrumbs.d.ts.map +1 -0
- package/dist/gap-analyzer/breadcrumbs.js +314 -0
- package/dist/gap-analyzer/index.d.ts +13 -0
- package/dist/gap-analyzer/index.d.ts.map +1 -0
- package/dist/gap-analyzer/index.js +88 -0
- package/dist/gap-analyzer/matrix.d.ts +29 -0
- package/dist/gap-analyzer/matrix.d.ts.map +1 -0
- package/dist/gap-analyzer/matrix.js +137 -0
- package/dist/gap-analyzer/tier-assigner.d.ts +22 -0
- package/dist/gap-analyzer/tier-assigner.d.ts.map +1 -0
- package/dist/gap-analyzer/tier-assigner.js +112 -0
- package/dist/generator/docx-writer.d.ts +15 -0
- package/dist/generator/docx-writer.d.ts.map +1 -0
- package/dist/generator/docx-writer.js +271 -0
- package/dist/generator/extractor.d.ts +11 -0
- package/dist/generator/extractor.d.ts.map +1 -0
- package/dist/generator/extractor.js +459 -0
- package/dist/generator/index.d.ts +25 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +106 -0
- package/dist/generator/markdown-writer.d.ts +27 -0
- package/dist/generator/markdown-writer.d.ts.map +1 -0
- package/dist/generator/markdown-writer.js +85 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +372 -0
- package/dist/scanner/artifact-scanner.d.ts +16 -0
- package/dist/scanner/artifact-scanner.d.ts.map +1 -0
- package/dist/scanner/artifact-scanner.js +189 -0
- package/dist/scanner/code-scanner.d.ts +17 -0
- package/dist/scanner/code-scanner.d.ts.map +1 -0
- package/dist/scanner/code-scanner.js +69 -0
- package/dist/scanner/file-scanner.d.ts +16 -0
- package/dist/scanner/file-scanner.d.ts.map +1 -0
- package/dist/scanner/file-scanner.js +119 -0
- package/dist/scanner/git-scanner.d.ts +10 -0
- package/dist/scanner/git-scanner.d.ts.map +1 -0
- package/dist/scanner/git-scanner.js +120 -0
- package/dist/scanner/index.d.ts +15 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +106 -0
- package/dist/state/index.d.ts +20 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +141 -0
- package/dist/state/schema.d.ts +101 -0
- package/dist/state/schema.d.ts.map +1 -0
- package/dist/state/schema.js +6 -0
- package/dist/templates/embedded/adr.md +45 -0
- package/dist/templates/embedded/api-spec.md +55 -0
- package/dist/templates/embedded/data-model.md +55 -0
- package/dist/templates/embedded/deployment-procedure.md +63 -0
- package/dist/templates/embedded/runbook.md +55 -0
- package/dist/templates/embedded/test-plan.md +55 -0
- package/dist/templates/embedded/threat-model.md +47 -0
- package/dist/templates/index.d.ts +20 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +106 -0
- package/dist/templates/registry.d.ts +31 -0
- package/dist/templates/registry.d.ts.map +1 -0
- package/dist/templates/registry.js +172 -0
- package/dist/templates/renderer.d.ts +26 -0
- package/dist/templates/renderer.d.ts.map +1 -0
- package/dist/templates/renderer.js +145 -0
- package/dist/utils/language-detect.d.ts +14 -0
- package/dist/utils/language-detect.d.ts.map +1 -0
- package/dist/utils/language-detect.js +58 -0
- package/dist/utils/logger.d.ts +16 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +35 -0
- package/dist/versioning/differ.d.ts +20 -0
- package/dist/versioning/differ.d.ts.map +1 -0
- package/dist/versioning/differ.js +160 -0
- package/dist/versioning/index.d.ts +44 -0
- package/dist/versioning/index.d.ts.map +1 -0
- package/dist/versioning/index.js +165 -0
- package/package.json +40 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Remote Template Registry Module
|
|
4
|
+
* Handles checking for and downloading remote template updates
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.checkForUpdates = checkForUpdates;
|
|
41
|
+
exports.downloadTemplate = downloadTemplate;
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const logger_1 = require("../utils/logger");
|
|
45
|
+
/**
|
|
46
|
+
* Check for template updates by fetching the manifest
|
|
47
|
+
* Falls back gracefully when offline
|
|
48
|
+
*/
|
|
49
|
+
async function checkForUpdates(manifestUrl, cacheDir) {
|
|
50
|
+
try {
|
|
51
|
+
logger_1.logger.debug('Checking for template updates', { manifestUrl });
|
|
52
|
+
const manifest = await fetchManifest(manifestUrl);
|
|
53
|
+
const updates = await compareWithCache(manifest.templates, cacheDir);
|
|
54
|
+
return {
|
|
55
|
+
hasUpdates: updates.length > 0,
|
|
56
|
+
availableUpdates: updates,
|
|
57
|
+
timestamp: manifest.timestamp,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
logger_1.logger.warn('Failed to check for updates, using cached templates', {
|
|
62
|
+
error: String(error),
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
hasUpdates: false,
|
|
66
|
+
availableUpdates: [],
|
|
67
|
+
timestamp: new Date().toISOString(),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Download a template and cache it
|
|
73
|
+
*/
|
|
74
|
+
async function downloadTemplate(docType, url, cacheDir) {
|
|
75
|
+
try {
|
|
76
|
+
logger_1.logger.debug('Downloading template', { docType, url });
|
|
77
|
+
const content = await fetchTemplate(url);
|
|
78
|
+
const templatesDir = path.join(cacheDir, 'templates');
|
|
79
|
+
// Ensure templates directory exists
|
|
80
|
+
fs.mkdirSync(templatesDir, { recursive: true });
|
|
81
|
+
const cachePath = path.join(templatesDir, `${docType}.md`);
|
|
82
|
+
fs.writeFileSync(cachePath, content, 'utf-8');
|
|
83
|
+
logger_1.logger.info('Template downloaded and cached', { docType, path: cachePath });
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logger_1.logger.error('Failed to download template', { docType, error: String(error) });
|
|
87
|
+
throw new Error(`Failed to download template for ${docType}: ${String(error)}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Fetch a manifest from a remote URL with timeout
|
|
92
|
+
*/
|
|
93
|
+
async function fetchManifest(manifestUrl) {
|
|
94
|
+
const controller = new AbortController();
|
|
95
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
96
|
+
try {
|
|
97
|
+
const response = await fetch(manifestUrl, {
|
|
98
|
+
signal: controller.signal,
|
|
99
|
+
});
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
throw new Error(`Failed to fetch manifest: ${response.status} ${response.statusText}`);
|
|
102
|
+
}
|
|
103
|
+
return (await response.json());
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
clearTimeout(timeoutId);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Fetch template content from a remote URL with timeout
|
|
111
|
+
*/
|
|
112
|
+
async function fetchTemplate(url) {
|
|
113
|
+
const controller = new AbortController();
|
|
114
|
+
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
|
115
|
+
try {
|
|
116
|
+
const response = await fetch(url, {
|
|
117
|
+
signal: controller.signal,
|
|
118
|
+
});
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
throw new Error(`Failed to fetch template: ${response.status} ${response.statusText}`);
|
|
121
|
+
}
|
|
122
|
+
return await response.text();
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
clearTimeout(timeoutId);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Compare remote templates with cached versions
|
|
130
|
+
* Returns list of templates with updates available
|
|
131
|
+
*/
|
|
132
|
+
async function compareWithCache(remoteTemplates, cacheDir) {
|
|
133
|
+
const updates = [];
|
|
134
|
+
for (const remoteTemplate of remoteTemplates) {
|
|
135
|
+
const cachePath = path.join(cacheDir, 'templates', `${remoteTemplate.docType}.md`);
|
|
136
|
+
// Check if cached version exists
|
|
137
|
+
if (!fs.existsSync(cachePath)) {
|
|
138
|
+
updates.push({
|
|
139
|
+
docType: remoteTemplate.docType,
|
|
140
|
+
url: remoteTemplate.url,
|
|
141
|
+
hash: remoteTemplate.hash,
|
|
142
|
+
version: remoteTemplate.version,
|
|
143
|
+
});
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
// Compare hashes
|
|
147
|
+
const cachedContent = fs.readFileSync(cachePath, 'utf-8');
|
|
148
|
+
const cachedHash = hashContent(cachedContent);
|
|
149
|
+
if (cachedHash !== remoteTemplate.hash) {
|
|
150
|
+
updates.push({
|
|
151
|
+
docType: remoteTemplate.docType,
|
|
152
|
+
url: remoteTemplate.url,
|
|
153
|
+
hash: remoteTemplate.hash,
|
|
154
|
+
version: remoteTemplate.version,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return updates;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Simple hash function for content comparison
|
|
162
|
+
* Not for security, just for change detection
|
|
163
|
+
*/
|
|
164
|
+
function hashContent(content) {
|
|
165
|
+
let hash = 0;
|
|
166
|
+
for (let i = 0; i < content.length; i++) {
|
|
167
|
+
const char = content.charCodeAt(i);
|
|
168
|
+
hash = (hash << 5) - hash + char;
|
|
169
|
+
hash = hash & hash; // Convert to 32-bit integer
|
|
170
|
+
}
|
|
171
|
+
return Math.abs(hash).toString(16);
|
|
172
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Renderer Module
|
|
3
|
+
* Renders templates with extracted and user-provided data
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Data provided to the renderer
|
|
7
|
+
*/
|
|
8
|
+
export interface RenderData {
|
|
9
|
+
extracted: Record<string, string>;
|
|
10
|
+
user: Record<string, string>;
|
|
11
|
+
metadata: {
|
|
12
|
+
docType: string;
|
|
13
|
+
generatedAt: string;
|
|
14
|
+
classification: string;
|
|
15
|
+
sourceArtifacts: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Render a template by replacing tokens with data
|
|
20
|
+
* - {{extracted.<section-name>}} - auto-extracted data
|
|
21
|
+
* - {{user.<section-name>}} - user-provided data
|
|
22
|
+
* Marks empty sections with guidance comments
|
|
23
|
+
* Tags confidence levels per section
|
|
24
|
+
*/
|
|
25
|
+
export declare function renderTemplate(template: string, data: RenderData): string;
|
|
26
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/templates/renderer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAaD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAwFzE"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Template Renderer Module
|
|
4
|
+
* Renders templates with extracted and user-provided data
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.renderTemplate = renderTemplate;
|
|
8
|
+
const logger_1 = require("../utils/logger");
|
|
9
|
+
/**
|
|
10
|
+
* Render a template by replacing tokens with data
|
|
11
|
+
* - {{extracted.<section-name>}} - auto-extracted data
|
|
12
|
+
* - {{user.<section-name>}} - user-provided data
|
|
13
|
+
* Marks empty sections with guidance comments
|
|
14
|
+
* Tags confidence levels per section
|
|
15
|
+
*/
|
|
16
|
+
function renderTemplate(template, data) {
|
|
17
|
+
let rendered = template;
|
|
18
|
+
const confidenceLevels = [];
|
|
19
|
+
// Extract all token patterns
|
|
20
|
+
const tokenPattern = /\{\{(extracted|user)\.([a-z0-9\-]+)\}\}/g;
|
|
21
|
+
const tokens = new Map();
|
|
22
|
+
let match;
|
|
23
|
+
while ((match = tokenPattern.exec(template)) !== null) {
|
|
24
|
+
const [fullToken, scope, sectionName] = match;
|
|
25
|
+
tokens.set(fullToken, sectionName);
|
|
26
|
+
}
|
|
27
|
+
// Replace tokens and track confidence
|
|
28
|
+
for (const [token, sectionName] of tokens.entries()) {
|
|
29
|
+
const [, scope] = token.match(/\{\{(extracted|user)/) || [];
|
|
30
|
+
const source = scope;
|
|
31
|
+
const extractedValue = data.extracted[sectionName]?.trim() || '';
|
|
32
|
+
const userValue = data.user[sectionName]?.trim() || '';
|
|
33
|
+
// Prefer user-provided data over extracted
|
|
34
|
+
let replacement;
|
|
35
|
+
let confidence;
|
|
36
|
+
let dataSource;
|
|
37
|
+
if (scope === 'user') {
|
|
38
|
+
if (userValue) {
|
|
39
|
+
replacement = userValue;
|
|
40
|
+
confidence = 'high';
|
|
41
|
+
dataSource = 'user';
|
|
42
|
+
}
|
|
43
|
+
else if (extractedValue) {
|
|
44
|
+
// User section can show extracted data as fallback with medium confidence
|
|
45
|
+
replacement = extractedValue;
|
|
46
|
+
confidence = 'medium';
|
|
47
|
+
dataSource = 'extracted';
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
replacement = '';
|
|
51
|
+
confidence = 'low';
|
|
52
|
+
dataSource = 'empty';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// extracted scope
|
|
57
|
+
if (extractedValue) {
|
|
58
|
+
replacement = extractedValue;
|
|
59
|
+
confidence = 'high';
|
|
60
|
+
dataSource = 'extracted';
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
replacement = '';
|
|
64
|
+
confidence = 'low';
|
|
65
|
+
dataSource = 'empty';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
rendered = rendered.replace(token, replacement);
|
|
69
|
+
confidenceLevels.push({ section: sectionName, confidence, source: dataSource });
|
|
70
|
+
logger_1.logger.debug('Rendered token', {
|
|
71
|
+
sectionName,
|
|
72
|
+
scope,
|
|
73
|
+
confidence,
|
|
74
|
+
hasData: !!replacement,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// Mark empty sections with guidance comments
|
|
78
|
+
const guidancePattern = /<!-- NEEDS INPUT: ([^-]*) -->/g;
|
|
79
|
+
let guidanceIndex = 0;
|
|
80
|
+
rendered = rendered.replace(guidancePattern, (match, guidance) => {
|
|
81
|
+
if (guidanceIndex < confidenceLevels.length) {
|
|
82
|
+
const { confidence } = confidenceLevels[guidanceIndex];
|
|
83
|
+
if (confidence === 'low') {
|
|
84
|
+
// Keep the guidance comment for empty sections
|
|
85
|
+
guidanceIndex++;
|
|
86
|
+
return match;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
guidanceIndex++;
|
|
90
|
+
// Remove guidance comments for sections with data
|
|
91
|
+
return '';
|
|
92
|
+
});
|
|
93
|
+
// Add confidence metadata as a comment at the top
|
|
94
|
+
const confidenceSummary = generateConfidenceSummary(confidenceLevels);
|
|
95
|
+
rendered = addMetadataComment(rendered, data.metadata, confidenceSummary);
|
|
96
|
+
return rendered;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Generate a summary of confidence levels per section
|
|
100
|
+
*/
|
|
101
|
+
function generateConfidenceSummary(levels) {
|
|
102
|
+
const summary = {};
|
|
103
|
+
for (const { section, confidence } of levels) {
|
|
104
|
+
summary[section] = confidence;
|
|
105
|
+
}
|
|
106
|
+
return summary;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Add metadata comment to the rendered template
|
|
110
|
+
*/
|
|
111
|
+
function addMetadataComment(template, metadata, confidenceSummary) {
|
|
112
|
+
const frontmatterMatch = template.match(/^---\n([\s\S]*?)\n---/);
|
|
113
|
+
if (!frontmatterMatch) {
|
|
114
|
+
logger_1.logger.warn('No frontmatter found in template');
|
|
115
|
+
return template;
|
|
116
|
+
}
|
|
117
|
+
const frontmatterEnd = frontmatterMatch[0].length;
|
|
118
|
+
const confidenceComment = generateConfidenceComment(metadata, confidenceSummary);
|
|
119
|
+
return (template.slice(0, frontmatterEnd) +
|
|
120
|
+
'\n' +
|
|
121
|
+
confidenceComment +
|
|
122
|
+
'\n' +
|
|
123
|
+
template.slice(frontmatterEnd));
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Generate a markdown comment with metadata and confidence levels
|
|
127
|
+
*/
|
|
128
|
+
function generateConfidenceComment(metadata, confidenceSummary) {
|
|
129
|
+
const highConfidence = Object.entries(confidenceSummary)
|
|
130
|
+
.filter(([, level]) => level === 'high')
|
|
131
|
+
.map(([section]) => section);
|
|
132
|
+
const lowConfidence = Object.entries(confidenceSummary)
|
|
133
|
+
.filter(([, level]) => level === 'low')
|
|
134
|
+
.map(([section]) => section);
|
|
135
|
+
const lines = [
|
|
136
|
+
'<!--',
|
|
137
|
+
`Generated: ${metadata.generatedAt}`,
|
|
138
|
+
`Classification: ${metadata.classification}`,
|
|
139
|
+
`Source artifacts: ${metadata.sourceArtifacts}`,
|
|
140
|
+
`High confidence sections: ${highConfidence.length} - ${highConfidence.join(', ') || 'none'}`,
|
|
141
|
+
`Needs input: ${lowConfidence.length} - ${lowConfidence.join(', ') || 'none'}`,
|
|
142
|
+
'-->',
|
|
143
|
+
];
|
|
144
|
+
return lines.join('\n');
|
|
145
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language Detection Utility
|
|
3
|
+
* Detects programming languages based on package configuration files
|
|
4
|
+
*/
|
|
5
|
+
export interface DetectedLanguage {
|
|
6
|
+
name: string;
|
|
7
|
+
confidence: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Detects programming languages from a list of package config file paths
|
|
11
|
+
* Returns array of detected languages with confidence scores
|
|
12
|
+
*/
|
|
13
|
+
export declare function detectLanguages(packageConfigPaths: string[]): DetectedLanguage[];
|
|
14
|
+
//# sourceMappingURL=language-detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language-detect.d.ts","sourceRoot":"","sources":["../../src/utils/language-detect.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,kBAAkB,EAAE,MAAM,EAAE,GAC3B,gBAAgB,EAAE,CA0DpB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Language Detection Utility
|
|
4
|
+
* Detects programming languages based on package configuration files
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.detectLanguages = detectLanguages;
|
|
8
|
+
/**
|
|
9
|
+
* Detects programming languages from a list of package config file paths
|
|
10
|
+
* Returns array of detected languages with confidence scores
|
|
11
|
+
*/
|
|
12
|
+
function detectLanguages(packageConfigPaths) {
|
|
13
|
+
const languageMap = new Map();
|
|
14
|
+
for (const filePath of packageConfigPaths) {
|
|
15
|
+
const fileName = filePath.split('/').pop() || '';
|
|
16
|
+
// Node.js/TypeScript
|
|
17
|
+
if (fileName === 'package.json') {
|
|
18
|
+
languageMap.set('TypeScript/JavaScript', (languageMap.get('TypeScript/JavaScript') || 0) + 1);
|
|
19
|
+
}
|
|
20
|
+
// Python
|
|
21
|
+
if (fileName === 'pyproject.toml' || fileName === 'setup.py') {
|
|
22
|
+
languageMap.set('Python', (languageMap.get('Python') || 0) + 1);
|
|
23
|
+
}
|
|
24
|
+
// Rust
|
|
25
|
+
if (fileName === 'Cargo.toml') {
|
|
26
|
+
languageMap.set('Rust', (languageMap.get('Rust') || 0) + 1);
|
|
27
|
+
}
|
|
28
|
+
// Go
|
|
29
|
+
if (fileName === 'go.mod') {
|
|
30
|
+
languageMap.set('Go', (languageMap.get('Go') || 0) + 1);
|
|
31
|
+
}
|
|
32
|
+
// Java/Kotlin
|
|
33
|
+
if (fileName === 'pom.xml') {
|
|
34
|
+
languageMap.set('Java/Kotlin', (languageMap.get('Java/Kotlin') || 0) + 1);
|
|
35
|
+
}
|
|
36
|
+
if (fileName === 'build.gradle' || fileName === 'build.gradle.kts') {
|
|
37
|
+
languageMap.set('Java/Kotlin', (languageMap.get('Java/Kotlin') || 0) + 1);
|
|
38
|
+
}
|
|
39
|
+
// C# / .NET
|
|
40
|
+
if (fileName === 'project.csproj' || fileName.endsWith('.csproj')) {
|
|
41
|
+
languageMap.set('C#/.NET', (languageMap.get('C#/.NET') || 0) + 1);
|
|
42
|
+
}
|
|
43
|
+
// Ruby
|
|
44
|
+
if (fileName === 'Gemfile') {
|
|
45
|
+
languageMap.set('Ruby', (languageMap.get('Ruby') || 0) + 1);
|
|
46
|
+
}
|
|
47
|
+
// PHP
|
|
48
|
+
if (fileName === 'composer.json') {
|
|
49
|
+
languageMap.set('PHP', (languageMap.get('PHP') || 0) + 1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Convert to array and sort by count (confidence)
|
|
53
|
+
const languages = Array.from(languageMap.entries()).map(([name, count]) => ({
|
|
54
|
+
name,
|
|
55
|
+
confidence: Math.min(count / packageConfigPaths.length, 1),
|
|
56
|
+
}));
|
|
57
|
+
return languages.sort((a, b) => b.confidence - a.confidence);
|
|
58
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured Logger
|
|
3
|
+
* Simple logging utility with info, warn, error, and debug levels
|
|
4
|
+
*/
|
|
5
|
+
declare class Logger {
|
|
6
|
+
private isDev;
|
|
7
|
+
private formatTimestamp;
|
|
8
|
+
private format;
|
|
9
|
+
info(message: string, data?: unknown): void;
|
|
10
|
+
warn(message: string, data?: unknown): void;
|
|
11
|
+
error(message: string, data?: unknown): void;
|
|
12
|
+
debug(message: string, data?: unknown): void;
|
|
13
|
+
}
|
|
14
|
+
export declare const logger: Logger;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,cAAM,MAAM;IACV,OAAO,CAAC,KAAK,CAA0C;IAEvD,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,MAAM;IAMd,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI3C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI3C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;CAK7C;AAED,eAAO,MAAM,MAAM,QAAe,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Structured Logger
|
|
4
|
+
* Simple logging utility with info, warn, error, and debug levels
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.logger = void 0;
|
|
8
|
+
class Logger {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.isDev = process.env.NODE_ENV === 'development';
|
|
11
|
+
}
|
|
12
|
+
formatTimestamp() {
|
|
13
|
+
return new Date().toISOString();
|
|
14
|
+
}
|
|
15
|
+
format(level, message, data) {
|
|
16
|
+
const timestamp = this.formatTimestamp();
|
|
17
|
+
const dataStr = data ? ` ${JSON.stringify(data)}` : '';
|
|
18
|
+
return `[${timestamp}] [${level.toUpperCase()}] ${message}${dataStr}`;
|
|
19
|
+
}
|
|
20
|
+
info(message, data) {
|
|
21
|
+
console.log(this.format('info', message, data));
|
|
22
|
+
}
|
|
23
|
+
warn(message, data) {
|
|
24
|
+
console.warn(this.format('warn', message, data));
|
|
25
|
+
}
|
|
26
|
+
error(message, data) {
|
|
27
|
+
console.error(this.format('error', message, data));
|
|
28
|
+
}
|
|
29
|
+
debug(message, data) {
|
|
30
|
+
if (this.isDev) {
|
|
31
|
+
console.debug(this.format('debug', message, data));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.logger = new Logger();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff Summary Generator
|
|
3
|
+
* Produces human-readable summaries of changes between document versions
|
|
4
|
+
*/
|
|
5
|
+
export interface DiffSummary {
|
|
6
|
+
sectionsAdded: string[];
|
|
7
|
+
sectionsRemoved: string[];
|
|
8
|
+
sectionsChanged: string[];
|
|
9
|
+
linesAdded: number;
|
|
10
|
+
linesRemoved: number;
|
|
11
|
+
summary: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate a diff summary between two document versions
|
|
15
|
+
* @param oldContent - Previous version content
|
|
16
|
+
* @param newContent - New version content
|
|
17
|
+
* @returns DiffSummary with changes and statistics
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateDiffSummary(oldContent: string, newContent: string): DiffSummary;
|
|
20
|
+
//# sourceMappingURL=differ.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"differ.d.ts","sourceRoot":"","sources":["../../src/versioning/differ.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAqDvF"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Diff Summary Generator
|
|
4
|
+
* Produces human-readable summaries of changes between document versions
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.generateDiffSummary = generateDiffSummary;
|
|
41
|
+
const Diff = __importStar(require("diff"));
|
|
42
|
+
/**
|
|
43
|
+
* Generate a diff summary between two document versions
|
|
44
|
+
* @param oldContent - Previous version content
|
|
45
|
+
* @param newContent - New version content
|
|
46
|
+
* @returns DiffSummary with changes and statistics
|
|
47
|
+
*/
|
|
48
|
+
function generateDiffSummary(oldContent, newContent) {
|
|
49
|
+
const oldLines = oldContent.split('\n');
|
|
50
|
+
const newLines = newContent.split('\n');
|
|
51
|
+
// Get line-level changes
|
|
52
|
+
const changes = Diff.diffLines(oldContent, newContent);
|
|
53
|
+
// Count additions and removals
|
|
54
|
+
let linesAdded = 0;
|
|
55
|
+
let linesRemoved = 0;
|
|
56
|
+
for (const change of changes) {
|
|
57
|
+
if (change.added) {
|
|
58
|
+
linesAdded += change.value.split('\n').filter((l) => l.length > 0).length;
|
|
59
|
+
}
|
|
60
|
+
else if (change.removed) {
|
|
61
|
+
linesRemoved += change.value.split('\n').filter((l) => l.length > 0).length;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Extract sections (markdown headers)
|
|
65
|
+
const oldSections = extractSections(oldLines);
|
|
66
|
+
const newSections = extractSections(newLines);
|
|
67
|
+
// Compare sections
|
|
68
|
+
const sectionsAdded = newSections.filter((s) => !oldSections.includes(s));
|
|
69
|
+
const sectionsRemoved = oldSections.filter((s) => !newSections.includes(s));
|
|
70
|
+
const sectionsChanged = findChangedSections(oldContent, newContent, oldSections, newSections);
|
|
71
|
+
// Build summary
|
|
72
|
+
const summaryParts = [];
|
|
73
|
+
if (sectionsAdded.length > 0) {
|
|
74
|
+
summaryParts.push(`Added ${sectionsAdded.length} section(s)`);
|
|
75
|
+
}
|
|
76
|
+
if (sectionsRemoved.length > 0) {
|
|
77
|
+
summaryParts.push(`Removed ${sectionsRemoved.length} section(s)`);
|
|
78
|
+
}
|
|
79
|
+
if (sectionsChanged.length > 0) {
|
|
80
|
+
summaryParts.push(`Updated ${sectionsChanged.length} section(s)`);
|
|
81
|
+
}
|
|
82
|
+
summaryParts.push(`+${linesAdded} -${linesRemoved} lines`);
|
|
83
|
+
const summary = summaryParts.join(', ');
|
|
84
|
+
return {
|
|
85
|
+
sectionsAdded,
|
|
86
|
+
sectionsRemoved,
|
|
87
|
+
sectionsChanged,
|
|
88
|
+
linesAdded,
|
|
89
|
+
linesRemoved,
|
|
90
|
+
summary,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Extract all markdown headers from content
|
|
95
|
+
* Matches ## and ### level headers
|
|
96
|
+
*/
|
|
97
|
+
function extractSections(lines) {
|
|
98
|
+
const sections = [];
|
|
99
|
+
for (const line of lines) {
|
|
100
|
+
if (line.match(/^##\s+/) || line.match(/^###\s+/)) {
|
|
101
|
+
// Extract header text (remove markdown syntax)
|
|
102
|
+
const text = line.replace(/^#+\s+/, '').trim();
|
|
103
|
+
if (text.length > 0) {
|
|
104
|
+
sections.push(text);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return sections;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Find sections that exist in both versions but have changed content
|
|
112
|
+
* This is a heuristic: we check if section content differs
|
|
113
|
+
*/
|
|
114
|
+
function findChangedSections(oldContent, newContent, oldSections, newSections) {
|
|
115
|
+
const common = oldSections.filter((s) => newSections.includes(s));
|
|
116
|
+
const changed = [];
|
|
117
|
+
for (const section of common) {
|
|
118
|
+
// Extract content for this section from both versions
|
|
119
|
+
const oldSectionContent = extractSectionContent(oldContent, section);
|
|
120
|
+
const newSectionContent = extractSectionContent(newContent, section);
|
|
121
|
+
// If content differs, it's changed
|
|
122
|
+
if (oldSectionContent !== newSectionContent) {
|
|
123
|
+
changed.push(section);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return changed;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Extract the content of a specific section from markdown
|
|
130
|
+
* Returns text from the header until the next header of same or higher level
|
|
131
|
+
*/
|
|
132
|
+
function extractSectionContent(content, sectionTitle) {
|
|
133
|
+
const lines = content.split('\n');
|
|
134
|
+
let startIdx = -1;
|
|
135
|
+
let endIdx = lines.length;
|
|
136
|
+
// Find the section header
|
|
137
|
+
for (let i = 0; i < lines.length; i++) {
|
|
138
|
+
if (lines[i].includes(sectionTitle)) {
|
|
139
|
+
startIdx = i;
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (startIdx === -1) {
|
|
144
|
+
return '';
|
|
145
|
+
}
|
|
146
|
+
// Find the next header of same or higher level (## or ###)
|
|
147
|
+
const headerMatch = lines[startIdx].match(/^(#+)\s+/);
|
|
148
|
+
const headerLevel = headerMatch ? headerMatch[1].length : 0;
|
|
149
|
+
for (let i = startIdx + 1; i < lines.length; i++) {
|
|
150
|
+
const nextHeaderMatch = lines[i].match(/^(#+)\s+/);
|
|
151
|
+
if (nextHeaderMatch) {
|
|
152
|
+
const nextLevel = nextHeaderMatch[1].length;
|
|
153
|
+
if (nextLevel <= headerLevel) {
|
|
154
|
+
endIdx = i;
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return lines.slice(startIdx, endIdx).join('\n');
|
|
160
|
+
}
|