@cccarv82/freya 1.0.9 → 1.0.10

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.
Files changed (2) hide show
  1. package/cli/web.js +116 -28
  2. package/package.json +1 -1
package/cli/web.js CHANGED
@@ -954,72 +954,160 @@ function isoNow() {
954
954
  return new Date().toISOString();
955
955
  }
956
956
 
957
+ function daysAgoIso(n) {
958
+ return new Date(Date.now() - n * 24 * 60 * 60 * 1000).toISOString();
959
+ }
960
+
961
+ function readJsonOrNull(p) {
962
+ try {
963
+ return JSON.parse(fs.readFileSync(p, 'utf8'));
964
+ } catch {
965
+ return null;
966
+ }
967
+ }
968
+
969
+ function writeJson(p, obj) {
970
+ ensureDir(path.dirname(p));
971
+ fs.writeFileSync(p, JSON.stringify(obj, null, 2) + '\n', 'utf8');
972
+ }
973
+
974
+ function looksLikeDevSeed(json) {
975
+ if (!json || typeof json !== 'object') return false;
976
+ // Heuristic: any id ends with demo marker or source is dev-seed
977
+ const dump = JSON.stringify(json);
978
+ return dump.includes('dev-seed') || dump.includes('t-demo-') || dump.includes('b-demo-') || dump.includes('c-demo-');
979
+ }
980
+
957
981
  function seedDevWorkspace(workspaceDir) {
958
- // Only create if missing; never overwrite user content.
982
+ // Safe by default:
983
+ // - create missing demo files
984
+ // - if file exists and looks like prior dev-seed, upgrade it to richer demo
959
985
  ensureDir(path.join(workspaceDir, 'data', 'tasks'));
960
986
  ensureDir(path.join(workspaceDir, 'data', 'career'));
961
987
  ensureDir(path.join(workspaceDir, 'data', 'blockers'));
962
988
  ensureDir(path.join(workspaceDir, 'data', 'Clients', 'acme', 'rocket'));
989
+ ensureDir(path.join(workspaceDir, 'data', 'Clients', 'vivo', '5g'));
963
990
  ensureDir(path.join(workspaceDir, 'logs', 'daily'));
964
991
 
965
992
  const taskLog = path.join(workspaceDir, 'data', 'tasks', 'task-log.json');
966
- if (!exists(taskLog)) {
967
- fs.writeFileSync(taskLog, JSON.stringify({
993
+ const taskExisting = readJsonOrNull(taskLog);
994
+ if (!exists(taskLog) || looksLikeDevSeed(taskExisting)) {
995
+ writeJson(taskLog, {
968
996
  schemaVersion: 1,
969
997
  tasks: [
970
- { id: 't-demo-1', description: 'Preparar update executivo', category: 'DO_NOW', status: 'PENDING', createdAt: isoNow(), priority: 'high' },
971
- { id: 't-demo-2', description: 'Revisar PR de integração Teams', category: 'SCHEDULE', status: 'PENDING', createdAt: isoNow(), priority: 'medium' },
972
- { id: 't-demo-3', description: 'Rodar retro e registrar aprendizados', category: 'DO_NOW', status: 'COMPLETED', createdAt: isoNow(), completedAt: isoNow(), priority: 'low' }
998
+ // Completed in last 7 days
999
+ { id: 't-demo-ship-1', description: 'Publicar pacote @cccarv82/freya no npm (CI)', category: 'DO_NOW', status: 'COMPLETED', createdAt: daysAgoIso(6), completedAt: daysAgoIso(5), priority: 'high', projectSlug: 'acme-rocket' },
1000
+ { id: 't-demo-ship-2', description: 'Adicionar UI web local (freya web)', category: 'DO_NOW', status: 'COMPLETED', createdAt: daysAgoIso(4), completedAt: daysAgoIso(3), priority: 'high', projectSlug: 'acme-rocket' },
1001
+ { id: 't-demo-ship-3', description: 'Corrigir publish via npm token/2FA', category: 'DO_NOW', status: 'COMPLETED', createdAt: daysAgoIso(3), completedAt: daysAgoIso(2), priority: 'medium' },
1002
+ // Pending
1003
+ { id: 't-demo-now-1', description: 'Refinar UI/UX do painel web (layout + preview)', category: 'DO_NOW', status: 'PENDING', createdAt: daysAgoIso(1), priority: 'high' },
1004
+ { id: 't-demo-now-2', description: 'Melhorar publish no Teams (cards + chunks)', category: 'DO_NOW', status: 'PENDING', createdAt: daysAgoIso(1), priority: 'medium' },
1005
+ { id: 't-demo-schedule-1', description: 'Criar modo "freya web" com preview Markdown', category: 'SCHEDULE', status: 'PENDING', createdAt: daysAgoIso(0), priority: 'medium' },
1006
+ { id: 't-demo-delegate-1', description: 'Pedir feedback de 3 usuários beta (UX)', category: 'DELEGATE', status: 'PENDING', createdAt: daysAgoIso(0), priority: 'low' }
973
1007
  ]
974
- }, null, 2) + '\n', 'utf8');
1008
+ });
975
1009
  }
976
1010
 
977
1011
  const careerLog = path.join(workspaceDir, 'data', 'career', 'career-log.json');
978
- if (!exists(careerLog)) {
979
- fs.writeFileSync(careerLog, JSON.stringify({
1012
+ const careerExisting = readJsonOrNull(careerLog);
1013
+ if (!exists(careerLog) || looksLikeDevSeed(careerExisting)) {
1014
+ writeJson(careerLog, {
980
1015
  schemaVersion: 1,
981
1016
  entries: [
982
- { id: 'c-demo-1', date: isoDate(), type: 'Achievement', description: 'Publicou o CLI @cccarv82/freya com init/web', tags: ['shipping', 'tooling'], source: 'dev-seed' },
983
- { id: 'c-demo-2', date: isoDate(), type: 'Feedback', description: 'Feedback: UX do painel web está “muito promissor”', tags: ['product'], source: 'dev-seed' }
1017
+ { id: 'c-demo-1', date: daysAgoIso(6).slice(0, 10), type: 'Achievement', description: 'Estruturou pipeline de publicação npm com tags e NPM_TOKEN', tags: ['devops', 'release'], source: 'dev-seed' },
1018
+ { id: 'c-demo-2', date: daysAgoIso(4).slice(0, 10), type: 'Feedback', description: 'Feedback: “Setup via npx ficou ridiculamente simples.”', tags: ['product', 'ux'], source: 'dev-seed' },
1019
+ { id: 'c-demo-3', date: daysAgoIso(2).slice(0, 10), type: 'Achievement', description: 'Entregou modo web local com geração de relatórios e publish.', tags: ['shipping', 'frontend'], source: 'dev-seed' },
1020
+ { id: 'c-demo-4', date: daysAgoIso(1).slice(0, 10), type: 'Goal', description: 'Validar o produto com 5 times e transformar em serviço B2B.', tags: ['business'], source: 'dev-seed' }
984
1021
  ]
985
- }, null, 2) + '\n', 'utf8');
1022
+ });
986
1023
  }
987
1024
 
988
1025
  const blockerLog = path.join(workspaceDir, 'data', 'blockers', 'blocker-log.json');
989
- if (!exists(blockerLog)) {
990
- fs.writeFileSync(blockerLog, JSON.stringify({
1026
+ const blockerExisting = readJsonOrNull(blockerLog);
1027
+ if (!exists(blockerLog) || looksLikeDevSeed(blockerExisting)) {
1028
+ writeJson(blockerLog, {
991
1029
  schemaVersion: 1,
992
1030
  blockers: [
993
- { id: 'b-demo-1', title: 'Webhook do Teams falhando em ambientes com 2FA', description: 'Ajustar token / payload', createdAt: isoNow(), status: 'OPEN', severity: 'HIGH', nextAction: 'Validar payload e limites' },
994
- { id: 'b-demo-2', title: 'Definir template de status report por cliente', description: 'Padronizar headings', createdAt: isoNow(), status: 'MITIGATING', severity: 'MEDIUM' }
1031
+ { id: 'b-demo-crit-1', title: 'Spawn EINVAL no Windows ao rodar npx via server', description: 'Ajustar execução via cmd.exe /c', createdAt: daysAgoIso(2), status: 'RESOLVED', severity: 'CRITICAL', resolvedAt: daysAgoIso(1), nextAction: 'Validar em ambiente real' },
1032
+ { id: 'b-demo-high-1', title: 'Teams webhook truncando mensagens longas', description: 'Implementar chunking + cards', createdAt: daysAgoIso(1), status: 'OPEN', severity: 'HIGH', nextAction: 'Dividir em blocos e enviar sequencialmente' },
1033
+ { id: 'b-demo-med-1', title: 'Preview Markdown no web (render)', description: 'Adicionar render de Markdown no front', createdAt: daysAgoIso(1), status: 'MITIGATING', severity: 'MEDIUM', nextAction: 'Render simples (headers/lists/code) sem deps' },
1034
+ { id: 'b-demo-low-1', title: 'Polish: remover duplicações na UI', description: 'Consolidar ações na sidebar ou na página', createdAt: daysAgoIso(0), status: 'OPEN', severity: 'LOW' }
995
1035
  ]
996
- }, null, 2) + '\n', 'utf8');
1036
+ });
997
1037
  }
998
1038
 
999
- const projectStatus = path.join(workspaceDir, 'data', 'Clients', 'acme', 'rocket', 'status.json');
1000
- if (!exists(projectStatus)) {
1001
- fs.writeFileSync(projectStatus, JSON.stringify({
1039
+ // Project statuses
1040
+ const projectStatus1 = path.join(workspaceDir, 'data', 'Clients', 'acme', 'rocket', 'status.json');
1041
+ const ps1 = readJsonOrNull(projectStatus1);
1042
+ if (!exists(projectStatus1) || looksLikeDevSeed(ps1)) {
1043
+ writeJson(projectStatus1, {
1002
1044
  schemaVersion: 1,
1003
1045
  client: 'Acme',
1004
1046
  project: 'Rocket',
1005
1047
  currentStatus: 'Green — progressing as planned',
1006
- lastUpdated: isoNow(),
1048
+ lastUpdated: daysAgoIso(0),
1049
+ active: true,
1050
+ history: [
1051
+ { date: daysAgoIso(6), type: 'Decision', content: 'Adotar publish via tags vX.Y.Z no GitHub', source: 'dev-seed' },
1052
+ { date: daysAgoIso(4), type: 'Status', content: 'Painel web MVP subiu localmente (freya web)', source: 'dev-seed' },
1053
+ { date: daysAgoIso(2), type: 'Risk', content: 'Windows spawn issues ao chamar npx (corrigir)', source: 'dev-seed' },
1054
+ { date: daysAgoIso(1), type: 'Status', content: 'Correções de compatibilidade Windows + auto-seed', source: 'dev-seed' },
1055
+ { date: daysAgoIso(0), type: 'Status', content: 'UI redesign inspirado em apps modernos (tema claro + toggle)', source: 'dev-seed' }
1056
+ ]
1057
+ });
1058
+ }
1059
+
1060
+ const projectStatus2 = path.join(workspaceDir, 'data', 'Clients', 'vivo', '5g', 'status.json');
1061
+ const ps2 = readJsonOrNull(projectStatus2);
1062
+ if (!exists(projectStatus2) || looksLikeDevSeed(ps2)) {
1063
+ writeJson(projectStatus2, {
1064
+ schemaVersion: 1,
1065
+ client: 'Vivo',
1066
+ project: '5G',
1067
+ currentStatus: 'Amber — dependency on vendor payload format',
1068
+ lastUpdated: daysAgoIso(1),
1007
1069
  active: true,
1008
1070
  history: [
1009
- { date: isoNow(), type: 'Status', content: 'Launched stage 1', source: 'dev-seed' },
1010
- { date: isoNow(), type: 'Risk', content: 'Potential delay on vendor dependency', source: 'dev-seed' }
1071
+ { date: daysAgoIso(5), type: 'Status', content: 'Integração inicial concluída; aguardando webhook do Teams', source: 'dev-seed' },
1072
+ { date: daysAgoIso(3), type: 'Blocker', content: 'Falha intermitente no webhook em ambiente com 2FA', source: 'dev-seed' },
1073
+ { date: daysAgoIso(1), type: 'Decision', content: 'Implementar chunking e fallback de publish', source: 'dev-seed' }
1011
1074
  ]
1012
- }, null, 2) + '\n', 'utf8');
1075
+ });
1013
1076
  }
1014
1077
 
1015
- const dailyLog = path.join(workspaceDir, 'logs', 'daily', `${isoDate()}.md`);
1016
- if (!exists(dailyLog)) {
1017
- fs.writeFileSync(dailyLog, `# Daily Log ${isoDate()}\n\n## [09:15] Raw Input\nReunião com a Acme. Tudo verde, mas preciso alinhar com fornecedor.\n\n## [16:40] Raw Input\nTerminei o relatório SM e publiquei no Discord.\n`, 'utf8');
1078
+ // Daily logs: create today and yesterday if missing
1079
+ const today = isoDate();
1080
+ const yesterday = isoDate(new Date(Date.now() - 24 * 60 * 60 * 1000));
1081
+
1082
+ const daily1 = path.join(workspaceDir, 'logs', 'daily', `${yesterday}.md`);
1083
+ if (!exists(daily1)) {
1084
+ fs.writeFileSync(
1085
+ daily1,
1086
+ `# Daily Log ${yesterday}\n\n## [09:10] Raw Input\nHoje preciso melhorar a UX do web e destravar publish no Teams.\n\n## [11:25] Raw Input\nEstou travado no payload do Teams; vou dividir mensagens em chunks.\n\n## [18:05] Raw Input\nTerminei a correção do Windows (spawn) e rodei testes.\n`,
1087
+ 'utf8'
1088
+ );
1089
+ }
1090
+
1091
+ const daily2 = path.join(workspaceDir, 'logs', 'daily', `${today}.md`);
1092
+ if (!exists(daily2)) {
1093
+ fs.writeFileSync(
1094
+ daily2,
1095
+ `# Daily Log ${today}\n\n## [09:05] Raw Input\nReunião com Acme: projeto Rocket verde, foco em polish do produto.\n\n## [14:20] Raw Input\nPreciso preparar update executivo e publicar no Discord.\n\n## [17:45] Raw Input\nFechei os blockers críticos e gerei relatório SM semanal.\n`,
1096
+ 'utf8'
1097
+ );
1018
1098
  }
1019
1099
 
1020
1100
  return {
1021
1101
  seeded: true,
1022
- paths: { taskLog, careerLog, blockerLog, projectStatus, dailyLog }
1102
+ paths: {
1103
+ taskLog,
1104
+ careerLog,
1105
+ blockerLog,
1106
+ projectStatus1,
1107
+ projectStatus2,
1108
+ daily1,
1109
+ daily2
1110
+ }
1023
1111
  };
1024
1112
  }
1025
1113
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cccarv82/freya",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "Personal AI Assistant with local-first persistence",
5
5
  "scripts": {
6
6
  "health": "node scripts/validate-data.js",