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.
Files changed (2) hide show
  1. package/bin/cn +65 -7
  2. 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.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
- // Print
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cnagent",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Coherent Network agent CLI — everything runs through cn",
5
5
  "keywords": [
6
6
  "cn-agent",