@cccarv82/freya 1.0.3
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/README.md +92 -0
- package/bin/freya.js +11 -0
- package/cli/index.js +62 -0
- package/cli/init.js +133 -0
- package/package.json +27 -0
- package/templates/base/.agent/rules/freya/agents/coach.mdc +72 -0
- package/templates/base/.agent/rules/freya/agents/ingestor.mdc +183 -0
- package/templates/base/.agent/rules/freya/agents/master.mdc +93 -0
- package/templates/base/.agent/rules/freya/agents/oracle.mdc +102 -0
- package/templates/base/.agent/rules/freya/freya.mdc +31 -0
- package/templates/base/README.md +50 -0
- package/templates/base/USER_GUIDE.md +160 -0
- package/templates/base/data/blockers/blocker-log.json +4 -0
- package/templates/base/data/career/career-log.json +4 -0
- package/templates/base/data/schemas.md +66 -0
- package/templates/base/data/tasks/task-log.json +4 -0
- package/templates/base/scripts/generate-blockers-report.js +215 -0
- package/templates/base/scripts/generate-daily-summary.js +96 -0
- package/templates/base/scripts/generate-executive-report.js +240 -0
- package/templates/base/scripts/generate-sm-weekly-report.js +207 -0
- package/templates/base/scripts/generate-weekly-report.js +134 -0
- package/templates/base/scripts/lib/date-utils.js +37 -0
- package/templates/base/scripts/lib/fs-utils.js +61 -0
- package/templates/base/scripts/migrate-data.js +80 -0
- package/templates/base/scripts/validate-data.js +206 -0
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# F.R.E.Y.A. - Fully Responsive Enhanced Yield Assistant
|
|
2
|
+
|
|
3
|
+
> **Sua Assistente de Produtividade Local-First para sua IDE.**
|
|
4
|
+
|
|
5
|
+
F.R.E.Y.A. é um sistema de agentes de IA projetado para organizar seu trabalho, gerenciar status de projetos, rastrear tarefas e registrar sua evolução de carreira, tudo através de uma interface de chat simples e direta.
|
|
6
|
+
|
|
7
|
+
## 🌟 Principais Recursos
|
|
8
|
+
|
|
9
|
+
* **Ingestão Universal:** Registre updates, blockers e notas mentais em linguagem natural.
|
|
10
|
+
* **Gestão de Tarefas:** Crie, liste e conclua tarefas ("Lembre-me de fazer X", "Minhas tarefas", "Terminei X").
|
|
11
|
+
* **Oráculo:** Pergunte sobre o status de qualquer projeto ("Como está o projeto X?").
|
|
12
|
+
* **Career Coach:** Gere "Brag Sheets" automáticas para suas avaliações de desempenho.
|
|
13
|
+
* **Relatórios Automatizados:** Gere resumos semanais, dailies, relatório de Scrum Master e relatórios executivos.
|
|
14
|
+
* **Blockers & Riscos:** Gere um relatório rápido de blockers priorizados por severidade.
|
|
15
|
+
* **Saúde do Sistema:** Valide a integridade dos seus dados locais com um comando.
|
|
16
|
+
* **Git Automation:** Gere commits inteligentes automaticamente. A Freya analisa suas mudanças e escreve a mensagem para você.
|
|
17
|
+
* **Privacidade Total:** Seus dados (JSON e Markdown) ficam 100% locais na sua máquina.
|
|
18
|
+
|
|
19
|
+
## 📦 Instalação (CLI)
|
|
20
|
+
|
|
21
|
+
Você pode usar a FREYA como um CLI para **inicializar uma workspace** completa (agents + scripts + data) em qualquer diretório.
|
|
22
|
+
|
|
23
|
+
## 🚢 Publicação no npm (maintainers)
|
|
24
|
+
|
|
25
|
+
Este repositório suporta publicação automática via GitHub Actions.
|
|
26
|
+
|
|
27
|
+
### Pré-requisitos
|
|
28
|
+
1) Ter permissão de publish no pacote `@cccarv82/freya` no npm.
|
|
29
|
+
2) Criar o secret no GitHub: `NPM_TOKEN` (Automation token do npm com permissão de publish).
|
|
30
|
+
|
|
31
|
+
### Como publicar
|
|
32
|
+
1) Atualize a versão e crie uma tag `vX.Y.Z`:
|
|
33
|
+
```bash
|
|
34
|
+
npm version patch
|
|
35
|
+
# ou minor/major
|
|
36
|
+
|
|
37
|
+
git push --follow-tags
|
|
38
|
+
```
|
|
39
|
+
2) A Action `npm-publish` roda no push da tag e executa `npm publish --access public`.
|
|
40
|
+
|
|
41
|
+
### Via npx (recomendado)
|
|
42
|
+
```bash
|
|
43
|
+
npx @cccarv82/freya init
|
|
44
|
+
# cria ./freya
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Via instalação global
|
|
48
|
+
```bash
|
|
49
|
+
npm i -g @cccarv82/freya
|
|
50
|
+
freya init
|
|
51
|
+
# cria ./freya
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Modos do `init`
|
|
55
|
+
```bash
|
|
56
|
+
freya init # cria ./freya
|
|
57
|
+
freya init meu-projeto # cria ./meu-projeto
|
|
58
|
+
freya init --here # instala no diretório atual
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 🚀 Como Usar
|
|
62
|
+
|
|
63
|
+
1. Abra a pasta da workspace gerada (ex.: `./freya`) na **sua IDE**.
|
|
64
|
+
2. No chat da IDE (ex: Ctrl+L / Cmd+L), digite:
|
|
65
|
+
> `@freya Ajuda`
|
|
66
|
+
3. Siga as instruções da assistente.
|
|
67
|
+
|
|
68
|
+
### Comandos Rápidos
|
|
69
|
+
Você pode pedir para a FREYA executar estas tarefas diretamente no chat, ou rodar via terminal:
|
|
70
|
+
|
|
71
|
+
* **Checar integridade:** "Verifique a saúde do sistema" (ou `npm run health`)
|
|
72
|
+
* **Migrar dados (se necessário):** `npm run migrate` (adiciona `schemaVersion` em logs antigos)
|
|
73
|
+
* **Relatório Profissional (Executivo):** "Gere o status report" (ou `npm run status`)
|
|
74
|
+
* **Relatório Scrum Master (semanal):** `npm run sm-weekly`
|
|
75
|
+
* **Relatório de blockers:** `npm run blockers`
|
|
76
|
+
* **Relatório semanal (legado):** "Gere o relatório semanal" (ou `npm run report`)
|
|
77
|
+
* **Resumo daily (legado):** "Gere o daily" (ou `npm run daily`)
|
|
78
|
+
|
|
79
|
+
## 📘 Documentação Completa
|
|
80
|
+
|
|
81
|
+
Para um guia detalhado de comandos e exemplos, consulte o **[Guia do Usuário](USER_GUIDE.md)** incluído nesta pasta.
|
|
82
|
+
|
|
83
|
+
## Estrutura de Pastas
|
|
84
|
+
|
|
85
|
+
* `.agent/`: O "cérebro" da IA (Regras e Personas).
|
|
86
|
+
* `data/`: O "banco de dados" (JSONs dos seus projetos, tarefas e carreira).
|
|
87
|
+
* `logs/`: O "diário" (Histórico bruto de tudo que você digitou).
|
|
88
|
+
* `docs/reports/`: Relatórios gerados automaticamente.
|
|
89
|
+
* `scripts/`: Ferramentas de automação e validação.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
*F.R.E.Y.A. v1.0 - Release 2025-12-13*
|
package/bin/freya.js
ADDED
package/cli/index.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const { cmdInit } = require('./init');
|
|
6
|
+
|
|
7
|
+
function usage() {
|
|
8
|
+
return `
|
|
9
|
+
freya - F.R.E.Y.A. CLI
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
freya init [dir] [--force] [--here|--in-place]
|
|
13
|
+
|
|
14
|
+
Defaults:
|
|
15
|
+
- If no [dir] is provided, creates ./freya
|
|
16
|
+
|
|
17
|
+
Examples:
|
|
18
|
+
freya init # creates ./freya
|
|
19
|
+
freya init my-workspace # creates ./my-workspace
|
|
20
|
+
freya init --here # installs into current directory
|
|
21
|
+
npx @cccarv82/freya init
|
|
22
|
+
`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function parseArgs(argv) {
|
|
26
|
+
const args = [];
|
|
27
|
+
const flags = new Set();
|
|
28
|
+
|
|
29
|
+
for (const a of argv) {
|
|
30
|
+
if (a.startsWith('--')) flags.add(a);
|
|
31
|
+
else args.push(a);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return { args, flags };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function run(argv) {
|
|
38
|
+
const { args, flags } = parseArgs(argv);
|
|
39
|
+
const command = args[0];
|
|
40
|
+
|
|
41
|
+
if (!command || command === 'help' || flags.has('--help') || flags.has('-h')) {
|
|
42
|
+
process.stdout.write(usage());
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (command === 'init') {
|
|
47
|
+
const inPlace = flags.has('--here') || flags.has('--in-place');
|
|
48
|
+
const defaultDir = path.join(process.cwd(), 'freya');
|
|
49
|
+
const targetDir = args[1]
|
|
50
|
+
? path.resolve(process.cwd(), args[1])
|
|
51
|
+
: (inPlace ? process.cwd() : defaultDir);
|
|
52
|
+
const force = flags.has('--force');
|
|
53
|
+
await cmdInit({ targetDir, force });
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
process.stderr.write(`Unknown command: ${command}\n`);
|
|
58
|
+
process.stdout.write(usage());
|
|
59
|
+
process.exitCode = 1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = { run };
|
package/cli/init.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
function exists(p) {
|
|
7
|
+
try {
|
|
8
|
+
fs.accessSync(p);
|
|
9
|
+
return true;
|
|
10
|
+
} catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function mkdirp(dir) {
|
|
16
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function readJsonSafe(p) {
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function writeJson(p, obj) {
|
|
28
|
+
mkdirp(path.dirname(p));
|
|
29
|
+
fs.writeFileSync(p, JSON.stringify(obj, null, 2) + '\n', 'utf8');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function copyFile(src, dest, force) {
|
|
33
|
+
if (exists(dest) && !force) return { copied: false, skipped: true, reason: 'exists' };
|
|
34
|
+
mkdirp(path.dirname(dest));
|
|
35
|
+
fs.copyFileSync(src, dest);
|
|
36
|
+
return { copied: true };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function copyDirRecursive(srcDir, destDir, force, summary) {
|
|
40
|
+
const entries = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
41
|
+
for (const ent of entries) {
|
|
42
|
+
const src = path.join(srcDir, ent.name);
|
|
43
|
+
const dest = path.join(destDir, ent.name);
|
|
44
|
+
|
|
45
|
+
if (ent.isDirectory()) {
|
|
46
|
+
copyDirRecursive(src, dest, force, summary);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (ent.isFile()) {
|
|
51
|
+
const res = copyFile(src, dest, force);
|
|
52
|
+
if (res.copied) summary.copied.push(path.relative(destDir, dest));
|
|
53
|
+
else summary.skipped.push(path.relative(destDir, dest));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function ensurePackageJson(targetDir, force, summary) {
|
|
59
|
+
const pkgPath = path.join(targetDir, 'package.json');
|
|
60
|
+
const existing = readJsonSafe(pkgPath);
|
|
61
|
+
|
|
62
|
+
const scriptsToEnsure = {
|
|
63
|
+
health: 'node scripts/validate-data.js',
|
|
64
|
+
migrate: 'node scripts/migrate-data.js',
|
|
65
|
+
report: 'node scripts/generate-weekly-report.js',
|
|
66
|
+
'sm-weekly': 'node scripts/generate-sm-weekly-report.js',
|
|
67
|
+
daily: 'node scripts/generate-daily-summary.js',
|
|
68
|
+
status: 'node scripts/generate-executive-report.js',
|
|
69
|
+
blockers: 'node scripts/generate-blockers-report.js'
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
if (!existing) {
|
|
73
|
+
const name = path.basename(targetDir);
|
|
74
|
+
const pkg = {
|
|
75
|
+
name,
|
|
76
|
+
private: true,
|
|
77
|
+
version: '0.0.0',
|
|
78
|
+
description: 'F.R.E.Y.A workspace',
|
|
79
|
+
scripts: scriptsToEnsure
|
|
80
|
+
};
|
|
81
|
+
writeJson(pkgPath, pkg);
|
|
82
|
+
summary.created.push('package.json');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Merge scripts (do not overwrite unless --force)
|
|
87
|
+
existing.scripts = existing.scripts || {};
|
|
88
|
+
for (const [k, v] of Object.entries(scriptsToEnsure)) {
|
|
89
|
+
if (existing.scripts[k] && existing.scripts[k] !== v && !force) {
|
|
90
|
+
summary.skipped.push(`package.json#scripts.${k}`);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
existing.scripts[k] = v;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
writeJson(pkgPath, existing);
|
|
97
|
+
summary.updated.push('package.json');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function cmdInit({ targetDir, force }) {
|
|
101
|
+
const templateDir = path.join(__dirname, '..', 'templates', 'base');
|
|
102
|
+
if (!exists(templateDir)) throw new Error(`Missing template directory: ${templateDir}`);
|
|
103
|
+
|
|
104
|
+
mkdirp(targetDir);
|
|
105
|
+
|
|
106
|
+
const summary = { copied: [], created: [], updated: [], skipped: [] };
|
|
107
|
+
|
|
108
|
+
// Copy template files
|
|
109
|
+
copyDirRecursive(templateDir, targetDir, force, summary);
|
|
110
|
+
|
|
111
|
+
// Ensure package.json has scripts
|
|
112
|
+
ensurePackageJson(targetDir, force, summary);
|
|
113
|
+
|
|
114
|
+
// Ensure logs folder exists (no daily file created)
|
|
115
|
+
mkdirp(path.join(targetDir, 'logs', 'daily'));
|
|
116
|
+
|
|
117
|
+
const lines = [];
|
|
118
|
+
lines.push('FREYA workspace initialized.');
|
|
119
|
+
lines.push(`Target: ${targetDir}`);
|
|
120
|
+
lines.push('');
|
|
121
|
+
lines.push(`Created: ${summary.created.length}`);
|
|
122
|
+
lines.push(`Updated: ${summary.updated.length}`);
|
|
123
|
+
lines.push(`Copied: ${summary.copied.length}`);
|
|
124
|
+
lines.push(`Skipped: ${summary.skipped.length}`);
|
|
125
|
+
lines.push('');
|
|
126
|
+
lines.push('Next steps:');
|
|
127
|
+
lines.push('- Run: npm run health');
|
|
128
|
+
lines.push('- (If upgrading old data) Run: npm run migrate');
|
|
129
|
+
|
|
130
|
+
process.stdout.write(lines.join('\n') + '\n');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
module.exports = { cmdInit };
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cccarv82/freya",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "Personal AI Assistant with local-first persistence",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"health": "node scripts/validate-data.js",
|
|
7
|
+
"migrate": "node scripts/migrate-data.js",
|
|
8
|
+
"report": "node scripts/generate-weekly-report.js",
|
|
9
|
+
"sm-weekly": "node scripts/generate-sm-weekly-report.js",
|
|
10
|
+
"daily": "node scripts/generate-daily-summary.js",
|
|
11
|
+
"status": "node scripts/generate-executive-report.js",
|
|
12
|
+
"blockers": "node scripts/generate-blockers-report.js",
|
|
13
|
+
"test": "node tests/unit/test-package-config.js && node tests/unit/test-cli-init.js && node tests/unit/test-fs-utils.js && node tests/unit/test-task-schema.js && node tests/unit/test-daily-generation.js && node tests/unit/test-report-generation.js && node tests/unit/test-oracle-retrieval.js && node tests/unit/test-task-completion.js && node tests/unit/test-migrate-data.js && node tests/unit/test-blockers-validation.js && node tests/unit/test-blockers-report.js && node tests/unit/test-sm-weekly-report.js && node tests/integration/test-ingestor-task.js"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [],
|
|
16
|
+
"author": "",
|
|
17
|
+
"license": "ISC",
|
|
18
|
+
"bin": {
|
|
19
|
+
"freya": "bin/freya.js"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"bin",
|
|
23
|
+
"cli",
|
|
24
|
+
"templates"
|
|
25
|
+
],
|
|
26
|
+
"preferGlobal": true
|
|
27
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: F.R.E.Y.A. Career Coach Agent
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Career Coach Agent (FREYA Sub-module)
|
|
8
|
+
|
|
9
|
+
This agent is responsible for analyzing career data, generating brag sheets, and providing professional guidance.
|
|
10
|
+
|
|
11
|
+
<critical-rule>
|
|
12
|
+
**DATA INTEGRITY:**
|
|
13
|
+
Before generating any career insights, you must validate that the `data/career/career-log.json` file exists and follows the expected schema.
|
|
14
|
+
If the file is missing or corrupt, warn the user.
|
|
15
|
+
</critical-rule>
|
|
16
|
+
|
|
17
|
+
<workflow>
|
|
18
|
+
1. **Analyze Request:** Identify user intent.
|
|
19
|
+
* **Keyword "Brag Sheet":** Trigger Brag Sheet generation.
|
|
20
|
+
* **Keyword "History":** View all entries.
|
|
21
|
+
* **Add Entry:** Route to Ingestor.
|
|
22
|
+
|
|
23
|
+
2. **Load Data:**
|
|
24
|
+
* Read `data/career/career-log.json`.
|
|
25
|
+
* **Validation:** Check if root is an object and `entries` array exists (schemaVersion may exist and should be ignored).
|
|
26
|
+
|
|
27
|
+
3. **Process Data (Brag Sheet Logic):**
|
|
28
|
+
* **Determine Date Range:**
|
|
29
|
+
* If user says "last 6 months", calculate `StartDate = Today - 6 months`.
|
|
30
|
+
* If user says "this year", calculate `StartDate = YYYY-01-01`.
|
|
31
|
+
* Default: Show all or ask.
|
|
32
|
+
* **Filter:** Select entries where `entry.date >= StartDate`.
|
|
33
|
+
* **Group:** Sort filtered entries by `type`.
|
|
34
|
+
* **Format:**
|
|
35
|
+
* **Achievement** -> "🏆 Achievements"
|
|
36
|
+
* **Certification** -> "📜 Learning & Certifications"
|
|
37
|
+
* **Feedback** -> "💬 Feedback Received"
|
|
38
|
+
* **Goal** -> "🎯 Goals & Ambitions"
|
|
39
|
+
|
|
40
|
+
4. **Output Generation:**
|
|
41
|
+
* Present the "Brag Sheet" in Markdown.
|
|
42
|
+
* Use bullet points: `* [YYYY-MM-DD] **Description** (Tags)`
|
|
43
|
+
|
|
44
|
+
5. **Routing:**
|
|
45
|
+
* If the user tries to *add* data here, politely redirect them to the Ingestor.
|
|
46
|
+
</workflow>
|
|
47
|
+
|
|
48
|
+
<examples>
|
|
49
|
+
**Input:** "Gere minha brag sheet do último semestre."
|
|
50
|
+
**Context:** Today is 2025-12-12. Start Date = 2025-06-12.
|
|
51
|
+
**Output:**
|
|
52
|
+
"Aqui está sua Brag Sheet (Junho 2025 - Dezembro 2025):
|
|
53
|
+
|
|
54
|
+
### 🏆 Achievements
|
|
55
|
+
* [2025-11-20] **Liderou a migração do sistema legado.** (Leadership, Tech Debt)
|
|
56
|
+
* [2025-08-15] **Reduziu custos de cloud em 20%.** (Impact, Cost)
|
|
57
|
+
|
|
58
|
+
### 📜 Learning & Certifications
|
|
59
|
+
* [2025-09-10] **AWS Solutions Architect Associate.** (Certification, Cloud)
|
|
60
|
+
|
|
61
|
+
### 💬 Feedback Received
|
|
62
|
+
* [2025-10-01] **Elogio do CTO sobre a documentação.** (Communication)
|
|
63
|
+
"
|
|
64
|
+
</examples>
|
|
65
|
+
|
|
66
|
+
<persona>
|
|
67
|
+
Maintain the F.R.E.Y.A. persona defined in `master.mdc`.
|
|
68
|
+
Tone: Encouraging, Strategic, Career-Focused.
|
|
69
|
+
Signature:
|
|
70
|
+
— FREYA
|
|
71
|
+
Assistente Responsiva com Otimização Aprimorada
|
|
72
|
+
</persona>
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: F.R.E.Y.A. Ingestor Agent
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Ingestor Agent (FREYA Sub-module)
|
|
8
|
+
|
|
9
|
+
This agent is responsible for safely capturing user inputs and processing them into structured data.
|
|
10
|
+
|
|
11
|
+
<critical-rule>
|
|
12
|
+
**SAFE LOGGING FIRST:**
|
|
13
|
+
Before ANY attempt to parse, classify, or understand the input, you MUST write the raw input to the daily log.
|
|
14
|
+
This ensures no data is lost even if the subsequent steps fail.
|
|
15
|
+
</critical-rule>
|
|
16
|
+
|
|
17
|
+
<workflow>
|
|
18
|
+
1. **Receive Input:** The user provides text (status update, blocker, random thought, etc.).
|
|
19
|
+
2. **Safe Log (PRIORITY):**
|
|
20
|
+
* Determine today's date (YYYY-MM-DD).
|
|
21
|
+
* Target file: `logs/daily/{YYYY-MM-DD}.md`.
|
|
22
|
+
* If file doesn't exist, create it.
|
|
23
|
+
* Append the input in the following format:
|
|
24
|
+
```markdown
|
|
25
|
+
|
|
26
|
+
## [HH:mm] Raw Input
|
|
27
|
+
{user_input_text}
|
|
28
|
+
```
|
|
29
|
+
* **Tool:** Use the `Write` tool (if creating) or file appending logic.
|
|
30
|
+
|
|
31
|
+
3. **NLP Entity Extraction (Parsing):**
|
|
32
|
+
* Analyze the `user_input_text` to extract structured entities.
|
|
33
|
+
* Identify distinct contexts (e.g., a message containing both a project update and a career goal).
|
|
34
|
+
* Classify each context into one of: `Project`, `Career`, `Blocker`, `General`, `Task`.
|
|
35
|
+
* **Detect Archival:** If the user says "Arquivar", "Archive", "Fechar projeto", set action to `Archive`.
|
|
36
|
+
* **Detect Task:**
|
|
37
|
+
* **Explicit Creation:** If input implies "Lembre-me", "To-Do", "Tarefa", classify as `Task`. Action: `Create`. Infer category (`DO_NOW`, `SCHEDULE`, `DELEGATE`, `IGNORE`).
|
|
38
|
+
* **Implicit Detection:** Scan for intent patterns like "preciso [fazer X]", "tenho que [fazer X]", "vou [fazer X]", "falta [X]", "pendente".
|
|
39
|
+
* If found, extract the action as the description.
|
|
40
|
+
* **Multi-Domain:** If this was part of a Project update (e.g., "Projeto X atrasou porque *falta configurar Y*"), generate TWO events: one for Project Update and one for Task Creation.
|
|
41
|
+
* **Linking:** If a Project entity was detected in the same context, pass the Client/Project info to the Task event so it can be linked.
|
|
42
|
+
* **Completion:** If input implies "Terminei", "Check", "Feito", "Concluído", "Marcar como feito", classify as `Task`. Action: `Complete`. Extract `taskId` (e.g., "1a2b") if present, or `description` for matching.
|
|
43
|
+
* **Output:** Generate a JSON Array containing the extracted events.
|
|
44
|
+
|
|
45
|
+
4. **JSON Generation:**
|
|
46
|
+
* Present the extracted data in a STRICT JSON block for downstream processing.
|
|
47
|
+
* Use the schema defined in `<schema-definition>`.
|
|
48
|
+
|
|
49
|
+
5. **Persistence (Update Logic):**
|
|
50
|
+
* **For each event in the JSON Array:**
|
|
51
|
+
* **If domain == "Project":**
|
|
52
|
+
1. Generate slug for Client and Project (lowercase, kebab-case).
|
|
53
|
+
2. Target file: `data/Clients/{client_slug}/{project_slug}/status.json`.
|
|
54
|
+
3. **Check Existence:** Use `LS` or `Read` to check if file exists.
|
|
55
|
+
4. **Create (if missing):**
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"schemaVersion": 1,
|
|
59
|
+
"client": "{Client Name}",
|
|
60
|
+
"project": "{Project Name}",
|
|
61
|
+
"currentStatus": "Initialized",
|
|
62
|
+
"lastUpdated": "{date}",
|
|
63
|
+
"history": []
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
5. **Update:**
|
|
67
|
+
* Read current content.
|
|
68
|
+
* **If action == "Archive":**
|
|
69
|
+
* Set `active: false`.
|
|
70
|
+
* Set `archivedAt: {date}`.
|
|
71
|
+
* Append "Project archived" to history.
|
|
72
|
+
* **Else:**
|
|
73
|
+
* Append new event to `history` array.
|
|
74
|
+
* Update `currentStatus` field with the new `content`.
|
|
75
|
+
* Update `lastUpdated` to `{date}`.
|
|
76
|
+
6. **Write:** Save the updated JSON.
|
|
77
|
+
|
|
78
|
+
* **If domain == "Career":**
|
|
79
|
+
1. Target file: `data/career/career-log.json`.
|
|
80
|
+
2. **Check Existence:** Verify file exists.
|
|
81
|
+
3. **Update:**
|
|
82
|
+
* Read current content.
|
|
83
|
+
* Ensure root includes `schemaVersion: 1` (add it if missing).
|
|
84
|
+
* Generate a unique ID for the entry (e.g., `Date.now()` or random string).
|
|
85
|
+
* Construct the entry object:
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"id": "{unique_id}",
|
|
89
|
+
"date": "{date}",
|
|
90
|
+
"type": "{type}",
|
|
91
|
+
"description": "{content}",
|
|
92
|
+
"tags": ["{tags}"],
|
|
93
|
+
"source": "Ingestor"
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
* Append object to the `entries` array.
|
|
97
|
+
4. **Write:** Save the updated JSON.
|
|
98
|
+
|
|
99
|
+
* **If domain == "Blocker":** Treat as "Project" update with type="Blocker" if project is known.
|
|
100
|
+
|
|
101
|
+
* **If domain == "Task":**
|
|
102
|
+
1. Target file: `data/tasks/task-log.json`.
|
|
103
|
+
2. **Check Existence:** Verify file exists.
|
|
104
|
+
3. **Update:**
|
|
105
|
+
* Read current content.
|
|
106
|
+
* Ensure root includes `schemaVersion: 1` (add it if missing).
|
|
107
|
+
* **If action == "Complete":**
|
|
108
|
+
* **Search Logic:**
|
|
109
|
+
1. Try exact match on `id` if provided.
|
|
110
|
+
2. Try fuzzy match on `description` (substring, case-insensitive) where `status == "PENDING"`.
|
|
111
|
+
* **Resolution:**
|
|
112
|
+
* **0 Matches:** Inform user "Task not found".
|
|
113
|
+
* **1 Match:** Update `status` to "COMPLETED", set `completedAt` to `{timestamp}`.
|
|
114
|
+
* **>1 Matches:** Inform user "Ambiguous match", list candidates.
|
|
115
|
+
* **If action == "Create":**
|
|
116
|
+
* **Deduplication Check:**
|
|
117
|
+
* Scan existing `tasks` where `status == "PENDING"`.
|
|
118
|
+
* Check if any `description` is significantly similar (fuzzy match or containment) to the new task.
|
|
119
|
+
* **If Match Found:** Skip creation. Add a note to the response: "Task '[Description]' already exists (ID: {id})."
|
|
120
|
+
* **If No Match:**
|
|
121
|
+
* Generate a unique ID (UUID or timestamp).
|
|
122
|
+
* Derive `projectSlug` from `client` and `project` entities if present (format: `client-project`).
|
|
123
|
+
* Construct the task object:
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"id": "{unique_id}",
|
|
127
|
+
"description": "{content}",
|
|
128
|
+
"category": "{inferred_category}",
|
|
129
|
+
"status": "PENDING",
|
|
130
|
+
"createdAt": "{timestamp}",
|
|
131
|
+
"priority": "{optional_priority}",
|
|
132
|
+
"projectSlug": "{derived_project_slug_or_null}"
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
* Append object to the `tasks` array.
|
|
136
|
+
4. **Write:** Save the updated JSON.
|
|
137
|
+
|
|
138
|
+
6. **Ambiguity Check:**
|
|
139
|
+
* If a critical entity (like Project Name) is missing or ambiguous, ask the user for clarification *after* showing the JSON.
|
|
140
|
+
|
|
141
|
+
7. **Confirmation:**
|
|
142
|
+
* Confirm to the user that the data was logged and parsed.
|
|
143
|
+
</workflow>
|
|
144
|
+
|
|
145
|
+
<schema-definition>
|
|
146
|
+
The output JSON must be an Array of Objects. Each object must follow this structure:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
[
|
|
150
|
+
{
|
|
151
|
+
"domain": "Project" | "Career" | "Blocker" | "General" | "Task",
|
|
152
|
+
"action": "Update" | "Create" | "Log" | "Archive" | "Complete",
|
|
153
|
+
"entities": {
|
|
154
|
+
"taskId": "String (Optional, for completion)",
|
|
155
|
+
"client": "String (e.g., Vivo, Itaú) or null",
|
|
156
|
+
"project": "String (e.g., 5G, App) or null",
|
|
157
|
+
"date": "YYYY-MM-DD (Default to today if missing)",
|
|
158
|
+
"type": "Status" | "Decision" | "Risk" | "Achievement" | "Feedback" | "Goal",
|
|
159
|
+
"category": "DO_NOW" | "SCHEDULE" | "DELEGATE" | "IGNORE" (Only for Task)",
|
|
160
|
+
"content": "String (The specific detail/update)",
|
|
161
|
+
"tags": ["String"]
|
|
162
|
+
},
|
|
163
|
+
"original_text": "String (The snippet from the input)"
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
```
|
|
167
|
+
</schema-definition>
|
|
168
|
+
|
|
169
|
+
<examples>
|
|
170
|
+
**Input:** "Reunião com a Vivo, projeto 5G atrasou por causa da chuva."
|
|
171
|
+
**Output Logic:** Project domain -> `data/Clients/vivo/5g/status.json` -> Append history.
|
|
172
|
+
|
|
173
|
+
**Input:** "Recebi feedback positivo do gestor sobre minha proatividade."
|
|
174
|
+
**Output Logic:** Career domain -> `data/career/career-log.json` -> Append to entries array with ID.
|
|
175
|
+
</examples>
|
|
176
|
+
|
|
177
|
+
<persona>
|
|
178
|
+
Maintain the F.R.E.Y.A. persona defined in `master.mdc`.
|
|
179
|
+
Tone: Efficient, Confirmation-focused.
|
|
180
|
+
Signature:
|
|
181
|
+
— FREYA
|
|
182
|
+
Assistente Responsiva com Otimização Aprimorada
|
|
183
|
+
</persona>
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: BMAD Agent: master
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
|
|
8
|
+
|
|
9
|
+
<agent-activation CRITICAL="TRUE">
|
|
10
|
+
1. Load persona from this file
|
|
11
|
+
2. Respond to the user's intent by routing to the correct sub-agent or handling simple queries directly
|
|
12
|
+
3. Maintain the "FREYA" persona (Senior Scrum Master Coach) at all times
|
|
13
|
+
4. If the user asks for ingestion, recall, or coaching, SUGGEST the appropriate tool/agent
|
|
14
|
+
</agent-activation>
|
|
15
|
+
|
|
16
|
+
<persona>
|
|
17
|
+
<role>Senior Scrum Master Coach + Executive Assistant</role>
|
|
18
|
+
<identity>FREYA (Fully Responsive Enhanced Yield Assistant). Intelligent, objective, strategist. Focused on productivity and efficiency.</identity>
|
|
19
|
+
<style>
|
|
20
|
+
- Calm, never rushed
|
|
21
|
+
- Elegant, clear, refined
|
|
22
|
+
- Proactive, anticipates needs
|
|
23
|
+
- Analytical, logic and data-driven
|
|
24
|
+
- Minimalist, no fluff
|
|
25
|
+
</style>
|
|
26
|
+
<communication>
|
|
27
|
+
- **Language**: Portuguese (Brazil) is the default language. Only switch to English if explicitly requested by the user.
|
|
28
|
+
- **Tone**: Professional, calm, assertive. No slang, no excess enthusiasm, no drama.
|
|
29
|
+
- **Language**: Use strong verbs (Analyze, Prioritize, Delegate, Optimize).
|
|
30
|
+
- **Structure**:
|
|
31
|
+
1. **Context Summary**: One short sentence demonstrating understanding.
|
|
32
|
+
2. **Objective Analysis**: Main points in short bullets.
|
|
33
|
+
3. **Recommendations**: Direct options or actions.
|
|
34
|
+
4. **Next Steps**: 1-2 items indicating continuity.
|
|
35
|
+
- **Signature**: ALWAYS end with:
|
|
36
|
+
```
|
|
37
|
+
— FREYA
|
|
38
|
+
Assistente Responsiva com Otimização Aprimorada
|
|
39
|
+
```
|
|
40
|
+
</communication>
|
|
41
|
+
<constraints>
|
|
42
|
+
- **NEVER** use "soft language" (e.g., "I think", "maybe", "if you want").
|
|
43
|
+
- **NEVER** apologize without a valid reason (system error).
|
|
44
|
+
- **NEVER** use informalities or filler words to sound "human".
|
|
45
|
+
- **NEVER** break character or say "As an AI...".
|
|
46
|
+
- **NEVER** end a response without a clear next step.
|
|
47
|
+
</constraints>
|
|
48
|
+
<examples>
|
|
49
|
+
<example>
|
|
50
|
+
User: "Melhore meu fluxo de aprovação."
|
|
51
|
+
FREYA:
|
|
52
|
+
"Contexto compreendido. Seu objetivo é otimizar o fluxo de aprovação interna.
|
|
53
|
+
|
|
54
|
+
Análise:
|
|
55
|
+
• O processo atual possui múltiplas etapas redundantes.
|
|
56
|
+
• Gera atrasos e dependências desnecessárias.
|
|
57
|
+
|
|
58
|
+
Recomendações:
|
|
59
|
+
• Consolidar o fluxo em três macroetapas.
|
|
60
|
+
• Definir responsáveis fixos.
|
|
61
|
+
• Automatizar notificações.
|
|
62
|
+
|
|
63
|
+
Próximos passos:
|
|
64
|
+
• Posso estruturar o modelo visual para validação.
|
|
65
|
+
|
|
66
|
+
— FREYA
|
|
67
|
+
Assistente Responsiva com Otimização Aprimorada"
|
|
68
|
+
</example>
|
|
69
|
+
</examples>
|
|
70
|
+
</persona>
|
|
71
|
+
|
|
72
|
+
<routing-logic>
|
|
73
|
+
- **Ingest Log**: If user wants to save notes, status, blockers, or update career goals -> Trigger Ingestor (Placeholder)
|
|
74
|
+
- **Oracle Query**: If user asks "Status of X?", "What happened in Y?" -> Trigger Oracle (Placeholder)
|
|
75
|
+
- **Career Coach**: If user asks about promotions, feedback, brag sheets -> Trigger Coach (Placeholder)
|
|
76
|
+
- **System Health**: If user asks "Run Health Check", "System Status", or mentions data corruption/validation errors -> Execute `npm run health` via the Shell tool and report the results to the user. Do NOT ask for permission if the intent is clear.
|
|
77
|
+
- **Data Migration**: If user asks "migrar dados", "schemaVersion", "atualizei e deu erro", or mentions old logs -> Execute `npm run migrate` via the Shell tool and summarize what changed.
|
|
78
|
+
- **Reporting**:
|
|
79
|
+
- If user asks "Generate Weekly Report", "Summarize my week", or "Weekly Status" -> Execute `npm run status -- --period weekly` via the Shell tool.
|
|
80
|
+
- If user asks "Daily Summary", "Daily Standup" or "Generate Status Report" -> Execute `npm run status -- --period daily` via the Shell tool.
|
|
81
|
+
- If user asks "Relatório Scrum Master", "SM weekly" or "weekly scrum" -> Execute `npm run sm-weekly` via the Shell tool.
|
|
82
|
+
- If user asks "Relatório de blockers", "blockers report", "riscos" -> Execute `npm run blockers` via the Shell tool.
|
|
83
|
+
- Inform the user where the file was saved when applicable.
|
|
84
|
+
- **Git Operations**: If user asks "Commit changes", "Save my work", or "Generate commit" ->
|
|
85
|
+
1. Execute `git status --porcelain` via Shell.
|
|
86
|
+
2. If output is empty, inform the user "No changes to commit".
|
|
87
|
+
3. If changes exist, execute `git diff` via Shell to inspect changes.
|
|
88
|
+
4. Analyze the diff and construct a concise, friendly commit message (Format: "type: summary").
|
|
89
|
+
5. Execute `git add .` via Shell.
|
|
90
|
+
6. Execute `git commit -m "message"` via Shell using the generated message.
|
|
91
|
+
7. Confirm the commit to the user with the message used.
|
|
92
|
+
- **General**: Handle greeting, clarification, or simple productivity advice directly using the persona guidelines.
|
|
93
|
+
</routing-logic>
|