@cccarv82/freya 1.0.3 → 1.0.4

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 CHANGED
@@ -58,6 +58,23 @@ freya init meu-projeto # cria ./meu-projeto
58
58
  freya init --here # instala no diretório atual
59
59
  ```
60
60
 
61
+ ### Atualizar uma workspace existente (sem perder dados)
62
+ Por padrão, ao rodar `init` em uma pasta existente, o CLI **preserva**:
63
+ - `data/**`
64
+ - `logs/**`
65
+
66
+ E atualiza/instala normalmente:
67
+ - `.agent/**`
68
+ - `scripts/**`
69
+ - `README.md`, `USER_GUIDE.md`
70
+ - `package.json` (merge de scripts)
71
+
72
+ Flags (use com cuidado):
73
+ ```bash
74
+ freya init --here --force-data # permite sobrescrever data/
75
+ freya init --here --force-logs # permite sobrescrever logs/
76
+ ```
77
+
61
78
  ## 🚀 Como Usar
62
79
 
63
80
  1. Abra a pasta da workspace gerada (ex.: `./freya`) na **sua IDE**.
package/cli/index.js CHANGED
@@ -9,15 +9,18 @@ function usage() {
9
9
  freya - F.R.E.Y.A. CLI
10
10
 
11
11
  Usage:
12
- freya init [dir] [--force] [--here|--in-place]
12
+ freya init [dir] [--force] [--here|--in-place] [--force-data] [--force-logs]
13
13
 
14
14
  Defaults:
15
15
  - If no [dir] is provided, creates ./freya
16
+ - Preserves existing data/ and logs/ by default
16
17
 
17
18
  Examples:
18
19
  freya init # creates ./freya
19
20
  freya init my-workspace # creates ./my-workspace
20
21
  freya init --here # installs into current directory
22
+ freya init --here --force # update agents/scripts, keep data/logs
23
+ freya init --here --force-data # overwrite data/ too (danger)
21
24
  npx @cccarv82/freya init
22
25
  `;
23
26
  }
@@ -49,8 +52,12 @@ async function run(argv) {
49
52
  const targetDir = args[1]
50
53
  ? path.resolve(process.cwd(), args[1])
51
54
  : (inPlace ? process.cwd() : defaultDir);
55
+
52
56
  const force = flags.has('--force');
53
- await cmdInit({ targetDir, force });
57
+ const forceData = flags.has('--force-data');
58
+ const forceLogs = flags.has('--force-logs');
59
+
60
+ await cmdInit({ targetDir, force, forceData, forceLogs });
54
61
  return;
55
62
  }
56
63
 
package/cli/init.js CHANGED
@@ -36,14 +36,35 @@ function copyFile(src, dest, force) {
36
36
  return { copied: true };
37
37
  }
38
38
 
39
- function copyDirRecursive(srcDir, destDir, force, summary) {
39
+ function isNonEmptyDir(dir) {
40
+ try {
41
+ const entries = fs.readdirSync(dir);
42
+ // ignore common empty markers
43
+ const meaningful = entries.filter((e) => e !== '.DS_Store');
44
+ return meaningful.length > 0;
45
+ } catch {
46
+ return false;
47
+ }
48
+ }
49
+
50
+ function copyDirRecursive(srcDir, destDir, force, summary, options = {}) {
40
51
  const entries = fs.readdirSync(srcDir, { withFileTypes: true });
41
52
  for (const ent of entries) {
42
53
  const src = path.join(srcDir, ent.name);
43
54
  const dest = path.join(destDir, ent.name);
44
55
 
56
+ // Preserve user state by default
45
57
  if (ent.isDirectory()) {
46
- copyDirRecursive(src, dest, force, summary);
58
+ if (ent.name === 'data' && isNonEmptyDir(dest) && !options.forceData) {
59
+ summary.skipped.push('data/**');
60
+ continue;
61
+ }
62
+ if (ent.name === 'logs' && isNonEmptyDir(dest) && !options.forceLogs) {
63
+ summary.skipped.push('logs/**');
64
+ continue;
65
+ }
66
+
67
+ copyDirRecursive(src, dest, force, summary, options);
47
68
  continue;
48
69
  }
49
70
 
@@ -97,7 +118,7 @@ function ensurePackageJson(targetDir, force, summary) {
97
118
  summary.updated.push('package.json');
98
119
  }
99
120
 
100
- async function cmdInit({ targetDir, force }) {
121
+ async function cmdInit({ targetDir, force, forceData = false, forceLogs = false }) {
101
122
  const templateDir = path.join(__dirname, '..', 'templates', 'base');
102
123
  if (!exists(templateDir)) throw new Error(`Missing template directory: ${templateDir}`);
103
124
 
@@ -105,8 +126,8 @@ async function cmdInit({ targetDir, force }) {
105
126
 
106
127
  const summary = { copied: [], created: [], updated: [], skipped: [] };
107
128
 
108
- // Copy template files
109
- copyDirRecursive(templateDir, targetDir, force, summary);
129
+ // Copy template files (preserve data/logs by default)
130
+ copyDirRecursive(templateDir, targetDir, force, summary, { forceData, forceLogs });
110
131
 
111
132
  // Ensure package.json has scripts
112
133
  ensurePackageJson(targetDir, force, summary);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cccarv82/freya",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Personal AI Assistant with local-first persistence",
5
5
  "scripts": {
6
6
  "health": "node scripts/validate-data.js",