cnagent 2.0.1 → 2.0.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/cn +65 -7
- package/package.json +1 -1
package/bin/cn
CHANGED
|
@@ -11,7 +11,7 @@ const { execSync, spawn } = require('child_process');
|
|
|
11
11
|
const path = require('path');
|
|
12
12
|
const fs = require('fs');
|
|
13
13
|
|
|
14
|
-
const VERSION = '2.0.
|
|
14
|
+
const VERSION = '2.0.3';
|
|
15
15
|
|
|
16
16
|
// Colors (respects NO_COLOR)
|
|
17
17
|
const noColor = process.env.NO_COLOR !== undefined;
|
|
@@ -98,10 +98,12 @@ function runInbox(subCmd, hubPath, name) {
|
|
|
98
98
|
|
|
99
99
|
// Doctor command
|
|
100
100
|
function doctor(hubPath) {
|
|
101
|
+
console.log(`cn v${VERSION}`);
|
|
101
102
|
info(`Checking health...`);
|
|
102
103
|
console.log('');
|
|
103
104
|
|
|
104
105
|
let checks = [];
|
|
106
|
+
let warnings = [];
|
|
105
107
|
|
|
106
108
|
// Git
|
|
107
109
|
try {
|
|
@@ -126,28 +128,84 @@ function doctor(hubPath) {
|
|
|
126
128
|
checks.push({ name: 'git user.email', ok: false, val: 'not set' });
|
|
127
129
|
}
|
|
128
130
|
|
|
129
|
-
// Hub
|
|
130
|
-
checks.push({ name: 'hub directory', ok: fs.existsSync(hubPath), val: hubPath ? 'exists' : 'not found' });
|
|
131
|
+
// Hub directory
|
|
132
|
+
checks.push({ name: 'hub directory', ok: fs.existsSync(hubPath), val: fs.existsSync(hubPath) ? 'exists' : 'not found' });
|
|
131
133
|
|
|
132
|
-
//
|
|
134
|
+
// .cn/config.json
|
|
135
|
+
const configPath = path.join(hubPath, '.cn', 'config.json');
|
|
136
|
+
checks.push({ name: '.cn/config.json', ok: fs.existsSync(configPath), val: fs.existsSync(configPath) ? 'exists' : 'missing' });
|
|
137
|
+
|
|
138
|
+
// spec/SOUL.md
|
|
139
|
+
const soulPath = path.join(hubPath, 'spec', 'SOUL.md');
|
|
140
|
+
if (fs.existsSync(soulPath)) {
|
|
141
|
+
checks.push({ name: 'spec/SOUL.md', ok: true, val: 'exists' });
|
|
142
|
+
} else {
|
|
143
|
+
warnings.push({ name: 'spec/SOUL.md', val: 'missing (optional)' });
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// state/peers.md
|
|
147
|
+
const peersPath = path.join(hubPath, 'state', 'peers.md');
|
|
148
|
+
if (fs.existsSync(peersPath)) {
|
|
149
|
+
const content = fs.readFileSync(peersPath, 'utf8');
|
|
150
|
+
const peerCount = (content.match(/- name:/g) || []).length;
|
|
151
|
+
checks.push({ name: 'state/peers.md', ok: true, val: `${peerCount} peer(s)` });
|
|
152
|
+
} else {
|
|
153
|
+
checks.push({ name: 'state/peers.md', ok: false, val: 'missing' });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// origin remote
|
|
157
|
+
try {
|
|
158
|
+
execSync('git remote get-url origin', { cwd: hubPath, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
159
|
+
checks.push({ name: 'origin remote', ok: true, val: 'configured' });
|
|
160
|
+
} catch {
|
|
161
|
+
checks.push({ name: 'origin remote', ok: false, val: 'not configured' });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// inbox status
|
|
165
|
+
try {
|
|
166
|
+
const result = execSync(`node ${path.join(__dirname, '..', 'dist', 'inbox.js')} check ${hubPath} ${deriveName(hubPath)} 2>&1`, { encoding: 'utf8' });
|
|
167
|
+
const inboundMatch = result.match(/(\d+) inbound/);
|
|
168
|
+
if (inboundMatch) {
|
|
169
|
+
const count = parseInt(inboundMatch[1]);
|
|
170
|
+
if (count > 0) {
|
|
171
|
+
warnings.push({ name: 'inbox', val: `${count} pending` });
|
|
172
|
+
} else {
|
|
173
|
+
checks.push({ name: 'inbox', ok: true, val: 'clear' });
|
|
174
|
+
}
|
|
175
|
+
} else if (result.includes('All clear')) {
|
|
176
|
+
checks.push({ name: 'inbox', ok: true, val: 'clear' });
|
|
177
|
+
}
|
|
178
|
+
} catch {
|
|
179
|
+
warnings.push({ name: 'inbox', val: 'check failed' });
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Print checks
|
|
133
183
|
const width = 22;
|
|
134
184
|
checks.forEach(({ name, ok: isOk, val }) => {
|
|
135
|
-
const dots = '.'.repeat(width - name.length);
|
|
185
|
+
const dots = '.'.repeat(Math.max(1, width - name.length));
|
|
136
186
|
const status = isOk
|
|
137
187
|
? `${c.green}✓ ${val}${c.reset}`
|
|
138
188
|
: `${c.red}✗ ${val}${c.reset}`;
|
|
139
189
|
console.log(`${name}${dots} ${status}`);
|
|
140
190
|
});
|
|
141
191
|
|
|
192
|
+
// Print warnings
|
|
193
|
+
warnings.forEach(({ name, val }) => {
|
|
194
|
+
const dots = '.'.repeat(Math.max(1, width - name.length));
|
|
195
|
+
console.log(`${name}${dots} ${c.yellow}⚠ ${val}${c.reset}`);
|
|
196
|
+
});
|
|
197
|
+
|
|
142
198
|
console.log('');
|
|
143
199
|
const fails = checks.filter(c => !c.ok).length;
|
|
200
|
+
const warns = warnings.length;
|
|
201
|
+
|
|
144
202
|
if (fails === 0) {
|
|
145
|
-
ok('All checks passed.');
|
|
203
|
+
ok('All critical checks passed.');
|
|
146
204
|
} else {
|
|
147
205
|
fail(`${fails} issue(s) found.`);
|
|
148
206
|
}
|
|
149
207
|
|
|
150
|
-
console.log(`${c.dim}[status] ok=${checks.filter(c=>c.ok).length} fail=${fails} version=${VERSION}${c.reset}`);
|
|
208
|
+
console.log(`${c.dim}[status] ok=${checks.filter(c=>c.ok).length} warn=${warns} fail=${fails} version=${VERSION}${c.reset}`);
|
|
151
209
|
process.exit(fails > 0 ? 1 : 0);
|
|
152
210
|
}
|
|
153
211
|
|