@cccarv82/freya 1.0.29 → 1.0.30
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-ui.js +6 -2
- package/cli/web.js +63 -2
- package/package.json +1 -1
package/cli/web-ui.js
CHANGED
|
@@ -347,7 +347,9 @@
|
|
|
347
347
|
const pri = (t.priority || '').toUpperCase();
|
|
348
348
|
row.innerHTML = '<div style="display:flex; justify-content:space-between; gap:10px; align-items:center">'
|
|
349
349
|
+ '<div style="min-width:0"><div style="font-weight:700">' + escapeHtml(t.description || '') + '</div>'
|
|
350
|
-
+ '<div style="opacity:.7; font-size:11px; margin-top:4px">' + escapeHtml(String(t.category || ''))
|
|
350
|
+
+ '<div style="opacity:.7; font-size:11px; margin-top:4px">' + escapeHtml(String(t.category || ''))
|
|
351
|
+
+ (t.projectSlug ? (' · <span style="font-family:var(--mono); opacity:.9">[' + escapeHtml(String(t.projectSlug)) + ']</span>') : '')
|
|
352
|
+
+ (pri ? (' · ' + escapeHtml(pri)) : '') + '</div></div>'
|
|
351
353
|
+ '<button class="btn small" type="button">Complete</button>'
|
|
352
354
|
+ '</div>';
|
|
353
355
|
const btn = row.querySelector('button');
|
|
@@ -383,7 +385,9 @@
|
|
|
383
385
|
const sev = String(b.severity || '').toUpperCase();
|
|
384
386
|
row.innerHTML = '<div style="display:flex; justify-content:space-between; gap:10px; align-items:center">'
|
|
385
387
|
+ '<div style="min-width:0"><div style="font-weight:800">' + escapeHtml(sev) + '</div>'
|
|
386
|
-
+ '<div style="margin-top:4px">' + escapeHtml(b.title || '')
|
|
388
|
+
+ '<div style="margin-top:4px">' + escapeHtml(b.title || '')
|
|
389
|
+
+ (b.projectSlug ? (' <span style="font-family:var(--mono); opacity:.8">[' + escapeHtml(String(b.projectSlug)) + ']</span>') : '')
|
|
390
|
+
+ '</div>'
|
|
387
391
|
+ '</div>'
|
|
388
392
|
+ '<div style="opacity:.7; font-size:11px; white-space:nowrap">' + escapeHtml(fmtWhen(new Date(b.createdAt || Date.now()).getTime())) + '</div>'
|
|
389
393
|
+ '</div>';
|
package/cli/web.js
CHANGED
|
@@ -91,6 +91,66 @@ function writeSettings(workspaceDir, settings) {
|
|
|
91
91
|
return out;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
function projectSlugMapPath(workspaceDir) {
|
|
95
|
+
return path.join(workspaceDir, 'data', 'settings', 'project-slug-map.json');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function readProjectSlugMap(workspaceDir) {
|
|
99
|
+
const p = projectSlugMapPath(workspaceDir);
|
|
100
|
+
try {
|
|
101
|
+
if (!exists(p)) {
|
|
102
|
+
ensureDir(path.dirname(p));
|
|
103
|
+
const defaults = {
|
|
104
|
+
schemaVersion: 1,
|
|
105
|
+
updatedAt: new Date().toISOString(),
|
|
106
|
+
rules: [
|
|
107
|
+
{ contains: 'fideliza', slug: 'vivo/fidelizacao' },
|
|
108
|
+
{ contains: 'bnpl', slug: 'vivo/bnpl' },
|
|
109
|
+
{ contains: 'dpgc', slug: 'vivo/bnpl/dpgc' },
|
|
110
|
+
{ contains: 'vivo+', slug: 'vivo/vivoplus' }
|
|
111
|
+
]
|
|
112
|
+
};
|
|
113
|
+
fs.writeFileSync(p, JSON.stringify(defaults, null, 2) + '\n', 'utf8');
|
|
114
|
+
return defaults;
|
|
115
|
+
}
|
|
116
|
+
const json = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
117
|
+
if (!json || !Array.isArray(json.rules)) return { schemaVersion: 1, rules: [] };
|
|
118
|
+
return json;
|
|
119
|
+
} catch {
|
|
120
|
+
return { schemaVersion: 1, rules: [] };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function inferProjectSlug(text, map) {
|
|
125
|
+
const t = String(text || '').toLowerCase();
|
|
126
|
+
if (!t.trim()) return '';
|
|
127
|
+
|
|
128
|
+
let base = '';
|
|
129
|
+
const rules = (map && Array.isArray(map.rules)) ? map.rules : [];
|
|
130
|
+
for (const r of rules) {
|
|
131
|
+
if (!r) continue;
|
|
132
|
+
const needle = String(r.contains || '').toLowerCase().trim();
|
|
133
|
+
const slug = String(r.slug || '').trim();
|
|
134
|
+
if (!needle || !slug) continue;
|
|
135
|
+
if (t.includes(needle)) { base = slug; break; }
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// CHG tags
|
|
139
|
+
const chg = (t.match(/\bchg\s*0*\d{4,}\b/i) || [])[0];
|
|
140
|
+
const chgNorm = chg ? chg.toLowerCase().replace(/\s+/g, '') : '';
|
|
141
|
+
|
|
142
|
+
// If no base but looks like Vivo context, at least prefix vivo
|
|
143
|
+
if (!base && (t.includes('vivo') || t.includes('vivo+'))) base = 'vivo';
|
|
144
|
+
|
|
145
|
+
if (base && chgNorm) {
|
|
146
|
+
// keep numeric id
|
|
147
|
+
const id = chgNorm.replace(/[^0-9]/g, '');
|
|
148
|
+
if (id) base = base.replace(/\/+$/g, '') + '/chg' + id;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return base;
|
|
152
|
+
}
|
|
153
|
+
|
|
94
154
|
function listReports(workspaceDir) {
|
|
95
155
|
const dir = path.join(workspaceDir, 'docs', 'reports');
|
|
96
156
|
if (!exists(dir)) return [];
|
|
@@ -1222,6 +1282,7 @@ async function cmdWeb({ port, dir, open, dev }) {
|
|
|
1222
1282
|
const now = new Date().toISOString();
|
|
1223
1283
|
const applyMode = String(payload.mode || 'all').trim();
|
|
1224
1284
|
const applied = { tasks: 0, blockers: 0, tasksSkipped: 0, blockersSkipped: 0, reportsSuggested: [], oracleQueries: [], mode: applyMode };
|
|
1285
|
+
const slugMap = readProjectSlugMap(workspaceDir);
|
|
1225
1286
|
|
|
1226
1287
|
function makeId(prefix) {
|
|
1227
1288
|
const rand = Math.random().toString(16).slice(2, 8);
|
|
@@ -1256,7 +1317,7 @@ async function cmdWeb({ port, dir, open, dev }) {
|
|
|
1256
1317
|
if (applyMode !== 'all' && applyMode !== 'tasks') continue;
|
|
1257
1318
|
const description = normalizeWhitespace(a.description);
|
|
1258
1319
|
if (!description) continue;
|
|
1259
|
-
const projectSlug = String(a.projectSlug || '').trim();
|
|
1320
|
+
const projectSlug = String(a.projectSlug || '').trim() || inferProjectSlug(description, slugMap);
|
|
1260
1321
|
const key = sha1(normalizeTextForKey((projectSlug ? projectSlug + ' ' : '') + description));
|
|
1261
1322
|
if (existingTaskKeys24h.has(key)) { applied.tasksSkipped++; continue; }
|
|
1262
1323
|
const category = validTaskCats.has(String(a.category || '').trim()) ? String(a.category).trim() : 'DO_NOW';
|
|
@@ -1278,7 +1339,7 @@ async function cmdWeb({ port, dir, open, dev }) {
|
|
|
1278
1339
|
if (type === 'create_blocker') {
|
|
1279
1340
|
if (applyMode !== 'all' && applyMode !== 'blockers') continue;
|
|
1280
1341
|
const title = normalizeWhitespace(a.title);
|
|
1281
|
-
const projectSlug = String(a.projectSlug || '').trim();
|
|
1342
|
+
const projectSlug = String(a.projectSlug || '').trim() || inferProjectSlug(title + ' ' + normalizeWhitespace(a.notes), slugMap);
|
|
1282
1343
|
const key = sha1(normalizeTextForKey((projectSlug ? projectSlug + ' ' : '') + title));
|
|
1283
1344
|
if (existingBlockerKeys24h.has(key)) { applied.blockersSkipped++; continue; }
|
|
1284
1345
|
const notes = normalizeWhitespace(a.notes);
|