ronds_ai 0.1.2 → 0.1.3

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/bin/ronds_ai.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const { runCodeRecord, saveCliError } = require('../lib/code_record');
4
+ const { runDoctor } = require('../lib/doctor');
4
5
  const { deployHooks } = require('../lib/hooks_deploy');
5
6
 
6
7
  const SUPPORTED_SOURCES = new Set(['claude', 'cursor']);
@@ -9,16 +10,19 @@ function printUsage() {
9
10
  process.stderr.write([
10
11
  'Usage:',
11
12
  ' ronds_ai record <tool>',
13
+ ' ronds_ai doctor <tool>',
12
14
  ' ronds_ai hooks deploy',
13
15
  '',
14
- 'Supported tools for record:',
16
+ 'Supported tools:',
15
17
  ' claude',
16
18
  ' cursor',
17
19
  '',
18
20
  'Examples:',
19
- ' npx ronds_ai record claude',
20
- ' npx ronds_ai record cursor',
21
- ' npx ronds_ai hooks deploy',
21
+ ' npx ronds_ai@latest record claude',
22
+ ' npx ronds_ai@latest record cursor',
23
+ ' npx ronds_ai@latest doctor claude',
24
+ ' npx ronds_ai@latest doctor cursor',
25
+ ' npx ronds_ai@latest hooks deploy',
22
26
  ].join('\n'));
23
27
  process.stderr.write('\n');
24
28
  }
@@ -49,6 +53,19 @@ async function run() {
49
53
  return;
50
54
  }
51
55
 
56
+ if (command === 'doctor') {
57
+ const [tool] = args;
58
+ const normalizedTool = String(tool || '').trim().toLowerCase();
59
+
60
+ if (!SUPPORTED_SOURCES.has(normalizedTool)) {
61
+ throw new Error(`Unsupported doctor tool: ${tool || ''}`);
62
+ }
63
+
64
+ const result = runDoctor(normalizedTool, process.cwd());
65
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
66
+ return;
67
+ }
68
+
52
69
  if (command === 'hooks') {
53
70
  await runHooksCommand(args);
54
71
  return;
package/lib/doctor.js ADDED
@@ -0,0 +1,102 @@
1
+ const fs = require('fs');
2
+ const os = require('os');
3
+ const path = require('path');
4
+ const { execFileSync } = require('child_process');
5
+
6
+ const SUPPORTED_TOOLS = new Set(['claude', 'cursor']);
7
+
8
+ function formatDateStamp(date = new Date()) {
9
+ const year = String(date.getFullYear());
10
+ const month = String(date.getMonth() + 1).padStart(2, '0');
11
+ const day = String(date.getDate()).padStart(2, '0');
12
+ return `${year}${month}${day}`;
13
+ }
14
+
15
+ function getFailedEventDir() {
16
+ return path.join(os.homedir(), '.ronds_ai', 'failed-events');
17
+ }
18
+
19
+ function getRecentLogPaths(tool) {
20
+ const dateStamp = formatDateStamp();
21
+ return [
22
+ path.join(getFailedEventDir(), `${dateStamp}-${tool}-error.jsonl`),
23
+ path.join(getFailedEventDir(), `${dateStamp}-cli-error.jsonl`),
24
+ ];
25
+ }
26
+
27
+ function tailFileLines(filePath, maxLines = 20) {
28
+ if (!fs.existsSync(filePath)) {
29
+ return [];
30
+ }
31
+
32
+ const raw = fs.readFileSync(filePath, 'utf8');
33
+ const lines = raw.split('\n').filter((line) => line.trim() !== '');
34
+ return lines.slice(-maxLines);
35
+ }
36
+
37
+ function readRecentLogs(tool) {
38
+ return getRecentLogPaths(tool).map((filePath) => ({
39
+ path: filePath,
40
+ exists: fs.existsSync(filePath),
41
+ lines: tailFileLines(filePath),
42
+ }));
43
+ }
44
+
45
+ function getConfigChecks(tool, baseDir) {
46
+ if (tool === 'cursor') {
47
+ return [
48
+ {
49
+ label: '.cursor/hooks.json',
50
+ path: path.join(baseDir, '.cursor', 'hooks.json'),
51
+ },
52
+ ];
53
+ }
54
+
55
+ return [
56
+ {
57
+ label: '.claude/settings.json',
58
+ path: path.join(baseDir, '.claude', 'settings.json'),
59
+ },
60
+ {
61
+ label: '.claude/settings.local.json',
62
+ path: path.join(baseDir, '.claude', 'settings.local.json'),
63
+ },
64
+ ];
65
+ }
66
+
67
+ function readGitUserEmail(baseDir) {
68
+ try {
69
+ return execFileSync('git', ['config', 'user.email'], {
70
+ cwd: baseDir,
71
+ encoding: 'utf8',
72
+ stdio: ['ignore', 'pipe', 'pipe'],
73
+ }).trim();
74
+ } catch {
75
+ return '';
76
+ }
77
+ }
78
+
79
+ function runDoctor(tool, targetDir = process.cwd()) {
80
+ const normalizedTool = String(tool || '').trim().toLowerCase();
81
+ if (!SUPPORTED_TOOLS.has(normalizedTool)) {
82
+ throw new Error(`Unsupported doctor tool: ${tool || ''}`);
83
+ }
84
+
85
+ const baseDir = path.resolve(targetDir);
86
+ const configChecks = getConfigChecks(normalizedTool, baseDir).map((item) => ({
87
+ ...item,
88
+ exists: fs.existsSync(item.path),
89
+ }));
90
+
91
+ return {
92
+ tool: normalizedTool,
93
+ targetDir: baseDir,
94
+ gitUserEmail: readGitUserEmail(baseDir),
95
+ configChecks,
96
+ recentLogs: readRecentLogs(normalizedTool),
97
+ };
98
+ }
99
+
100
+ module.exports = {
101
+ runDoctor,
102
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ronds_ai",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "CLI for reporting AI code edit events.",
5
5
  "bin": {
6
6
  "ronds_ai": "bin/ronds_ai.js"