@cccarv82/freya 1.0.52 → 1.0.53
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/cli/web.js +83 -19
- package/package.json +1 -1
package/cli/web.js
CHANGED
|
@@ -30,6 +30,12 @@ function escapeHtml(str) {
|
|
|
30
30
|
|
|
31
31
|
const APP_VERSION = readAppVersion();
|
|
32
32
|
|
|
33
|
+
const CHAT_ID_PATTERNS = [
|
|
34
|
+
/\bPTI\d{4,}-\d+\b/gi,
|
|
35
|
+
/\bINC\d+\b/gi,
|
|
36
|
+
/\bCHG\d+\b/gi
|
|
37
|
+
];
|
|
38
|
+
|
|
33
39
|
function guessNpmCmd() {
|
|
34
40
|
// We'll execute via cmd.exe on Windows for reliability.
|
|
35
41
|
return process.platform === 'win32' ? 'npm' : 'npm';
|
|
@@ -637,6 +643,61 @@ function isAllowedChatSearchPath(relPath) {
|
|
|
637
643
|
return relPath.startsWith('data/') || relPath.startsWith('logs/') || relPath.startsWith('docs/');
|
|
638
644
|
}
|
|
639
645
|
|
|
646
|
+
function extractChatIds(text) {
|
|
647
|
+
const tokens = new Set();
|
|
648
|
+
const q = String(text || '');
|
|
649
|
+
for (const re of CHAT_ID_PATTERNS) {
|
|
650
|
+
const matches = q.match(re);
|
|
651
|
+
if (matches) {
|
|
652
|
+
for (const m of matches) tokens.add(m.toUpperCase());
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return Array.from(tokens);
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
function extractProjectToken(text) {
|
|
659
|
+
const raw = String(text || '');
|
|
660
|
+
const m = raw.match(/project\s*[:=]\s*([A-Za-z0-9_\/-]+)/i);
|
|
661
|
+
if (m && m[1]) return m[1].trim();
|
|
662
|
+
const m2 = raw.match(/project\s*\(([^)]+)\)/i);
|
|
663
|
+
if (m2 && m2[1]) return m2[1].trim();
|
|
664
|
+
return '';
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
function projectFromPath(relPath) {
|
|
668
|
+
const p = String(relPath || '');
|
|
669
|
+
const m = p.match(/data\/Clients\/([^/]+)\/([^/]+)/i);
|
|
670
|
+
if (m && m[1] && m[2]) return `${m[1]}/${m[2]}`;
|
|
671
|
+
return '';
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
function matchKey(m) {
|
|
675
|
+
const ids = extractChatIds(`${m.file || ''} ${m.snippet || ''}`);
|
|
676
|
+
if (ids.length) return `id:${ids[0]}`;
|
|
677
|
+
const proj = projectFromPath(m.file) || extractProjectToken(`${m.file || ''} ${m.snippet || ''}`);
|
|
678
|
+
if (proj) return `proj:${proj.toLowerCase()}`;
|
|
679
|
+
return `file:${m.file || ''}`;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
function mergeMatches(primary, secondary, limit = 8) {
|
|
683
|
+
const list = [];
|
|
684
|
+
const seen = new Set();
|
|
685
|
+
const push = (m) => {
|
|
686
|
+
if (!m || !m.file || !isAllowedChatSearchPath(m.file)) return;
|
|
687
|
+
const key = matchKey(m);
|
|
688
|
+
if (seen.has(key)) return;
|
|
689
|
+
seen.add(key);
|
|
690
|
+
list.push(m);
|
|
691
|
+
};
|
|
692
|
+
|
|
693
|
+
(primary || []).forEach(push);
|
|
694
|
+
(secondary || []).forEach(push);
|
|
695
|
+
|
|
696
|
+
const total = list.length;
|
|
697
|
+
const trimmed = list.slice(0, Math.max(1, Math.min(20, limit)));
|
|
698
|
+
return { matches: trimmed, total };
|
|
699
|
+
}
|
|
700
|
+
|
|
640
701
|
async function copilotSearch(workspaceDir, query, opts = {}) {
|
|
641
702
|
const q = String(query || '').trim();
|
|
642
703
|
if (!q) return { ok: false, error: 'Missing query' };
|
|
@@ -723,8 +784,8 @@ async function copilotSearch(workspaceDir, query, opts = {}) {
|
|
|
723
784
|
return { ok: true, answer, matches, evidence };
|
|
724
785
|
}
|
|
725
786
|
|
|
726
|
-
function buildChatAnswer(query, matches, summary, evidence, answer) {
|
|
727
|
-
const count = matches.length;
|
|
787
|
+
function buildChatAnswer(query, matches, summary, evidence, answer, totalCount) {
|
|
788
|
+
const count = typeof totalCount === 'number' ? totalCount : matches.length;
|
|
728
789
|
let summaryText = String(summary || '').trim();
|
|
729
790
|
let answerText = String(answer || '').trim();
|
|
730
791
|
if (!answerText) {
|
|
@@ -740,7 +801,7 @@ function buildChatAnswer(query, matches, summary, evidence, answer) {
|
|
|
740
801
|
|
|
741
802
|
const lines = [];
|
|
742
803
|
lines.push(`Encontrei ${count} registro(s).`);
|
|
743
|
-
lines.push(`
|
|
804
|
+
lines.push(`Resposta curta: ${answerText}`);
|
|
744
805
|
|
|
745
806
|
const evidences = Array.isArray(evidence) && evidence.length
|
|
746
807
|
? evidence
|
|
@@ -749,15 +810,15 @@ function buildChatAnswer(query, matches, summary, evidence, answer) {
|
|
|
749
810
|
if (!evidences.length) return lines.join('\n');
|
|
750
811
|
|
|
751
812
|
lines.push('');
|
|
752
|
-
lines.push('
|
|
813
|
+
lines.push('Detalhes:');
|
|
753
814
|
for (const m of evidences.slice(0, 5)) {
|
|
754
|
-
const parts = [];
|
|
755
|
-
if (m.date) parts.push(`**${m.date}**`);
|
|
756
|
-
if (m.file) parts.push('`' + m.file + '`');
|
|
757
|
-
const prefix = parts.length ? parts.join(' — ') + ':' : '';
|
|
758
815
|
const detail = (m.detail || m.snippet || '').toString().trim();
|
|
759
816
|
if (!detail) continue;
|
|
760
|
-
|
|
817
|
+
const meta = [];
|
|
818
|
+
if (m.file) meta.push(m.file);
|
|
819
|
+
if (m.date) meta.push(m.date);
|
|
820
|
+
const suffix = meta.length ? ` (${meta.join(' · ')})` : '';
|
|
821
|
+
lines.push(`- ${detail}${suffix}`);
|
|
761
822
|
}
|
|
762
823
|
|
|
763
824
|
return lines.join('\n');
|
|
@@ -1781,24 +1842,27 @@ async function cmdWeb({ port, dir, open, dev }) {
|
|
|
1781
1842
|
if (!query) return safeJson(res, 400, { error: 'Missing query' });
|
|
1782
1843
|
|
|
1783
1844
|
const copilotResult = await copilotSearch(workspaceDir, query, { limit: 8 });
|
|
1845
|
+
const indexMatches = searchIndex(workspaceDir, query, { limit: 12 });
|
|
1846
|
+
const baseMatches = indexMatches.length
|
|
1847
|
+
? indexMatches
|
|
1848
|
+
: searchWorkspace(workspaceDir, query, { limit: 12 });
|
|
1849
|
+
|
|
1784
1850
|
if (copilotResult.ok) {
|
|
1785
|
-
const
|
|
1851
|
+
const merged = mergeMatches(copilotResult.matches || [], baseMatches, 8);
|
|
1786
1852
|
const answer = buildChatAnswer(
|
|
1787
1853
|
query,
|
|
1788
|
-
matches,
|
|
1854
|
+
merged.matches,
|
|
1789
1855
|
copilotResult.summary,
|
|
1790
1856
|
copilotResult.evidence,
|
|
1791
|
-
copilotResult.answer
|
|
1857
|
+
copilotResult.answer,
|
|
1858
|
+
merged.total
|
|
1792
1859
|
);
|
|
1793
|
-
return safeJson(res, 200, { ok: true, sessionId, answer, matches });
|
|
1860
|
+
return safeJson(res, 200, { ok: true, sessionId, answer, matches: merged.matches });
|
|
1794
1861
|
}
|
|
1795
1862
|
|
|
1796
|
-
const
|
|
1797
|
-
const
|
|
1798
|
-
|
|
1799
|
-
: searchWorkspace(workspaceDir, query, { limit: 8 });
|
|
1800
|
-
const answer = buildChatAnswer(query, matches, '');
|
|
1801
|
-
return safeJson(res, 200, { ok: true, sessionId, answer, matches });
|
|
1863
|
+
const merged = mergeMatches(baseMatches, [], 8);
|
|
1864
|
+
const answer = buildChatAnswer(query, merged.matches, '', [], '', merged.total);
|
|
1865
|
+
return safeJson(res, 200, { ok: true, sessionId, answer, matches: merged.matches });
|
|
1802
1866
|
}
|
|
1803
1867
|
|
|
1804
1868
|
// Chat persistence (per session)
|