codecrypto-cli 1.0.21 → 1.0.23
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/dist/commands/deploy-mcp.d.ts.map +1 -1
- package/dist/commands/deploy-mcp.js +162 -36
- package/dist/commands/deploy-mcp.js.map +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +162 -36
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +199 -14
- package/dist/commands/doctor.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/deploy-mcp.ts +187 -42
- package/src/commands/deploy.ts +187 -42
- package/src/commands/doctor.ts +206 -19
package/src/commands/doctor.ts
CHANGED
|
@@ -127,23 +127,210 @@ export const doctorCommand = new Command('doctor')
|
|
|
127
127
|
});
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
// 6. Check Docker
|
|
131
|
-
const dockerAuthCheck = ora('Checking Docker
|
|
130
|
+
// 6. Check Docker authentication
|
|
131
|
+
const dockerAuthCheck = ora('Checking Docker authentication...').start();
|
|
132
132
|
try {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
133
|
+
// Obtener email del token.json para comparar
|
|
134
|
+
const tokenFilePath = path.join(os.homedir(), '.codecrypto', 'token.json');
|
|
135
|
+
let tokenEmail: string | null = null;
|
|
136
|
+
if (fs.existsSync(tokenFilePath)) {
|
|
137
|
+
try {
|
|
138
|
+
const tokenData = JSON.parse(fs.readFileSync(tokenFilePath, 'utf-8'));
|
|
139
|
+
tokenEmail = tokenData.email || null;
|
|
140
|
+
} catch {
|
|
141
|
+
// Ignorar errores al leer token
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Verificar si hay credenciales guardadas en Docker config
|
|
146
|
+
const dockerConfigPath = path.join(os.homedir(), '.docker', 'config.json');
|
|
147
|
+
let dockerUsername: string | null = null;
|
|
148
|
+
let dockerEmail: string | null = null;
|
|
149
|
+
let hasDockerAuth = false;
|
|
150
|
+
let dockerAuthInfo = '';
|
|
151
|
+
|
|
152
|
+
if (fs.existsSync(dockerConfigPath)) {
|
|
153
|
+
try {
|
|
154
|
+
const dockerConfig = JSON.parse(fs.readFileSync(dockerConfigPath, 'utf-8'));
|
|
155
|
+
|
|
156
|
+
// Verificar si hay auths configurados
|
|
157
|
+
if (dockerConfig.auths && Object.keys(dockerConfig.auths).length > 0) {
|
|
158
|
+
hasDockerAuth = true;
|
|
159
|
+
const registries = Object.keys(dockerConfig.auths);
|
|
160
|
+
dockerAuthInfo = `Authenticated to: ${registries.join(', ')}`;
|
|
161
|
+
|
|
162
|
+
// Intentar obtener el username de Docker Hub
|
|
163
|
+
const dockerHubKey = registries.find(reg =>
|
|
164
|
+
reg.includes('docker.io') ||
|
|
165
|
+
reg.includes('hub.docker.com') ||
|
|
166
|
+
reg === 'https://index.docker.io/v1/'
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
if (dockerHubKey && dockerConfig.auths[dockerHubKey]) {
|
|
170
|
+
// El username puede estar en auths[registry].auth (base64) o directamente
|
|
171
|
+
const authData = dockerConfig.auths[dockerHubKey];
|
|
172
|
+
if (authData && authData.username) {
|
|
173
|
+
dockerUsername = authData.username;
|
|
174
|
+
// Si el username parece un email, usarlo como email
|
|
175
|
+
if (dockerUsername && dockerUsername.includes('@')) {
|
|
176
|
+
dockerEmail = dockerUsername;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Intentar obtener username de docker info como fallback
|
|
182
|
+
if (!dockerUsername) {
|
|
183
|
+
try {
|
|
184
|
+
const dockerInfo = execSync('docker info', { encoding: 'utf-8', stdio: 'pipe', timeout: 5000 });
|
|
185
|
+
const usernameMatch = dockerInfo.match(/Username:\s*(.+)/i);
|
|
186
|
+
if (usernameMatch) {
|
|
187
|
+
dockerUsername = usernameMatch[1].trim();
|
|
188
|
+
if (dockerUsername.includes('@')) {
|
|
189
|
+
dockerEmail = dockerUsername;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
} catch {
|
|
193
|
+
// Ignorar errores
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Verificar específicamente Docker Hub
|
|
198
|
+
const hasDockerHub = registries.some(reg =>
|
|
199
|
+
reg.includes('docker.io') ||
|
|
200
|
+
reg.includes('hub.docker.com') ||
|
|
201
|
+
reg === 'https://index.docker.io/v1/'
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
// Construir mensaje con información de email/usuario
|
|
205
|
+
let authMessage = `Docker authentication verified: ${dockerAuthInfo}`;
|
|
206
|
+
if (dockerUsername || dockerEmail) {
|
|
207
|
+
const dockerIdentity = dockerEmail || dockerUsername;
|
|
208
|
+
authMessage += ` (User: ${dockerIdentity})`;
|
|
209
|
+
|
|
210
|
+
// Comparar con token.json
|
|
211
|
+
if (tokenEmail && dockerEmail) {
|
|
212
|
+
if (dockerEmail.toLowerCase() === tokenEmail.toLowerCase()) {
|
|
213
|
+
authMessage += ` ✓ Matches token.json email`;
|
|
214
|
+
} else {
|
|
215
|
+
authMessage += ` ⚠ Different from token.json email (${tokenEmail})`;
|
|
216
|
+
}
|
|
217
|
+
} else if (tokenEmail && dockerUsername && !dockerEmail) {
|
|
218
|
+
// Comparar username con email del token (parte antes del @)
|
|
219
|
+
const tokenUsername = tokenEmail.split('@')[0].toLowerCase();
|
|
220
|
+
if (dockerUsername.toLowerCase() === tokenUsername) {
|
|
221
|
+
authMessage += ` ✓ Username matches token.json email`;
|
|
222
|
+
} else {
|
|
223
|
+
authMessage += ` ⚠ Username differs from token.json email (${tokenEmail})`;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (hasDockerHub) {
|
|
229
|
+
dockerAuthCheck.succeed(`Docker authentication OK (Docker Hub configured)`);
|
|
230
|
+
checks.push({
|
|
231
|
+
name: 'Docker Auth',
|
|
232
|
+
status: 'success',
|
|
233
|
+
message: authMessage
|
|
234
|
+
});
|
|
235
|
+
} else {
|
|
236
|
+
dockerAuthCheck.succeed(`Docker authentication OK (${registries.length} registry/registries configured)`);
|
|
237
|
+
checks.push({
|
|
238
|
+
name: 'Docker Auth',
|
|
239
|
+
status: 'success',
|
|
240
|
+
message: authMessage
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
} else {
|
|
244
|
+
// No hay auths configurados, intentar verificar con pull
|
|
245
|
+
try {
|
|
246
|
+
execSync('docker pull hello-world:latest', { encoding: 'utf-8', stdio: 'pipe', timeout: 10000 });
|
|
247
|
+
dockerAuthCheck.succeed('Docker authentication OK (public access)');
|
|
248
|
+
let message = 'Docker can access public images (authentication may not be required)';
|
|
249
|
+
if (tokenEmail) {
|
|
250
|
+
message += ` (Token email: ${tokenEmail})`;
|
|
251
|
+
}
|
|
252
|
+
checks.push({
|
|
253
|
+
name: 'Docker Auth',
|
|
254
|
+
status: 'success',
|
|
255
|
+
message: message
|
|
256
|
+
});
|
|
257
|
+
} catch (pullError) {
|
|
258
|
+
dockerAuthCheck.warn('Docker authentication not configured');
|
|
259
|
+
let details = 'Run "docker login" if you need to push images to Docker Hub or private registries';
|
|
260
|
+
if (tokenEmail) {
|
|
261
|
+
details += ` (Token email: ${tokenEmail})`;
|
|
262
|
+
}
|
|
263
|
+
checks.push({
|
|
264
|
+
name: 'Docker Auth',
|
|
265
|
+
status: 'warning',
|
|
266
|
+
message: 'Docker authentication not configured',
|
|
267
|
+
details: details
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
} catch (configError) {
|
|
272
|
+
// Error leyendo config, intentar verificar con pull
|
|
273
|
+
try {
|
|
274
|
+
execSync('docker pull hello-world:latest', { encoding: 'utf-8', stdio: 'pipe', timeout: 10000 });
|
|
275
|
+
dockerAuthCheck.succeed('Docker authentication OK');
|
|
276
|
+
let message = 'Docker can access public images';
|
|
277
|
+
if (tokenEmail) {
|
|
278
|
+
message += ` (Token email: ${tokenEmail})`;
|
|
279
|
+
}
|
|
280
|
+
checks.push({
|
|
281
|
+
name: 'Docker Auth',
|
|
282
|
+
status: 'success',
|
|
283
|
+
message: message
|
|
284
|
+
});
|
|
285
|
+
} catch (pullError) {
|
|
286
|
+
dockerAuthCheck.warn('Docker authentication may be required');
|
|
287
|
+
let details = 'Run "docker login" if you need to push images';
|
|
288
|
+
if (tokenEmail) {
|
|
289
|
+
details += ` (Token email: ${tokenEmail})`;
|
|
290
|
+
}
|
|
291
|
+
checks.push({
|
|
292
|
+
name: 'Docker Auth',
|
|
293
|
+
status: 'warning',
|
|
294
|
+
message: 'Docker authentication not verified',
|
|
295
|
+
details: details
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
} else {
|
|
300
|
+
// No existe config.json, intentar verificar con pull
|
|
301
|
+
try {
|
|
302
|
+
execSync('docker pull hello-world:latest', { encoding: 'utf-8', stdio: 'pipe', timeout: 10000 });
|
|
303
|
+
dockerAuthCheck.succeed('Docker authentication OK (public access)');
|
|
304
|
+
let message = 'Docker can access public images (authentication may not be required)';
|
|
305
|
+
if (tokenEmail) {
|
|
306
|
+
message += ` (Token email: ${tokenEmail})`;
|
|
307
|
+
}
|
|
308
|
+
checks.push({
|
|
309
|
+
name: 'Docker Auth',
|
|
310
|
+
status: 'success',
|
|
311
|
+
message: message
|
|
312
|
+
});
|
|
313
|
+
} catch (error) {
|
|
314
|
+
dockerAuthCheck.warn('Docker authentication not configured');
|
|
315
|
+
let details = 'Run "docker login" if you need to push images to Docker Hub or private registries';
|
|
316
|
+
if (tokenEmail) {
|
|
317
|
+
details += ` (Token email: ${tokenEmail})`;
|
|
318
|
+
}
|
|
319
|
+
checks.push({
|
|
320
|
+
name: 'Docker Auth',
|
|
321
|
+
status: 'warning',
|
|
322
|
+
message: 'Docker authentication not configured',
|
|
323
|
+
details: details
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
} catch (error: any) {
|
|
328
|
+
dockerAuthCheck.fail('Docker authentication check failed');
|
|
142
329
|
checks.push({
|
|
143
|
-
name: 'Docker
|
|
144
|
-
status: '
|
|
145
|
-
message: 'Docker
|
|
146
|
-
details:
|
|
330
|
+
name: 'Docker Auth',
|
|
331
|
+
status: 'error',
|
|
332
|
+
message: 'Docker authentication check failed',
|
|
333
|
+
details: `Error: ${error.message || String(error)}`
|
|
147
334
|
});
|
|
148
335
|
}
|
|
149
336
|
|
|
@@ -499,11 +686,11 @@ export const doctorCommand = new Command('doctor')
|
|
|
499
686
|
}
|
|
500
687
|
|
|
501
688
|
besu1Check.succeed(`Besu1 network accessible (chain-id: ${chainId}, block: ${blockNumber})`);
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
689
|
+
checks.push({
|
|
690
|
+
name: 'Besu1 Network',
|
|
691
|
+
status: 'success',
|
|
505
692
|
message: `Besu1 network accessible: ${rpcUrl} (chain-id: ${chainId}, block: ${blockNumber})`
|
|
506
|
-
|
|
693
|
+
});
|
|
507
694
|
}
|
|
508
695
|
} catch (error: any) {
|
|
509
696
|
const errorMsg = error.message || String(error);
|