shakers-cli 0.15.0 → 0.17.0
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/README.md +56 -1203
- package/bin/ai-usage.js +32 -58
- package/bin/login.js +10 -10
- package/bin/mcp.js +17 -12
- package/bin/mcpb.js +1 -1
- package/bin/onboarding.js +3 -2
- package/bin/register.js +19 -5
- package/bin/report-html.js +2 -2
- package/bin/shakers-cli.js +352 -0
- package/bin/shakers.js +20 -344
- package/bin/share.js +1 -1
- package/bin/superadmin.js +5 -5
- package/bin/version.js +3 -0
- package/package.json +12 -3
- package/src/account-marker.js +40 -0
- package/src/account-trace.js +23 -0
- package/src/agent-category.js +1 -1
- package/src/agent-evaluation.js +3 -3
- package/src/agent-org-chart.js +5 -5
- package/src/agent-synthesis.js +3 -3
- package/src/agent-usage.js +1 -1
- package/src/agents-client.js +4 -4
- package/src/ai-usage-review.js +101 -0
- package/src/ai.js +1 -1
- package/src/ansi.js +1 -1
- package/src/auth-client.js +18 -4
- package/src/auth-method-picker.js +1 -1
- package/src/auth-methods.js +1 -1
- package/src/auth-session-store.js +18 -8
- package/src/authorship-mismatch.js +1 -1
- package/src/authorship.js +2 -2
- package/src/automations-detector.js +1 -1
- package/src/backend-request.js +5 -3
- package/src/brand-ansi.js +1 -1
- package/src/browser-tools-detector.js +1 -1
- package/src/certify-disclaimer.js +1 -1
- package/src/certify-remediation-prompt.js +1 -1
- package/src/cli-args.js +2 -2
- package/src/command-audit.js +8 -5
- package/src/config-dir.js +1 -1
- package/src/config.js +114 -48
- package/src/consent-flow.js +7 -6
- package/src/consent-skip.js +1 -1
- package/src/detection-evidence.js +2 -2
- package/src/detection-noise.js +1 -1
- package/src/detectors.js +1 -1
- package/src/device-login.js +12 -1
- package/src/email-verification.js +3 -3
- package/src/env-paths.js +1 -1
- package/src/find-projects-client.js +12 -0
- package/src/find-projects-flow.js +1 -13
- package/src/git-activity.js +1 -1
- package/src/graph-certs.js +3 -3
- package/src/graph-scan.js +9 -9
- package/src/i18n.js +148 -138
- package/src/interactive-select.js +1 -1
- package/src/interview-client.js +6 -1
- package/src/interview-transcript.js +1 -1
- package/src/legal-notice.js +1 -1
- package/src/maturity.js +6 -6
- package/src/mcp-ai-usage-result-tool.js +34 -12
- package/src/mcp-ai-usage-tool.js +282 -163
- package/src/mcp-auth-form.js +7 -3
- package/src/mcp-detector.js +3 -3
- package/src/mcp-device-login-tools.js +2 -1
- package/src/mcp-find-projects-tools.js +1 -2
- package/src/mcp-install.js +279 -44
- package/src/mcp-instructions.js +1 -1
- package/src/mcp-onboarding-tools.js +4 -4
- package/src/mcp-prompts.js +4 -4
- package/src/mcp-register-tools.js +1 -0
- package/src/mcp-role-tools.js +24 -1
- package/src/mcp-server.js +5 -1
- package/src/mcp-signup-client.js +2 -2
- package/src/mcp-signup-tools.js +39 -9
- package/src/memory-structure-detector.js +1 -1
- package/src/model-call-record.js +2 -2
- package/src/onboarding-flow.js +63 -42
- package/src/onboarding-funnel.js +153 -20
- package/src/open-file.js +1 -1
- package/src/osc-link.js +1 -1
- package/src/portfolio-client.js +11 -1
- package/src/portfolio-git-info.js +1 -1
- package/src/profile-flow.js +1 -1
- package/src/profile-switch.js +5 -12
- package/src/render-certification.js +10 -10
- package/src/render-html.js +6 -6
- package/src/render-report-text.js +1 -1
- package/src/render-sheet.js +10 -10
- package/src/render-terminal.js +6 -6
- package/src/repo-scope.js +132 -0
- package/src/report-gating.js +5 -3
- package/src/report-store.js +13 -8
- package/src/roadmap-content.js +5 -5
- package/src/roadmap-personalization.js +3 -3
- package/src/roadmap-prompt.js +2 -2
- package/src/roles-flow.js +8 -5
- package/src/scan-exclusions.js +1 -1
- package/src/scanner.js +14 -14
- package/src/secret-prompt.js +1 -1
- package/src/session-gate.js +1 -1
- package/src/session-refresh.js +33 -3
- package/src/session-scan.js +1 -1
- package/src/shakers-wordmark.js +1 -1
- package/src/share-card.js +2 -2
- package/src/share-certification.js +4 -4
- package/src/share-consent-state.js +9 -9
- package/src/share-payload.js +7 -7
- package/src/share.js +7 -7
- package/src/signup-client.js +1 -1
- package/src/signup-copy.js +177 -2
- package/src/skills-client.js +1 -1
- package/src/start-add-agents.js +2 -2
- package/src/start-add-portfolio.js +3 -13
- package/src/start-add-skills.js +2 -2
- package/src/stdin-ask.js +16 -4
- package/src/strip-internal-comments.js +1 -1
- package/src/tech-detector.js +2 -2
- package/src/templates/report-sheet.html +11 -13
- package/src/terminal-agents.js +8 -8
- package/src/terminal-format.js +3 -3
- package/src/terminal-sections.js +11 -11
- package/src/tier-engine.js +3 -3
- package/src/tier-projection.js +2 -2
- package/src/transcript-turns.js +1 -1
- package/src/typewriter.js +1 -1
- package/src/usage-model-calls.js +6 -6
- package/src/usage-oneshot-commands.js +5 -5
- package/src/usage-repo-scope.js +11 -129
- package/src/usage-run-steps.js +82 -181
- package/src/usage-scan.js +235 -0
- package/src/work-streams.js +1 -1
package/src/i18n.js
CHANGED
|
@@ -227,7 +227,7 @@ const catalogs = {
|
|
|
227
227
|
},
|
|
228
228
|
ladder: {
|
|
229
229
|
levelsHeading: 'Niveles de madurez (0-4)',
|
|
230
|
-
//
|
|
230
|
+
// The ladder now groups tiers by SETUP LEVEL, not the 0-4 band.
|
|
231
231
|
setupHeading: 'Nivel de setup',
|
|
232
232
|
setupIntro:
|
|
233
233
|
'Tu nivel de setup (S1–S3) resume tu uso de IA de un vistazo; el tier (T0-T7) es el eje '
|
|
@@ -262,7 +262,7 @@ const catalogs = {
|
|
|
262
262
|
T7: 'Taller orquestado: hooks automatizan el taller y los agentes se orquestan entre sí.',
|
|
263
263
|
},
|
|
264
264
|
},
|
|
265
|
-
// Agent classification against the AI-agent catalog
|
|
265
|
+
// Agent classification against the AI-agent catalog + the "how to improve" tips.
|
|
266
266
|
classification: {
|
|
267
267
|
label: 'Clasificación',
|
|
268
268
|
noCategory: 'Sin categoría',
|
|
@@ -273,14 +273,14 @@ const catalogs = {
|
|
|
273
273
|
agentsEvalPartial: (names, count = 2) => (count === 1
|
|
274
274
|
? `Este agente se quedó fuera de esta ejecución: ${names}. La respuesta del modelo no llegó a cubrirlo, así que no es que no tenga categoría: es que no se llegó a evaluarlo. Vuelve a ejecutar \`usage\` para completarlo.`
|
|
275
275
|
: `Estos agentes se quedaron fuera de esta ejecución: ${names}. La respuesta del modelo no llegó a cubrirlos, así que no es que no tengan categoría: es que no se llegó a evaluarlos. Vuelve a ejecutar \`usage\` para completarlos.`),
|
|
276
|
-
// LA EVALUACIÓN FALLÓ ENTERA
|
|
276
|
+
// LA EVALUACIÓN FALLÓ ENTERA.
|
|
277
277
|
agentsEvalMissing: 'La categoría de tus agentes no se pudo calcular en esta ejecución: la evaluación no llegó a responder. No es que no tengan categoría. Vuelve a ejecutar `usage` para intentarlo otra vez.',
|
|
278
|
-
//
|
|
278
|
+
// Se parte el aviso genérico en dos, y el motivo es que apuntan a sitios distintos.
|
|
279
279
|
agentsEvalUnreachable: 'No se pudo conectar con Shakers, así que tus agentes salen sin categoría. Comprueba tu conexión y vuelve a ejecutar `usage`.',
|
|
280
280
|
agentsEvalErrored: 'Shakers respondió con un error, así que tus agentes salen sin categoría. No es cosa de tu configuración; vuelve a intentarlo en un rato.',
|
|
281
281
|
agentsEvalTimedOut: (count) => `La evaluación de tus agentes no respondió dentro del plazo, así que esta vez salen sin categoría. Ese tiempo crece con el número de agentes y tienes ${count}, así que volver a ejecutarlo tal cual probablemente acabe igual.`,
|
|
282
282
|
improvementsHeading: 'Cómo mejorar este agente',
|
|
283
|
-
// LAS OCHO CATEGORÍAS DEL CATÁLOGO DEL SERVICIO: siete especialidades y el SUELO (
|
|
283
|
+
// LAS OCHO CATEGORÍAS DEL CATÁLOGO DEL SERVICIO: siete especialidades y el SUELO (el catálogo vive en el servicio).
|
|
284
284
|
categories: {
|
|
285
285
|
developer: 'Desarrollo',
|
|
286
286
|
product: 'Producto',
|
|
@@ -298,7 +298,7 @@ const catalogs = {
|
|
|
298
298
|
},
|
|
299
299
|
},
|
|
300
300
|
// LEGACY 0-4 band names — kept only for older persisted reports / the
|
|
301
|
-
// unchanged sent payload
|
|
301
|
+
// unchanged sent payload; the report shows `setupLevels` instead.
|
|
302
302
|
levelNames: {
|
|
303
303
|
none: 'Sin rastro de IA',
|
|
304
304
|
exploring: 'Explorando',
|
|
@@ -306,7 +306,7 @@ const catalogs = {
|
|
|
306
306
|
power: 'Power user',
|
|
307
307
|
orchestrator: 'Orquestador',
|
|
308
308
|
},
|
|
309
|
-
// Setup Level (Talent Certification Framework
|
|
309
|
+
// Setup Level (Talent Certification Framework): the 3-value rollup that REPLACES the 0-4 band on every surface.
|
|
310
310
|
setupLevels: {
|
|
311
311
|
none: {
|
|
312
312
|
label: 'Sin certificar',
|
|
@@ -343,7 +343,7 @@ const catalogs = {
|
|
|
343
343
|
brandSub: 'perfil de uso de IA',
|
|
344
344
|
toolsDetected: (n, total) => `${n}/${total} herramientas detectadas`,
|
|
345
345
|
level: (level, name) => `Nivel ${level} · ${name}`,
|
|
346
|
-
//
|
|
346
|
+
// Setup Level shown in the top bar (replaces the 0-4 level line).
|
|
347
347
|
setupLevel: (label) => `Setup · ${label}`,
|
|
348
348
|
// Current tier appended to the top bar, next to the level (report req 1 addendum).
|
|
349
349
|
tierInline: (key, name) => ` · Tier ${key} · ${name}`,
|
|
@@ -371,16 +371,16 @@ const catalogs = {
|
|
|
371
371
|
environment: 'Entorno',
|
|
372
372
|
editors: 'editores',
|
|
373
373
|
noEditorsDetected: 'ninguno detectado',
|
|
374
|
-
//
|
|
374
|
+
// Agent evaluation (terminal, one line per agent): compact usage
|
|
375
375
|
// signal derived from the local Claude Code history.
|
|
376
376
|
agentUsed: (n) => `usado ${n}×`,
|
|
377
377
|
agentUnused: 'sin uso local',
|
|
378
378
|
agentUsageUnavailable: '(sin historial local de Claude Code: uso no disponible)',
|
|
379
|
-
//
|
|
379
|
+
// Discoverability hint for the next-steps section (behind --roadmap).
|
|
380
380
|
roadmapHint: 'Ejecuta `usage --roadmap` para ver los pasos que te separan del siguiente nivel de uso de IA. No son pasos de esta herramienta: son cambios en tu forma de trabajar, para las próximas semanas.',
|
|
381
381
|
aiProfileGenerating: 'Generando tu perfil de IA (matriz, visión y cómo trabajas)…',
|
|
382
382
|
aiProfilePendingRetry: 'Tu perfil de IA (matriz, visión y cómo trabajas) se está generando; re-lanza `report` en un momento para verlo.',
|
|
383
|
-
//
|
|
383
|
+
// Se muestra cuando había una sesión y ha caducado, para que el talento entienda por qué vuelve a ver el informe completo.
|
|
384
384
|
sessionExpiredNotice: 'Tu sesión ha caducado. Estás viendo el informe completo como usuario general; ejecuta `login` para volver a entrar.',
|
|
385
385
|
nextStep: 'Siguiente paso para subir de nivel',
|
|
386
386
|
files: (n) => `${n} ${n === 1 ? 'fichero' : 'ficheros'}`,
|
|
@@ -393,7 +393,7 @@ const catalogs = {
|
|
|
393
393
|
h1: 'Tu perfil de uso de IA',
|
|
394
394
|
sub: 'Un vistazo local a qué herramientas de IA tienes y cuánto las has configurado.',
|
|
395
395
|
levelOf: (level) => `Nivel ${level} de 4`,
|
|
396
|
-
//
|
|
396
|
+
// Hero label for the Setup Level (replaces the 0-4 "Nivel X de 4").
|
|
397
397
|
setupLevelOf: 'Nivel de setup',
|
|
398
398
|
// Current tier shown in the hero bar next to the level (report req 1 addendum).
|
|
399
399
|
currentTier: (key, name) => `Tier ${key} · ${name}`,
|
|
@@ -402,7 +402,7 @@ const catalogs = {
|
|
|
402
402
|
detectedSuffix: (total) => `de ${total} herramientas detectadas`,
|
|
403
403
|
maturity: 'Madurez',
|
|
404
404
|
tools: 'Herramientas',
|
|
405
|
-
//
|
|
405
|
+
// Only DETECTED tools are listed now (undetected ones were pure noise — any relevant next step already lives in the tier roadmap section).
|
|
406
406
|
toolsEmpty: 'No se ha detectado ninguna herramienta de IA en tu entorno.',
|
|
407
407
|
configIntensity: 'intensidad de configuración',
|
|
408
408
|
files: (n) => `${n} ${n === 1 ? 'fichero' : 'ficheros'}`,
|
|
@@ -416,21 +416,21 @@ const catalogs = {
|
|
|
416
416
|
diagramHeading: 'Agentes',
|
|
417
417
|
agentsEmpty: 'No se han detectado agentes de IA configurados (p. ej. .claude/agents/).',
|
|
418
418
|
orchestratorLabel: 'Orchestrator',
|
|
419
|
-
// Last-resort description fallback (
|
|
419
|
+
// Last-resort description fallback (a card must NEVER show only name+model, no description at all).
|
|
420
420
|
agentDescriptionFromName: (name) => `Agente "${name}" (sin descripción declarada en su fichero).`,
|
|
421
421
|
// AI product an agent belongs to, derived from its source (proper nouns; same es/en).
|
|
422
422
|
aiProducts: { 'claude-code': 'Claude Code' },
|
|
423
|
-
//
|
|
423
|
+
// Agent evaluation (HTML per-agent detail): definition-quality score + LLM rationale + local usage signal.
|
|
424
424
|
agentScoreLabel: 'Calidad de la definición (0-100)',
|
|
425
425
|
agentQualityLabel: 'Por qué:',
|
|
426
426
|
agentUsageLabel: 'Uso local (historial de Claude Code)',
|
|
427
427
|
agentUsedTimes: (n) => `usado ${n}×`,
|
|
428
428
|
agentUnused: 'sin uso local',
|
|
429
|
-
// Project technologies
|
|
429
|
+
// Project technologies.
|
|
430
430
|
technologiesHeading: 'Tecnologías del proyecto',
|
|
431
431
|
technologiesEmpty: 'No se reconoció ningún framework o librería en los manifiestos de dependencias (package.json, requirements.txt, go.mod, pyproject.toml).',
|
|
432
|
-
// MCP servers by name
|
|
433
|
-
//
|
|
432
|
+
// MCP servers by name.
|
|
433
|
+
// Esta clave existía desde la 015 y NO la pintaba nadie — los servidores MCP se detectaban, contaban para el tier y no se nombraban en ninguna superficie.
|
|
434
434
|
mcpHeading: 'Servicios conectados por MCP',
|
|
435
435
|
mcpEmpty: 'No se ha detectado ningún servidor MCP. Conectar uno es el criterio que te sube a T3 (Banco conectado).',
|
|
436
436
|
mcpUnidentified: (n) => `${n} ${n === 1 ? 'servidor más, cuyo servicio no' : 'servidores más, cuyo servicio no'} hemos podido identificar por su nombre.`,
|
|
@@ -447,18 +447,18 @@ const catalogs = {
|
|
|
447
447
|
roadmapConsolidationLabel: 'Pasos de consolidación',
|
|
448
448
|
roadmapHonestyLabel: 'Nota de honestidad',
|
|
449
449
|
roadmapContentUnavailable: 'El contenido detallado de este nivel aún no está disponible en este idioma.',
|
|
450
|
-
//
|
|
450
|
+
// Shown only when the 4 prose gaps below were actually replaced by a validated, project-adapted response — never on fallback to the curated content.
|
|
451
451
|
roadmapPersonalizedNotice: 'Contenido adaptado a tu proyecto.',
|
|
452
|
-
//
|
|
453
|
-
roadmapNotPersonalizedNotice: 'Este roadmap es el genérico de tu tier: esta vez no se ha podido adaptar a tu proyecto. Vuelve a ejecutar `usage` para intentarlo otra vez.',
|
|
454
|
-
//
|
|
452
|
+
// Los dos avisos que faltaban, hermanos del `agentsEvalMissing` que añadió la 106.
|
|
453
|
+
roadmapNotPersonalizedNotice: 'Este roadmap es el genérico de tu tier: esta vez no se ha podido adaptar a tu proyecto. Vuelve a ejecutar `usage --roadmap` para intentarlo otra vez.',
|
|
454
|
+
// El antes y el después del roadmap.
|
|
455
455
|
roadmapNowLabel: 'De dónde partes',
|
|
456
456
|
roadmapProjectionLabel: 'Dónde te deja esta ruta',
|
|
457
457
|
roadmapProjectionTag: 'proyección',
|
|
458
458
|
roadmapProjectionNote: 'Calculado con el mismo motor que tu evaluación, aplicando el mínimo que piden estos pasos. Es una proyección, no una promesa: la evaluación mide uso real, así que darlos es condición necesaria y no suficiente.',
|
|
459
459
|
implementationPromptHeading: 'Prompt para implementar',
|
|
460
460
|
implementationPromptHint: 'Copia este prompt y pégalo en tu IA de confianza (Claude Code, Cursor, ChatGPT...) para que lo implemente en tu proyecto.',
|
|
461
|
-
// Copy-to-clipboard button (HTML report only
|
|
461
|
+
// Copy-to-clipboard button (HTML report only): navigator.clipboard with a document.execCommand fallback, both inline, zero-network.
|
|
462
462
|
implementationPromptCopyLabel: 'Copiar',
|
|
463
463
|
implementationPromptCopiedLabel: 'Copiado ✓',
|
|
464
464
|
privacyNote:
|
|
@@ -470,9 +470,9 @@ const catalogs = {
|
|
|
470
470
|
rawData: 'Ver los datos exactos de este informe (JSON)',
|
|
471
471
|
},
|
|
472
472
|
cli: {
|
|
473
|
-
// Reporting redesign
|
|
473
|
+
// Reporting redesign: el HTML ya NO es opt-in (se retira --html).
|
|
474
474
|
reportLink: (url) => `Abre tu informe en el navegador:\n ${url}`,
|
|
475
|
-
// `share` command
|
|
475
|
+
// `share` command: copy del CLI que envuelve a la tarjeta branded para LinkedIn.
|
|
476
476
|
share: {
|
|
477
477
|
help: 'share — crea una tarjeta branded con tu resultado de uso de IA (tier + nota) para compartir en LinkedIn.\n'
|
|
478
478
|
+ ' Usa `usage` primero; `share` toma el último uso de IA de este proyecto.\n'
|
|
@@ -522,7 +522,7 @@ const catalogs = {
|
|
|
522
522
|
available: (from, to) => `Hay una versión nueva del CLI de Shakers: ${from} → ${to}`,
|
|
523
523
|
howTo: 'Ejecuta `shakers update` para actualizar.',
|
|
524
524
|
},
|
|
525
|
-
// `report` command
|
|
525
|
+
// `report` command: genera y ABRE el informe HTML completo y compartible de este proyecto (uso de IA + Skills certificadas).
|
|
526
526
|
report: {
|
|
527
527
|
help: 'report — genera y abre el informe HTML completo de este proyecto (uso de IA + Skills certificadas) para compartir con tu equipo.\n'
|
|
528
528
|
+ ' Usa `usage` (y opcionalmente `certify`) primero; `report` reúne su resultado.\n'
|
|
@@ -534,7 +534,7 @@ const catalogs = {
|
|
|
534
534
|
},
|
|
535
535
|
frameworkIntroUsage:
|
|
536
536
|
'Esto mide tu fluidez con IA en dos ejes: Setup (madurez de tu tooling, T0–T7, determinista) y Usage (cómo lo usas, evaluado en entrevista + código). Te sitúa en el mapa 3×3 (Explorer → AI Native). Completarlo posiciona tu perfil agéntico para los proyectos que valoran cómo trabajas con IA. Por defecto leo el uso de IA de todo este equipo y asumo que es tuyo (un equipo = tú).',
|
|
537
|
-
// Terminal progress feedback
|
|
537
|
+
// Terminal progress feedback: stderr-only status
|
|
538
538
|
// during the two slow phases (see src/terminal-progress.js).
|
|
539
539
|
scanningLabel: 'Escaneando entorno y detectores…',
|
|
540
540
|
// Loader de la fase de agregación por repo seleccionado (git + sesiones + steering/decisiones + evidencia + org-chart de agentes).
|
|
@@ -555,14 +555,15 @@ const catalogs = {
|
|
|
555
555
|
`Evaluación de toda la máquina limitada a ${shown} de ${total} repos detectados (los más activos primero).`,
|
|
556
556
|
reposScopeAll: 'Evaluando todo el uso de IA de la máquina.',
|
|
557
557
|
synthesizingLabel: 'Sintetizando agentes con IA…',
|
|
558
|
-
// Roadmap personalization
|
|
558
|
+
// Roadmap personalization: reuses the
|
|
559
559
|
// same spinner mechanism as synthesizingLabel above.
|
|
560
560
|
personalizingRoadmapLabel: 'Personalizando roadmap…',
|
|
561
|
-
|
|
561
|
+
roadmapNotForAccounts: 'El roadmap no está disponible para cuentas de Shakers: tu nivel sale de certificarte.',
|
|
562
|
+
// Agent definition-quality evaluation (ephemeral LLM call).
|
|
562
563
|
evaluatingAgentsLabel: 'Evaluando la calidad de tus agentes…',
|
|
563
|
-
// "Construir el siguiente nivel ahora"
|
|
564
|
+
// "Construir el siguiente nivel ahora": now a SECONDARY, opt-in alternative — the copyable implementation prompt (below) is the PRIMARY "how do I implement this" path.
|
|
564
565
|
buildNextLevelHint: 'Alternativamente, ejecuta `usage --build-next-level` para generar el fichero de partida directamente en tu proyecto.',
|
|
565
|
-
// Ayuda localizada
|
|
566
|
+
// Ayuda localizada: antes estaba hardcodeada en español en bin/report.js; ahora pasa por i18n y respeta la locale de la máquina.
|
|
566
567
|
help:
|
|
567
568
|
'\nShakers — perfil local de uso de herramientas de IA\n\n'
|
|
568
569
|
+ 'Uso:\n usage [opciones]\n\n'
|
|
@@ -575,7 +576,7 @@ const catalogs = {
|
|
|
575
576
|
+ ' --repo Evalúa solo el repo actual\n'
|
|
576
577
|
+ ' --scope machine|repo Igual que --machine / --repo (salta el selector)\n'
|
|
577
578
|
+ ' --all-repos Alias de --machine\n'
|
|
578
|
-
+ ' --roadmap Muestra los pasos para subir tu nivel de uso de IA (
|
|
579
|
+
+ ' --roadmap Muestra los pasos para subir tu nivel de uso de IA (solo sin cuenta de Shakers)\n'
|
|
579
580
|
+ ' --build-next-level Genera el starter del siguiente tier (alternativa secundaria)\n'
|
|
580
581
|
+ ' --force Junto a --build-next-level, sobrescribe un fichero existente\n'
|
|
581
582
|
+ ' --lang es|en Fuerza el idioma (informe + prompt) en vez de detectarlo del sistema\n'
|
|
@@ -616,7 +617,7 @@ const catalogs = {
|
|
|
616
617
|
label: 'AVISO LEGAL',
|
|
617
618
|
},
|
|
618
619
|
consent: {
|
|
619
|
-
//
|
|
620
|
+
// The disclosure wall (what's sent / never sent, itemized) is RETIRED from the CLI — that content now lives in the repo's README.
|
|
620
621
|
persistIntro:
|
|
621
622
|
'Este informe se ha generado y mostrado en tu equipo, siempre. '
|
|
622
623
|
+ 'Guardarlo en Shakers es opcional y revocable en cualquier momento '
|
|
@@ -644,11 +645,11 @@ const catalogs = {
|
|
|
644
645
|
savedUnderEmail: (email) => `El informe se guardará a nombre de: ${email}`,
|
|
645
646
|
invalidEmail: 'Correo no válido, inténtalo de nuevo.',
|
|
646
647
|
notObtained: 'No se ha podido registrar tu respuesta; se te volverá a preguntar la próxima vez.',
|
|
647
|
-
//
|
|
648
|
+
// Esta pregunta se pide ahora ANTES de cualquier llamada de IA/egress (agent-synthesis, agent-evaluation, personalización de roadmap), no después.
|
|
648
649
|
noReportWithoutConsent: 'Sin tu consentimiento, este informe no incluirá síntesis, evaluación ni roadmap generados por IA esta vez (el resto del informe se muestra igual). Vuelve a ejecutar `usage` y acepta para incluirlos, o usa --consent-reset si quieres que se te pregunte de nuevo.',
|
|
649
650
|
deniedSaved: 'Entendido, no se guardará nada. Puedes cambiar de opinión más adelante volviendo a ejecutar el comando.',
|
|
650
|
-
grantedSaved: (email) => `Gracias.
|
|
651
|
-
//
|
|
651
|
+
grantedSaved: (email) => `Gracias. Antes de subir nada a Shakers te enseñaré lo que se enviaría y solo lo subiré si lo apruebas (correo: ${email}, máx. 1 vez por hora).`,
|
|
652
|
+
// Un talento logueado NUNCA ve el prompt de email (su cuenta ya prueba su identidad).
|
|
652
653
|
noSessionEmail: 'No hay un correo asociado a tu sesión todavía, así que no se puede guardar el informe esta vez. Se te preguntará de nuevo la próxima ejecución.',
|
|
653
654
|
skipAlreadyDecided: (decision, path) =>
|
|
654
655
|
`Consentimiento ya respondido (${decision === 'granted' ? 'concedido' : 'rechazado'}) — guardado en ${path}. `
|
|
@@ -681,8 +682,8 @@ const catalogs = {
|
|
|
681
682
|
showConfigFile: (url, path) => `Endpoint de ingesta efectivo: ${url}\n Origen: fichero de config (${path}).`,
|
|
682
683
|
showConfigInvalid: (path) => `El fichero de config (${path}) tiene un endpoint no válido o inseguro; se ignora. Corrígelo con usage --set-endpoint <url>.`,
|
|
683
684
|
showNone: 'No hay endpoint de ingesta configurado. Define SHAKERS_CLI_INGEST_ENDPOINT o usa usage --set-endpoint <url>. Sin él, el informe se sigue mostrando pero no se envía a Shakers.',
|
|
684
|
-
//
|
|
685
|
-
//
|
|
685
|
+
// El CLI habla con una CADENA de dos backends — PRIMARIO (servicio de certificaciones, arriba) y FALLBACK (hub-backend, aquí).
|
|
686
|
+
// The second backend was retired, so the five `showFallback*`/ `setFallbackOk` strings that explained the chain are gone with it.
|
|
686
687
|
showFallbackRetired: 'Nota: tu config.json todavía tiene `ingestEndpointFallback`. Ya no se usa: el CLI habla con un solo backend. Puedes borrar esa línea a mano; dejarla no afecta a nada.',
|
|
687
688
|
confirmHostPrompt: (host) => `El host "${host}" no es localhost ni un dominio conocido de Shakers. Si continúas, tu código muestreado y tus señales de IA se enviarán ahí.\n Escribe el hostname exacto para confirmar (déjalo en blanco para cancelar):`,
|
|
688
689
|
confirmHostMismatch: 'No coincide con el hostname mostrado. Cancelado: no se ha guardado nada.',
|
|
@@ -716,7 +717,7 @@ const catalogs = {
|
|
|
716
717
|
}
|
|
717
718
|
},
|
|
718
719
|
},
|
|
719
|
-
// Email-ownership verification
|
|
720
|
+
// Email-ownership verification: the OTP "modo espera" copy, shared by both binaries.
|
|
720
721
|
verify: {
|
|
721
722
|
sent: (email) => `Te enviamos un código de verificación a ${email}.`,
|
|
722
723
|
waitHint: 'Pega aquí el código. Pulsa "r" y Enter para reenviarlo, o Enter en blanco para cancelar.',
|
|
@@ -732,7 +733,7 @@ const catalogs = {
|
|
|
732
733
|
cancelled: 'Verificación cancelada. No se guardará el informe (el reporte ya se te ha mostrado).',
|
|
733
734
|
unavailable: 'La verificación de correo no está disponible ahora mismo; no se guardará el informe (el reporte ya se te ha mostrado).',
|
|
734
735
|
},
|
|
735
|
-
// Skill Code Certification
|
|
736
|
+
// Skill Code Certification.
|
|
736
737
|
// Copy for the SECOND binary `ai-certify` (resolve phase V1). Localized
|
|
737
738
|
// like the consent flow — legal/disclaimer copy must not default to a
|
|
738
739
|
// language the Talent may not read. Vocabulario CONTEXT: Talent, Skill.
|
|
@@ -972,12 +973,13 @@ const catalogs = {
|
|
|
972
973
|
},
|
|
973
974
|
mcpInstall: {
|
|
974
975
|
title: 'Conectando el MCP de Shakers',
|
|
975
|
-
clients: { claudeDesktop: 'Claude Desktop', claudeCode: 'Claude Code', cursor: 'Cursor', geminiCli: 'Gemini CLI', codex: 'Codex
|
|
976
|
+
clients: { claudeDesktop: 'Claude Desktop', claudeCode: 'Claude Code', cursor: 'Cursor', geminiCli: 'Gemini CLI', codex: 'Codex / ChatGPT', vscode: 'VS Code', windsurf: 'Windsurf' },
|
|
976
977
|
status: {
|
|
977
978
|
configured: 'conectado',
|
|
978
979
|
unchanged: 'ya estaba conectado',
|
|
979
980
|
'not-found': 'no instalado en esta máquina',
|
|
980
|
-
'invalid-
|
|
981
|
+
'invalid-config': 'no puedo editar su configuración con seguridad; no la he tocado',
|
|
982
|
+
manual: 'ejecuta este comando en tu terminal:',
|
|
981
983
|
failed: 'no se pudo conectar',
|
|
982
984
|
},
|
|
983
985
|
removedLegacy: 'Sustituye a la entrada antigua "shakers-ai-usage".',
|
|
@@ -985,7 +987,10 @@ const catalogs = {
|
|
|
985
987
|
confirm: '¿Conecto Shakers a ellas para que puedas usarlo desde tu IA? [S/n]',
|
|
986
988
|
declined: 'No he tocado nada. Para conectarlo más tarde, vuelve a ejecutar el instalador.',
|
|
987
989
|
noTerminal: 'No hay una terminal donde preguntarte, así que no he tocado nada. Vuelve a ejecutar el instalador en tu terminal para conectarlo.',
|
|
988
|
-
restart:
|
|
990
|
+
restart: (apps) => `Reinicia ${apps} (o recarga sus servidores MCP) para que aparezcan las herramientas de Shakers.`,
|
|
991
|
+
alreadyConnected: 'Shakers ya estaba conectado. Si no ves sus herramientas, reinicia la app o recarga sus servidores MCP.',
|
|
992
|
+
yesHint: 'Para conectarlas sin preguntar (por ejemplo, desde un asistente de IA): shakers mcp install --yes',
|
|
993
|
+
help: 'mcp install — conecta Shakers a las apps de IA de esta máquina (Claude Desktop, Claude Code, Cursor, Gemini CLI, Codex / ChatGPT, VS Code, Windsurf).\n\nUso:\n shakers mcp install pregunta en la terminal y conecta las apps encontradas\n shakers mcp install --yes conecta sin preguntar (-y; para asistentes de IA y scripts)\n shakers mcp install --json imprime el resultado como un único objeto JSON\n\nSin --yes y sin terminal no toca nada. SHAKERS_MCP_INSTALL=1 equivale a --yes.\nAl terminar, reinicia las apps que indique (o recarga sus servidores MCP) para que aparezcan las herramientas de Shakers.',
|
|
989
994
|
noneFound: 'No he encontrado ninguna app de IA compatible en esta máquina.',
|
|
990
995
|
failedAll: 'No he podido conectar Shakers a tus apps de IA. Vuelve a ejecutar el instalador para reintentarlo.',
|
|
991
996
|
},
|
|
@@ -1117,7 +1122,7 @@ const catalogs = {
|
|
|
1117
1122
|
failed: (reason) => `No se pudo hablar con Alma (${reason}). Inténtalo de nuevo en un momento.`,
|
|
1118
1123
|
},
|
|
1119
1124
|
certify: {
|
|
1120
|
-
// Aviso legal
|
|
1125
|
+
// Aviso legal: asume el proyecto propiedad del Talent y le
|
|
1121
1126
|
// atribuye la responsabilidad. Aceptación explícita obligatoria.
|
|
1122
1127
|
disclaimer:
|
|
1123
1128
|
'AVISO LEGAL — léelo antes de continuar:\n'
|
|
@@ -1140,7 +1145,7 @@ const catalogs = {
|
|
|
1140
1145
|
disclaimerDeclined: 'No has aceptado el aviso legal. No se ha enviado nada.',
|
|
1141
1146
|
disclaimerInvalidAnswer: 'Respuesta no reconocida. Responde "s" (sí) o "n" (no).',
|
|
1142
1147
|
disclaimerNoAnswer: 'No se ha obtenido respuesta. No se ha enviado nada.',
|
|
1143
|
-
// Certify report (terminal + HTML). Rúbrica anclada + agregación determinista
|
|
1148
|
+
// Certify report (terminal + HTML). Rúbrica anclada + agregación determinista.
|
|
1144
1149
|
report: {
|
|
1145
1150
|
heading: 'Resultado de certificación de Skills TÉCNICAS',
|
|
1146
1151
|
noInterviewNote: 'Preliminar, sin entrevista: la certificación combinada de esta Skill requiere completar su entrevista.',
|
|
@@ -1152,7 +1157,7 @@ const catalogs = {
|
|
|
1152
1157
|
partialSampleWarning:
|
|
1153
1158
|
'Muestra parcial: por los límites de tamaño la valoración se basa en una muestra del '
|
|
1154
1159
|
+ 'código, no en todo el proyecto.',
|
|
1155
|
-
//
|
|
1160
|
+
// Skill levels (by decision power, NOT points) — replace the
|
|
1156
1161
|
// numeric grade in the skill output. `key` from skillLevelForScore.
|
|
1157
1162
|
levelLine: (label) => `Nivel: ${label}`,
|
|
1158
1163
|
skillLevels: {
|
|
@@ -1161,7 +1166,7 @@ const catalogs = {
|
|
|
1161
1166
|
expert: 'Expert',
|
|
1162
1167
|
na: '—',
|
|
1163
1168
|
},
|
|
1164
|
-
//
|
|
1169
|
+
// Rubric dimensions.
|
|
1165
1170
|
dimensionsLabel: 'Dimensiones',
|
|
1166
1171
|
dimensionNA: 'N/A',
|
|
1167
1172
|
dimensionLabels: {
|
|
@@ -1173,7 +1178,7 @@ const catalogs = {
|
|
|
1173
1178
|
},
|
|
1174
1179
|
rationaleLabel: 'Por qué',
|
|
1175
1180
|
improvementsLabel: 'Mejoras sugeridas',
|
|
1176
|
-
//
|
|
1181
|
+
// Authorship receipt (atribución, NO prueba criptográfica).
|
|
1177
1182
|
receipt: {
|
|
1178
1183
|
label: 'Autoría',
|
|
1179
1184
|
repoLabel: 'Repo',
|
|
@@ -1196,11 +1201,11 @@ const catalogs = {
|
|
|
1196
1201
|
`No hay muestreo definido para la tecnología "${technology}": todavía no se puede certificar por código.`,
|
|
1197
1202
|
htmlTitle: 'Certificación de Skills técnicas · Shakers',
|
|
1198
1203
|
noItems: 'No hay resultados de certificación que mostrar.',
|
|
1199
|
-
// Coste
|
|
1204
|
+
// Coste: input mayor = más € por run.
|
|
1200
1205
|
costNote:
|
|
1201
1206
|
'Nota de coste: se analiza bastante código por Skill (hasta ~150k tokens/Skill), '
|
|
1202
1207
|
+ 'lo que tiene un coste por ejecución.',
|
|
1203
|
-
// Prompt de remediación
|
|
1208
|
+
// Prompt de remediación: generado en local desde las mejoras.
|
|
1204
1209
|
remediationHeading: 'Prompt para aplicar las mejoras',
|
|
1205
1210
|
remediationHint: 'Copia este prompt y pégalo en tu herramienta de IA (Claude Code, Cursor…) para aplicar las mejoras.',
|
|
1206
1211
|
remediationIntro: (skillName, technology) =>
|
|
@@ -1213,7 +1218,7 @@ const catalogs = {
|
|
|
1213
1218
|
remediationCopiedLabel: 'Copiado ✓',
|
|
1214
1219
|
},
|
|
1215
1220
|
},
|
|
1216
|
-
// Branded mini-shell chrome
|
|
1221
|
+
// Branded mini-shell chrome.
|
|
1217
1222
|
login: {
|
|
1218
1223
|
intro: 'Inicia sesión con tu email y contraseña de Shakers.',
|
|
1219
1224
|
sessionExpiredIntro: 'Tu sesión anterior caducó. Vuelve a iniciar sesión.',
|
|
@@ -1224,7 +1229,7 @@ const catalogs = {
|
|
|
1224
1229
|
needInput: 'Se necesitan email y contraseña para iniciar sesión.',
|
|
1225
1230
|
success: 'Sesión iniciada. Tu informe ya no incluye el roadmap ni las sugerencias de mejora: tu nivel sale de certificarte.',
|
|
1226
1231
|
expiresAt: (iso) => `La sesión caduca: ${iso}. Cuando expire te lo diré y podrás volver a entrar con \`login\`.`,
|
|
1227
|
-
loggedOut: 'Sesión cerrada. Vuelves a ver
|
|
1232
|
+
loggedOut: 'Sesión cerrada. Vuelves a ver las sugerencias de mejora en tu informe.',
|
|
1228
1233
|
notLoggedIn: 'No había ninguna sesión iniciada. No hay nada que cerrar.',
|
|
1229
1234
|
errorInvalidCredentials: 'Credenciales incorrectas: revisa tu email y contraseña e inténtalo otra vez.',
|
|
1230
1235
|
errorNoEmailPassword: 'Esta cuenta existe pero no tiene contraseña de email: la registraste con Google o LinkedIn. Si fue con Google, usa `login --google`. Si fue con LinkedIn, entra desde la web para añadir una contraseña por ahora.',
|
|
@@ -1234,7 +1239,7 @@ const catalogs = {
|
|
|
1234
1239
|
errorNoEndpoint: 'No hay endpoint configurado. login usa la misma base que usage: define SHAKERS_CLI_INGEST_ENDPOINT o usa `usage --set-endpoint <url>`.',
|
|
1235
1240
|
errorPersist: 'El inicio de sesión funcionó, pero no se pudo guardar la sesión en disco. Revisa los permisos de ~/.config/shakers y vuelve a intentarlo.',
|
|
1236
1241
|
errorGeneric: 'No se pudo iniciar sesión. Inténtalo de nuevo.',
|
|
1237
|
-
//
|
|
1242
|
+
// Login con Google por loopback (`login --google`).
|
|
1238
1243
|
googleIntro: 'Inicia sesión con Google. Se abrirá tu navegador para autorizar; al terminar, vuelve aquí.',
|
|
1239
1244
|
googleOpening: 'Abriendo el navegador para iniciar sesión con Google…',
|
|
1240
1245
|
googlePasteUrl: 'Si el navegador no se abre solo, pega esta URL en él:',
|
|
@@ -1264,7 +1269,7 @@ const catalogs = {
|
|
|
1264
1269
|
selectHint: 'Flechas ↑/↓ para moverte · enter para elegir · esc para cancelar',
|
|
1265
1270
|
chooseMethodPrompt: (max) => `Número (1-${max}), vacío para cancelar: `,
|
|
1266
1271
|
},
|
|
1267
|
-
// `start
|
|
1272
|
+
// `start`: la herramienta para un talento YA registrado en Shakers que quiere completar su perfil agéntico.
|
|
1268
1273
|
start: {
|
|
1269
1274
|
help:
|
|
1270
1275
|
'start — completa tu perfil de talento agéntico en Shakers: inicia sesión, evalúa tu uso de IA\n'
|
|
@@ -1288,10 +1293,10 @@ const catalogs = {
|
|
|
1288
1293
|
menuHint: 'Flechas ↑/↓ para moverte · enter para elegir · esc para cancelar',
|
|
1289
1294
|
menuPrompt: (max) => `Número (1-${max}), vacío para cancelar: `,
|
|
1290
1295
|
menuRerun: 'Volver a lanzar la evaluación de uso de IA',
|
|
1291
|
-
//
|
|
1296
|
+
// Renombrado — el label decía "Añadir" pero la acción es declarar/subir lo detectado al PERFIL de Shakers, no crear algo nuevo desde cero.
|
|
1292
1297
|
menuAddSkills: 'Subir skills a tu perfil',
|
|
1293
1298
|
menuAddAgents: 'Subir agentes a tu perfil',
|
|
1294
|
-
//
|
|
1299
|
+
// "Añadir proyecto al portfolio" — junto a las de skills/agentes, antes de certificar (declarar cosas de tu perfil, luego certificarlas).
|
|
1295
1300
|
menuAddPortfolio: 'Añadir proyecto al portfolio',
|
|
1296
1301
|
menuCertifySkills: 'Certificar skills',
|
|
1297
1302
|
menuCertifyAgents: 'Certificar agentes',
|
|
@@ -1310,7 +1315,7 @@ const catalogs = {
|
|
|
1310
1315
|
menuCertifyAgentsDesc:
|
|
1311
1316
|
'Un reto valida que el agente es real, es tuyo y lo operas con criterio. Obtienes el agente Certified con su tracción → la señal más fuerte de tu perfil agéntico.',
|
|
1312
1317
|
menuCancelled: 'Cancelado. No se ha hecho nada.',
|
|
1313
|
-
//
|
|
1318
|
+
// Cierre del BUCLE del menú — usado tanto al elegir "Salir" explícitamente como al cancelar (esc / respuesta vacía) DESDE DENTRO del bucle.
|
|
1314
1319
|
menuGoodbye: 'Sesión de `start` terminada. Ejecuta `start` de nuevo cuando quieras seguir completando tu perfil.',
|
|
1315
1320
|
addAgentsComingSoon:
|
|
1316
1321
|
'Añadir agentes: próximamente. Tus agentes serán activos de tu perfil agéntico — todavía no existe esa ficha en Shakers, así que de momento no hay dónde guardarlos.',
|
|
@@ -1329,7 +1334,7 @@ const catalogs = {
|
|
|
1329
1334
|
addSkillsNoneChosen: 'No has elegido ninguna skill. No se ha añadido nada a tu perfil.',
|
|
1330
1335
|
addSkillsDeclaredOne: (skillName) => `✓ Añadida a tu perfil: ${skillName} (sin verificar).`,
|
|
1331
1336
|
addSkillsDeclareFailed: (skillName, reason) => `✗ No se pudo añadir ${skillName}: ${reason}`,
|
|
1332
|
-
// Cierre de la visión
|
|
1337
|
+
// Cierre de la visión: UNA vez, después del lote — no repetido por cada skill (repetir la misma frase por ítem es ruido, no refuerzo).
|
|
1333
1338
|
addSkillsProfileBoost: 'Cada skill que añades suma a tu perfil: apareces en más búsquedas.',
|
|
1334
1339
|
addSkillsHubSessionExpired: 'Tu sesión de Shakers ha caducado mientras añadíamos tus skills.',
|
|
1335
1340
|
addSkillsOfferRelogin: '¿Quieres volver a iniciar sesión ahora para seguir? (s/n):',
|
|
@@ -1344,7 +1349,7 @@ const catalogs = {
|
|
|
1344
1349
|
addSkillsRelateSkipped: (skillName) => `"${skillName}" añadida sin relacionar.`,
|
|
1345
1350
|
addSkillsRelated: (skillName, portfolioName) => ` ✓ "${skillName}" relacionada con "${portfolioName}".`,
|
|
1346
1351
|
addSkillsRelateFailed: (skillName, portfolioName, reason) => ` ✗ No se pudo relacionar "${skillName}" con "${portfolioName}": ${reason}`,
|
|
1347
|
-
//
|
|
1352
|
+
// "Añadir proyecto al portfolio".
|
|
1348
1353
|
portfolioIntro:
|
|
1349
1354
|
'Vamos a añadir este proyecto a tu portfolio de Shakers. La mayoría de los datos vienen pre-rellenados desde tu código y tu git: confirma o edita cada uno.',
|
|
1350
1355
|
portfolioErrorNoEndpoint:
|
|
@@ -1356,7 +1361,7 @@ const catalogs = {
|
|
|
1356
1361
|
portfolioDuplicateName: (name) => `Ya tienes un proyecto llamado "${name}" en tu portfolio. No se ha creado uno duplicado — vuelve a ejecutar esta opción con otro título si quieres añadir uno distinto.`,
|
|
1357
1362
|
// (1) Título ← nombre del directorio, editable.
|
|
1358
1363
|
portfolioTitlePrompt: (def) => `Título del proyecto [${def}]:`,
|
|
1359
|
-
// (2) Tipo ← PORTFOLIO/EXPERIENCE, obligatorio. Copy de visión
|
|
1364
|
+
// (2) Tipo ← PORTFOLIO/EXPERIENCE, obligatorio. Copy de visión:
|
|
1360
1365
|
// qué significa cada tipo para tu perfil, mostrado SOLO al resaltar.
|
|
1361
1366
|
portfolioTypeHeading: '¿Qué tipo de entrada es?',
|
|
1362
1367
|
portfolioTypeHint: 'Flechas ↑/↓ para moverte · enter para elegir · esc para cancelar',
|
|
@@ -1367,7 +1372,7 @@ const catalogs = {
|
|
|
1367
1372
|
portfolioTypeExperience: 'Experiencia',
|
|
1368
1373
|
portfolioTypeExperienceDesc:
|
|
1369
1374
|
'Lo añade a tu perfil como experiencia profesional (freelance o de plantilla): cuenta en tu trayectoria, no como una pieza para mostrar.',
|
|
1370
|
-
// (3) Descripción ← IA pre-redacta tras consentimiento
|
|
1375
|
+
// (3) Descripción ← IA pre-redacta tras consentimiento.
|
|
1371
1376
|
portfolioDescriptionConsentDisclaimer:
|
|
1372
1377
|
'Para redactar un borrador de la descripción con IA, se enviarán a Shakers: el nombre del proyecto, las tecnologías detectadas y, si existen, el contenido del README y la descripción del package.json.',
|
|
1373
1378
|
portfolioDescriptionDraftLabel: 'Borrador generado por IA:',
|
|
@@ -1395,7 +1400,7 @@ const catalogs = {
|
|
|
1395
1400
|
portfolioRelaunchAfterRelogin: 'Sesión renovada. Reintentamos añadir el proyecto a tu portfolio.',
|
|
1396
1401
|
portfolioRelaunchDeclined: 'Vale. Ejecuta `login` y vuelve a elegir "Añadir proyecto al portfolio" cuando quieras.',
|
|
1397
1402
|
portfolioReloginFailed: 'No se pudo volver a iniciar sesión. El proyecto no se ha añadido a tu portfolio.',
|
|
1398
|
-
//
|
|
1403
|
+
// "Añadir agente al perfil".
|
|
1399
1404
|
agentErrorNoEndpoint:
|
|
1400
1405
|
'No hay endpoint configurado. `start` usa la misma base que `usage`: define el endpoint con `usage --set-endpoint <url>` (o SHAKERS_CLI_INGEST_ENDPOINT).',
|
|
1401
1406
|
agentNoHubToken:
|
|
@@ -1416,7 +1421,7 @@ const catalogs = {
|
|
|
1416
1421
|
agentCancelled: 'Cancelado. No se ha añadido ningún agente a tu perfil.',
|
|
1417
1422
|
// (3) Nombre ← detectado, editable.
|
|
1418
1423
|
agentNamePrompt: (def) => `Nombre del agente [${def}]:`,
|
|
1419
|
-
// (4) whatItDoes + humanDecides ← IA pre-redacta tras consentimiento
|
|
1424
|
+
// (4) whatItDoes + humanDecides ← IA pre-redacta tras consentimiento.
|
|
1420
1425
|
agentFieldsConsentDisclaimer:
|
|
1421
1426
|
'Para redactar un borrador con IA de qué hace tu agente y qué decides tú, se enviarán a Shakers: el nombre del agente, sus herramientas/modelo/agente padre detectados y un resumen de su definición (sus propias instrucciones).',
|
|
1422
1427
|
agentDraftingLabel: 'Redactando un borrador con IA…',
|
|
@@ -1459,7 +1464,7 @@ const catalogs = {
|
|
|
1459
1464
|
errorReasonHttp: (status) => `el servidor respondió con un error (HTTP ${status}).`,
|
|
1460
1465
|
},
|
|
1461
1466
|
superadmin: {
|
|
1462
|
-
//
|
|
1467
|
+
// Sesión de superadmin autenticada por contraseña (no-prod).
|
|
1463
1468
|
sessionIntro:
|
|
1464
1469
|
'Abre una sesión de superadmin (solo entornos no productivos): certify funcionará con CUALQUIER email en CUALQUIER repo, saltándose los gates de identidad y autoría.',
|
|
1465
1470
|
passwordPrompt: 'Contraseña de superadmin:',
|
|
@@ -1472,7 +1477,7 @@ const catalogs = {
|
|
|
1472
1477
|
sessionHint:
|
|
1473
1478
|
'Ejecuta: certify --email <cualquiera> --accept-disclaimer --skill <nombre> · Para cerrarla: superadmin --logout',
|
|
1474
1479
|
loggedOut: 'Sesión de superadmin olvidada (token local eliminado).',
|
|
1475
|
-
//
|
|
1480
|
+
// Conmutador de perfil vía superadmin: conveniencia de dev/testing — cambia entre perfil talent/external sin reinstalar.
|
|
1476
1481
|
profileMenuHeading: '¿Qué quieres hacer?',
|
|
1477
1482
|
profileMenuHint: 'Flechas ↑/↓ para moverte · enter para elegir · esc para cancelar',
|
|
1478
1483
|
profileMenuPrompt: (max) => `Número (1-${max}), vacío para cancelar: `,
|
|
@@ -1487,7 +1492,7 @@ const catalogs = {
|
|
|
1487
1492
|
profileMenuCancelled: 'Cancelado. No se ha cambiado nada.',
|
|
1488
1493
|
profileAlreadyOn: (profile) => `Ya estás en el perfil ${profile === 'talent' ? 'Talent' : 'External'}. No se ha cambiado ni purgado nada.`,
|
|
1489
1494
|
profileSwitched: (profile) => `Perfil cambiado a ${profile === 'talent' ? 'Talent' : 'External'} · historial limpiado (informe, consentimiento, sesión de talento) · efecto inmediato, sin reiniciar.`,
|
|
1490
|
-
//
|
|
1495
|
+
// Superadmin es DELIBERADAMENTE single-hop, SOLO PRIMARIO (servicio de certificaciones) — nunca hub.
|
|
1491
1496
|
queryingPrimary: (endpoint) => `Consultando Shakers: ${endpoint}`,
|
|
1492
1497
|
errorNoEndpoint:
|
|
1493
1498
|
'No hay endpoint configurado. Configura el backend (SHAKERS_CLI_INGEST_ENDPOINT o usage --set-endpoint) y reinténtalo.',
|
|
@@ -1495,7 +1500,7 @@ const catalogs = {
|
|
|
1495
1500
|
errorDisabled:
|
|
1496
1501
|
'Endpoint no disponible: la sesión de superadmin está deshabilitada fuera de entornos no productivos.',
|
|
1497
1502
|
errorGeneric: 'No se pudo abrir la sesión de superadmin. Inténtalo de nuevo.',
|
|
1498
|
-
// Inspect
|
|
1503
|
+
// Inspect — recibo de atribución de certificaciones YA guardadas.
|
|
1499
1504
|
inspectIntro:
|
|
1500
1505
|
'Audita la evidencia de autoría de las certificaciones ya guardadas (solo lectura, entornos no productivos).',
|
|
1501
1506
|
inspectEmailPrompt: 'Email cuya(s) certificación(es) quieres inspeccionar:',
|
|
@@ -1521,7 +1526,7 @@ const catalogs = {
|
|
|
1521
1526
|
// in-shell command help and messages — the commands keep their own copy.
|
|
1522
1527
|
repl: {
|
|
1523
1528
|
prompt: 'ϟ shakers ›',
|
|
1524
|
-
//
|
|
1529
|
+
// El BANNER de arranque (src/repl-shell.js) ahora es profile-aware y localizado.
|
|
1525
1530
|
bannerWelcome: 'Bienvenido a',
|
|
1526
1531
|
bannerTalentLine1: 'Completa o actualiza tu perfil de talento',
|
|
1527
1532
|
bannerTalentLine2: 'agéntico en Shakers: no solo qué sabes, sino',
|
|
@@ -1542,7 +1547,7 @@ const catalogs = {
|
|
|
1542
1547
|
bannerExternalMapDesc: 'informe LOCAL (grafo)',
|
|
1543
1548
|
bannerExternalReportDesc: 'informe HTML compartible',
|
|
1544
1549
|
bannerExternalShareDesc: 'tarjeta para LinkedIn',
|
|
1545
|
-
// FLUJO DE COMANDOS
|
|
1550
|
+
// FLUJO DE COMANDOS VOCABULARIO, y lo hereda la 083: aquí se habla de COMANDOS de la herramienta.
|
|
1546
1551
|
completeNeeds: (cmd) => `(necesita: ${cmd})`,
|
|
1547
1552
|
completeDone: '(ya ejecutado)',
|
|
1548
1553
|
completeDoneStale: (days) => `(ya ejecutado, hace ${days} días)`,
|
|
@@ -1575,7 +1580,7 @@ const catalogs = {
|
|
|
1575
1580
|
journeyDone: 'Has completado el recorrido de la herramienta: no queda ningún comando por ejecutar. Los siguientes pasos para subir tu nivel de uso de IA son otra cosa y están en `usage --roadmap`.',
|
|
1576
1581
|
goodbye: 'Hasta pronto.',
|
|
1577
1582
|
unknown: (cmd) => `Comando no reconocido: "${cmd}". Escribe "help" para ver los comandos disponibles.`,
|
|
1578
|
-
// ORDEN: lo declara src/command-graph.js
|
|
1583
|
+
// ORDEN: lo declara src/command-graph.js.
|
|
1579
1584
|
help:
|
|
1580
1585
|
'Shakers — comandos disponibles\n\n'
|
|
1581
1586
|
+ ' usage [opciones] Escanea este proyecto y tu equipo; puntúa tu setup de IA (T0-T7)\n'
|
|
@@ -1618,7 +1623,7 @@ const catalogs = {
|
|
|
1618
1623
|
toolsS: 'Clientes de IA presentes en tu entorno.',
|
|
1619
1624
|
techT: 'Tecnologías del proyecto',
|
|
1620
1625
|
techS: 'Stack reconocido en el repositorio.',
|
|
1621
|
-
//
|
|
1626
|
+
// Los SERVICIOS detrás de los MCP.
|
|
1622
1627
|
mcpT: 'Servicios conectados por MCP',
|
|
1623
1628
|
mcpS: 'Productos a los que tu IA tiene acceso.',
|
|
1624
1629
|
mcpEmpty: 'No se ha detectado ningún servidor MCP. Conectar uno es el criterio que te sube a T3 (Banco conectado).',
|
|
@@ -1626,7 +1631,7 @@ const catalogs = {
|
|
|
1626
1631
|
// 085: la pestaña decía "Skills" a secas junto a una de "Agentes", que es
|
|
1627
1632
|
// la colisión exacta que la issue nombra.
|
|
1628
1633
|
skills: 'Skills técnicas',
|
|
1629
|
-
// ---- Agentes DETECTADOS, columna izquierda
|
|
1634
|
+
// ---- Agentes DETECTADOS, columna izquierda --------------
|
|
1630
1635
|
agentsT: 'Agentes detectados',
|
|
1631
1636
|
agentsS: 'Todos los agentes que hay configurados en tu entorno. Certificar es otra cosa y está en la columna de la derecha.',
|
|
1632
1637
|
agentsEmpty: 'No se ha detectado ningún agente configurado (p. ej. en .claude/agents/). Si tienes agentes y no salen aquí, es que la herramienta no los ha encontrado, no que no cuenten.',
|
|
@@ -1642,7 +1647,7 @@ const catalogs = {
|
|
|
1642
1647
|
hereYouAre: 'Estás aquí',
|
|
1643
1648
|
noFoot: 'Aún no hay uso de IA. Ejecuta usage en este proyecto.',
|
|
1644
1649
|
noSkills: 'Aún no hay Skills técnicas certificadas. Ejecuta certify skills.',
|
|
1645
|
-
// Agent certifications were removed from the report
|
|
1650
|
+
// Agent certifications were removed from the report; the sheet's agent-cert tab, its empty state and its detected-vs-certified copy went with it.
|
|
1646
1651
|
footer: 'Informe generado localmente · Shakers',
|
|
1647
1652
|
// Template chrome that used to be hardcoded Spanish in report-sheet.html (including inside its inline <script>), so an English report shipped Spanish controls.
|
|
1648
1653
|
themeToggle: 'Cambiar tema',
|
|
@@ -1869,10 +1874,10 @@ const catalogs = {
|
|
|
1869
1874
|
t7Blocking: (n) => `To reach T7 (Orchestrated workshop) you need at least one automation hook configured — you have ${n} now.`,
|
|
1870
1875
|
},
|
|
1871
1876
|
},
|
|
1872
|
-
// Progression ladder
|
|
1877
|
+
// Progression ladder — see the es block.
|
|
1873
1878
|
ladder: {
|
|
1874
1879
|
levelsHeading: 'Maturity levels (0-4)',
|
|
1875
|
-
//
|
|
1880
|
+
// The ladder now groups tiers by SETUP LEVEL, not the 0-4 band.
|
|
1876
1881
|
setupHeading: 'Setup Level',
|
|
1877
1882
|
setupIntro:
|
|
1878
1883
|
'Your setup level (S1–S3) sums up your AI usage at a glance; the tier (T0-T7) is the '
|
|
@@ -1909,7 +1914,7 @@ const catalogs = {
|
|
|
1909
1914
|
T7: 'Orchestrated workshop: hooks automate the workshop and agents orchestrate each other.',
|
|
1910
1915
|
},
|
|
1911
1916
|
},
|
|
1912
|
-
// Agent classification + improvement tips
|
|
1917
|
+
// Agent classification + improvement tips — see the es block.
|
|
1913
1918
|
classification: {
|
|
1914
1919
|
label: 'Classification',
|
|
1915
1920
|
noCategory: 'No category',
|
|
@@ -1946,7 +1951,7 @@ const catalogs = {
|
|
|
1946
1951
|
},
|
|
1947
1952
|
},
|
|
1948
1953
|
// LEGACY 0-4 band names — kept only for older persisted reports / the
|
|
1949
|
-
// unchanged sent payload
|
|
1954
|
+
// unchanged sent payload; the report shows `setupLevels` instead.
|
|
1950
1955
|
levelNames: {
|
|
1951
1956
|
none: 'No AI usage',
|
|
1952
1957
|
exploring: 'Exploring',
|
|
@@ -1954,7 +1959,7 @@ const catalogs = {
|
|
|
1954
1959
|
power: 'Power user',
|
|
1955
1960
|
orchestrator: 'Orchestrator',
|
|
1956
1961
|
},
|
|
1957
|
-
// Setup Level (Talent Certification Framework
|
|
1962
|
+
// Setup Level (Talent Certification Framework): the 3-value rollup that REPLACES the 0-4 band on every surface.
|
|
1958
1963
|
setupLevels: {
|
|
1959
1964
|
none: {
|
|
1960
1965
|
label: 'Not certified',
|
|
@@ -1991,7 +1996,7 @@ const catalogs = {
|
|
|
1991
1996
|
brandSub: 'AI usage profile',
|
|
1992
1997
|
toolsDetected: (n, total) => `${n}/${total} tools detected`,
|
|
1993
1998
|
level: (level, name) => `Level ${level} · ${name}`,
|
|
1994
|
-
//
|
|
1999
|
+
// Setup Level shown in the top bar (replaces the 0-4 level line).
|
|
1995
2000
|
setupLevel: (label) => `Setup · ${label}`,
|
|
1996
2001
|
// Current tier appended to the top bar, next to the level (report req 1 addendum).
|
|
1997
2002
|
tierInline: (key, name) => ` · Tier ${key} · ${name}`,
|
|
@@ -2019,22 +2024,22 @@ const catalogs = {
|
|
|
2019
2024
|
environment: 'Environment',
|
|
2020
2025
|
editors: 'editors',
|
|
2021
2026
|
noEditorsDetected: 'none detected',
|
|
2022
|
-
//
|
|
2027
|
+
// Agent evaluation (terminal, one line per agent): compact usage
|
|
2023
2028
|
// signal derived from the local Claude Code history.
|
|
2024
2029
|
agentUsed: (n) => `used ${n}×`,
|
|
2025
2030
|
agentUnused: 'no local use',
|
|
2026
2031
|
agentUsageUnavailable: '(no local Claude Code history: usage unavailable)',
|
|
2027
|
-
//
|
|
2032
|
+
// Discoverability hint for the next-steps section (behind --roadmap).
|
|
2028
2033
|
roadmapHint: 'Run `usage --roadmap` to see the steps between you and the next AI-usage level. These are not steps in this tool: they are changes to how you work, over the coming weeks.',
|
|
2029
2034
|
aiProfileGenerating: 'Generating your AI profile (matrix, vision and how you work)…',
|
|
2030
2035
|
aiProfilePendingRetry: 'Your AI profile (matrix, vision and how you work) is still being generated; re-run `report` in a moment to see it.',
|
|
2031
|
-
//
|
|
2036
|
+
// Shown when a session existed and has expired. Opens
|
|
2032
2037
|
// with "Your session has expired" — see the Spanish catalog.
|
|
2033
2038
|
sessionExpiredNotice: 'Your session has expired. You are seeing the full report as a general user; run `login` to sign in again.',
|
|
2034
2039
|
nextStep: 'Next step to level up',
|
|
2035
2040
|
files: (n) => `${n} ${n === 1 ? 'file' : 'files'}`,
|
|
2036
2041
|
lastModified: (label) => `last modified: ${label}`,
|
|
2037
|
-
//
|
|
2042
|
+
// "Project technologies" is renamed "Skills" for the TALENT profile only (naming unicity with the rest of the talent surface).
|
|
2038
2043
|
skillsHeading: 'Skills',
|
|
2039
2044
|
},
|
|
2040
2045
|
html: {
|
|
@@ -2043,7 +2048,7 @@ const catalogs = {
|
|
|
2043
2048
|
h1: 'Your AI usage profile',
|
|
2044
2049
|
sub: 'A local snapshot of which AI tools you have and how deeply you have configured them.',
|
|
2045
2050
|
levelOf: (level) => `Level ${level} of 4`,
|
|
2046
|
-
//
|
|
2051
|
+
// Hero label for the Setup Level (replaces the 0-4 "Level X of 4").
|
|
2047
2052
|
setupLevelOf: 'Setup Level',
|
|
2048
2053
|
// Current tier shown in the hero bar next to the level (report req 1 addendum).
|
|
2049
2054
|
currentTier: (key, name) => `Tier ${key} · ${name}`,
|
|
@@ -2066,17 +2071,17 @@ const catalogs = {
|
|
|
2066
2071
|
agentDescriptionFromName: (name) => `"${name}" agent (no description declared in its file).`,
|
|
2067
2072
|
// AI product an agent belongs to, derived from its source (proper nouns; same es/en).
|
|
2068
2073
|
aiProducts: { 'claude-code': 'Claude Code' },
|
|
2069
|
-
//
|
|
2074
|
+
// Agent evaluation (HTML per-agent detail): definition-quality score + LLM rationale + local usage signal.
|
|
2070
2075
|
agentScoreLabel: 'Definition quality (0-100)',
|
|
2071
2076
|
agentQualityLabel: 'Why:',
|
|
2072
2077
|
agentUsageLabel: 'Local usage (Claude Code history)',
|
|
2073
2078
|
agentUsedTimes: (n) => `used ${n}×`,
|
|
2074
2079
|
agentUnused: 'no local use',
|
|
2075
|
-
// Project technologies
|
|
2080
|
+
// Project technologies. Refined: shows
|
|
2076
2081
|
// recognized FRAMEWORKS/LIBRARIES only, not a raw dependency dump.
|
|
2077
2082
|
technologiesHeading: 'Project technologies',
|
|
2078
2083
|
technologiesEmpty: 'No recognized framework or library was found in the dependency manifests (package.json, requirements.txt, go.mod, pyproject.toml).',
|
|
2079
|
-
// MCP servers by name
|
|
2084
|
+
// MCP servers by name.
|
|
2080
2085
|
mcpHeading: 'Services connected over MCP',
|
|
2081
2086
|
mcpEmpty: 'No MCP server detected. Connecting one is the criterion that takes you to T3 (Connected bench).',
|
|
2082
2087
|
mcpUnidentified: (n) => `${n} more server${n === 1 ? '' : 's'} whose service we could not identify from its name.`,
|
|
@@ -2092,10 +2097,10 @@ const catalogs = {
|
|
|
2092
2097
|
roadmapHonestyLabel: 'Honesty note',
|
|
2093
2098
|
roadmapContentUnavailable: "This level's detailed content isn't available in this language yet.",
|
|
2094
2099
|
roadmapPersonalizedNotice: 'Content adapted to your project.',
|
|
2095
|
-
//
|
|
2100
|
+
// See the Spanish catalog for why these say what was lost
|
|
2096
2101
|
// rather than what went wrong, and when they are allowed to show.
|
|
2097
|
-
roadmapNotPersonalizedNotice: 'This roadmap is the generic one for your tier: it could not be adapted to your project this run. Run `usage` again to retry.',
|
|
2098
|
-
//
|
|
2102
|
+
roadmapNotPersonalizedNotice: 'This roadmap is the generic one for your tier: it could not be adapted to your project this run. Run `usage --roadmap` again to retry.',
|
|
2103
|
+
// See the Spanish catalog for why the tag sits next to the
|
|
2099
2104
|
// heading instead of in a footnote.
|
|
2100
2105
|
roadmapNowLabel: 'Where you start from',
|
|
2101
2106
|
roadmapProjectionLabel: 'Where this path leaves you',
|
|
@@ -2114,9 +2119,9 @@ const catalogs = {
|
|
|
2114
2119
|
rawData: "View this report's exact data (JSON)",
|
|
2115
2120
|
},
|
|
2116
2121
|
cli: {
|
|
2117
|
-
// Reporting redesign
|
|
2122
|
+
// Reporting redesign: HTML is no longer opt-in (--html retired).
|
|
2118
2123
|
reportLink: (url) => `Open your report in your browser:\n ${url}`,
|
|
2119
|
-
// `share` command
|
|
2124
|
+
// `share` command: CLI copy wrapping the branded LinkedIn card.
|
|
2120
2125
|
share: {
|
|
2121
2126
|
help: 'share — build a branded card with your AI usage result (tier + score) to post on LinkedIn.\n'
|
|
2122
2127
|
+ ' Run `usage` first; `share` uses this project\'s latest AI usage.\n'
|
|
@@ -2166,7 +2171,7 @@ const catalogs = {
|
|
|
2166
2171
|
available: (from, to) => `A newer Shakers CLI is available: ${from} → ${to}`,
|
|
2167
2172
|
howTo: 'Run `shakers update` to upgrade.',
|
|
2168
2173
|
},
|
|
2169
|
-
// `report` command
|
|
2174
|
+
// `report` command: builds and OPENS the full, shareable HTML report for this project (AI usage + certified Skills).
|
|
2170
2175
|
report: {
|
|
2171
2176
|
help: 'report — build and open the full HTML report for this project (AI usage + certified Skills) to share with your team.\n'
|
|
2172
2177
|
+ ' Run `usage` (and optionally `certify`) first; `report` gathers their result.\n'
|
|
@@ -2198,10 +2203,11 @@ const catalogs = {
|
|
|
2198
2203
|
reposScopeAll: 'Evaluating all AI usage on this machine.',
|
|
2199
2204
|
synthesizingLabel: 'Synthesizing agents with AI…',
|
|
2200
2205
|
personalizingRoadmapLabel: 'Personalizing roadmap…',
|
|
2201
|
-
|
|
2206
|
+
roadmapNotForAccounts: 'The roadmap is not available for Shakers accounts: your level comes from certifying.',
|
|
2207
|
+
// Agent definition-quality evaluation (ephemeral LLM call).
|
|
2202
2208
|
evaluatingAgentsLabel: 'Evaluating your agents’ quality…',
|
|
2203
2209
|
buildNextLevelHint: 'Alternatively, run `usage --build-next-level` to generate the starter file directly in your project.',
|
|
2204
|
-
// Localized help
|
|
2210
|
+
// Localized help: previously hardcoded Spanish in bin/report.js; now routed through i18n so it respects the machine locale.
|
|
2205
2211
|
help:
|
|
2206
2212
|
'\nShakers — local profile of your AI-tool usage\n\n'
|
|
2207
2213
|
+ 'Usage:\n usage [options]\n\n'
|
|
@@ -2214,7 +2220,7 @@ const catalogs = {
|
|
|
2214
2220
|
+ ' --repo Evaluate the current repo only\n'
|
|
2215
2221
|
+ ' --scope machine|repo Same as --machine / --repo (skips the picker)\n'
|
|
2216
2222
|
+ ' --all-repos Alias of --machine\n'
|
|
2217
|
-
+ ' --roadmap Show the steps to raise your AI-usage level (
|
|
2223
|
+
+ ' --roadmap Show the steps to raise your AI-usage level (only without a Shakers account)\n'
|
|
2218
2224
|
+ ' --build-next-level Generate the next tier starter (secondary alternative)\n'
|
|
2219
2225
|
+ ' --force With --build-next-level, overwrite an existing file\n'
|
|
2220
2226
|
+ ' --lang es|en Force the language (report + prompt) instead of OS detection\n'
|
|
@@ -2236,7 +2242,7 @@ const catalogs = {
|
|
|
2236
2242
|
+ 'file (--set-endpoint) > none. Without an endpoint, the report is shown but not sent\n'
|
|
2237
2243
|
+ 'to Shakers.\n',
|
|
2238
2244
|
},
|
|
2239
|
-
// Cumulative report
|
|
2245
|
+
// Cumulative report — English mirror.
|
|
2240
2246
|
cumulative: {
|
|
2241
2247
|
title: 'Your Shakers report',
|
|
2242
2248
|
privacyNote: 'This report is generated and stored only on your machine. Nothing is sent to Shakers unless you give explicit consent.',
|
|
@@ -2252,12 +2258,12 @@ const catalogs = {
|
|
|
2252
2258
|
noFileTarget: "The next step isn't a file this command can create — check the roadmap snippet in the report.",
|
|
2253
2259
|
unrecognizedTier: "Couldn't determine your current tier.",
|
|
2254
2260
|
},
|
|
2255
|
-
//
|
|
2261
|
+
// Mirrors the es catalog's `legalNotice` — see its comment.
|
|
2256
2262
|
legalNotice: {
|
|
2257
2263
|
label: 'LEGAL NOTICE',
|
|
2258
2264
|
},
|
|
2259
2265
|
consent: {
|
|
2260
|
-
//
|
|
2266
|
+
// The disclosure wall (itemized sends / never sends) is RETIRED from the CLI — that content now lives in the repo's README.
|
|
2261
2267
|
persistIntro:
|
|
2262
2268
|
'This report has already been generated and shown on your machine, '
|
|
2263
2269
|
+ 'always. Saving it in Shakers is optional and revocable at any '
|
|
@@ -2284,11 +2290,11 @@ const catalogs = {
|
|
|
2284
2290
|
savedUnderEmail: (email) => `The report will be saved under: ${email}`,
|
|
2285
2291
|
invalidEmail: 'Invalid email, try again.',
|
|
2286
2292
|
notObtained: "Couldn't record your answer; you'll be asked again next time.",
|
|
2287
|
-
//
|
|
2293
|
+
// This question is now asked BEFORE any AI/egress call (agent-synthesis, agent-evaluation, roadmap personalization), not after.
|
|
2288
2294
|
noReportWithoutConsent: 'Without your consent, this report will not include AI-generated synthesis, evaluation, or roadmap this time (the rest of the report is shown as usual). Run `usage` again and accept to include them, or use --consent-reset if you want to be asked again.',
|
|
2289
2295
|
deniedSaved: 'Understood, nothing will be saved. You can change your mind later by running the command again.',
|
|
2290
|
-
grantedSaved: (email) => `Thanks.
|
|
2291
|
-
//
|
|
2296
|
+
grantedSaved: (email) => `Thanks. Before anything is uploaded to Shakers I will show you what would be sent, and I will upload it only if you approve it (email: ${email}, at most once an hour).`,
|
|
2297
|
+
// A logged-in Talent is NEVER asked for an email (their account already proves identity).
|
|
2292
2298
|
noSessionEmail: "There's no email on file for your session yet, so this report can't be saved this time. You'll be asked again next run.",
|
|
2293
2299
|
skipAlreadyDecided: (decision, path) =>
|
|
2294
2300
|
`Consent already answered (${decision}) — stored at ${path}. `
|
|
@@ -2321,7 +2327,7 @@ const catalogs = {
|
|
|
2321
2327
|
showConfigFile: (url, path) => `Effective ingest endpoint: ${url}\n Source: config file (${path}).`,
|
|
2322
2328
|
showConfigInvalid: (path) => `The config file (${path}) has an invalid or insecure endpoint; it is ignored. Fix it with usage --set-endpoint <url>.`,
|
|
2323
2329
|
showNone: 'No ingest endpoint configured. Set SHAKERS_CLI_INGEST_ENDPOINT or use usage --set-endpoint <url>. Without it, the report is still shown but not sent to Shakers.',
|
|
2324
|
-
//
|
|
2330
|
+
// The CLI now talks to a CHAIN of two backends — PRIMARY (certifications service, above) and FALLBACK (hub-backend, here).
|
|
2325
2331
|
showFallbackRetired: 'Note: your config.json still has `ingestEndpointFallback`. It is no longer used: the CLI talks to a single backend. You can delete that line by hand; leaving it changes nothing.',
|
|
2326
2332
|
confirmHostPrompt: (host) => `The host "${host}" is not localhost or a known Shakers domain. If you continue, your sampled code and AI signals will be sent there.\n Type the exact hostname to confirm (leave blank to cancel):`,
|
|
2327
2333
|
confirmHostMismatch: "That didn't match the hostname shown. Cancelled: nothing was saved.",
|
|
@@ -2355,7 +2361,7 @@ const catalogs = {
|
|
|
2355
2361
|
}
|
|
2356
2362
|
},
|
|
2357
2363
|
},
|
|
2358
|
-
// Email-ownership verification
|
|
2364
|
+
// Email-ownership verification: the OTP "wait mode" copy, shared by both binaries.
|
|
2359
2365
|
verify: {
|
|
2360
2366
|
sent: (email) => `We sent a verification code to ${email}.`,
|
|
2361
2367
|
waitHint: 'Paste the code here. Press "r" then Enter to resend it, or Enter on a blank line to cancel.',
|
|
@@ -2371,7 +2377,7 @@ const catalogs = {
|
|
|
2371
2377
|
cancelled: 'Verification cancelled. The report will not be saved (it has already been shown to you).',
|
|
2372
2378
|
unavailable: 'Email verification is not available right now; the report will not be saved (it has already been shown to you).',
|
|
2373
2379
|
},
|
|
2374
|
-
// Skill Code Certification
|
|
2380
|
+
// Skill Code Certification —
|
|
2375
2381
|
// English mirror of the `certify` catalog. Same content/invariants.
|
|
2376
2382
|
certifyDimension: {
|
|
2377
2383
|
help:
|
|
@@ -2609,12 +2615,13 @@ const catalogs = {
|
|
|
2609
2615
|
},
|
|
2610
2616
|
mcpInstall: {
|
|
2611
2617
|
title: 'Connecting the Shakers MCP',
|
|
2612
|
-
clients: { claudeDesktop: 'Claude Desktop', claudeCode: 'Claude Code', cursor: 'Cursor', geminiCli: 'Gemini CLI', codex: 'Codex
|
|
2618
|
+
clients: { claudeDesktop: 'Claude Desktop', claudeCode: 'Claude Code', cursor: 'Cursor', geminiCli: 'Gemini CLI', codex: 'Codex / ChatGPT', vscode: 'VS Code', windsurf: 'Windsurf' },
|
|
2613
2619
|
status: {
|
|
2614
2620
|
configured: 'connected',
|
|
2615
2621
|
unchanged: 'already connected',
|
|
2616
2622
|
'not-found': 'not installed on this machine',
|
|
2617
|
-
'invalid-
|
|
2623
|
+
'invalid-config': 'its config cannot be edited safely; left untouched',
|
|
2624
|
+
manual: 'run this command in your terminal:',
|
|
2618
2625
|
failed: 'could not connect',
|
|
2619
2626
|
},
|
|
2620
2627
|
removedLegacy: 'Replaces the old "shakers-ai-usage" entry.',
|
|
@@ -2622,7 +2629,10 @@ const catalogs = {
|
|
|
2622
2629
|
confirm: 'Connect Shakers to them so you can use it from your AI? [Y/n]',
|
|
2623
2630
|
declined: 'Nothing touched. To connect it later, run the installer again.',
|
|
2624
2631
|
noTerminal: 'There is no terminal to ask you on, so nothing was touched. Run the installer again in your terminal to connect it.',
|
|
2625
|
-
restart:
|
|
2632
|
+
restart: (apps) => `Restart ${apps} (or reload their MCP servers) so the Shakers tools appear.`,
|
|
2633
|
+
alreadyConnected: 'Shakers was already connected. If its tools do not appear, restart the app or reload its MCP servers.',
|
|
2634
|
+
yesHint: 'To connect them without being asked (for example from an AI assistant): shakers mcp install --yes',
|
|
2635
|
+
help: 'mcp install — connect Shakers to the AI apps on this machine (Claude Desktop, Claude Code, Cursor, Gemini CLI, Codex / ChatGPT, VS Code, Windsurf).\n\nUsage:\n shakers mcp install ask on the terminal, then connect every app found\n shakers mcp install --yes connect without asking (-y; for AI assistants and scripts)\n shakers mcp install --json print the result as one JSON object\n\nWithout --yes and without a terminal, nothing is touched. SHAKERS_MCP_INSTALL=1 works like --yes.\nWhen it finishes, restart the apps it names (or reload their MCP servers) so the Shakers tools appear.',
|
|
2626
2636
|
noneFound: 'Found no supported AI app on this machine.',
|
|
2627
2637
|
failedAll: 'Could not connect Shakers to your AI apps. Re-run this installer to retry.',
|
|
2628
2638
|
},
|
|
@@ -2787,7 +2797,7 @@ const catalogs = {
|
|
|
2787
2797
|
partialSampleWarning:
|
|
2788
2798
|
'Partial sample: due to size limits the assessment is based on a sample of the code, '
|
|
2789
2799
|
+ 'not the whole project.',
|
|
2790
|
-
//
|
|
2800
|
+
// Skill levels (by decision power, NOT points) — replace the
|
|
2791
2801
|
// numeric grade in the skill output. `key` from skillLevelForScore.
|
|
2792
2802
|
levelLine: (label) => `Level: ${label}`,
|
|
2793
2803
|
skillLevels: {
|
|
@@ -2796,7 +2806,7 @@ const catalogs = {
|
|
|
2796
2806
|
expert: 'Expert',
|
|
2797
2807
|
na: '—',
|
|
2798
2808
|
},
|
|
2799
|
-
//
|
|
2809
|
+
// Rubric dimensions.
|
|
2800
2810
|
dimensionsLabel: 'Dimensions',
|
|
2801
2811
|
dimensionNA: 'N/A',
|
|
2802
2812
|
dimensionLabels: {
|
|
@@ -2808,7 +2818,7 @@ const catalogs = {
|
|
|
2808
2818
|
},
|
|
2809
2819
|
rationaleLabel: 'Why',
|
|
2810
2820
|
improvementsLabel: 'Suggested improvements',
|
|
2811
|
-
//
|
|
2821
|
+
// Authorship receipt (attribution, NOT cryptographic proof).
|
|
2812
2822
|
receipt: {
|
|
2813
2823
|
label: 'Authorship',
|
|
2814
2824
|
repoLabel: 'Repo',
|
|
@@ -2846,7 +2856,7 @@ const catalogs = {
|
|
|
2846
2856
|
remediationCopiedLabel: 'Copied ✓',
|
|
2847
2857
|
},
|
|
2848
2858
|
},
|
|
2849
|
-
// Branded mini-shell chrome
|
|
2859
|
+
// Branded mini-shell chrome.
|
|
2850
2860
|
login: {
|
|
2851
2861
|
intro: 'Log in with your Shakers email and password.',
|
|
2852
2862
|
sessionExpiredIntro: 'Your previous session expired. Log in again.',
|
|
@@ -2857,7 +2867,7 @@ const catalogs = {
|
|
|
2857
2867
|
needInput: 'Email and password are required to log in.',
|
|
2858
2868
|
success: 'Logged in. Your report no longer includes the roadmap or the improvement suggestions: your level comes from certifying.',
|
|
2859
2869
|
expiresAt: (iso) => `The session expires: ${iso}. When it does I will tell you, and you can log in again with \`login\`.`,
|
|
2860
|
-
loggedOut: 'Logged out.
|
|
2870
|
+
loggedOut: 'Logged out. Your report shows the improvement suggestions again.',
|
|
2861
2871
|
notLoggedIn: 'No session was active. Nothing to log out of.',
|
|
2862
2872
|
errorInvalidCredentials: 'Wrong credentials: check your email and password and try again.',
|
|
2863
2873
|
errorNoEmailPassword: 'This account exists but has no email password: you registered with Google or LinkedIn. If it was Google, use `login --google`. If it was LinkedIn, sign in on the web to add a password for now.',
|
|
@@ -2867,7 +2877,7 @@ const catalogs = {
|
|
|
2867
2877
|
errorNoEndpoint: 'No endpoint configured. login uses the same base as usage: set SHAKERS_CLI_INGEST_ENDPOINT or use `usage --set-endpoint <url>`.',
|
|
2868
2878
|
errorPersist: 'Login succeeded, but the session could not be saved to disk. Check the permissions of ~/.config/shakers and try again.',
|
|
2869
2879
|
errorGeneric: 'Could not log in. Try again.',
|
|
2870
|
-
//
|
|
2880
|
+
// Google login by loopback (`login --google`).
|
|
2871
2881
|
googleIntro: 'Log in with Google. Your browser will open to authorize; when you are done, come back here.',
|
|
2872
2882
|
googleOpening: 'Opening your browser to log in with Google…',
|
|
2873
2883
|
googlePasteUrl: 'If your browser does not open on its own, paste this URL into it:',
|
|
@@ -2898,7 +2908,7 @@ const catalogs = {
|
|
|
2898
2908
|
selectHint: 'Arrows ↑/↓ to move · enter to pick · esc to cancel',
|
|
2899
2909
|
chooseMethodPrompt: (max) => `Number (1-${max}), empty to cancel: `,
|
|
2900
2910
|
},
|
|
2901
|
-
// `start
|
|
2911
|
+
// `start`: the tool for a talent ALREADY registered in Shakers who wants to complete their agentic profile.
|
|
2902
2912
|
start: {
|
|
2903
2913
|
help:
|
|
2904
2914
|
'start — complete your agentic talent profile in Shakers: log in, run the AI-usage\n'
|
|
@@ -2922,16 +2932,16 @@ const catalogs = {
|
|
|
2922
2932
|
menuHint: 'Arrows ↑/↓ to move · enter to pick · esc to cancel',
|
|
2923
2933
|
menuPrompt: (max) => `Number (1-${max}), empty to cancel: `,
|
|
2924
2934
|
menuRerun: 'Run the AI-usage evaluation again',
|
|
2925
|
-
//
|
|
2935
|
+
// Renamed — the label said "Add" but the action is declaring/uploading what was DETECTED to the Shakers profile, not creating something new from scratch.
|
|
2926
2936
|
menuAddSkills: 'Upload skills to profile',
|
|
2927
2937
|
menuAddAgents: 'Upload agents to profile',
|
|
2928
|
-
//
|
|
2938
|
+
// "Add project to portfolio" — grouped with skills/agents, before certifying (declare things on your profile, then certify them).
|
|
2929
2939
|
menuAddPortfolio: 'Add project to portfolio',
|
|
2930
2940
|
menuCertifySkills: 'Certify skills',
|
|
2931
2941
|
menuCertifyAgents: 'Certify agents',
|
|
2932
2942
|
menuExit: 'Exit',
|
|
2933
2943
|
menuExitDesc: 'Ends this `start` session. Run it again whenever you want to keep completing your profile.',
|
|
2934
|
-
// Per-option descriptions
|
|
2944
|
+
// Per-option descriptions: shown ONLY for the HIGHLIGHTED item in the interactive picker (or compactly in the numbered fallback) — never all at once.
|
|
2935
2945
|
menuRerunDesc:
|
|
2936
2946
|
'Re-scans your AI setup and recomputes your AI fluency. You get your updated position on the map (Explorer → AI Native) on your profile.',
|
|
2937
2947
|
menuAddSkillsDesc:
|
|
@@ -2945,7 +2955,7 @@ const catalogs = {
|
|
|
2945
2955
|
menuCertifyAgentsDesc:
|
|
2946
2956
|
'A challenge validates the agent is real, is yours, and you run it with judgment. You get the agent Certified with its traction → the strongest signal of your agentic profile.',
|
|
2947
2957
|
menuCancelled: 'Cancelled. Nothing was done.',
|
|
2948
|
-
//
|
|
2958
|
+
// Closes the menu LOOP — used both when "Exit" is explicitly chosen and when cancelling (esc / empty answer) FROM INSIDE the loop.
|
|
2949
2959
|
menuGoodbye: '`start` session ended. Run `start` again whenever you want to keep completing your profile.',
|
|
2950
2960
|
addAgentsComingSoon:
|
|
2951
2961
|
"Add agents: coming soon. Your agents will become assets of your agentic profile — that record doesn't exist in Shakers yet, so there's nowhere to save them for now.",
|
|
@@ -2964,7 +2974,7 @@ const catalogs = {
|
|
|
2964
2974
|
addSkillsNoneChosen: 'No skill was chosen. Nothing was added to your profile.',
|
|
2965
2975
|
addSkillsDeclaredOne: (skillName) => `✓ Added to your profile: ${skillName} (unverified).`,
|
|
2966
2976
|
addSkillsDeclareFailed: (skillName, reason) => `✗ Could not add ${skillName}: ${reason}`,
|
|
2967
|
-
// Vision close
|
|
2977
|
+
// Vision close: ONCE, after the batch — not repeated per skill (the same line repeated per item is noise, not reinforcement).
|
|
2968
2978
|
addSkillsProfileBoost: 'Every skill you add counts toward your profile: you show up in more searches.',
|
|
2969
2979
|
addSkillsHubSessionExpired: 'Your Shakers session expired while we were adding your skills.',
|
|
2970
2980
|
addSkillsOfferRelogin: 'Do you want to log in again now to continue? (y/n):',
|
|
@@ -2979,7 +2989,7 @@ const catalogs = {
|
|
|
2979
2989
|
addSkillsRelateSkipped: (skillName) => `"${skillName}" added without a relation.`,
|
|
2980
2990
|
addSkillsRelated: (skillName, portfolioName) => ` ✓ "${skillName}" related to "${portfolioName}".`,
|
|
2981
2991
|
addSkillsRelateFailed: (skillName, portfolioName, reason) => ` ✗ Could not relate "${skillName}" to "${portfolioName}": ${reason}`,
|
|
2982
|
-
//
|
|
2992
|
+
// "Add project to portfolio".
|
|
2983
2993
|
portfolioIntro:
|
|
2984
2994
|
"Let's add this project to your Shakers portfolio. Most of the data is pre-filled from your code and your git history: confirm or edit each one.",
|
|
2985
2995
|
portfolioErrorNoEndpoint:
|
|
@@ -2991,7 +3001,7 @@ const catalogs = {
|
|
|
2991
3001
|
portfolioDuplicateName: (name) => `You already have a project named "${name}" in your portfolio. No duplicate was created — run this option again with a different title if you want to add a distinct one.`,
|
|
2992
3002
|
// (1) Title ← directory name, editable.
|
|
2993
3003
|
portfolioTitlePrompt: (def) => `Project title [${def}]:`,
|
|
2994
|
-
// (2) Type ← PORTFOLIO/EXPERIENCE, obligatorio. Vision copy
|
|
3004
|
+
// (2) Type ← PORTFOLIO/EXPERIENCE, obligatorio. Vision copy:
|
|
2995
3005
|
// what each type means for your profile, shown ONLY on highlight.
|
|
2996
3006
|
portfolioTypeHeading: 'What type of entry is this?',
|
|
2997
3007
|
portfolioTypeHint: 'Arrows ↑/↓ to move · enter to pick · esc to cancel',
|
|
@@ -3002,7 +3012,7 @@ const catalogs = {
|
|
|
3002
3012
|
portfolioTypeExperience: 'Experience',
|
|
3003
3013
|
portfolioTypeExperienceDesc:
|
|
3004
3014
|
"Adds it to your profile as professional experience (freelance or in-house): counts toward your track record, not as a piece to show.",
|
|
3005
|
-
// (3) Description ← AI pre-drafts after consent
|
|
3015
|
+
// (3) Description ← AI pre-drafts after consent.
|
|
3006
3016
|
portfolioDescriptionConsentDisclaimer:
|
|
3007
3017
|
'To draft a description with AI, this will send to Shakers: the project name, the detected technologies, and — if present — the README content and the package.json description.',
|
|
3008
3018
|
portfolioDescriptionDraftLabel: 'AI-drafted description:',
|
|
@@ -3031,8 +3041,8 @@ const catalogs = {
|
|
|
3031
3041
|
portfolioRelaunchAfterRelogin: 'Session renewed. Retrying adding the project to your portfolio.',
|
|
3032
3042
|
portfolioRelaunchDeclined: 'OK. Run `login` and pick "Add project to portfolio" again whenever you want.',
|
|
3033
3043
|
portfolioReloginFailed: 'Could not log in again. The project was not added to your portfolio.',
|
|
3034
|
-
//
|
|
3035
|
-
// portfolio
|
|
3044
|
+
// "Add agent to profile". Same model as the
|
|
3045
|
+
// portfolio: AI pre-drafts, the talent edits.
|
|
3036
3046
|
agentErrorNoEndpoint:
|
|
3037
3047
|
'No endpoint configured. `start` uses the same base as `usage`: set the endpoint with `usage --set-endpoint <url>` (or SHAKERS_CLI_INGEST_ENDPOINT).',
|
|
3038
3048
|
agentNoHubToken:
|
|
@@ -3053,7 +3063,7 @@ const catalogs = {
|
|
|
3053
3063
|
agentCancelled: 'Cancelled. No agent was added to your profile.',
|
|
3054
3064
|
// (3) Name ← detected, editable.
|
|
3055
3065
|
agentNamePrompt: (def) => `Agent name [${def}]:`,
|
|
3056
|
-
// (4) whatItDoes + humanDecides ← AI pre-drafts after consent
|
|
3066
|
+
// (4) whatItDoes + humanDecides ← AI pre-drafts after consent.
|
|
3057
3067
|
agentFieldsConsentDisclaimer:
|
|
3058
3068
|
"To draft what your agent does and what you decide with AI, this will send to Shakers: the agent name, its detected tools/model/parent, and a summary of its definition (its own instructions).",
|
|
3059
3069
|
agentDraftingLabel: 'Drafting with AI…',
|
|
@@ -3069,7 +3079,7 @@ const catalogs = {
|
|
|
3069
3079
|
agentDeclaredSuccess: (name) => `✓ "${name}" added to your profile.`,
|
|
3070
3080
|
agentDeclareFailed: (reason) => `✗ Could not add the agent to your profile: ${reason}`,
|
|
3071
3081
|
agentHubSessionExpired: 'Your Shakers session expired while we were adding the agent to your profile.',
|
|
3072
|
-
//
|
|
3082
|
+
// AFTER the agent is declared, offer to relate it to the experiences/projects the talent already declared (portfolioId only).
|
|
3073
3083
|
agentRelateNoPortfolios: "You don't have any experiences in your profile yet, so the agent was added without a relation. Add one with \"Add project to portfolio\" and relate it later.",
|
|
3074
3084
|
agentRelateAsk: (agentName) => `Do you want to relate "${agentName}" to any of your experiences? (y/n):`,
|
|
3075
3085
|
agentRelateSelectHeading: (agentName) => `Relate "${agentName}" to one or more experiences:`,
|
|
@@ -3096,7 +3106,7 @@ const catalogs = {
|
|
|
3096
3106
|
},
|
|
3097
3107
|
errorReasonHttp: (status) => `the server answered with an error (HTTP ${status}).`,
|
|
3098
3108
|
},
|
|
3099
|
-
//
|
|
3109
|
+
// Password-authenticated superadmin SESSION (NON-PROD only).
|
|
3100
3110
|
superadmin: {
|
|
3101
3111
|
sessionIntro:
|
|
3102
3112
|
'Open a superadmin session (non-production environments only): certify will run against ANY email on ANY repo, bypassing the identity and authorship gates.',
|
|
@@ -3110,7 +3120,7 @@ const catalogs = {
|
|
|
3110
3120
|
sessionHint:
|
|
3111
3121
|
'Run: certify --email <anyone> --accept-disclaimer --skill <name> · To end it: superadmin --logout',
|
|
3112
3122
|
loggedOut: 'Superadmin session forgotten (local token removed).',
|
|
3113
|
-
//
|
|
3123
|
+
// Profile switch via superadmin: a dev/testing convenience — flips between the talent/ external profile without reinstalling.
|
|
3114
3124
|
profileMenuHeading: 'What do you want to do?',
|
|
3115
3125
|
profileMenuHint: 'Arrows ↑/↓ to move · enter to pick · esc to cancel',
|
|
3116
3126
|
profileMenuPrompt: (max) => `Number (1-${max}), empty to cancel: `,
|
|
@@ -3125,7 +3135,7 @@ const catalogs = {
|
|
|
3125
3135
|
profileMenuCancelled: 'Cancelled. Nothing was changed.',
|
|
3126
3136
|
profileAlreadyOn: (profile) => `You are already on the ${profile === 'talent' ? 'Talent' : 'External'} profile. Nothing was changed or purged.`,
|
|
3127
3137
|
profileSwitched: (profile) => `Profile switched to ${profile === 'talent' ? 'Talent' : 'External'} · history cleared (report, consent, talent session) · takes effect immediately, no restart needed.`,
|
|
3128
|
-
//
|
|
3138
|
+
// Superadmin is DELIBERATELY single-hop, PRIMARY (certifications service) ONLY — never hub.
|
|
3129
3139
|
queryingPrimary: (endpoint) => `Querying Shakers: ${endpoint}`,
|
|
3130
3140
|
errorNoEndpoint:
|
|
3131
3141
|
'No endpoint configured. Set the backend (SHAKERS_CLI_INGEST_ENDPOINT or usage --set-endpoint) and retry.',
|
|
@@ -3133,7 +3143,7 @@ const catalogs = {
|
|
|
3133
3143
|
errorDisabled:
|
|
3134
3144
|
'Endpoint unavailable: the superadmin session is disabled outside non-production environments.',
|
|
3135
3145
|
errorGeneric: 'Could not open the superadmin session. Try again.',
|
|
3136
|
-
// Inspect
|
|
3146
|
+
// Inspect — attribution receipt for ALREADY-stored certifications.
|
|
3137
3147
|
inspectIntro:
|
|
3138
3148
|
'Audit the authorship evidence of already-stored certifications (read-only, non-production).',
|
|
3139
3149
|
inspectEmailPrompt: 'Email whose certification(s) to inspect:',
|
|
@@ -3158,7 +3168,7 @@ const catalogs = {
|
|
|
3158
3168
|
// `shakers` REPL is the single entrypoint; this covers the prompt, the in-shell command help and messages — the commands keep their own copy.
|
|
3159
3169
|
repl: {
|
|
3160
3170
|
prompt: 'ϟ shakers ›',
|
|
3161
|
-
//
|
|
3171
|
+
// The startup BANNER (src/repl-shell.js) is now profile-aware and localized.
|
|
3162
3172
|
bannerWelcome: 'Welcome to',
|
|
3163
3173
|
bannerTalentLine1: 'Complete or update your agentic talent',
|
|
3164
3174
|
bannerTalentLine2: "profile on Shakers: it's not just what you know,",
|
|
@@ -3178,7 +3188,7 @@ const catalogs = {
|
|
|
3178
3188
|
bannerExternalMapDesc: 'LOCAL report (graph)',
|
|
3179
3189
|
bannerExternalReportDesc: 'shareable HTML report',
|
|
3180
3190
|
bannerExternalShareDesc: 'card for LinkedIn',
|
|
3181
|
-
// COMMAND FLOW
|
|
3191
|
+
// COMMAND FLOW VOCABULARY: this is about the tool's COMMANDS.
|
|
3182
3192
|
completeNeeds: (cmd) => `(needs: ${cmd})`,
|
|
3183
3193
|
completeDone: '(already run)',
|
|
3184
3194
|
completeDoneStale: (days) => `(already run, ${days} days ago)`,
|
|
@@ -3207,7 +3217,7 @@ const catalogs = {
|
|
|
3207
3217
|
journeyDone: 'You have completed the tool\u2019s flow: there is no command left to run. The next steps for raising your AI-usage level are a different thing, and they live in `usage --roadmap`.',
|
|
3208
3218
|
goodbye: 'See you soon.',
|
|
3209
3219
|
unknown: (cmd) => `Unknown command: "${cmd}". Type "help" to list the available commands.`,
|
|
3210
|
-
// ORDER: declared by src/command-graph.js
|
|
3220
|
+
// ORDER: declared by src/command-graph.js.
|
|
3211
3221
|
help:
|
|
3212
3222
|
'Shakers — available commands\n\n'
|
|
3213
3223
|
+ ' usage [options] Scan this project + your machine; score your AI setup (T0-T7)\n'
|
|
@@ -3250,7 +3260,7 @@ const catalogs = {
|
|
|
3250
3260
|
toolsS: 'AI clients present in your environment.',
|
|
3251
3261
|
techT: 'Project technologies',
|
|
3252
3262
|
techS: 'Stack recognized in the repository.',
|
|
3253
|
-
//
|
|
3263
|
+
// See the Spanish catalog for why the service is shown and the
|
|
3254
3264
|
// server name never is, and why the empty state carries the T3 criterion.
|
|
3255
3265
|
mcpT: 'Services connected over MCP',
|
|
3256
3266
|
mcpS: 'Products your AI has access to.',
|
|
@@ -3259,7 +3269,7 @@ const catalogs = {
|
|
|
3259
3269
|
// 085: the tab said a bare "Skills" next to an "Agents" one, which is the
|
|
3260
3270
|
// exact collision the issue names.
|
|
3261
3271
|
skills: 'Technical Skills',
|
|
3262
|
-
// ---- DETECTED agents, left column
|
|
3272
|
+
// ---- DETECTED agents, left column -----------------------
|
|
3263
3273
|
agentsT: 'Detected agents',
|
|
3264
3274
|
agentsS: 'Every agent configured in your environment. Certifying is a different thing, and it lives in the right-hand column.',
|
|
3265
3275
|
agentsEmpty: 'No configured agent detected (e.g. under .claude/agents/). If you have agents and they are not here, the tool did not find them — it is not that they do not count.',
|
|
@@ -3275,7 +3285,7 @@ const catalogs = {
|
|
|
3275
3285
|
hereYouAre: 'You are here',
|
|
3276
3286
|
noFoot: 'No AI usage yet. Run usage in this project.',
|
|
3277
3287
|
noSkills: 'No certified technical Skills yet. Run certify skills.',
|
|
3278
|
-
// Agent certifications were removed from the report
|
|
3288
|
+
// Agent certifications were removed from the report; the sheet's agent-cert tab, its empty state and its detected-vs-certified copy went with it.
|
|
3279
3289
|
footer: 'Report generated locally · Shakers',
|
|
3280
3290
|
themeToggle: 'Toggle theme',
|
|
3281
3291
|
themeDark: 'Dark',
|
|
@@ -3333,7 +3343,7 @@ function tierName(tierKey, lang) {
|
|
|
3333
3343
|
return (names && names[tierKey]) || tierKey;
|
|
3334
3344
|
}
|
|
3335
3345
|
|
|
3336
|
-
// Defensive i18n lookup
|
|
3346
|
+
// Defensive i18n lookup.
|
|
3337
3347
|
function label(value, fallback) {
|
|
3338
3348
|
return typeof value === 'string' && value ? value : fallback;
|
|
3339
3349
|
}
|