amalfa 1.0.19 → 1.0.23

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.
@@ -1,258 +0,0 @@
1
- import { exec } from "node:child_process";
2
- import { promisify } from "node:util";
3
-
4
- const execAsync = promisify(exec);
5
-
6
- export interface ZombieReport {
7
- ghosts: string[];
8
- duplicates: string[];
9
- unknowns: string[];
10
- clean: boolean;
11
- }
12
-
13
- // Services intended to run as singletons
14
- const WHITELIST = [
15
- // AMALFA core services
16
- "src/mcp/index.ts",
17
- "src/resonance/services/vector-daemon.ts",
18
- "src/daemon/index.ts",
19
- // Legacy services
20
- "src/resonance/daemon.ts",
21
- "scripts/cli/dev.ts",
22
- "src/resonance/cli/ingest.ts",
23
- "bun run build:data",
24
- "bun run mcp",
25
- "bun run daemon",
26
- "bun run dev",
27
- "bun run watch:css",
28
- "bun run watch:js",
29
- "scripts/verify/test_mcp_query.ts",
30
- "src/services/olmo3.ts",
31
- "src/services/phi.ts",
32
- "src/services/llama.ts",
33
- "src/services/llamauv.ts",
34
- "scripts/cli/servers.ts",
35
- "bun run olmo3",
36
- "bun run phi",
37
- "bun run llama",
38
- "bun run llamauv",
39
- "bun run servers",
40
- ];
41
-
42
- export const ZombieDefense = {
43
- /**
44
- * Scan the environment for unauthorized or stale processes.
45
- */
46
- async scan(excludePids: string[] = []): Promise<ZombieReport> {
47
- const report: ZombieReport = {
48
- ghosts: [],
49
- duplicates: [],
50
- unknowns: [],
51
- clean: true,
52
- };
53
-
54
- const protectedPids = new Set([
55
- process.pid.toString(),
56
- process.ppid.toString(),
57
- ...excludePids,
58
- ]);
59
-
60
- // 1. Ghost Check (Deleted File Handles)
61
- try {
62
- const { stdout } = await execAsync("lsof +L1");
63
- const lines = stdout.split("\n");
64
- // Strict Filter: Only worry about resonance.db or files in our project scope
65
- report.ghosts = lines.filter((l) => {
66
- if (!l.includes("bun")) return false;
67
- // Must be relevant file
68
- return l.includes("resonance.db") || l.includes(process.cwd());
69
- });
70
- } catch (_e) {
71
- // lsof exits 1 if nothing found
72
- }
73
-
74
- // 2. Process Table Check
75
- try {
76
- const { stdout } = await execAsync("ps aux | grep bun | grep -v grep");
77
- const processes = stdout.split("\n").filter((l) => l.trim().length > 0);
78
- const activeMap = new Map<string, number>();
79
-
80
- processes.forEach((p) => {
81
- // Ignore self and parent immediately
82
- const match = p.match(/\s+(\d+)\s+/);
83
- if (match?.[1] && protectedPids.has(match[1])) return;
84
-
85
- // Ignore CLI commands that are just launching services (parent processes)
86
- if (
87
- p.includes("src/cli.ts") ||
88
- p.includes("cli.ts daemon") ||
89
- p.includes("cli.ts vector") ||
90
- p.includes("cli.ts servers")
91
- ) {
92
- return;
93
- }
94
-
95
- // Strict Filter: Must be in our CWD or explicit bun run
96
- if (!p.includes(process.cwd()) && !p.includes("bun run")) return;
97
-
98
- const isWhitelisted = WHITELIST.some((w) => p.includes(w));
99
-
100
- if (isWhitelisted) {
101
- WHITELIST.forEach((w) => {
102
- if (p.includes(w)) {
103
- // HEURISTIC: Don't count "bun run scripts/foo.ts" and "bun scripts/foo.ts" as duplicates of each other if they are the same PID (obviously),
104
- // but here we already filtered by PID.
105
- // We need to be careful about the wrapper vs the actual process.
106
-
107
- const count = (activeMap.get(w) || 0) + 1;
108
- activeMap.set(w, count);
109
- if (count > 1) {
110
- report.duplicates.push(p);
111
- }
112
- }
113
- });
114
- } else {
115
- // Ignore self (if running from a script calling this)
116
- if (
117
- !p.includes("detect_zombies.ts") &&
118
- !p.includes("ZombieDefense")
119
- ) {
120
- report.unknowns.push(p);
121
- }
122
- }
123
- });
124
- } catch (_e) {
125
- // No bun processes
126
- }
127
-
128
- if (
129
- report.ghosts.length > 0 ||
130
- report.duplicates.length > 0 ||
131
- report.unknowns.length > 0
132
- ) {
133
- report.clean = false;
134
- }
135
-
136
- return report;
137
- },
138
-
139
- /**
140
- * Helper: Extract PIDs from report lines
141
- */
142
- extractPids(lines: string[]): string[] {
143
- const pids = new Set<string>();
144
- lines.forEach((line) => {
145
- const match = line.match(/\s+(\d+)\s+/);
146
- if (match?.[1]) {
147
- pids.add(match[1]);
148
- }
149
- });
150
- return Array.from(pids);
151
- },
152
-
153
- /**
154
- * Terminate identified zombie PIDs
155
- */
156
- async killZombies(report: ZombieReport) {
157
- let targets = [
158
- ...new Set([
159
- ...this.extractPids(report.ghosts),
160
- ...this.extractPids(report.duplicates),
161
- ]),
162
- ];
163
-
164
- // SAFETY: Exclude self
165
- const selfPid = process.pid.toString();
166
- targets = targets.filter((pid) => pid !== selfPid);
167
-
168
- if (targets.length === 0) return;
169
-
170
- console.error(
171
- `šŸ”Ŗ Killing ${targets.length} zombie processes: ${targets.join(", ")}`,
172
- );
173
- try {
174
- await execAsync(`kill -9 ${targets.join(" ")}`);
175
- console.error(" āœ… Zombies terminated.");
176
- } catch (err) {
177
- const e = err as Error;
178
- console.error(` āŒ Failed to kill zombies: ${e.message}`);
179
- }
180
- },
181
-
182
- /**
183
- * Enforce a clean state. Exits process if zombies found.
184
- * @param serviceName Name of the service calling this guard
185
- * @param interactive If true, prompts user to kill zombies.
186
- */
187
- async assertClean(serviceName: string, interactive = false) {
188
- if (process.env.SKIP_ZOMBIE_CHECK === "true") {
189
- return;
190
- }
191
- console.error(`šŸ›”ļø [${serviceName}] Running Zombie Defense Protocol...`);
192
- let report = await this.scan();
193
-
194
- if (report.clean) {
195
- console.error(" āœ… Environment Clean.");
196
- return;
197
- }
198
-
199
- console.error("\nšŸ›‘ STARTUP ABORTED: ZOMBIE PROCESSES DETECTED");
200
-
201
- if (report.ghosts.length > 0) {
202
- console.error("\nšŸ‘» GHOSTS (Holding deleted files):");
203
- report.ghosts.forEach((g) => {
204
- console.error(` ${g}`);
205
- });
206
- }
207
-
208
- if (report.duplicates.length > 0) {
209
- console.error("\nšŸ‘Æ DUPLICATES (Service already running?):");
210
- report.duplicates.forEach((d) => {
211
- console.error(` ${d}`);
212
- });
213
- }
214
-
215
- if (report.unknowns.length > 0) {
216
- console.error(
217
- "\nšŸ‘½ UNKNOWNS (Rogue processes - Manual Check Recommended):",
218
- );
219
- report.unknowns.forEach((u) => {
220
- console.error(` ${u}`);
221
- });
222
- }
223
-
224
- if (interactive) {
225
- const targets = this.extractPids([
226
- ...report.ghosts,
227
- ...report.duplicates,
228
- ]);
229
- if (targets.length > 0) {
230
- process.stderr.write(
231
- `\nšŸ‘‡ Found ${targets.length} confirmable zombies. Kill and Proceed? [y/N] `,
232
- );
233
- const answer = await new Promise<string>((resolve) => {
234
- // Simple one-off prompt since Bun used here might not have 'prompt' in all envs
235
- // Using Bun.stdin reader
236
- process.stdin.once("data", (d) => resolve(d.toString().trim()));
237
- });
238
-
239
- if (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes") {
240
- await this.killZombies(report);
241
- // Re-scan to verify
242
- report = await this.scan();
243
- if (report.clean) {
244
- console.error(" āœ… Environment Cleared. Proceeding...");
245
- return;
246
- }
247
- console.error(" āŒ Environment still dirty after kill attempt.");
248
- }
249
- }
250
- } else {
251
- console.error(
252
- "\nšŸ‘‰ ACTION REQUIRED: Run 'pkill -f bun' to clear the environment.",
253
- );
254
- }
255
-
256
- process.exit(1);
257
- },
258
- };
package/tsconfig.json DELETED
@@ -1,46 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- // Environment setup & latest features
4
- "lib": ["ESNext"],
5
- "target": "ESNext",
6
- "module": "Preserve",
7
- "moduleDetection": "force",
8
- "jsx": "react-jsx",
9
- "allowJs": true,
10
-
11
- // Bundler mode
12
- "moduleResolution": "bundler",
13
- "allowImportingTsExtensions": true,
14
- "verbatimModuleSyntax": true,
15
- "noEmit": true,
16
-
17
- // Best practices
18
- "strict": true,
19
- "skipLibCheck": true,
20
- "noFallthroughCasesInSwitch": true,
21
- "noUncheckedIndexedAccess": true,
22
- "noImplicitOverride": true,
23
-
24
- // Some stricter flags (disabled by default)
25
- "noUnusedLocals": false,
26
- "noUnusedParameters": false,
27
- "noPropertyAccessFromIndexSignature": false,
28
- "baseUrl": ".",
29
- "paths": {
30
- "@src/*": ["./src/*"],
31
- "@scripts/*": ["./scripts/*"],
32
- "@resonance/*": ["./src/resonance/*"],
33
- "@/*": ["./*"]
34
- }
35
- },
36
- "exclude": [
37
- "public/docs",
38
- "docs/webdocs",
39
- "node_modules",
40
- "dist",
41
- ".resonance",
42
- "briefs",
43
- "examples",
44
- "experiments"
45
- ]
46
- }