autonomous-flow-daemon 1.6.0 → 1.9.0

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 (61) hide show
  1. package/CHANGELOG.md +85 -85
  2. package/LICENSE +21 -21
  3. package/README-ko.md +282 -0
  4. package/README.md +282 -266
  5. package/mcp-config.json +10 -10
  6. package/package.json +4 -2
  7. package/src/adapters/index.ts +370 -370
  8. package/src/cli.ts +162 -127
  9. package/src/commands/benchmark.ts +187 -187
  10. package/src/commands/correlate.ts +180 -0
  11. package/src/commands/dashboard.ts +404 -0
  12. package/src/commands/evolution.ts +84 -1
  13. package/src/commands/fix.ts +158 -158
  14. package/src/commands/lang.ts +41 -41
  15. package/src/commands/plugin.ts +110 -0
  16. package/src/commands/restart.ts +14 -14
  17. package/src/commands/score.ts +276 -276
  18. package/src/commands/start.ts +155 -155
  19. package/src/commands/status.ts +157 -157
  20. package/src/commands/stop.ts +68 -68
  21. package/src/commands/suggest.ts +211 -0
  22. package/src/commands/sync.ts +329 -16
  23. package/src/constants.ts +32 -32
  24. package/src/core/boast.ts +280 -280
  25. package/src/core/config.ts +49 -49
  26. package/src/core/correlation-engine.ts +265 -0
  27. package/src/core/db.ts +145 -117
  28. package/src/core/discovery.ts +65 -65
  29. package/src/core/federation.ts +129 -0
  30. package/src/core/hologram/engine.ts +71 -71
  31. package/src/core/hologram/fallback.ts +11 -11
  32. package/src/core/hologram/go-extractor.ts +203 -0
  33. package/src/core/hologram/incremental.ts +227 -227
  34. package/src/core/hologram/py-extractor.ts +132 -132
  35. package/src/core/hologram/rust-extractor.ts +244 -0
  36. package/src/core/hologram/ts-extractor.ts +406 -320
  37. package/src/core/hologram/types.ts +27 -25
  38. package/src/core/hologram.ts +73 -71
  39. package/src/core/i18n/messages.ts +309 -309
  40. package/src/core/locale.ts +88 -88
  41. package/src/core/log-rotate.ts +33 -33
  42. package/src/core/log-utils.ts +38 -38
  43. package/src/core/lru-map.ts +61 -61
  44. package/src/core/notify.ts +74 -74
  45. package/src/core/plugin-manager.ts +225 -0
  46. package/src/core/rule-suggestion.ts +127 -0
  47. package/src/core/validator-generator.ts +224 -0
  48. package/src/core/workspace.ts +28 -28
  49. package/src/daemon/client.ts +78 -65
  50. package/src/daemon/event-batcher.ts +108 -108
  51. package/src/daemon/guards.ts +13 -13
  52. package/src/daemon/http-routes.ts +376 -293
  53. package/src/daemon/mcp-handler.ts +575 -270
  54. package/src/daemon/mcp-subscriptions.ts +81 -0
  55. package/src/daemon/mesh.ts +51 -0
  56. package/src/daemon/server.ts +655 -590
  57. package/src/daemon/types.ts +121 -100
  58. package/src/daemon/workspace-map.ts +104 -92
  59. package/src/platform.ts +60 -60
  60. package/src/version.ts +15 -15
  61. package/README.ko.md +0 -266
@@ -1,158 +1,158 @@
1
- import { writeFileSync, mkdirSync, existsSync } from "fs";
2
- import { dirname } from "path";
3
- import { daemonRequest } from "../daemon/client";
4
- import type { Symptom, PatchOp, DiagnosisResult } from "../core/immune";
5
-
6
- const SEVERITY_ICON: Record<string, string> = {
7
- critical: "[!]",
8
- warning: "[~]",
9
- info: "[i]",
10
- };
11
-
12
- function applyPatch(patch: PatchOp): boolean {
13
- // Map JSON-Patch path to filesystem path (strip leading /)
14
- const filePath = patch.path.replace(/^\//, "");
15
-
16
- // Guard: reject path traversal attempts
17
- if (filePath.includes("..") || filePath.startsWith("/") || /^[A-Za-z]:/.test(filePath)) return false;
18
-
19
- if (patch.op === "add") {
20
- if (existsSync(filePath)) return false; // don't overwrite
21
- const dir = dirname(filePath);
22
- if (dir !== ".") mkdirSync(dir, { recursive: true });
23
- writeFileSync(filePath, patch.value ?? "", "utf-8");
24
- return true;
25
- }
26
-
27
- if (patch.op === "replace") {
28
- const dir = dirname(filePath);
29
- if (dir !== ".") mkdirSync(dir, { recursive: true });
30
- writeFileSync(filePath, patch.value ?? "", "utf-8");
31
- return true;
32
- }
33
-
34
- // remove, move, copy, test — not needed yet
35
- return false;
36
- }
37
-
38
- async function learnAntibody(symptom: Symptom): Promise<void> {
39
- await fetch(
40
- `http://127.0.0.1:${(await getDaemonPort())}/antibodies/learn`,
41
- {
42
- method: "POST",
43
- headers: { "Content-Type": "application/json" },
44
- body: JSON.stringify({
45
- id: symptom.id,
46
- patternType: symptom.patternType,
47
- fileTarget: symptom.fileTarget,
48
- patches: symptom.patches,
49
- }),
50
- }
51
- );
52
- }
53
-
54
- async function getDaemonPort(): Promise<number> {
55
- const { readFileSync } = await import("fs");
56
- const { resolveWorkspacePaths } = await import("../constants");
57
- const paths = resolveWorkspacePaths();
58
- return parseInt(readFileSync(paths.portFile, "utf-8").trim(), 10);
59
- }
60
-
61
- export async function fixCommand() {
62
- let diagnosis: DiagnosisResult;
63
- try {
64
- diagnosis = await daemonRequest<DiagnosisResult>("/diagnose");
65
- } catch (err: unknown) {
66
- const msg = err instanceof Error ? err.message : String(err);
67
- console.error(`[afd fix] ${msg}`);
68
- process.exit(1);
69
- }
70
-
71
- if (diagnosis.symptoms.length === 0) {
72
- console.log("[afd fix] No symptoms detected. System is healthy.");
73
- if (diagnosis.healthy.length > 0) {
74
- console.log(`[afd fix] Passed checks: ${diagnosis.healthy.join(", ")}`);
75
- }
76
- return;
77
- }
78
-
79
- // Display symptoms
80
- console.log(`\n[afd fix] Found ${diagnosis.symptoms.length} symptom(s):\n`);
81
-
82
- for (const s of diagnosis.symptoms) {
83
- const icon = SEVERITY_ICON[s.severity] ?? "[?]";
84
- console.log(` ${icon} ${s.id}: ${s.title} (${s.severity})`);
85
- console.log(` ${s.description}`);
86
- if (s.patches.length > 0) {
87
- console.log(` Patch: ${s.patches.map(p => `${p.op} ${p.path}`).join(", ")}`);
88
- }
89
- console.log();
90
- }
91
-
92
- // Extract phase: inject hologram context for AI consumers
93
- const symptomsWithHologram = diagnosis.symptoms as (Symptom & { hologram?: string })[];
94
- const holograms = symptomsWithHologram.filter(s => s.hologram);
95
- if (holograms.length > 0) {
96
- console.log("[afd fix] Hologram Context (Extract phase — token-optimized file structures):\n");
97
- for (const s of holograms) {
98
- console.log(` --- ${s.fileTarget} ---`);
99
- console.log(` Here is the structural hologram of the file to help you understand`);
100
- console.log(` its interfaces without consuming too many tokens:\n`);
101
- for (const line of s.hologram!.split("\n")) {
102
- console.log(` ${line}`);
103
- }
104
- console.log(`\n Now, generate the JSON-Patch based on the structure above.\n`);
105
- }
106
- }
107
-
108
- // Back-stage: dump full JSON-Patch for AI consumers
109
- const allPatches = diagnosis.symptoms.flatMap(s =>
110
- s.patches.map(p => ({ symptomId: s.id, ...p }))
111
- );
112
- console.log("[afd fix] JSON-Patch (back-stage):");
113
- console.log(JSON.stringify(allPatches, null, 2));
114
- console.log();
115
-
116
- // Prompt user
117
- process.stdout.write("Apply these fixes? [Y/n] ");
118
- const answer = await readLine();
119
-
120
- if (answer.toLowerCase() === "n") {
121
- console.log("[afd fix] Aborted.");
122
- return;
123
- }
124
-
125
- // Apply patches and learn antibodies
126
- let applied = 0;
127
- for (const symptom of diagnosis.symptoms) {
128
- if (symptom.patches.length === 0) continue;
129
- let success = true;
130
- for (const patch of symptom.patches) {
131
- if (!applyPatch(patch)) {
132
- console.log(` [skip] ${patch.op} ${patch.path} (already exists or unsupported)`);
133
- success = false;
134
- } else {
135
- console.log(` [done] ${patch.op} ${patch.path}`);
136
- applied++;
137
- }
138
- }
139
- if (success) {
140
- await learnAntibody(symptom);
141
- console.log(` [immune] Learned antibody: ${symptom.id}`);
142
- }
143
- }
144
-
145
- console.log(`\n[afd fix] Applied ${applied} patch(es). Immune system updated.`);
146
- }
147
-
148
- function readLine(): Promise<string> {
149
- return new Promise((resolve) => {
150
- const buf: Buffer[] = [];
151
- process.stdin.setEncoding("utf-8");
152
- process.stdin.resume();
153
- process.stdin.once("data", (chunk: string) => {
154
- process.stdin.pause();
155
- resolve(chunk.toString().trim());
156
- });
157
- });
158
- }
1
+ import { writeFileSync, mkdirSync, existsSync } from "fs";
2
+ import { dirname } from "path";
3
+ import { daemonRequest } from "../daemon/client";
4
+ import type { Symptom, PatchOp, DiagnosisResult } from "../core/immune";
5
+
6
+ const SEVERITY_ICON: Record<string, string> = {
7
+ critical: "[!]",
8
+ warning: "[~]",
9
+ info: "[i]",
10
+ };
11
+
12
+ function applyPatch(patch: PatchOp): boolean {
13
+ // Map JSON-Patch path to filesystem path (strip leading /)
14
+ const filePath = patch.path.replace(/^\//, "");
15
+
16
+ // Guard: reject path traversal attempts
17
+ if (filePath.includes("..") || filePath.startsWith("/") || /^[A-Za-z]:/.test(filePath)) return false;
18
+
19
+ if (patch.op === "add") {
20
+ if (existsSync(filePath)) return false; // don't overwrite
21
+ const dir = dirname(filePath);
22
+ if (dir !== ".") mkdirSync(dir, { recursive: true });
23
+ writeFileSync(filePath, patch.value ?? "", "utf-8");
24
+ return true;
25
+ }
26
+
27
+ if (patch.op === "replace") {
28
+ const dir = dirname(filePath);
29
+ if (dir !== ".") mkdirSync(dir, { recursive: true });
30
+ writeFileSync(filePath, patch.value ?? "", "utf-8");
31
+ return true;
32
+ }
33
+
34
+ // remove, move, copy, test — not needed yet
35
+ return false;
36
+ }
37
+
38
+ async function learnAntibody(symptom: Symptom): Promise<void> {
39
+ await fetch(
40
+ `http://127.0.0.1:${(await getDaemonPort())}/antibodies/learn`,
41
+ {
42
+ method: "POST",
43
+ headers: { "Content-Type": "application/json" },
44
+ body: JSON.stringify({
45
+ id: symptom.id,
46
+ patternType: symptom.patternType,
47
+ fileTarget: symptom.fileTarget,
48
+ patches: symptom.patches,
49
+ }),
50
+ }
51
+ );
52
+ }
53
+
54
+ async function getDaemonPort(): Promise<number> {
55
+ const { readFileSync } = await import("fs");
56
+ const { resolveWorkspacePaths } = await import("../constants");
57
+ const paths = resolveWorkspacePaths();
58
+ return parseInt(readFileSync(paths.portFile, "utf-8").trim(), 10);
59
+ }
60
+
61
+ export async function fixCommand() {
62
+ let diagnosis: DiagnosisResult;
63
+ try {
64
+ diagnosis = await daemonRequest<DiagnosisResult>("/diagnose");
65
+ } catch (err: unknown) {
66
+ const msg = err instanceof Error ? err.message : String(err);
67
+ console.error(`[afd fix] ${msg}`);
68
+ process.exit(1);
69
+ }
70
+
71
+ if (diagnosis.symptoms.length === 0) {
72
+ console.log("[afd fix] No symptoms detected. System is healthy.");
73
+ if (diagnosis.healthy.length > 0) {
74
+ console.log(`[afd fix] Passed checks: ${diagnosis.healthy.join(", ")}`);
75
+ }
76
+ return;
77
+ }
78
+
79
+ // Display symptoms
80
+ console.log(`\n[afd fix] Found ${diagnosis.symptoms.length} symptom(s):\n`);
81
+
82
+ for (const s of diagnosis.symptoms) {
83
+ const icon = SEVERITY_ICON[s.severity] ?? "[?]";
84
+ console.log(` ${icon} ${s.id}: ${s.title} (${s.severity})`);
85
+ console.log(` ${s.description}`);
86
+ if (s.patches.length > 0) {
87
+ console.log(` Patch: ${s.patches.map(p => `${p.op} ${p.path}`).join(", ")}`);
88
+ }
89
+ console.log();
90
+ }
91
+
92
+ // Extract phase: inject hologram context for AI consumers
93
+ const symptomsWithHologram = diagnosis.symptoms as (Symptom & { hologram?: string })[];
94
+ const holograms = symptomsWithHologram.filter(s => s.hologram);
95
+ if (holograms.length > 0) {
96
+ console.log("[afd fix] Hologram Context (Extract phase — token-optimized file structures):\n");
97
+ for (const s of holograms) {
98
+ console.log(` --- ${s.fileTarget} ---`);
99
+ console.log(` Here is the structural hologram of the file to help you understand`);
100
+ console.log(` its interfaces without consuming too many tokens:\n`);
101
+ for (const line of s.hologram!.split("\n")) {
102
+ console.log(` ${line}`);
103
+ }
104
+ console.log(`\n Now, generate the JSON-Patch based on the structure above.\n`);
105
+ }
106
+ }
107
+
108
+ // Back-stage: dump full JSON-Patch for AI consumers
109
+ const allPatches = diagnosis.symptoms.flatMap(s =>
110
+ s.patches.map(p => ({ symptomId: s.id, ...p }))
111
+ );
112
+ console.log("[afd fix] JSON-Patch (back-stage):");
113
+ console.log(JSON.stringify(allPatches, null, 2));
114
+ console.log();
115
+
116
+ // Prompt user
117
+ process.stdout.write("Apply these fixes? [Y/n] ");
118
+ const answer = await readLine();
119
+
120
+ if (answer.toLowerCase() === "n") {
121
+ console.log("[afd fix] Aborted.");
122
+ return;
123
+ }
124
+
125
+ // Apply patches and learn antibodies
126
+ let applied = 0;
127
+ for (const symptom of diagnosis.symptoms) {
128
+ if (symptom.patches.length === 0) continue;
129
+ let success = true;
130
+ for (const patch of symptom.patches) {
131
+ if (!applyPatch(patch)) {
132
+ console.log(` [skip] ${patch.op} ${patch.path} (already exists or unsupported)`);
133
+ success = false;
134
+ } else {
135
+ console.log(` [done] ${patch.op} ${patch.path}`);
136
+ applied++;
137
+ }
138
+ }
139
+ if (success) {
140
+ await learnAntibody(symptom);
141
+ console.log(` [immune] Learned antibody: ${symptom.id}`);
142
+ }
143
+ }
144
+
145
+ console.log(`\n[afd fix] Applied ${applied} patch(es). Immune system updated.`);
146
+ }
147
+
148
+ function readLine(): Promise<string> {
149
+ return new Promise((resolve) => {
150
+ const buf: Buffer[] = [];
151
+ process.stdin.setEncoding("utf-8");
152
+ process.stdin.resume();
153
+ process.stdin.once("data", (chunk: string) => {
154
+ process.stdin.pause();
155
+ resolve(chunk.toString().trim());
156
+ });
157
+ });
158
+ }
@@ -1,41 +1,41 @@
1
- import { getSystemLanguage, getSupportedLanguages, setLanguageOverride } from "../core/locale";
2
- import type { SupportedLang } from "../core/locale";
3
- import { writeConfig, getConfigPath } from "../core/config";
4
- import { getMessages, t } from "../core/i18n/messages";
5
-
6
- export function langCommand(targetLang?: string, options?: { list?: boolean }) {
7
- const currentLang = getSystemLanguage();
8
- const msg = getMessages(currentLang);
9
- const supported = getSupportedLanguages();
10
-
11
- // afd lang --list
12
- if (options?.list) {
13
- console.log(msg.LANG_LIST_TITLE);
14
- for (const lang of supported) {
15
- const marker = lang === currentLang ? " ← current" : "";
16
- console.log(` ${lang}${marker}`);
17
- }
18
- return;
19
- }
20
-
21
- // afd lang (no argument) — show current
22
- if (!targetLang) {
23
- console.log(t(msg.LANG_CURRENT, { lang: currentLang }));
24
- return;
25
- }
26
-
27
- // afd lang <en|ko> — change language
28
- if (!supported.includes(targetLang as SupportedLang)) {
29
- console.error(t(msg.LANG_INVALID, { lang: targetLang, supported: supported.join(", ") }));
30
- process.exit(1);
31
- }
32
-
33
- const newLang = targetLang as SupportedLang;
34
- writeConfig({ lang: newLang });
35
- setLanguageOverride(newLang);
36
-
37
- // Print feedback in the NEW language
38
- const newMsg = getMessages(newLang);
39
- console.log(t(newMsg.LANG_CHANGED, { lang: newLang }));
40
- console.log(t(newMsg.LANG_SAVED, { path: getConfigPath() }));
41
- }
1
+ import { getSystemLanguage, getSupportedLanguages, setLanguageOverride } from "../core/locale";
2
+ import type { SupportedLang } from "../core/locale";
3
+ import { writeConfig, getConfigPath } from "../core/config";
4
+ import { getMessages, t } from "../core/i18n/messages";
5
+
6
+ export function langCommand(targetLang?: string, options?: { list?: boolean }) {
7
+ const currentLang = getSystemLanguage();
8
+ const msg = getMessages(currentLang);
9
+ const supported = getSupportedLanguages();
10
+
11
+ // afd lang --list
12
+ if (options?.list) {
13
+ console.log(msg.LANG_LIST_TITLE);
14
+ for (const lang of supported) {
15
+ const marker = lang === currentLang ? " ← current" : "";
16
+ console.log(` ${lang}${marker}`);
17
+ }
18
+ return;
19
+ }
20
+
21
+ // afd lang (no argument) — show current
22
+ if (!targetLang) {
23
+ console.log(t(msg.LANG_CURRENT, { lang: currentLang }));
24
+ return;
25
+ }
26
+
27
+ // afd lang <en|ko> — change language
28
+ if (!supported.includes(targetLang as SupportedLang)) {
29
+ console.error(t(msg.LANG_INVALID, { lang: targetLang, supported: supported.join(", ") }));
30
+ process.exit(1);
31
+ }
32
+
33
+ const newLang = targetLang as SupportedLang;
34
+ writeConfig({ lang: newLang });
35
+ setLanguageOverride(newLang);
36
+
37
+ // Print feedback in the NEW language
38
+ const newMsg = getMessages(newLang);
39
+ console.log(t(newMsg.LANG_CHANGED, { lang: newLang }));
40
+ console.log(t(newMsg.LANG_SAVED, { path: getConfigPath() }));
41
+ }
@@ -0,0 +1,110 @@
1
+ /**
2
+ * afd plugin — Third-party validator plugin manager
3
+ *
4
+ * Sub-commands:
5
+ * afd plugin install <npm-package> — install a validator plugin from npm
6
+ * afd plugin list — list installed plugins
7
+ * afd plugin remove <name> — uninstall a plugin
8
+ */
9
+
10
+ import { installPlugin, listPlugins, removePlugin } from "../core/plugin-manager";
11
+ import { getSystemLanguage } from "../core/locale";
12
+
13
+ const msgs = {
14
+ en: {
15
+ usage: `Usage:
16
+ afd plugin install <npm-package> Install a validator plugin from npm
17
+ afd plugin list List installed plugins
18
+ afd plugin remove <name> Uninstall a plugin`,
19
+ noPlugins: "No plugins installed.",
20
+ installing: "Installing",
21
+ installed: "Installed Plugins",
22
+ },
23
+ ko: {
24
+ usage: `사용법:
25
+ afd plugin install <npm-package> npm 플러그인 설치
26
+ afd plugin list 설치된 플러그인 목록
27
+ afd plugin remove <name> 플러그인 제거`,
28
+ noPlugins: "설치된 플러그인이 없습니다.",
29
+ installing: "설치 중",
30
+ installed: "설치된 플러그인",
31
+ },
32
+ };
33
+
34
+ const BOX = { tl: "┌", tr: "┐", bl: "└", br: "┘", h: "─", v: "│", ml: "├", mr: "┤" };
35
+ const W = 58;
36
+ function hline(l: string, r: string) { return `${l}${BOX.h.repeat(W)}${r}`; }
37
+ function row(s: string) {
38
+ const pad = Math.max(0, W - 2 - s.length);
39
+ return `${BOX.v} ${s}${" ".repeat(pad)} ${BOX.v}`;
40
+ }
41
+
42
+ export async function pluginCommand(subcommand?: string, arg?: string) {
43
+ const lang = getSystemLanguage();
44
+ const m = msgs[lang];
45
+
46
+ if (!subcommand) {
47
+ console.log(m.usage);
48
+ return;
49
+ }
50
+
51
+ switch (subcommand) {
52
+ case "install": {
53
+ if (!arg) {
54
+ console.error("Usage: afd plugin install <npm-package>");
55
+ process.exit(1);
56
+ }
57
+ console.log(`🔌 ${m.installing}: ${arg} …`);
58
+ const result = installPlugin(arg);
59
+ console.log(hline(BOX.tl, BOX.tr));
60
+ if (result.success) {
61
+ console.log(row(`✅ ${result.message}`));
62
+ if (result.manifest?.description) {
63
+ console.log(row(` ${result.manifest.description}`));
64
+ }
65
+ console.log(row(" Hot-reload active — daemon picks this up instantly."));
66
+ } else {
67
+ console.log(row(`❌ ${result.message}`));
68
+ }
69
+ console.log(hline(BOX.bl, BOX.br));
70
+ if (!result.success) process.exit(1);
71
+ break;
72
+ }
73
+
74
+ case "list": {
75
+ const plugins = listPlugins();
76
+ console.log(hline(BOX.tl, BOX.tr));
77
+ console.log(row(`🔌 ${m.installed}`));
78
+ console.log(hline(BOX.ml, BOX.mr));
79
+ if (plugins.length === 0) {
80
+ console.log(row(m.noPlugins));
81
+ } else {
82
+ for (const p of plugins) {
83
+ console.log(row(`📦 ${p.package}@${p.version}`));
84
+ if (p.description) console.log(row(` ${p.description}`));
85
+ console.log(row(` validator: .afd/validators/${p.validatorFile}`));
86
+ console.log(row(` installed: ${p.installDate.slice(0, 10)}`));
87
+ console.log(row(""));
88
+ }
89
+ }
90
+ console.log(hline(BOX.bl, BOX.br));
91
+ break;
92
+ }
93
+
94
+ case "remove": {
95
+ if (!arg) {
96
+ console.error("Usage: afd plugin remove <name>");
97
+ process.exit(1);
98
+ }
99
+ const result = removePlugin(arg);
100
+ console.log(hline(BOX.tl, BOX.tr));
101
+ console.log(row(result.success ? `✅ ${result.message}` : `❌ ${result.message}`));
102
+ console.log(hline(BOX.bl, BOX.br));
103
+ if (!result.success) process.exit(1);
104
+ break;
105
+ }
106
+
107
+ default:
108
+ console.log(m.usage);
109
+ }
110
+ }
@@ -1,14 +1,14 @@
1
- import { stopCommand } from "./stop";
2
- import { startCommand } from "./start";
3
- import { getSystemLanguage } from "../core/locale";
4
- import { getMessages } from "../core/i18n/messages";
5
-
6
- export async function restartCommand() {
7
- const lang = getSystemLanguage();
8
- const msg = getMessages(lang);
9
-
10
- console.log(msg.DAEMON_RESTARTING);
11
-
12
- await stopCommand();
13
- await startCommand();
14
- }
1
+ import { stopCommand } from "./stop";
2
+ import { startCommand } from "./start";
3
+ import { getSystemLanguage } from "../core/locale";
4
+ import { getMessages } from "../core/i18n/messages";
5
+
6
+ export async function restartCommand() {
7
+ const lang = getSystemLanguage();
8
+ const msg = getMessages(lang);
9
+
10
+ console.log(msg.DAEMON_RESTARTING);
11
+
12
+ await stopCommand();
13
+ await startCommand();
14
+ }