sigma-memory 0.2.1 → 0.2.2

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/src/notes.ts CHANGED
@@ -1,163 +1,163 @@
1
- import { readFileSync, writeFileSync, readdirSync, statSync, existsSync, mkdirSync, appendFileSync } from 'fs';
2
- import { join, resolve } from 'path';
3
- import { execSync } from 'child_process';
4
- import type { MemoryConfig, Note } from './types.js';
1
+ import { execSync } from "child_process";
2
+ import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "fs";
3
+ import { join, resolve } from "path";
4
+ import type { MemoryConfig, Note } from "./types.js";
5
5
 
6
6
  export class NotesManager {
7
- private config: MemoryConfig;
8
- private notesDir: string;
9
-
10
- constructor(config: MemoryConfig) {
11
- this.config = config;
12
- this.notesDir = join(config.memoryDir, 'notes');
13
- this.ensureDirectories();
14
- }
15
-
16
- private ensureDirectories(): void {
17
- if (!existsSync(this.config.memoryDir)) {
18
- mkdirSync(this.config.memoryDir, { recursive: true });
19
- }
20
- if (!existsSync(this.notesDir)) {
21
- mkdirSync(this.notesDir, { recursive: true });
22
- }
23
- }
24
-
25
- /**
26
- * Écrit dans un fichier .md (date du jour si pas de nom)
27
- */
28
- write(content: string, filename?: string): void {
29
- const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD
30
- const file = filename || `${today}.md`;
31
- const filePath = join(this.notesDir, file);
32
-
33
- writeFileSync(filePath, content, 'utf8');
34
- }
35
-
36
- /**
37
- * Lit un fichier
38
- */
39
- read(filename: string): string {
40
- const filePath = join(this.notesDir, filename);
41
- if (!existsSync(filePath)) {
42
- throw new Error(`File not found: ${filename}`);
43
- }
44
- return readFileSync(filePath, 'utf8');
45
- }
46
-
47
- /**
48
- * Liste tous les fichiers .md avec leur taille et date
49
- */
50
- list(): Array<{ name: string; size: number; date: string }> {
51
- if (!existsSync(this.notesDir)) {
52
- return [];
53
- }
54
-
55
- return readdirSync(this.notesDir)
56
- .filter(file => file.endsWith('.md'))
57
- .map(file => {
58
- const filePath = join(this.notesDir, file);
59
- const stats = statSync(filePath);
60
- return {
61
- name: file,
62
- size: stats.size,
63
- date: stats.mtime.toISOString()
64
- };
65
- })
66
- .sort((a, b) => b.date.localeCompare(a.date));
67
- }
68
-
69
- /**
70
- * Recherche full-text (grep-like) dans tous les .md
71
- */
72
- search(query: string): Array<{ file: string; line: number; content: string }> {
73
- if (!existsSync(this.notesDir)) {
74
- return [];
75
- }
76
-
77
- const results: Array<{ file: string; line: number; content: string }> = [];
78
-
79
- try {
80
- // Utilise grep pour une recherche efficace
81
- const grepResult = execSync(
82
- `grep -n "${query.replace(/"/g, '\\"')}" "${this.notesDir}"/*.md 2>/dev/null || true`,
83
- { encoding: 'utf8' }
84
- );
85
-
86
- if (grepResult.trim()) {
87
- const lines = grepResult.trim().split('\n');
88
- for (const line of lines) {
89
- const match = line.match(/^(.+?):(\d+):(.+)$/);
90
- if (match) {
91
- const [, fullPath, lineNumber, content] = match;
92
- const filename = fullPath.replace(this.notesDir + '/', '');
93
- results.push({
94
- file: filename,
95
- line: parseInt(lineNumber),
96
- content: content.trim()
97
- });
98
- }
99
- }
100
- }
101
- } catch (error) {
102
- // Fallback to JavaScript search if grep fails
103
- const files = readdirSync(this.notesDir).filter(f => f.endsWith('.md'));
104
- for (const file of files) {
105
- const filePath = join(this.notesDir, file);
106
- const content = readFileSync(filePath, 'utf8');
107
- const lines = content.split('\n');
108
-
109
- lines.forEach((line, index) => {
110
- if (line.toLowerCase().includes(query.toLowerCase())) {
111
- results.push({
112
- file,
113
- line: index + 1,
114
- content: line.trim()
115
- });
116
- }
117
- });
118
- }
119
- }
120
-
121
- return results;
122
- }
123
-
124
- /**
125
- * Retourne les notes des N derniers jours
126
- */
127
- getRecent(days: number): Note[] {
128
- const cutoffDate = new Date();
129
- cutoffDate.setDate(cutoffDate.getDate() - days);
130
-
131
- const files = this.list().filter(file => {
132
- const fileDate = new Date(file.date);
133
- return fileDate >= cutoffDate;
134
- });
135
-
136
- return files.map(file => {
137
- const content = this.read(file.name);
138
- return {
139
- file: file.name,
140
- date: file.date,
141
- content
142
- };
143
- });
144
- }
145
-
146
- /**
147
- * Ajoute à un fichier existant
148
- */
149
- append(content: string, filename?: string): void {
150
- const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD
151
- const file = filename || `${today}.md`;
152
- const filePath = join(this.notesDir, file);
153
-
154
- // Add blank line if file exists and doesn't end with one
155
- if (existsSync(filePath)) {
156
- const existingContent = readFileSync(filePath, 'utf8');
157
- const separator = existingContent.endsWith('\n') ? '' : '\n';
158
- appendFileSync(filePath, separator + content, 'utf8');
159
- } else {
160
- writeFileSync(filePath, content, 'utf8');
161
- }
162
- }
163
- }
7
+ private config: MemoryConfig;
8
+ private notesDir: string;
9
+
10
+ constructor(config: MemoryConfig) {
11
+ this.config = config;
12
+ this.notesDir = join(config.memoryDir, "notes");
13
+ this.ensureDirectories();
14
+ }
15
+
16
+ private ensureDirectories(): void {
17
+ if (!existsSync(this.config.memoryDir)) {
18
+ mkdirSync(this.config.memoryDir, { recursive: true });
19
+ }
20
+ if (!existsSync(this.notesDir)) {
21
+ mkdirSync(this.notesDir, { recursive: true });
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Écrit dans un fichier .md (date du jour si pas de nom)
27
+ */
28
+ write(content: string, filename?: string): void {
29
+ const today = new Date().toISOString().split("T")[0]; // YYYY-MM-DD
30
+ const file = filename || `${today}.md`;
31
+ const filePath = join(this.notesDir, file);
32
+
33
+ writeFileSync(filePath, content, "utf8");
34
+ }
35
+
36
+ /**
37
+ * Lit un fichier
38
+ */
39
+ read(filename: string): string {
40
+ const filePath = join(this.notesDir, filename);
41
+ if (!existsSync(filePath)) {
42
+ throw new Error(`File not found: ${filename}`);
43
+ }
44
+ return readFileSync(filePath, "utf8");
45
+ }
46
+
47
+ /**
48
+ * Liste tous les fichiers .md avec leur taille et date
49
+ */
50
+ list(): Array<{ name: string; size: number; date: string }> {
51
+ if (!existsSync(this.notesDir)) {
52
+ return [];
53
+ }
54
+
55
+ return readdirSync(this.notesDir)
56
+ .filter((file) => file.endsWith(".md"))
57
+ .map((file) => {
58
+ const filePath = join(this.notesDir, file);
59
+ const stats = statSync(filePath);
60
+ return {
61
+ name: file,
62
+ size: stats.size,
63
+ date: stats.mtime.toISOString(),
64
+ };
65
+ })
66
+ .sort((a, b) => b.date.localeCompare(a.date));
67
+ }
68
+
69
+ /**
70
+ * Recherche full-text (grep-like) dans tous les .md
71
+ */
72
+ search(query: string): Array<{ file: string; line: number; content: string }> {
73
+ if (!existsSync(this.notesDir)) {
74
+ return [];
75
+ }
76
+
77
+ const results: Array<{ file: string; line: number; content: string }> = [];
78
+
79
+ try {
80
+ // Utilise grep pour une recherche efficace
81
+ const grepResult = execSync(
82
+ `grep -n "${query.replace(/"/g, '\\"')}" "${this.notesDir}"/*.md 2>/dev/null || true`,
83
+ { encoding: "utf8" },
84
+ );
85
+
86
+ if (grepResult.trim()) {
87
+ const lines = grepResult.trim().split("\n");
88
+ for (const line of lines) {
89
+ const match = line.match(/^(.+?):(\d+):(.+)$/);
90
+ if (match) {
91
+ const [, fullPath, lineNumber, content] = match;
92
+ const filename = fullPath.replace(this.notesDir + "/", "");
93
+ results.push({
94
+ file: filename,
95
+ line: parseInt(lineNumber),
96
+ content: content.trim(),
97
+ });
98
+ }
99
+ }
100
+ }
101
+ } catch (error) {
102
+ // Fallback to JavaScript search if grep fails
103
+ const files = readdirSync(this.notesDir).filter((f) => f.endsWith(".md"));
104
+ for (const file of files) {
105
+ const filePath = join(this.notesDir, file);
106
+ const content = readFileSync(filePath, "utf8");
107
+ const lines = content.split("\n");
108
+
109
+ lines.forEach((line, index) => {
110
+ if (line.toLowerCase().includes(query.toLowerCase())) {
111
+ results.push({
112
+ file,
113
+ line: index + 1,
114
+ content: line.trim(),
115
+ });
116
+ }
117
+ });
118
+ }
119
+ }
120
+
121
+ return results;
122
+ }
123
+
124
+ /**
125
+ * Retourne les notes des N derniers jours
126
+ */
127
+ getRecent(days: number): Note[] {
128
+ const cutoffDate = new Date();
129
+ cutoffDate.setDate(cutoffDate.getDate() - days);
130
+
131
+ const files = this.list().filter((file) => {
132
+ const fileDate = new Date(file.date);
133
+ return fileDate >= cutoffDate;
134
+ });
135
+
136
+ return files.map((file) => {
137
+ const content = this.read(file.name);
138
+ return {
139
+ file: file.name,
140
+ date: file.date,
141
+ content,
142
+ };
143
+ });
144
+ }
145
+
146
+ /**
147
+ * Ajoute à un fichier existant
148
+ */
149
+ append(content: string, filename?: string): void {
150
+ const today = new Date().toISOString().split("T")[0]; // YYYY-MM-DD
151
+ const file = filename || `${today}.md`;
152
+ const filePath = join(this.notesDir, file);
153
+
154
+ // Add blank line if file exists and doesn't end with one
155
+ if (existsSync(filePath)) {
156
+ const existingContent = readFileSync(filePath, "utf8");
157
+ const separator = existingContent.endsWith("\n") ? "" : "\n";
158
+ appendFileSync(filePath, separator + content, "utf8");
159
+ } else {
160
+ writeFileSync(filePath, content, "utf8");
161
+ }
162
+ }
163
+ }