openclaw-watcher 0.0.1

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 (130) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/.dockerignore +21 -0
  3. package/.env.example +31 -0
  4. package/.eslintrc.json +26 -0
  5. package/.prettierrc.json +9 -0
  6. package/CHANGELOG.md +93 -0
  7. package/Dockerfile +47 -0
  8. package/README.md +408 -0
  9. package/build.sh +33 -0
  10. package/dist/ai/ai-orchestrator.d.ts +11 -0
  11. package/dist/ai/ai-orchestrator.d.ts.map +1 -0
  12. package/dist/ai/ai-orchestrator.js +85 -0
  13. package/dist/ai/ai-orchestrator.js.map +1 -0
  14. package/dist/ai/cli-client.d.ts +17 -0
  15. package/dist/ai/cli-client.d.ts.map +1 -0
  16. package/dist/ai/cli-client.js +239 -0
  17. package/dist/ai/cli-client.js.map +1 -0
  18. package/dist/cli.d.ts +3 -0
  19. package/dist/cli.d.ts.map +1 -0
  20. package/dist/cli.js +33 -0
  21. package/dist/cli.js.map +1 -0
  22. package/dist/commands/config.d.ts +7 -0
  23. package/dist/commands/config.d.ts.map +1 -0
  24. package/dist/commands/config.js +52 -0
  25. package/dist/commands/config.js.map +1 -0
  26. package/dist/commands/init.d.ts +6 -0
  27. package/dist/commands/init.d.ts.map +1 -0
  28. package/dist/commands/init.js +205 -0
  29. package/dist/commands/init.js.map +1 -0
  30. package/dist/commands/start.d.ts +6 -0
  31. package/dist/commands/start.d.ts.map +1 -0
  32. package/dist/commands/start.js +49 -0
  33. package/dist/commands/start.js.map +1 -0
  34. package/dist/commands/status.d.ts +2 -0
  35. package/dist/commands/status.d.ts.map +1 -0
  36. package/dist/commands/status.js +48 -0
  37. package/dist/commands/status.js.map +1 -0
  38. package/dist/config/default.d.ts +5 -0
  39. package/dist/config/default.d.ts.map +1 -0
  40. package/dist/config/default.js +22 -0
  41. package/dist/config/default.js.map +1 -0
  42. package/dist/healthcheck/gateway-monitor.d.ts +19 -0
  43. package/dist/healthcheck/gateway-monitor.d.ts.map +1 -0
  44. package/dist/healthcheck/gateway-monitor.js +116 -0
  45. package/dist/healthcheck/gateway-monitor.js.map +1 -0
  46. package/dist/healthcheck/health-checker.d.ts +11 -0
  47. package/dist/healthcheck/health-checker.d.ts.map +1 -0
  48. package/dist/healthcheck/health-checker.js +60 -0
  49. package/dist/healthcheck/health-checker.js.map +1 -0
  50. package/dist/index.d.ts +2 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +39 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/recovery/auto-fixer.d.ts +16 -0
  55. package/dist/recovery/auto-fixer.d.ts.map +1 -0
  56. package/dist/recovery/auto-fixer.js +162 -0
  57. package/dist/recovery/auto-fixer.js.map +1 -0
  58. package/dist/recovery/change-recorder.d.ts +8 -0
  59. package/dist/recovery/change-recorder.d.ts.map +1 -0
  60. package/dist/recovery/change-recorder.js +41 -0
  61. package/dist/recovery/change-recorder.js.map +1 -0
  62. package/dist/setup/config-initializer.d.ts +13 -0
  63. package/dist/setup/config-initializer.d.ts.map +1 -0
  64. package/dist/setup/config-initializer.js +46 -0
  65. package/dist/setup/config-initializer.js.map +1 -0
  66. package/dist/setup/config-loader.d.ts +9 -0
  67. package/dist/setup/config-loader.d.ts.map +1 -0
  68. package/dist/setup/config-loader.js +17 -0
  69. package/dist/setup/config-loader.js.map +1 -0
  70. package/dist/setup/git-initializer.d.ts +15 -0
  71. package/dist/setup/git-initializer.d.ts.map +1 -0
  72. package/dist/setup/git-initializer.js +189 -0
  73. package/dist/setup/git-initializer.js.map +1 -0
  74. package/dist/setup/safe-config-generator.d.ts +9 -0
  75. package/dist/setup/safe-config-generator.d.ts.map +1 -0
  76. package/dist/setup/safe-config-generator.js +85 -0
  77. package/dist/setup/safe-config-generator.js.map +1 -0
  78. package/dist/types/index.d.ts +60 -0
  79. package/dist/types/index.d.ts.map +1 -0
  80. package/dist/types/index.js +2 -0
  81. package/dist/types/index.js.map +1 -0
  82. package/dist/utils/executor.d.ts +17 -0
  83. package/dist/utils/executor.d.ts.map +1 -0
  84. package/dist/utils/executor.js +57 -0
  85. package/dist/utils/executor.js.map +1 -0
  86. package/dist/utils/git-manager.d.ts +14 -0
  87. package/dist/utils/git-manager.d.ts.map +1 -0
  88. package/dist/utils/git-manager.js +116 -0
  89. package/dist/utils/git-manager.js.map +1 -0
  90. package/dist/utils/github-cli.d.ts +9 -0
  91. package/dist/utils/github-cli.d.ts.map +1 -0
  92. package/dist/utils/github-cli.js +31 -0
  93. package/dist/utils/github-cli.js.map +1 -0
  94. package/dist/utils/logger.d.ts +4 -0
  95. package/dist/utils/logger.d.ts.map +1 -0
  96. package/dist/utils/logger.js +26 -0
  97. package/dist/utils/logger.js.map +1 -0
  98. package/dist/utils/paths.d.ts +6 -0
  99. package/dist/utils/paths.d.ts.map +1 -0
  100. package/dist/utils/paths.js +19 -0
  101. package/dist/utils/paths.js.map +1 -0
  102. package/docker-compose.yml +43 -0
  103. package/nodemon.json +9 -0
  104. package/package.json +59 -0
  105. package/prompts/fix-openclaw.md +202 -0
  106. package/scripts/setup.sh +105 -0
  107. package/src/ai/ai-orchestrator.ts +95 -0
  108. package/src/ai/cli-client.ts +296 -0
  109. package/src/cli.ts +40 -0
  110. package/src/commands/config.ts +57 -0
  111. package/src/commands/init.ts +239 -0
  112. package/src/commands/start.ts +75 -0
  113. package/src/commands/status.ts +79 -0
  114. package/src/config/default.ts +25 -0
  115. package/src/healthcheck/gateway-monitor.ts +137 -0
  116. package/src/healthcheck/health-checker.ts +71 -0
  117. package/src/index.ts +48 -0
  118. package/src/recovery/auto-fixer.ts +184 -0
  119. package/src/recovery/change-recorder.ts +46 -0
  120. package/src/setup/config-initializer.ts +63 -0
  121. package/src/setup/config-loader.ts +25 -0
  122. package/src/setup/git-initializer.ts +203 -0
  123. package/src/setup/safe-config-generator.ts +100 -0
  124. package/src/types/index.ts +67 -0
  125. package/src/utils/executor.ts +75 -0
  126. package/src/utils/git-manager.ts +121 -0
  127. package/src/utils/github-cli.ts +37 -0
  128. package/src/utils/logger.ts +39 -0
  129. package/src/utils/paths.ts +25 -0
  130. package/tsconfig.json +29 -0
@@ -0,0 +1,205 @@
1
+ import inquirer from 'inquirer';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import boxen from 'boxen';
5
+ import fs from 'fs/promises';
6
+ import path from 'path';
7
+ import os from 'os';
8
+ import { ConfigInitializer } from '../setup/config-initializer.js';
9
+ import { GitInitializer } from '../setup/git-initializer.js';
10
+ import { SafeConfigGenerator } from '../setup/safe-config-generator.js';
11
+ import { GitHubCli } from '../utils/github-cli.js';
12
+ import { getConfigPath } from '../utils/paths.js';
13
+ export async function initCommand(options) {
14
+ console.log(boxen(chalk.bold.cyan('OpenClaw Watcher'), {
15
+ padding: 1,
16
+ margin: 1,
17
+ borderStyle: 'round',
18
+ borderColor: 'cyan',
19
+ }));
20
+ console.log(chalk.gray('AI-powered health monitoring and auto-repair for OpenClaw Gateway\n'));
21
+ const answers = await inquirer.prompt([
22
+ {
23
+ type: 'input',
24
+ name: 'openclawConfigPath',
25
+ message: 'OpenClaw configuration directory:',
26
+ default: path.join(os.homedir(), '.openclaw'),
27
+ validate: async (input) => {
28
+ const expandedPath = input.replace(/^~/, os.homedir());
29
+ try {
30
+ const stats = await fs.stat(expandedPath);
31
+ if (!stats.isDirectory()) {
32
+ return 'Path must be a directory';
33
+ }
34
+ return true;
35
+ }
36
+ catch {
37
+ return 'Directory does not exist';
38
+ }
39
+ },
40
+ },
41
+ {
42
+ type: 'input',
43
+ name: 'gatewayUrl',
44
+ message: 'OpenClaw Gateway URL:',
45
+ default: 'http://localhost:10002',
46
+ validate: (input) => {
47
+ try {
48
+ new URL(input);
49
+ return true;
50
+ }
51
+ catch {
52
+ return 'Please enter a valid URL';
53
+ }
54
+ },
55
+ },
56
+ {
57
+ type: 'list',
58
+ name: 'aiProvider',
59
+ message: 'AI provider:',
60
+ choices: [
61
+ { name: 'Claude Code CLI (Recommended)', value: 'claude' },
62
+ { name: 'Kimi Code CLI', value: 'kimi' },
63
+ ],
64
+ default: 'claude',
65
+ },
66
+ {
67
+ type: 'confirm',
68
+ name: 'initGit',
69
+ message: 'Initialize Git repository for config tracking?',
70
+ default: options.git !== false,
71
+ when: () => options.git !== false,
72
+ },
73
+ {
74
+ type: 'input',
75
+ name: 'gitRepoName',
76
+ message: 'Git repository name:',
77
+ default: 'openclaw-config',
78
+ when: (answers) => answers.initGit,
79
+ },
80
+ {
81
+ type: 'confirm',
82
+ name: 'useGitHubCli',
83
+ message: 'Sync repair history to GitHub? (requires gh CLI)',
84
+ default: true,
85
+ when: (answers) => answers.initGit,
86
+ },
87
+ ]);
88
+ console.log('');
89
+ const spinner = ora('Initializing configuration...').start();
90
+ try {
91
+ // Expand paths
92
+ const openclawConfigPath = answers.openclawConfigPath.replace(/^~/, os.homedir());
93
+ // 1. Create config file
94
+ spinner.text = 'Creating configuration file...';
95
+ const configInitializer = new ConfigInitializer();
96
+ await configInitializer.create({
97
+ openclawConfigPath,
98
+ gatewayUrl: answers.gatewayUrl,
99
+ healthCheckInterval: 30000,
100
+ failureThreshold: 3,
101
+ aiProvider: answers.aiProvider,
102
+ gitTracking: answers.initGit || false,
103
+ useGitHubCli: answers.useGitHubCli || false,
104
+ });
105
+ // 2. Initialize Git repository if requested
106
+ if (answers.initGit) {
107
+ spinner.text = 'Initializing Git repository...';
108
+ const gitInitializer = new GitInitializer(openclawConfigPath);
109
+ await gitInitializer.init({
110
+ repoName: answers.gitRepoName,
111
+ isPrivate: true,
112
+ });
113
+ // 3. Generate safe config
114
+ spinner.text = 'Generating safe configuration file...';
115
+ const safeConfigGen = new SafeConfigGenerator(openclawConfigPath);
116
+ await safeConfigGen.generate();
117
+ // 4. Setup pre-commit hook
118
+ spinner.text = 'Setting up pre-commit hook...';
119
+ await gitInitializer.setupPreCommitHook();
120
+ // 5. Initial commit
121
+ spinner.text = 'Creating initial commit...';
122
+ await gitInitializer.initialCommit();
123
+ // 6. GitHub sync if requested
124
+ if (answers.useGitHubCli) {
125
+ await setupGitHubSync(spinner, answers.gitRepoName, openclawConfigPath);
126
+ }
127
+ }
128
+ spinner.succeed(chalk.green('Initialization complete!'));
129
+ console.log('');
130
+ console.log(boxen(chalk.white.bold('Next Steps:\n\n') +
131
+ chalk.cyan('1. ') +
132
+ 'Review configuration: ' +
133
+ chalk.yellow(getConfigPath()) +
134
+ '\n' +
135
+ chalk.cyan('2. ') +
136
+ 'Start monitoring: ' +
137
+ chalk.yellow('npx openclaw-watcher start') +
138
+ '\n' +
139
+ chalk.cyan('3. ') +
140
+ 'Check status: ' +
141
+ chalk.yellow('npx openclaw-watcher status'), {
142
+ padding: 1,
143
+ margin: 1,
144
+ borderStyle: 'round',
145
+ borderColor: 'green',
146
+ }));
147
+ if (answers.initGit) {
148
+ console.log(chalk.gray(`\n📂 Git repository initialized at: ${chalk.white(openclawConfigPath)}`));
149
+ console.log(chalk.gray(` - ${chalk.white('openclaw.safe.json')} is tracked (sensitive data redacted)`));
150
+ console.log(chalk.gray(` - ${chalk.white('openclaw.json')} is ignored (contains secrets)`));
151
+ if (answers.useGitHubCli) {
152
+ console.log(chalk.gray(` - ${chalk.white('GitHub sync')} enabled (auto-push after each repair)`));
153
+ }
154
+ }
155
+ }
156
+ catch (error) {
157
+ spinner.fail(chalk.red('Initialization failed'));
158
+ console.error(chalk.red(`\nError: ${error.message}`));
159
+ process.exit(1);
160
+ }
161
+ }
162
+ async function setupGitHubSync(spinner, repoName, localPath) {
163
+ const gh = new GitHubCli();
164
+ // Check gh CLI installed
165
+ spinner.text = 'Checking GitHub CLI...';
166
+ if (!(await gh.isInstalled())) {
167
+ spinner.warn(chalk.yellow('GitHub CLI (gh) not found — skipping GitHub sync'));
168
+ console.log(chalk.gray(' Install: https://cli.github.com'));
169
+ spinner.start('Continuing initialization...');
170
+ return;
171
+ }
172
+ // Check gh auth
173
+ if (!(await gh.isAuthenticated())) {
174
+ spinner.stop();
175
+ console.log(chalk.yellow('\n⚠ GitHub CLI not authenticated.'));
176
+ console.log(chalk.gray(' Run `gh auth login` in another terminal, then continue.\n'));
177
+ const { retry } = await inquirer.prompt([
178
+ {
179
+ type: 'confirm',
180
+ name: 'retry',
181
+ message: 'Have you completed gh auth login?',
182
+ default: true,
183
+ },
184
+ ]);
185
+ spinner.start('Checking authentication...');
186
+ if (!retry || !(await gh.isAuthenticated())) {
187
+ spinner.warn(chalk.yellow('GitHub auth not ready — skipping GitHub sync'));
188
+ spinner.start('Continuing initialization...');
189
+ return;
190
+ }
191
+ }
192
+ // Create repo and push
193
+ spinner.text = 'Creating GitHub repository...';
194
+ const result = await gh.createRepoAndPush(repoName, localPath);
195
+ if (result.success) {
196
+ spinner.succeed(chalk.green(`GitHub repository created: ${repoName}`));
197
+ spinner.start('Finalizing...');
198
+ }
199
+ else {
200
+ spinner.warn(chalk.yellow(`GitHub repo creation failed — you can set it up later`));
201
+ console.log(chalk.gray(` ${result.stderr}`));
202
+ spinner.start('Continuing initialization...');
203
+ }
204
+ }
205
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAMjD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAoB;IACpD,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE;QACzC,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;QACT,WAAW,EAAE,OAAO;QACpB,WAAW,EAAE,MAAM;KACpB,CAAC,CACH,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAC,CAAC;IAE/F,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QACpC;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,oBAAoB;YAC1B,OAAO,EAAE,mCAAmC;YAC5C,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC;YAC7C,QAAQ,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;gBAChC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;gBACvD,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;oBAC1C,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;wBACzB,OAAO,0BAA0B,CAAC;oBACpC,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,0BAA0B,CAAC;gBACpC,CAAC;YACH,CAAC;SACF;QACD;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,uBAAuB;YAChC,OAAO,EAAE,wBAAwB;YACjC,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC1B,IAAI,CAAC;oBACH,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;oBACf,OAAO,IAAI,CAAC;gBACd,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,0BAA0B,CAAC;gBACpC,CAAC;YACH,CAAC;SACF;QACD;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,cAAc;YACvB,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,+BAA+B,EAAE,KAAK,EAAE,QAAQ,EAAE;gBAC1D,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE;aACzC;YACD,OAAO,EAAE,QAAQ;SAClB;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,gDAAgD;YACzD,OAAO,EAAE,OAAO,CAAC,GAAG,KAAK,KAAK;YAC9B,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,KAAK,KAAK;SAClC;QACD;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,sBAAsB;YAC/B,OAAO,EAAE,iBAAiB;YAC1B,IAAI,EAAE,CAAC,OAAY,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO;SACxC;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,kDAAkD;YAC3D,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,CAAC,OAAY,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO;SACxC;KACF,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,MAAM,OAAO,GAAG,GAAG,CAAC,+BAA+B,CAAC,CAAC,KAAK,EAAE,CAAC;IAE7D,IAAI,CAAC;QACH,eAAe;QACf,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QAElF,wBAAwB;QACxB,OAAO,CAAC,IAAI,GAAG,gCAAgC,CAAC;QAChD,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC;QAClD,MAAM,iBAAiB,CAAC,MAAM,CAAC;YAC7B,kBAAkB;YAClB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,mBAAmB,EAAE,KAAK;YAC1B,gBAAgB,EAAE,CAAC;YACnB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,WAAW,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;YACrC,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,KAAK;SAC5C,CAAC,CAAC;QAEH,4CAA4C;QAC5C,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,GAAG,gCAAgC,CAAC;YAChD,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,kBAAkB,CAAC,CAAC;YAC9D,MAAM,cAAc,CAAC,IAAI,CAAC;gBACxB,QAAQ,EAAE,OAAO,CAAC,WAAW;gBAC7B,SAAS,EAAE,IAAI;aAChB,CAAC,CAAC;YAEH,0BAA0B;YAC1B,OAAO,CAAC,IAAI,GAAG,uCAAuC,CAAC;YACvD,MAAM,aAAa,GAAG,IAAI,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;YAClE,MAAM,aAAa,CAAC,QAAQ,EAAE,CAAC;YAE/B,2BAA2B;YAC3B,OAAO,CAAC,IAAI,GAAG,+BAA+B,CAAC;YAC/C,MAAM,cAAc,CAAC,kBAAkB,EAAE,CAAC;YAE1C,oBAAoB;YACpB,OAAO,CAAC,IAAI,GAAG,4BAA4B,CAAC;YAC5C,MAAM,cAAc,CAAC,aAAa,EAAE,CAAC;YAErC,8BAA8B;YAC9B,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACzB,MAAM,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;QAEzD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CACT,KAAK,CACH,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YACjB,wBAAwB;YACxB,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC7B,IAAI;YACJ,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YACjB,oBAAoB;YACpB,KAAK,CAAC,MAAM,CAAC,4BAA4B,CAAC;YAC1C,IAAI;YACJ,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YACjB,gBAAgB;YAChB,KAAK,CAAC,MAAM,CAAC,6BAA6B,CAAC,EAC7C;YACE,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,CAAC;YACT,WAAW,EAAE,OAAO;YACpB,WAAW,EAAE,OAAO;SACrB,CACF,CACF,CAAC;QAEF,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,uCAAuC,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,CACrF,CAAC;YACF,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,uCAAuC,CAAC,CAC7F,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,gCAAgC,CAAC,CAAC,CAAC;YAC9F,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,wCAAwC,CAAC,CACvF,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC;QACjD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,OAA+B,EAAE,QAAgB,EAAE,SAAiB;IACjG,MAAM,EAAE,GAAG,IAAI,SAAS,EAAE,CAAC;IAE3B,yBAAyB;IACzB,OAAO,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACxC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,kDAAkD,CAAC,CAAC,CAAC;QAC/E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,gBAAgB;IAChB,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,eAAe,EAAE,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,mCAAmC,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC,CAAC;QAEvF,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;YACtC;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,mCAAmC;gBAC5C,OAAO,EAAE,IAAI;aACd;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAE5C,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,eAAe,EAAE,CAAC,EAAE,CAAC;YAC5C,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,8CAA8C,CAAC,CAAC,CAAC;YAC3E,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,OAAO,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE/D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,8BAA8B,QAAQ,EAAE,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,uDAAuD,CAAC,CAAC,CAAC;QACpF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC9C,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface StartOptions {
2
+ daemon?: boolean;
3
+ }
4
+ export declare function startCommand(_options: StartOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAMA,UAAU,YAAY;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,YAAY,iBAgExD"}
@@ -0,0 +1,49 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { loadConfig } from '../setup/config-loader.js';
4
+ import { GatewayMonitor } from '../healthcheck/gateway-monitor.js';
5
+ import logger from '../utils/logger.js';
6
+ export async function startCommand(_options) {
7
+ const spinner = ora('Loading configuration...').start();
8
+ try {
9
+ const config = await loadConfig();
10
+ if (!config) {
11
+ spinner.fail(chalk.red('Configuration not found'));
12
+ console.log(chalk.yellow('\nPlease run initialization first: npx openclaw-watcher init'));
13
+ process.exit(1);
14
+ }
15
+ spinner.text = 'Starting OpenClaw Watcher...';
16
+ const monitor = new GatewayMonitor(config.monitor, config.ai, config.recovery);
17
+ await monitor.start();
18
+ spinner.succeed(chalk.green('OpenClaw Watcher started successfully!'));
19
+ console.log('');
20
+ console.log(chalk.cyan('📊 Monitoring:'), chalk.white(config.monitor.gatewayUrl));
21
+ console.log(chalk.cyan('⏱️ Check interval:'), chalk.white(`${config.monitor.checkInterval / 1000}s`));
22
+ console.log(chalk.cyan('🚨 Failure threshold:'), chalk.white(config.monitor.failureThreshold));
23
+ console.log(chalk.cyan('🤖 AI Provider:'), chalk.white(config.ai.provider));
24
+ console.log('');
25
+ console.log(chalk.gray('Press Ctrl+C to stop'));
26
+ // Handle graceful shutdown
27
+ process.on('SIGINT', () => {
28
+ console.log('\n');
29
+ const stopSpinner = ora('Stopping OpenClaw Watcher...').start();
30
+ monitor.stop();
31
+ stopSpinner.succeed(chalk.green('Stopped'));
32
+ process.exit(0);
33
+ });
34
+ process.on('SIGTERM', () => {
35
+ console.log('\n');
36
+ const stopSpinner = ora('Stopping OpenClaw Watcher...').start();
37
+ monitor.stop();
38
+ stopSpinner.succeed(chalk.green('Stopped'));
39
+ process.exit(0);
40
+ });
41
+ }
42
+ catch (error) {
43
+ spinner.fail(chalk.red('Failed to start'));
44
+ console.error(chalk.red(`\nError: ${error.message}`));
45
+ logger.error('Failed to start', { error: error.message });
46
+ process.exit(1);
47
+ }
48
+ }
49
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function statusCommand(): Promise<void>;
2
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAKA,wBAAsB,aAAa,kBAyElC"}
@@ -0,0 +1,48 @@
1
+ import chalk from 'chalk';
2
+ import { loadConfig } from '../setup/config-loader.js';
3
+ import fs from 'fs/promises';
4
+ import { getChangesFilePath } from '../utils/paths.js';
5
+ export async function statusCommand() {
6
+ try {
7
+ const config = await loadConfig();
8
+ if (!config) {
9
+ console.log(chalk.yellow('⚠️ Not initialized'));
10
+ console.log(chalk.gray('\nRun: npx openclaw-watcher init'));
11
+ return;
12
+ }
13
+ console.log(chalk.bold.cyan('\n📊 OpenClaw Watcher Status\n'));
14
+ console.log(chalk.white('Configuration:'));
15
+ console.log(chalk.gray(' Gateway URL:'), chalk.white(config.monitor.gatewayUrl));
16
+ console.log(chalk.gray(' Check Interval:'), chalk.white(`${config.monitor.checkInterval / 1000}s`));
17
+ console.log(chalk.gray(' Failure Threshold:'), chalk.white(config.monitor.failureThreshold));
18
+ console.log(chalk.gray(' AI Provider:'), chalk.white(config.ai.provider));
19
+ console.log(chalk.gray(' Config Path:'), chalk.white(config.recovery.openclawConfigPath));
20
+ console.log(chalk.gray(' Git Tracking:'), config.recovery.useGitTracking ? chalk.green('✓ Enabled') : chalk.gray('✗ Disabled'));
21
+ // Check repair history
22
+ const changeLogPath = getChangesFilePath();
23
+ try {
24
+ const changeLogContent = await fs.readFile(changeLogPath, 'utf-8');
25
+ const changes = JSON.parse(changeLogContent);
26
+ console.log(chalk.white('\nRepair History:'));
27
+ console.log(chalk.gray(' Total Repairs:'), chalk.white(changes.length));
28
+ if (changes.length > 0) {
29
+ const lastChange = changes[changes.length - 1];
30
+ console.log(chalk.gray(' Last Repair:'), chalk.white(new Date(lastChange.timestamp).toLocaleString()));
31
+ console.log(chalk.gray(' Last Issue:'), chalk.white(lastChange.diagnosis.issue));
32
+ console.log(chalk.gray(' Success:'), lastChange.recovery.success
33
+ ? chalk.green('✓ Yes')
34
+ : chalk.red('✗ No'));
35
+ }
36
+ }
37
+ catch {
38
+ console.log(chalk.white('\nRepair History:'));
39
+ console.log(chalk.gray(' No repairs recorded yet'));
40
+ }
41
+ console.log('');
42
+ }
43
+ catch (error) {
44
+ console.error(chalk.red(`Error: ${error.message}`));
45
+ process.exit(1);
46
+ }
47
+ }
48
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { MonitorConfig, RecoveryConfig, AIClientConfig } from '../types';
2
+ export declare const defaultMonitorConfig: MonitorConfig;
3
+ export declare const defaultRecoveryConfig: RecoveryConfig;
4
+ export declare const defaultAIConfig: AIClientConfig;
5
+ //# sourceMappingURL=default.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../src/config/default.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAExE,eAAO,MAAM,oBAAoB,EAAE,aAOlC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,cAQnC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAG7B,CAAC"}
@@ -0,0 +1,22 @@
1
+ export const defaultMonitorConfig = {
2
+ gatewayUrl: process.env.OPENCLAW_GATEWAY_URL || 'http://localhost:10002',
3
+ healthEndpoint: process.env.OPENCLAW_HEALTH_ENDPOINT || '/',
4
+ checkInterval: parseInt(process.env.HEALTH_CHECK_INTERVAL || '30000', 10),
5
+ timeout: parseInt(process.env.HEALTH_CHECK_TIMEOUT || '10000', 10),
6
+ maxRetries: parseInt(process.env.MAX_RETRY_ATTEMPTS || '3', 10),
7
+ failureThreshold: parseInt(process.env.FAILURE_THRESHOLD || '3', 10),
8
+ };
9
+ export const defaultRecoveryConfig = {
10
+ useGitTracking: process.env.USE_GIT_TRACKING === 'true',
11
+ useGitHubCli: process.env.USE_GITHUB_CLI === 'true',
12
+ gitCommitPrefix: process.env.GIT_COMMIT_MESSAGE_PREFIX || '[AutoFix]',
13
+ backupBeforeChange: process.env.BACKUP_CONFIG_BEFORE_CHANGE !== 'false',
14
+ openclawConfigPath: process.env.OPENCLAW_CONFIG_PATH || '~/.openclaw',
15
+ maxRecoveryRetries: parseInt(process.env.MAX_RECOVERY_RETRIES || '3', 10),
16
+ recoveryCooldownMs: parseInt(process.env.RECOVERY_COOLDOWN_MS || '300000', 10), // 5 minutes
17
+ };
18
+ export const defaultAIConfig = {
19
+ provider: process.env.AI_PROVIDER || 'claude',
20
+ timeout: 300000, // 5 minutes for AI to complete the fix
21
+ };
22
+ //# sourceMappingURL=default.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default.js","sourceRoot":"","sources":["../../src/config/default.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,oBAAoB,GAAkB;IACjD,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,wBAAwB;IACxE,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,GAAG;IAC3D,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,EAAE,EAAE,CAAC;IACzE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO,EAAE,EAAE,CAAC;IAClE,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,GAAG,EAAE,EAAE,CAAC;IAC/D,gBAAgB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,GAAG,EAAE,EAAE,CAAC;CACrE,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAmB;IACnD,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,MAAM;IACvD,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM;IACnD,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,WAAW;IACrE,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B,KAAK,OAAO;IACvE,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,aAAa;IACrE,kBAAkB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,GAAG,EAAE,EAAE,CAAC;IACzE,kBAAkB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,QAAQ,EAAE,EAAE,CAAC,EAAE,YAAY;CAC7F,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAmB;IAC7C,QAAQ,EAAG,OAAO,CAAC,GAAG,CAAC,WAA0C,IAAI,QAAQ;IAC7E,OAAO,EAAE,MAAM,EAAE,uCAAuC;CACzD,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { MonitorConfig, AIClientConfig, RecoveryConfig } from '../types';
2
+ export declare class GatewayMonitor {
3
+ private healthChecker;
4
+ private aiOrchestrator;
5
+ private autoFixer;
6
+ private cronJob;
7
+ private isRecovering;
8
+ private consecutiveRecoveryFailures;
9
+ private lastRecoveryEndTime;
10
+ private maxRecoveryRetries;
11
+ private recoveryCooldownMs;
12
+ constructor(monitorConfig: MonitorConfig, aiConfig: AIClientConfig, recoveryConfig: RecoveryConfig);
13
+ start(): Promise<void>;
14
+ private performHealthCheck;
15
+ private triggerRecovery;
16
+ private convertMsToCron;
17
+ stop(): void;
18
+ }
19
+ //# sourceMappingURL=gateway-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-monitor.d.ts","sourceRoot":"","sources":["../../src/healthcheck/gateway-monitor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAExE,qBAAa,cAAc;IACzB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,2BAA2B,CAAa;IAChD,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,kBAAkB,CAAS;gBAGjC,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,cAAc,EACxB,cAAc,EAAE,cAAc;IAS1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAoBd,kBAAkB;YAkClB,eAAe;IAqC7B,OAAO,CAAC,eAAe;IASvB,IAAI,IAAI,IAAI;CAMb"}
@@ -0,0 +1,116 @@
1
+ import cron from 'node-cron';
2
+ import { HealthChecker } from './health-checker.js';
3
+ import { AIOrchestrator } from '../ai/ai-orchestrator.js';
4
+ import { AutoFixer } from '../recovery/auto-fixer.js';
5
+ import logger from '../utils/logger.js';
6
+ export class GatewayMonitor {
7
+ healthChecker;
8
+ aiOrchestrator;
9
+ autoFixer;
10
+ cronJob = null;
11
+ isRecovering = false;
12
+ consecutiveRecoveryFailures = 0;
13
+ lastRecoveryEndTime = 0;
14
+ maxRecoveryRetries;
15
+ recoveryCooldownMs;
16
+ constructor(monitorConfig, aiConfig, recoveryConfig) {
17
+ this.healthChecker = new HealthChecker(monitorConfig);
18
+ this.aiOrchestrator = new AIOrchestrator(aiConfig, recoveryConfig);
19
+ this.autoFixer = new AutoFixer(recoveryConfig);
20
+ this.maxRecoveryRetries = recoveryConfig.maxRecoveryRetries;
21
+ this.recoveryCooldownMs = recoveryConfig.recoveryCooldownMs;
22
+ }
23
+ async start() {
24
+ logger.info('Starting Gateway Monitor');
25
+ // Initialize AI orchestrator
26
+ await this.aiOrchestrator.initialize();
27
+ // Run initial health check
28
+ await this.performHealthCheck();
29
+ // Schedule periodic health checks
30
+ const intervalMs = this.healthChecker['config'].checkInterval;
31
+ const cronExpression = this.convertMsToCron(intervalMs);
32
+ this.cronJob = cron.schedule(cronExpression, async () => {
33
+ await this.performHealthCheck();
34
+ });
35
+ logger.info('Gateway Monitor started', { interval: intervalMs });
36
+ }
37
+ async performHealthCheck() {
38
+ if (this.isRecovering) {
39
+ logger.info('Recovery in progress, skipping health check');
40
+ return;
41
+ }
42
+ if (this.consecutiveRecoveryFailures >= this.maxRecoveryRetries) {
43
+ logger.warn('Max recovery retries reached, manual intervention required', {
44
+ consecutiveFailures: this.consecutiveRecoveryFailures,
45
+ maxRetries: this.maxRecoveryRetries,
46
+ });
47
+ return;
48
+ }
49
+ const cooldownRemaining = this.lastRecoveryEndTime + this.recoveryCooldownMs - Date.now();
50
+ if (cooldownRemaining > 0) {
51
+ logger.info('Recovery cooldown active, skipping health check', {
52
+ cooldownRemainingMs: cooldownRemaining,
53
+ });
54
+ return;
55
+ }
56
+ const result = await this.healthChecker.check();
57
+ if (!result.healthy && this.healthChecker.shouldTriggerRecovery()) {
58
+ logger.warn('Health check threshold exceeded, triggering recovery', {
59
+ consecutiveFailures: this.healthChecker.getConsecutiveFailures(),
60
+ recoveryAttempt: this.consecutiveRecoveryFailures + 1,
61
+ maxRetries: this.maxRecoveryRetries,
62
+ });
63
+ await this.triggerRecovery(result.error || 'Unknown error');
64
+ }
65
+ }
66
+ async triggerRecovery(error) {
67
+ this.isRecovering = true;
68
+ try {
69
+ logger.info('Starting AI-powered recovery process', { error });
70
+ // AI directly diagnoses and fixes the problem
71
+ const diagnosis = await this.aiOrchestrator.diagnoseAndFix(error);
72
+ logger.info('AI diagnosis and fix completed', diagnosis);
73
+ // Record the fix (AI already applied it)
74
+ const recovery = await this.autoFixer.recordFix(diagnosis);
75
+ logger.info('Fix recorded', recovery);
76
+ if (recovery.success) {
77
+ this.healthChecker.reset();
78
+ this.consecutiveRecoveryFailures = 0;
79
+ logger.info('Recovery successful, resetting failure counter');
80
+ }
81
+ else {
82
+ this.consecutiveRecoveryFailures++;
83
+ logger.error('Recovery verification failed', {
84
+ errors: recovery.errors,
85
+ consecutiveFailures: this.consecutiveRecoveryFailures,
86
+ });
87
+ }
88
+ }
89
+ catch (error) {
90
+ this.consecutiveRecoveryFailures++;
91
+ logger.error('Recovery process failed', {
92
+ error: error.message,
93
+ consecutiveFailures: this.consecutiveRecoveryFailures,
94
+ });
95
+ }
96
+ finally {
97
+ this.isRecovering = false;
98
+ this.lastRecoveryEndTime = Date.now();
99
+ }
100
+ }
101
+ convertMsToCron(ms) {
102
+ const seconds = Math.floor(ms / 1000);
103
+ if (seconds < 60) {
104
+ return `*/${seconds} * * * * *`;
105
+ }
106
+ const minutes = Math.floor(seconds / 60);
107
+ return `*/${minutes} * * * *`;
108
+ }
109
+ stop() {
110
+ if (this.cronJob) {
111
+ this.cronJob.stop();
112
+ logger.info('Gateway Monitor stopped');
113
+ }
114
+ }
115
+ }
116
+ //# sourceMappingURL=gateway-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-monitor.js","sourceRoot":"","sources":["../../src/healthcheck/gateway-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,MAAM,MAAM,mBAAmB,CAAC;AAGvC,MAAM,OAAO,cAAc;IACjB,aAAa,CAAgB;IAC7B,cAAc,CAAiB;IAC/B,SAAS,CAAY;IACrB,OAAO,GAA8B,IAAI,CAAC;IAC1C,YAAY,GAAY,KAAK,CAAC;IAC9B,2BAA2B,GAAW,CAAC,CAAC;IACxC,mBAAmB,GAAW,CAAC,CAAC;IAChC,kBAAkB,CAAS;IAC3B,kBAAkB,CAAS;IAEnC,YACE,aAA4B,EAC5B,QAAwB,EACxB,cAA8B;QAE9B,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,aAAa,CAAC,CAAC;QACtD,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACnE,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC,cAAc,CAAC,CAAC;QAC/C,IAAI,CAAC,kBAAkB,GAAG,cAAc,CAAC,kBAAkB,CAAC;QAC5D,IAAI,CAAC,kBAAkB,GAAG,cAAc,CAAC,kBAAkB,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAExC,6BAA6B;QAC7B,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC;QAEvC,2BAA2B;QAC3B,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAEhC,kCAAkC;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC;QAC9D,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QAExD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,IAAI,EAAE;YACtD,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;IACnE,CAAC;IAEO,KAAK,CAAC,kBAAkB;QAC9B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,2BAA2B,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAChE,MAAM,CAAC,IAAI,CAAC,4DAA4D,EAAE;gBACxE,mBAAmB,EAAE,IAAI,CAAC,2BAA2B;gBACrD,UAAU,EAAE,IAAI,CAAC,kBAAkB;aACpC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1F,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,iDAAiD,EAAE;gBAC7D,mBAAmB,EAAE,iBAAiB;aACvC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAEhD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,aAAa,CAAC,qBAAqB,EAAE,EAAE,CAAC;YAClE,MAAM,CAAC,IAAI,CAAC,sDAAsD,EAAE;gBAClE,mBAAmB,EAAE,IAAI,CAAC,aAAa,CAAC,sBAAsB,EAAE;gBAChE,eAAe,EAAE,IAAI,CAAC,2BAA2B,GAAG,CAAC;gBACrD,UAAU,EAAE,IAAI,CAAC,kBAAkB;aACpC,CAAC,CAAC;YACH,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,KAAa;QACzC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzB,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YAE/D,8CAA8C;YAC9C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YAClE,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE,SAAS,CAAC,CAAC;YAEzD,yCAAyC;YACzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YAC3D,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;YAEtC,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;gBAC3B,IAAI,CAAC,2BAA2B,GAAG,CAAC,CAAC;gBACrC,MAAM,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;YAChE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,2BAA2B,EAAE,CAAC;gBACnC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE;oBAC3C,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,mBAAmB,EAAE,IAAI,CAAC,2BAA2B;iBACtD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,CAAC,2BAA2B,EAAE,CAAC;YACnC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE;gBACtC,KAAK,EAAE,KAAK,CAAC,OAAO;gBACpB,mBAAmB,EAAE,IAAI,CAAC,2BAA2B;aACtD,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;YAC1B,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACxC,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,EAAU;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QACtC,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;YACjB,OAAO,KAAK,OAAO,YAAY,CAAC;QAClC,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACzC,OAAO,KAAK,OAAO,UAAU,CAAC;IAChC,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import { HealthCheckResult, MonitorConfig } from '../types';
2
+ export declare class HealthChecker {
3
+ private config;
4
+ private consecutiveFailures;
5
+ constructor(config: MonitorConfig);
6
+ check(): Promise<HealthCheckResult>;
7
+ shouldTriggerRecovery(): boolean;
8
+ getConsecutiveFailures(): number;
9
+ reset(): void;
10
+ }
11
+ //# sourceMappingURL=health-checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-checker.d.ts","sourceRoot":"","sources":["../../src/healthcheck/health-checker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE3D,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,mBAAmB,CAAa;gBAE5B,MAAM,EAAE,aAAa;IAI3B,KAAK,IAAI,OAAO,CAAC,iBAAiB,CAAC;IA+CzC,qBAAqB,IAAI,OAAO;IAIhC,sBAAsB,IAAI,MAAM;IAIhC,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,60 @@
1
+ import axios, { AxiosError } from 'axios';
2
+ import logger from '../utils/logger.js';
3
+ export class HealthChecker {
4
+ config;
5
+ consecutiveFailures = 0;
6
+ constructor(config) {
7
+ this.config = config;
8
+ }
9
+ async check() {
10
+ const url = `${this.config.gatewayUrl}${this.config.healthEndpoint}`;
11
+ const startTime = Date.now();
12
+ try {
13
+ const response = await axios.get(url, {
14
+ timeout: this.config.timeout,
15
+ validateStatus: (status) => status < 500,
16
+ });
17
+ const responseTime = Date.now() - startTime;
18
+ const healthy = response.status >= 200 && response.status < 300;
19
+ if (healthy) {
20
+ this.consecutiveFailures = 0;
21
+ }
22
+ else {
23
+ this.consecutiveFailures++;
24
+ }
25
+ const result = {
26
+ healthy,
27
+ timestamp: new Date(),
28
+ endpoint: url,
29
+ responseTime,
30
+ statusCode: response.status,
31
+ };
32
+ logger.info('Health check completed', result);
33
+ return result;
34
+ }
35
+ catch (error) {
36
+ this.consecutiveFailures++;
37
+ const responseTime = Date.now() - startTime;
38
+ const result = {
39
+ healthy: false,
40
+ timestamp: new Date(),
41
+ endpoint: url,
42
+ responseTime,
43
+ error: error instanceof AxiosError ? error.message : String(error),
44
+ statusCode: error instanceof AxiosError ? error.response?.status : undefined,
45
+ };
46
+ logger.error('Health check failed', result);
47
+ return result;
48
+ }
49
+ }
50
+ shouldTriggerRecovery() {
51
+ return this.consecutiveFailures >= this.config.failureThreshold;
52
+ }
53
+ getConsecutiveFailures() {
54
+ return this.consecutiveFailures;
55
+ }
56
+ reset() {
57
+ this.consecutiveFailures = 0;
58
+ }
59
+ }
60
+ //# sourceMappingURL=health-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-checker.js","sourceRoot":"","sources":["../../src/healthcheck/health-checker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,MAAM,MAAM,mBAAmB,CAAC;AAGvC,MAAM,OAAO,aAAa;IAChB,MAAM,CAAgB;IACtB,mBAAmB,GAAW,CAAC,CAAC;IAExC,YAAY,MAAqB;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QACrE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;gBACpC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;gBAC5B,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,GAAG,GAAG;aACzC,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC;YAEhE,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,CAAC;YAED,MAAM,MAAM,GAAsB;gBAChC,OAAO;gBACP,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,QAAQ,EAAE,GAAG;gBACb,YAAY;gBACZ,UAAU,EAAE,QAAQ,CAAC,MAAM;aAC5B,CAAC;YAEF,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;YAC9C,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAE5C,MAAM,MAAM,GAAsB;gBAChC,OAAO,EAAE,KAAK;gBACd,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,QAAQ,EAAE,GAAG;gBACb,YAAY;gBACZ,KAAK,EAAE,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBAClE,UAAU,EAAE,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS;aAC7E,CAAC;YAEF,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;YAC5C,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,qBAAqB;QACnB,OAAO,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC;IAClE,CAAC;IAED,sBAAsB;QACpB,OAAO,IAAI,CAAC,mBAAmB,CAAC;IAClC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;IAC/B,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ import 'dotenv/config';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC"}