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
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { palette, styleQuestion } = require('./ansi');
|
|
4
4
|
const { BRAND_ANSI } = require('./brand-ansi');
|
|
5
5
|
|
|
6
|
-
// Zero-dependency interactive multi-select
|
|
6
|
+
// Zero-dependency interactive multi-select.
|
|
7
7
|
|
|
8
8
|
// COLOUR goes through the one gate (src/ansi.js).
|
|
9
9
|
const ANSI = palette({
|
package/src/interview-client.js
CHANGED
|
@@ -100,7 +100,7 @@ class InterviewClient {
|
|
|
100
100
|
|
|
101
101
|
// The end of the interview is a protocol message, not a sentence: matching the
|
|
102
102
|
// goodbye text never fired (certs sends no closingMessage), so the CLI kept
|
|
103
|
-
// asking for answers until its turn-timeout
|
|
103
|
+
// asking for answers until its turn-timeout.
|
|
104
104
|
if (RoomEvent && RoomEvent.DataReceived && typeof room.on === 'function') {
|
|
105
105
|
room.on(RoomEvent.DataReceived, (payload, _participant, _kind, topic) => {
|
|
106
106
|
if (topic !== PROTOCOL_TOPIC) return;
|
|
@@ -216,8 +216,13 @@ class InterviewClient {
|
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
function createInterviewClient(opts) {
|
|
220
|
+
return new InterviewClient(opts);
|
|
221
|
+
}
|
|
222
|
+
|
|
219
223
|
module.exports = {
|
|
220
224
|
InterviewClient,
|
|
225
|
+
createInterviewClient,
|
|
221
226
|
LiveKitNotInstalledError,
|
|
222
227
|
loadLiveKitSdk,
|
|
223
228
|
CHAT_TOPIC,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
// Upper case: certs validates the role against its AGENT/USER enum and 400s the
|
|
6
6
|
// whole PATCH otherwise, so every terminal onboarding lost its transcript
|
|
7
|
-
// ("no se pudo guardar la transcripcion (http-400)"
|
|
7
|
+
// ("no se pudo guardar la transcripcion (http-400)").
|
|
8
8
|
const ROLE_AGENT = 'AGENT';
|
|
9
9
|
const ROLE_USER = 'USER';
|
|
10
10
|
|
package/src/legal-notice.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
// Shared PRESENTATION for the CLI's legal/consent disclosures
|
|
3
|
+
// Shared PRESENTATION for the CLI's legal/consent disclosures.
|
|
4
4
|
|
|
5
5
|
const { palette, colorEnabled } = require('./ansi');
|
|
6
6
|
const { BRAND_ANSI } = require('./brand-ansi');
|
package/src/maturity.js
CHANGED
|
@@ -12,7 +12,7 @@ const LEVELS = [
|
|
|
12
12
|
{ level: 4, key: 'orchestrator', name: 'Orquestador', emoji: '●' },
|
|
13
13
|
];
|
|
14
14
|
|
|
15
|
-
// DECISION
|
|
15
|
+
// DECISION: the level definitions (LEVELS) have NOT been touched.
|
|
16
16
|
function depthTotals(tools) {
|
|
17
17
|
let instructions = 0; // project instructions/rules files
|
|
18
18
|
let mcp = 0; // configured MCP servers
|
|
@@ -30,7 +30,7 @@ function depthTotals(tools) {
|
|
|
30
30
|
return { instructions, mcp, custom, hooks };
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
// Score model 0-100 for the visual meter — RECALIBRATED
|
|
33
|
+
// Score model 0-100 for the visual meter — RECALIBRATED.
|
|
34
34
|
const SCORE_MODEL = [
|
|
35
35
|
{ key: 'breadth', weight: 12, full: 3 }, // number of AI tools detected
|
|
36
36
|
{ key: 'context', weight: 16, full: 2 }, // instructions + config files
|
|
@@ -61,7 +61,7 @@ function classify(report) {
|
|
|
61
61
|
? report.agentCounts.agents
|
|
62
62
|
: 0;
|
|
63
63
|
|
|
64
|
-
// Score scope reverted to PROJECT ∪ HOME
|
|
64
|
+
// Score scope reverted to PROJECT ∪ HOME.
|
|
65
65
|
const score = computeScore({
|
|
66
66
|
breadth,
|
|
67
67
|
context: d.instructions, // depthTotals already folds `config` into instructions
|
|
@@ -72,7 +72,7 @@ function classify(report) {
|
|
|
72
72
|
multiAgent: agentCount,
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
-
// Band 0-4 derived from the tier engine (
|
|
75
|
+
// Band 0-4 derived from the tier engine (single source of truth).
|
|
76
76
|
const tierResult = computeTierResult(report);
|
|
77
77
|
const level = tierResult.band;
|
|
78
78
|
const meta = LEVELS[level];
|
|
@@ -87,11 +87,11 @@ function classify(report) {
|
|
|
87
87
|
depth: d,
|
|
88
88
|
hasAgentic,
|
|
89
89
|
next: nextStep(level, { breadth, ...d, hasAgentic }),
|
|
90
|
-
// Tier (T0-T7
|
|
90
|
+
// Tier (T0-T7): the fine-grained axis the band is derived from.
|
|
91
91
|
tier: tierResult.tier,
|
|
92
92
|
tierKey: tierResult.tierKey,
|
|
93
93
|
tierName: tierResult.tierName,
|
|
94
|
-
// Setup Level
|
|
94
|
+
// Setup Level: the 3-value rollup shown to the talent, derived
|
|
95
95
|
// from the tier. `{key, code, rank, emoji}`; label localized via i18n.
|
|
96
96
|
setupLevel: tierResult.setupLevel,
|
|
97
97
|
};
|
|
@@ -52,6 +52,8 @@ async function pollClassifiedInventory({
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
const RESULT_MESSAGE = 'Print relayVerbatim word for word: the result in "My work with AI", what it means and how to ask for a human review.';
|
|
56
|
+
const PROFILE_PENDING_MESSAGE = 'The profile result is not ready yet: call ai_usage_result again in a few minutes.';
|
|
55
57
|
const READY_MESSAGE = 'Shakers finished classifying the agents.';
|
|
56
58
|
const PENDING_MESSAGE = 'Shakers is still classifying the agents — this is normal, call ai_usage_result again shortly to keep waiting.';
|
|
57
59
|
|
|
@@ -65,6 +67,12 @@ function makeAiUsageResultTool(deps = {}) {
|
|
|
65
67
|
now = () => Date.now(),
|
|
66
68
|
intervalMs = POLL_INTERVAL_MS,
|
|
67
69
|
capMs = POLL_CAP_MS,
|
|
70
|
+
resolveAiProfilePreview = require('./ai-profile-preview').resolveAiProfilePreview,
|
|
71
|
+
getAiProfileEndpoint = require('./config').getAiProfileEndpoint,
|
|
72
|
+
ensureFreshSession = require('./session-refresh').ensureFreshSession,
|
|
73
|
+
aiProfileWaitMs = 30000,
|
|
74
|
+
resultText = require('./ai-usage-review').resultText,
|
|
75
|
+
lang = () => require('./signup-language').signupLanguage(require('./i18n').detectFlowLang()),
|
|
68
76
|
} = deps;
|
|
69
77
|
|
|
70
78
|
async function handler() {
|
|
@@ -77,27 +85,41 @@ function makeAiUsageResultTool(deps = {}) {
|
|
|
77
85
|
throw new Error('discovered-inventory endpoint is not configured (set SHAKERS_CLI_INGEST_ENDPOINT).');
|
|
78
86
|
}
|
|
79
87
|
|
|
80
|
-
const result = await
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
const [result, aiProfile] = await Promise.all([
|
|
89
|
+
pollClassifiedInventory({
|
|
90
|
+
accessToken: session.accessToken,
|
|
91
|
+
endpoint,
|
|
92
|
+
requestDiscoveredInventory,
|
|
93
|
+
sleep,
|
|
94
|
+
now,
|
|
95
|
+
intervalMs,
|
|
96
|
+
capMs,
|
|
97
|
+
}),
|
|
98
|
+
resolveAiProfilePreview(
|
|
99
|
+
{ session, endpoint: getAiProfileEndpoint(), timeoutMs: aiProfileWaitMs },
|
|
100
|
+
{
|
|
101
|
+
refreshToken: async () => {
|
|
102
|
+
const fresh = await ensureFreshSession(process.env);
|
|
103
|
+
return fresh ? { accessToken: fresh.accessToken, hubAccessToken: fresh.hubAccessToken } : null;
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
).catch(() => ({ status: 'unavailable', preview: null })),
|
|
107
|
+
]);
|
|
108
|
+
const profileReady = aiProfile.status === 'ready';
|
|
89
109
|
return {
|
|
90
110
|
...result,
|
|
91
|
-
|
|
111
|
+
aiProfile,
|
|
112
|
+
relayVerbatim: resultText(lang(), profileReady ? aiProfile.preview : null),
|
|
113
|
+
message: `${RESULT_MESSAGE} ${result.status === 'ready' ? READY_MESSAGE : PENDING_MESSAGE}${profileReady ? '' : ` ${PROFILE_PENDING_MESSAGE}`}`,
|
|
92
114
|
};
|
|
93
115
|
}
|
|
94
116
|
|
|
95
117
|
return {
|
|
96
118
|
name: 'ai_usage_result',
|
|
97
119
|
title: 'Results of your AI analysis',
|
|
98
|
-
description: 'Fetches from Shakers the
|
|
120
|
+
description: 'Fetches from Shakers the result of the AI analysis you approved, what it means, and the description of each AI agent found. It reads nothing on this computer.',
|
|
99
121
|
guidance:
|
|
100
|
-
"Retrieve the enriched Shakers classification for the talent's agents
|
|
122
|
+
"Retrieve the result after an approved upload: relayVerbatim is the 'My work with AI' result with its levels and explanation in plain words, and how to ask for a human review; print it word for word. It also returns the enriched Shakers classification for the talent's agents. Shakers classifies agents and writes their descriptions server-side (no client LLM), so this reads the result: per agent { name, tools, model, category, role, level, code, whatItDoes }. Session-keyed, no arguments. Server-side classification can take a few minutes, so this does a bounded internal poll (~90s max, never a long-held call): returns { status: 'ready', agents } once every agent has been classified, or { status: 'pending', agents } while Shakers is still processing (call it again to keep waiting — 'pending' is normal progress, not an error). Present agents to the talent by NAME and category/role only; the `code` field is an internal handle for add_agent, never show it. Requires an active session.",
|
|
101
123
|
inputSchema: RESULT_INPUT_SCHEMA,
|
|
102
124
|
handler,
|
|
103
125
|
};
|