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.
- package/.claude/settings.local.json +7 -0
- package/.dockerignore +21 -0
- package/.env.example +31 -0
- package/.eslintrc.json +26 -0
- package/.prettierrc.json +9 -0
- package/CHANGELOG.md +93 -0
- package/Dockerfile +47 -0
- package/README.md +408 -0
- package/build.sh +33 -0
- package/dist/ai/ai-orchestrator.d.ts +11 -0
- package/dist/ai/ai-orchestrator.d.ts.map +1 -0
- package/dist/ai/ai-orchestrator.js +85 -0
- package/dist/ai/ai-orchestrator.js.map +1 -0
- package/dist/ai/cli-client.d.ts +17 -0
- package/dist/ai/cli-client.d.ts.map +1 -0
- package/dist/ai/cli-client.js +239 -0
- package/dist/ai/cli-client.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +33 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/config.d.ts +7 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +52 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +205 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/start.d.ts +6 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +49 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +48 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/config/default.d.ts +5 -0
- package/dist/config/default.d.ts.map +1 -0
- package/dist/config/default.js +22 -0
- package/dist/config/default.js.map +1 -0
- package/dist/healthcheck/gateway-monitor.d.ts +19 -0
- package/dist/healthcheck/gateway-monitor.d.ts.map +1 -0
- package/dist/healthcheck/gateway-monitor.js +116 -0
- package/dist/healthcheck/gateway-monitor.js.map +1 -0
- package/dist/healthcheck/health-checker.d.ts +11 -0
- package/dist/healthcheck/health-checker.d.ts.map +1 -0
- package/dist/healthcheck/health-checker.js +60 -0
- package/dist/healthcheck/health-checker.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/recovery/auto-fixer.d.ts +16 -0
- package/dist/recovery/auto-fixer.d.ts.map +1 -0
- package/dist/recovery/auto-fixer.js +162 -0
- package/dist/recovery/auto-fixer.js.map +1 -0
- package/dist/recovery/change-recorder.d.ts +8 -0
- package/dist/recovery/change-recorder.d.ts.map +1 -0
- package/dist/recovery/change-recorder.js +41 -0
- package/dist/recovery/change-recorder.js.map +1 -0
- package/dist/setup/config-initializer.d.ts +13 -0
- package/dist/setup/config-initializer.d.ts.map +1 -0
- package/dist/setup/config-initializer.js +46 -0
- package/dist/setup/config-initializer.js.map +1 -0
- package/dist/setup/config-loader.d.ts +9 -0
- package/dist/setup/config-loader.d.ts.map +1 -0
- package/dist/setup/config-loader.js +17 -0
- package/dist/setup/config-loader.js.map +1 -0
- package/dist/setup/git-initializer.d.ts +15 -0
- package/dist/setup/git-initializer.d.ts.map +1 -0
- package/dist/setup/git-initializer.js +189 -0
- package/dist/setup/git-initializer.js.map +1 -0
- package/dist/setup/safe-config-generator.d.ts +9 -0
- package/dist/setup/safe-config-generator.d.ts.map +1 -0
- package/dist/setup/safe-config-generator.js +85 -0
- package/dist/setup/safe-config-generator.js.map +1 -0
- package/dist/types/index.d.ts +60 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/executor.d.ts +17 -0
- package/dist/utils/executor.d.ts.map +1 -0
- package/dist/utils/executor.js +57 -0
- package/dist/utils/executor.js.map +1 -0
- package/dist/utils/git-manager.d.ts +14 -0
- package/dist/utils/git-manager.d.ts.map +1 -0
- package/dist/utils/git-manager.js +116 -0
- package/dist/utils/git-manager.js.map +1 -0
- package/dist/utils/github-cli.d.ts +9 -0
- package/dist/utils/github-cli.d.ts.map +1 -0
- package/dist/utils/github-cli.js +31 -0
- package/dist/utils/github-cli.js.map +1 -0
- package/dist/utils/logger.d.ts +4 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +26 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/paths.d.ts +6 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +19 -0
- package/dist/utils/paths.js.map +1 -0
- package/docker-compose.yml +43 -0
- package/nodemon.json +9 -0
- package/package.json +59 -0
- package/prompts/fix-openclaw.md +202 -0
- package/scripts/setup.sh +105 -0
- package/src/ai/ai-orchestrator.ts +95 -0
- package/src/ai/cli-client.ts +296 -0
- package/src/cli.ts +40 -0
- package/src/commands/config.ts +57 -0
- package/src/commands/init.ts +239 -0
- package/src/commands/start.ts +75 -0
- package/src/commands/status.ts +79 -0
- package/src/config/default.ts +25 -0
- package/src/healthcheck/gateway-monitor.ts +137 -0
- package/src/healthcheck/health-checker.ts +71 -0
- package/src/index.ts +48 -0
- package/src/recovery/auto-fixer.ts +184 -0
- package/src/recovery/change-recorder.ts +46 -0
- package/src/setup/config-initializer.ts +63 -0
- package/src/setup/config-loader.ts +25 -0
- package/src/setup/git-initializer.ts +203 -0
- package/src/setup/safe-config-generator.ts +100 -0
- package/src/types/index.ts +67 -0
- package/src/utils/executor.ts +75 -0
- package/src/utils/git-manager.ts +121 -0
- package/src/utils/github-cli.ts +37 -0
- package/src/utils/logger.ts +39 -0
- package/src/utils/paths.ts +25 -0
- package/tsconfig.json +29 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import logger from '../utils/logger.js';
|
|
4
|
+
export class SafeConfigGenerator {
|
|
5
|
+
configPath;
|
|
6
|
+
constructor(configPath) {
|
|
7
|
+
this.configPath = configPath;
|
|
8
|
+
}
|
|
9
|
+
async generate() {
|
|
10
|
+
const openclawJsonPath = path.join(this.configPath, 'openclaw.json');
|
|
11
|
+
const safeJsonPath = path.join(this.configPath, 'openclaw.safe.json');
|
|
12
|
+
try {
|
|
13
|
+
// Read original config
|
|
14
|
+
const content = await fs.readFile(openclawJsonPath, 'utf-8');
|
|
15
|
+
const config = JSON.parse(content);
|
|
16
|
+
// Redact sensitive data
|
|
17
|
+
const safeConfig = this.redactSensitiveData(config);
|
|
18
|
+
// Write safe config
|
|
19
|
+
await fs.writeFile(safeJsonPath, JSON.stringify(safeConfig, null, 2), 'utf-8');
|
|
20
|
+
logger.info('Safe configuration generated', { path: safeJsonPath });
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
logger.error('Failed to generate safe configuration', { error: error.message });
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async update() {
|
|
28
|
+
// Same as generate - always regenerate from openclaw.json
|
|
29
|
+
await this.generate();
|
|
30
|
+
}
|
|
31
|
+
redactSensitiveData(obj) {
|
|
32
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
33
|
+
return obj;
|
|
34
|
+
}
|
|
35
|
+
if (Array.isArray(obj)) {
|
|
36
|
+
return obj.map((item) => this.redactSensitiveData(item));
|
|
37
|
+
}
|
|
38
|
+
const result = {};
|
|
39
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
40
|
+
const lowerKey = key.toLowerCase();
|
|
41
|
+
// Check if key indicates sensitive data
|
|
42
|
+
if (lowerKey.includes('key') ||
|
|
43
|
+
lowerKey.includes('token') ||
|
|
44
|
+
lowerKey.includes('secret') ||
|
|
45
|
+
lowerKey.includes('password') ||
|
|
46
|
+
lowerKey.includes('apikey') ||
|
|
47
|
+
lowerKey.includes('api_key') ||
|
|
48
|
+
lowerKey === 'bearer') {
|
|
49
|
+
// Replace with placeholder
|
|
50
|
+
result[key] = this.getPlaceholder(lowerKey, value);
|
|
51
|
+
}
|
|
52
|
+
else if (typeof value === 'object' && value !== null) {
|
|
53
|
+
// Recursively process nested objects
|
|
54
|
+
result[key] = this.redactSensitiveData(value);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// Keep non-sensitive values
|
|
58
|
+
result[key] = value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
getPlaceholder(key, value) {
|
|
64
|
+
if (typeof value !== 'string') {
|
|
65
|
+
return '<REDACTED>';
|
|
66
|
+
}
|
|
67
|
+
if (key.includes('apikey') || key.includes('api_key')) {
|
|
68
|
+
return '<YOUR_API_KEY_HERE>';
|
|
69
|
+
}
|
|
70
|
+
if (key.includes('token')) {
|
|
71
|
+
return '<YOUR_TOKEN_HERE>';
|
|
72
|
+
}
|
|
73
|
+
if (key.includes('secret')) {
|
|
74
|
+
return '<YOUR_SECRET_HERE>';
|
|
75
|
+
}
|
|
76
|
+
if (key.includes('password')) {
|
|
77
|
+
return '<YOUR_PASSWORD_HERE>';
|
|
78
|
+
}
|
|
79
|
+
if (key.includes('key')) {
|
|
80
|
+
return '<YOUR_KEY_HERE>';
|
|
81
|
+
}
|
|
82
|
+
return '<REDACTED>';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=safe-config-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-config-generator.js","sourceRoot":"","sources":["../../src/setup/safe-config-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface HealthCheckResult {
|
|
2
|
+
healthy: boolean;
|
|
3
|
+
timestamp: Date;
|
|
4
|
+
endpoint: string;
|
|
5
|
+
responseTime?: number;
|
|
6
|
+
error?: string;
|
|
7
|
+
statusCode?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface DiagnosisResult {
|
|
10
|
+
issue: string;
|
|
11
|
+
rootCause: string;
|
|
12
|
+
suggestedFix: string;
|
|
13
|
+
commands: string[];
|
|
14
|
+
configChanges?: ConfigChange[];
|
|
15
|
+
confidence: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ConfigChange {
|
|
18
|
+
file: string;
|
|
19
|
+
path: string;
|
|
20
|
+
oldValue: unknown;
|
|
21
|
+
newValue: unknown;
|
|
22
|
+
reason: string;
|
|
23
|
+
}
|
|
24
|
+
export interface RecoveryResult {
|
|
25
|
+
success: boolean;
|
|
26
|
+
actions: string[];
|
|
27
|
+
errors?: string[];
|
|
28
|
+
configChanges?: ConfigChange[];
|
|
29
|
+
restartRequired: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface ChangeRecord {
|
|
32
|
+
timestamp: Date;
|
|
33
|
+
trigger: string;
|
|
34
|
+
diagnosis: DiagnosisResult;
|
|
35
|
+
recovery: RecoveryResult;
|
|
36
|
+
gitCommit?: string;
|
|
37
|
+
}
|
|
38
|
+
export type AIProvider = 'claude' | 'kimi';
|
|
39
|
+
export interface AIClientConfig {
|
|
40
|
+
provider: AIProvider;
|
|
41
|
+
timeout?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface MonitorConfig {
|
|
44
|
+
gatewayUrl: string;
|
|
45
|
+
healthEndpoint: string;
|
|
46
|
+
checkInterval: number;
|
|
47
|
+
timeout: number;
|
|
48
|
+
maxRetries: number;
|
|
49
|
+
failureThreshold: number;
|
|
50
|
+
}
|
|
51
|
+
export interface RecoveryConfig {
|
|
52
|
+
useGitTracking: boolean;
|
|
53
|
+
useGitHubCli: boolean;
|
|
54
|
+
gitCommitPrefix: string;
|
|
55
|
+
backupBeforeChange: boolean;
|
|
56
|
+
openclawConfigPath: string;
|
|
57
|
+
maxRecoveryRetries: number;
|
|
58
|
+
recoveryCooldownMs: number;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,UAAU,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;CAC5B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface CommandResult {
|
|
2
|
+
stdout: string;
|
|
3
|
+
stderr: string;
|
|
4
|
+
exitCode: number;
|
|
5
|
+
success: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare class CommandExecutor {
|
|
8
|
+
private timeout;
|
|
9
|
+
constructor(timeout?: number);
|
|
10
|
+
execute(command: string, cwd?: string): Promise<CommandResult>;
|
|
11
|
+
executeOpenClawCommand(subcommand: string): Promise<CommandResult>;
|
|
12
|
+
restartGateway(): Promise<CommandResult>;
|
|
13
|
+
getGatewayStatus(): Promise<CommandResult>;
|
|
14
|
+
getGatewayLogs(lines?: number): Promise<CommandResult>;
|
|
15
|
+
}
|
|
16
|
+
export declare const executor: CommandExecutor;
|
|
17
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/utils/executor.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,MAAc;IAI7B,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAmC9D,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAKlE,cAAc,IAAI,OAAO,CAAC,aAAa,CAAC;IAKxC,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC;IAI1C,cAAc,CAAC,KAAK,GAAE,MAAY,GAAG,OAAO,CAAC,aAAa,CAAC;CAGlE;AAED,eAAO,MAAM,QAAQ,iBAAwB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { exec } from 'child_process';
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
import logger from './logger.js';
|
|
4
|
+
const execAsync = promisify(exec);
|
|
5
|
+
export class CommandExecutor {
|
|
6
|
+
timeout;
|
|
7
|
+
constructor(timeout = 30000) {
|
|
8
|
+
this.timeout = timeout;
|
|
9
|
+
}
|
|
10
|
+
async execute(command, cwd) {
|
|
11
|
+
logger.info('Executing command', { command, cwd });
|
|
12
|
+
try {
|
|
13
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
14
|
+
timeout: this.timeout,
|
|
15
|
+
cwd,
|
|
16
|
+
shell: '/bin/bash',
|
|
17
|
+
});
|
|
18
|
+
logger.info('Command executed successfully', { command, stdout, stderr });
|
|
19
|
+
return {
|
|
20
|
+
stdout: stdout.trim(),
|
|
21
|
+
stderr: stderr.trim(),
|
|
22
|
+
exitCode: 0,
|
|
23
|
+
success: true,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
logger.error('Command execution failed', {
|
|
28
|
+
command,
|
|
29
|
+
error: error.message,
|
|
30
|
+
stdout: error.stdout,
|
|
31
|
+
stderr: error.stderr,
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
stdout: error.stdout?.trim() || '',
|
|
35
|
+
stderr: error.stderr?.trim() || error.message,
|
|
36
|
+
exitCode: error.code || 1,
|
|
37
|
+
success: false,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async executeOpenClawCommand(subcommand) {
|
|
42
|
+
const command = `openclaw ${subcommand}`;
|
|
43
|
+
return this.execute(command);
|
|
44
|
+
}
|
|
45
|
+
async restartGateway() {
|
|
46
|
+
logger.info('Attempting to restart OpenClaw gateway');
|
|
47
|
+
return this.executeOpenClawCommand('gateway restart');
|
|
48
|
+
}
|
|
49
|
+
async getGatewayStatus() {
|
|
50
|
+
return this.executeOpenClawCommand('gateway status');
|
|
51
|
+
}
|
|
52
|
+
async getGatewayLogs(lines = 100) {
|
|
53
|
+
return this.executeOpenClawCommand(`gateway logs --lines ${lines}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export const executor = new CommandExecutor();
|
|
57
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/utils/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AASlC,MAAM,OAAO,eAAe;IAClB,OAAO,CAAS;IAExB,YAAY,UAAkB,KAAK;QACjC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,GAAY;QACzC,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QAEnD,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE;gBAClD,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,GAAG;gBACH,KAAK,EAAE,WAAW;aACnB,CAAC,CAAC;YAEH,MAAM,CAAC,IAAI,CAAC,+BAA+B,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAE1E,OAAO;gBACL,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;gBACrB,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;gBACrB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE;gBACvC,OAAO;gBACP,KAAK,EAAE,KAAK,CAAC,OAAO;gBACpB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,MAAM,EAAE,KAAK,CAAC,MAAM;aACrB,CAAC,CAAC;YAEH,OAAO;gBACL,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE;gBAClC,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,CAAC,OAAO;gBAC7C,QAAQ,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;gBACzB,OAAO,EAAE,KAAK;aACf,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,UAAkB;QAC7C,MAAM,OAAO,GAAG,YAAY,UAAU,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,OAAO,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAAgB,GAAG;QACtC,OAAO,IAAI,CAAC,sBAAsB,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;IACtE,CAAC;CACF;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class GitManager {
|
|
2
|
+
private git;
|
|
3
|
+
private repoPath;
|
|
4
|
+
constructor(repoPath: string);
|
|
5
|
+
init(): Promise<void>;
|
|
6
|
+
private createGitignore;
|
|
7
|
+
commit(message: string, files?: string[]): Promise<string>;
|
|
8
|
+
createBackup(files: string[]): Promise<void>;
|
|
9
|
+
getDiff(file?: string): Promise<string>;
|
|
10
|
+
hasRemote(): Promise<boolean>;
|
|
11
|
+
push(): Promise<boolean>;
|
|
12
|
+
getLog(maxCount?: number): Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=git-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-manager.d.ts","sourceRoot":"","sources":["../../src/utils/git-manager.ts"],"names":[],"mappings":"AAKA,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,EAAE,MAAM;IAKtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAgBb,eAAe;IAYvB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAuB1D,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB5C,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUvC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAS7B,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAWxB,MAAM,CAAC,QAAQ,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,CAAC;CASrD"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import simpleGit from 'simple-git';
|
|
2
|
+
import logger from './logger.js';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import fs from 'fs/promises';
|
|
5
|
+
export class GitManager {
|
|
6
|
+
git;
|
|
7
|
+
repoPath;
|
|
8
|
+
constructor(repoPath) {
|
|
9
|
+
this.repoPath = repoPath;
|
|
10
|
+
this.git = simpleGit(repoPath);
|
|
11
|
+
}
|
|
12
|
+
async init() {
|
|
13
|
+
try {
|
|
14
|
+
const isRepo = await this.git.checkIsRepo();
|
|
15
|
+
if (!isRepo) {
|
|
16
|
+
logger.info('Initializing git repository', { path: this.repoPath });
|
|
17
|
+
await this.git.init();
|
|
18
|
+
await this.createGitignore();
|
|
19
|
+
await this.git.add('.gitignore');
|
|
20
|
+
await this.git.commit('Initial commit: Setup config tracking');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
logger.error('Failed to initialize git repository', { error: error.message });
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async createGitignore() {
|
|
29
|
+
const gitignorePath = path.join(this.repoPath, '.gitignore');
|
|
30
|
+
const content = `# Ignore sensitive files
|
|
31
|
+
*.key
|
|
32
|
+
*.pem
|
|
33
|
+
*.secret
|
|
34
|
+
secrets/
|
|
35
|
+
*.env
|
|
36
|
+
`;
|
|
37
|
+
await fs.writeFile(gitignorePath, content, 'utf-8');
|
|
38
|
+
}
|
|
39
|
+
async commit(message, files) {
|
|
40
|
+
try {
|
|
41
|
+
if (files && files.length > 0) {
|
|
42
|
+
await this.git.add(files);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
await this.git.add('.');
|
|
46
|
+
}
|
|
47
|
+
const status = await this.git.status();
|
|
48
|
+
if (status.files.length === 0) {
|
|
49
|
+
logger.info('No changes to commit');
|
|
50
|
+
return '';
|
|
51
|
+
}
|
|
52
|
+
const result = await this.git.commit(message);
|
|
53
|
+
logger.info('Changes committed', { message, hash: result.commit });
|
|
54
|
+
return result.commit;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
logger.error('Failed to commit changes', { error: error.message });
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async createBackup(files) {
|
|
62
|
+
try {
|
|
63
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
64
|
+
const backupBranch = `backup-${timestamp}`;
|
|
65
|
+
const currentBranch = await this.git.revparse(['--abbrev-ref', 'HEAD']);
|
|
66
|
+
await this.git.checkoutBranch(backupBranch, currentBranch.trim());
|
|
67
|
+
await this.git.checkout(currentBranch.trim());
|
|
68
|
+
logger.info('Backup created', { branch: backupBranch, files });
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
logger.error('Failed to create backup', { error: error.message });
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async getDiff(file) {
|
|
76
|
+
try {
|
|
77
|
+
const diff = file ? await this.git.diff([file]) : await this.git.diff();
|
|
78
|
+
return diff;
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
logger.error('Failed to get diff', { error: error.message });
|
|
82
|
+
return '';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async hasRemote() {
|
|
86
|
+
try {
|
|
87
|
+
const remotes = await this.git.getRemotes();
|
|
88
|
+
return remotes.some((r) => r.name === 'origin');
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async push() {
|
|
95
|
+
try {
|
|
96
|
+
await this.git.push('origin', 'HEAD');
|
|
97
|
+
logger.info('Pushed to remote');
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
logger.warn('Failed to push to remote', { error: error.message });
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async getLog(maxCount = 10) {
|
|
106
|
+
try {
|
|
107
|
+
const log = await this.git.log({ maxCount });
|
|
108
|
+
return log.all.map((commit) => `${commit.hash.substring(0, 7)} - ${commit.message}`).join('\n');
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
logger.error('Failed to get log', { error: error.message });
|
|
112
|
+
return '';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=git-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-manager.js","sourceRoot":"","sources":["../../src/utils/git-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CommandResult } from './executor.js';
|
|
2
|
+
export declare class GitHubCli {
|
|
3
|
+
private executor;
|
|
4
|
+
constructor();
|
|
5
|
+
isInstalled(): Promise<boolean>;
|
|
6
|
+
isAuthenticated(): Promise<boolean>;
|
|
7
|
+
createRepoAndPush(repoName: string, localPath: string): Promise<CommandResult>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=github-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-cli.d.ts","sourceRoot":"","sources":["../../src/utils/github-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,aAAa,EAAE,MAAM,eAAe,CAAC;AAG/D,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAkB;;IAM5B,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAK/B,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAKnC,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC;CAa1B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { CommandExecutor } from './executor.js';
|
|
2
|
+
import logger from './logger.js';
|
|
3
|
+
export class GitHubCli {
|
|
4
|
+
executor;
|
|
5
|
+
constructor() {
|
|
6
|
+
this.executor = new CommandExecutor(60000);
|
|
7
|
+
}
|
|
8
|
+
async isInstalled() {
|
|
9
|
+
const result = await this.executor.execute('gh --version');
|
|
10
|
+
return result.success;
|
|
11
|
+
}
|
|
12
|
+
async isAuthenticated() {
|
|
13
|
+
const result = await this.executor.execute('gh auth status');
|
|
14
|
+
return result.success;
|
|
15
|
+
}
|
|
16
|
+
async createRepoAndPush(repoName, localPath) {
|
|
17
|
+
const command = `gh repo create ${repoName} --private --source="${localPath}" --remote=origin --push`;
|
|
18
|
+
const result = await this.executor.execute(command, localPath);
|
|
19
|
+
if (result.success) {
|
|
20
|
+
logger.info('GitHub repository created and pushed', { repoName });
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
logger.error('Failed to create GitHub repository', {
|
|
24
|
+
repoName,
|
|
25
|
+
stderr: result.stderr,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=github-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-cli.js","sourceRoot":"","sources":["../../src/utils/github-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAiB,MAAM,eAAe,CAAC;AAC/D,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,OAAO,SAAS;IACZ,QAAQ,CAAkB;IAElC;QACE,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC3D,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,QAAgB,EAChB,SAAiB;QAEjB,MAAM,OAAO,GAAG,kBAAkB,QAAQ,wBAAwB,SAAS,0BAA0B,CAAC;QACtG,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,oCAAoC,EAAE;gBACjD,QAAQ;gBACR,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAM9B,QAAA,MAAM,MAAM,gBAgBV,CAAC;AAgBH,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import winston from 'winston';
|
|
2
|
+
import { getLogFilePath } from '../utils/paths.js';
|
|
3
|
+
const logLevel = process.env.LOG_LEVEL || 'info';
|
|
4
|
+
const logFilePath = process.env.LOG_FILE_PATH || getLogFilePath();
|
|
5
|
+
const logger = winston.createLogger({
|
|
6
|
+
level: logLevel,
|
|
7
|
+
format: winston.format.combine(winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.errors({ stack: true }), winston.format.splat(), winston.format.json()),
|
|
8
|
+
defaultMeta: { service: 'openclaw-healthcheck' },
|
|
9
|
+
transports: [
|
|
10
|
+
new winston.transports.File({
|
|
11
|
+
filename: logFilePath.replace('.log', '-error.log'),
|
|
12
|
+
level: 'error',
|
|
13
|
+
}),
|
|
14
|
+
new winston.transports.File({ filename: logFilePath }),
|
|
15
|
+
],
|
|
16
|
+
});
|
|
17
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
18
|
+
logger.add(new winston.transports.Console({
|
|
19
|
+
format: winston.format.combine(winston.format.colorize(), winston.format.printf(({ level, message, timestamp, ...meta }) => {
|
|
20
|
+
const metaStr = Object.keys(meta).length ? JSON.stringify(meta, null, 2) : '';
|
|
21
|
+
return `${timestamp} [${level}]: ${message} ${metaStr}`;
|
|
22
|
+
})),
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
export default logger;
|
|
26
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC;AACjD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,cAAc,EAAE,CAAC;AAElE,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAClC,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAC5B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC,EAC3D,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACtC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EACtB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CACtB;IACD,WAAW,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE;IAChD,UAAU,EAAE;QACV,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YAC1B,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC;YACnD,KAAK,EAAE,OAAO;SACf,CAAC;QACF,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;KACvD;CACF,CAAC,CAAC;AAEH,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;IAC1C,MAAM,CAAC,GAAG,CACR,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;QAC7B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,EACzB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE;YAC/D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9E,OAAO,GAAG,SAAS,KAAK,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;QAC1D,CAAC,CAAC,CACH;KACF,CAAC,CACH,CAAC;AACJ,CAAC;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function getWatcherHome(): string;
|
|
2
|
+
export declare function getConfigPath(): string;
|
|
3
|
+
export declare function getLogsDir(): string;
|
|
4
|
+
export declare function getLogFilePath(): string;
|
|
5
|
+
export declare function getChangesFilePath(): string;
|
|
6
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAMA,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
const WATCHER_HOME = process.env.WATCHER_HOME || path.join(os.homedir(), '.openclaw-watcher');
|
|
4
|
+
export function getWatcherHome() {
|
|
5
|
+
return WATCHER_HOME;
|
|
6
|
+
}
|
|
7
|
+
export function getConfigPath() {
|
|
8
|
+
return path.join(WATCHER_HOME, 'config.json');
|
|
9
|
+
}
|
|
10
|
+
export function getLogsDir() {
|
|
11
|
+
return path.join(WATCHER_HOME, 'logs');
|
|
12
|
+
}
|
|
13
|
+
export function getLogFilePath() {
|
|
14
|
+
return path.join(WATCHER_HOME, 'logs', 'healthcheck.log');
|
|
15
|
+
}
|
|
16
|
+
export function getChangesFilePath() {
|
|
17
|
+
return path.join(WATCHER_HOME, 'logs', 'changes.json');
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,YAAY,GAChB,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,mBAAmB,CAAC,CAAC;AAE3E,MAAM,UAAU,cAAc;IAC5B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
openclaw-healthcheck:
|
|
5
|
+
build: .
|
|
6
|
+
container_name: openclaw-healthcheck
|
|
7
|
+
restart: unless-stopped
|
|
8
|
+
env_file:
|
|
9
|
+
- .env
|
|
10
|
+
environment:
|
|
11
|
+
- NODE_ENV=production
|
|
12
|
+
- TZ=Asia/Shanghai
|
|
13
|
+
volumes:
|
|
14
|
+
# Mount logs directory
|
|
15
|
+
- ./logs:/app/logs
|
|
16
|
+
# Mount OpenClaw config directory (adjust path as needed)
|
|
17
|
+
- ${OPENCLAW_CONFIG_PATH}:/opt/openclaw/config
|
|
18
|
+
# Mount git credentials if using git tracking
|
|
19
|
+
- ~/.gitconfig:/root/.gitconfig:ro
|
|
20
|
+
networks:
|
|
21
|
+
- openclaw-network
|
|
22
|
+
# If you need to connect to local OpenClaw gateway
|
|
23
|
+
extra_hosts:
|
|
24
|
+
- "host.docker.internal:host-gateway"
|
|
25
|
+
# Resource limits (optional)
|
|
26
|
+
deploy:
|
|
27
|
+
resources:
|
|
28
|
+
limits:
|
|
29
|
+
cpus: '1'
|
|
30
|
+
memory: 512M
|
|
31
|
+
reservations:
|
|
32
|
+
cpus: '0.5'
|
|
33
|
+
memory: 256M
|
|
34
|
+
# Logging
|
|
35
|
+
logging:
|
|
36
|
+
driver: "json-file"
|
|
37
|
+
options:
|
|
38
|
+
max-size: "10m"
|
|
39
|
+
max-file: "3"
|
|
40
|
+
|
|
41
|
+
networks:
|
|
42
|
+
openclaw-network:
|
|
43
|
+
driver: bridge
|
package/nodemon.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openclaw-watcher",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "AI-powered automated health monitoring and self-healing CLI for OpenClaw Gateway",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"openclaw-watcher": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "nodemon --exec tsx src/index.ts",
|
|
12
|
+
"build": "tsc && tsc-alias",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"lint": "eslint . --ext .ts",
|
|
15
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
16
|
+
"type-check": "tsc --noEmit",
|
|
17
|
+
"prepublishOnly": "pnpm build"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"openclaw",
|
|
21
|
+
"healthcheck",
|
|
22
|
+
"auto-healing",
|
|
23
|
+
"monitoring",
|
|
24
|
+
"ai-powered"
|
|
25
|
+
],
|
|
26
|
+
"author": "",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"axios": "^1.7.9",
|
|
30
|
+
"boxen": "^7.1.1",
|
|
31
|
+
"chalk": "^5.3.0",
|
|
32
|
+
"commander": "^11.1.0",
|
|
33
|
+
"dotenv": "^16.4.7",
|
|
34
|
+
"inquirer": "^9.2.12",
|
|
35
|
+
"js-yaml": "^4.1.0",
|
|
36
|
+
"node-cron": "^3.0.3",
|
|
37
|
+
"ora": "^7.0.1",
|
|
38
|
+
"simple-git": "^3.27.0",
|
|
39
|
+
"winston": "^3.17.0",
|
|
40
|
+
"zod": "^3.24.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/inquirer": "^9.0.9",
|
|
44
|
+
"@types/js-yaml": "^4.0.9",
|
|
45
|
+
"@types/node": "^22.10.5",
|
|
46
|
+
"@types/node-cron": "^3.0.11",
|
|
47
|
+
"@typescript-eslint/eslint-plugin": "^8.20.0",
|
|
48
|
+
"@typescript-eslint/parser": "^8.20.0",
|
|
49
|
+
"eslint": "^9.18.0",
|
|
50
|
+
"nodemon": "^3.1.9",
|
|
51
|
+
"prettier": "^3.4.2",
|
|
52
|
+
"tsc-alias": "^1.8.10",
|
|
53
|
+
"tsx": "^4.19.2",
|
|
54
|
+
"typescript": "^5.7.3"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=22.0.0"
|
|
58
|
+
}
|
|
59
|
+
}
|