shakers-cli 0.15.0 → 0.16.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.
Files changed (123) hide show
  1. package/README.md +51 -1203
  2. package/bin/ai-usage.js +11 -56
  3. package/bin/login.js +10 -10
  4. package/bin/mcp.js +13 -9
  5. package/bin/mcpb.js +1 -1
  6. package/bin/onboarding.js +3 -2
  7. package/bin/register.js +17 -4
  8. package/bin/report-html.js +2 -2
  9. package/bin/shakers-cli.js +352 -0
  10. package/bin/shakers.js +20 -344
  11. package/bin/share.js +1 -1
  12. package/bin/superadmin.js +5 -5
  13. package/bin/version.js +3 -0
  14. package/package.json +12 -3
  15. package/src/agent-category.js +1 -1
  16. package/src/agent-evaluation.js +3 -3
  17. package/src/agent-org-chart.js +5 -5
  18. package/src/agent-synthesis.js +3 -3
  19. package/src/agent-usage.js +1 -1
  20. package/src/agents-client.js +4 -4
  21. package/src/ai.js +1 -1
  22. package/src/ansi.js +1 -1
  23. package/src/auth-client.js +18 -4
  24. package/src/auth-method-picker.js +1 -1
  25. package/src/auth-methods.js +1 -1
  26. package/src/auth-session-store.js +11 -8
  27. package/src/authorship-mismatch.js +1 -1
  28. package/src/authorship.js +2 -2
  29. package/src/automations-detector.js +1 -1
  30. package/src/backend-request.js +3 -3
  31. package/src/brand-ansi.js +1 -1
  32. package/src/browser-tools-detector.js +1 -1
  33. package/src/certify-disclaimer.js +1 -1
  34. package/src/certify-remediation-prompt.js +1 -1
  35. package/src/cli-args.js +2 -2
  36. package/src/command-audit.js +8 -5
  37. package/src/config-dir.js +1 -1
  38. package/src/config.js +112 -48
  39. package/src/consent-flow.js +4 -4
  40. package/src/consent-skip.js +1 -1
  41. package/src/detection-evidence.js +2 -2
  42. package/src/detection-noise.js +1 -1
  43. package/src/detectors.js +1 -1
  44. package/src/device-login.js +12 -1
  45. package/src/email-verification.js +3 -3
  46. package/src/env-paths.js +1 -1
  47. package/src/find-projects-client.js +12 -0
  48. package/src/find-projects-flow.js +1 -13
  49. package/src/git-activity.js +1 -1
  50. package/src/graph-certs.js +3 -3
  51. package/src/graph-scan.js +9 -9
  52. package/src/i18n.js +124 -124
  53. package/src/interactive-select.js +1 -1
  54. package/src/interview-client.js +6 -1
  55. package/src/interview-transcript.js +1 -1
  56. package/src/legal-notice.js +1 -1
  57. package/src/maturity.js +6 -6
  58. package/src/mcp-ai-usage-tool.js +1 -1
  59. package/src/mcp-auth-form.js +1 -1
  60. package/src/mcp-detector.js +3 -3
  61. package/src/mcp-device-login-tools.js +2 -1
  62. package/src/mcp-find-projects-tools.js +1 -2
  63. package/src/mcp-onboarding-tools.js +4 -4
  64. package/src/mcp-prompts.js +2 -2
  65. package/src/mcp-register-tools.js +1 -0
  66. package/src/mcp-server.js +5 -1
  67. package/src/mcp-signup-client.js +2 -2
  68. package/src/mcp-signup-tools.js +26 -2
  69. package/src/memory-structure-detector.js +1 -1
  70. package/src/model-call-record.js +2 -2
  71. package/src/onboarding-flow.js +16 -16
  72. package/src/onboarding-funnel.js +110 -17
  73. package/src/open-file.js +1 -1
  74. package/src/osc-link.js +1 -1
  75. package/src/portfolio-client.js +11 -1
  76. package/src/portfolio-git-info.js +1 -1
  77. package/src/profile-flow.js +1 -1
  78. package/src/profile-switch.js +5 -12
  79. package/src/render-certification.js +10 -10
  80. package/src/render-html.js +6 -6
  81. package/src/render-sheet.js +10 -10
  82. package/src/render-terminal.js +6 -6
  83. package/src/repo-scope.js +132 -0
  84. package/src/report-gating.js +1 -1
  85. package/src/report-store.js +6 -6
  86. package/src/roadmap-content.js +5 -5
  87. package/src/roadmap-personalization.js +3 -3
  88. package/src/roadmap-prompt.js +2 -2
  89. package/src/scan-exclusions.js +1 -1
  90. package/src/scanner.js +14 -14
  91. package/src/secret-prompt.js +1 -1
  92. package/src/session-gate.js +1 -1
  93. package/src/session-refresh.js +33 -3
  94. package/src/session-scan.js +1 -1
  95. package/src/shakers-wordmark.js +1 -1
  96. package/src/share-card.js +2 -2
  97. package/src/share-certification.js +4 -4
  98. package/src/share-consent-state.js +7 -7
  99. package/src/share-payload.js +7 -7
  100. package/src/share.js +7 -7
  101. package/src/signup-client.js +1 -1
  102. package/src/signup-copy.js +1 -1
  103. package/src/skills-client.js +1 -1
  104. package/src/start-add-agents.js +2 -2
  105. package/src/start-add-portfolio.js +3 -13
  106. package/src/start-add-skills.js +2 -2
  107. package/src/stdin-ask.js +3 -3
  108. package/src/strip-internal-comments.js +1 -1
  109. package/src/tech-detector.js +2 -2
  110. package/src/templates/report-sheet.html +11 -13
  111. package/src/terminal-agents.js +8 -8
  112. package/src/terminal-format.js +3 -3
  113. package/src/terminal-sections.js +11 -11
  114. package/src/tier-engine.js +3 -3
  115. package/src/tier-projection.js +2 -2
  116. package/src/transcript-turns.js +1 -1
  117. package/src/typewriter.js +1 -1
  118. package/src/usage-model-calls.js +6 -6
  119. package/src/usage-oneshot-commands.js +5 -5
  120. package/src/usage-repo-scope.js +11 -129
  121. package/src/usage-run-steps.js +32 -184
  122. package/src/usage-scan.js +235 -0
  123. package/src/work-streams.js +1 -1
package/README.md CHANGED
@@ -1,1234 +1,82 @@
1
- # Shakers `shakers`
1
+ # Shakers CLI and MCP
2
2
 
3
- A **local-first** Shakers CLI (`shakers`) — a plain argument dispatcher:
4
- `shakers <command> [flags]` runs one command and exits; run `shakers` with no
5
- command to print the usage help. There is no interactive shell (the former
6
- REPL was retired — ADR-060). Its commands:
3
+ Shakers for freelance talent, from your terminal or your AI assistant. It scans your
4
+ AI-tool setup on your own machine and shows how you work with AI. It also lets you sign
5
+ up on Shakers, keep your profile up to date, find projects and ask Alma, the Shakers AI
6
+ assistant.
7
7
 
8
- - **`ai-usage`** — builds, **locally**, a deterministic profile of your AI
9
- tool setup: which copilots/agents you have configured, how deep that
10
- configuration goes, and what "level-up" **tier** (T0-T7) you're at. Its
11
- terminal output leads with **why** you're at that tier, then the score, your
12
- tools, technologies and a **one-line-per-agent** summary (each agent scored
13
- for how well it's built + how often you've actually used it). The tier
14
- roadmap / next-steps is available behind `--roadmap`.
15
- - **`certify`** — certifies Skills from your Shakers catalog by analyzing your
16
- local project's code (resolve which Skills apply, then sample and send
17
- secret-scrubbed code for a per-Skill assessment), and certifies how deeply
18
- you command your own agents (`certify agents`) through an interview. Both
19
- require you to be [logged in](#login-login--logout) first.
20
- - **`report`** — builds and **opens** the full, shareable HTML report for the
21
- current project (usage + certified Skills, with the complete per-agent
22
- detail). `ai-usage`/`certify` persist their result silently; `report` is how
23
- you produce and open the HTML to share with your team.
24
- - **`share`** — *(temporarily disabled)* turns the project's latest `ai-usage`
25
- result (tier + score) into a branded card you can post on LinkedIn (built
26
- offline; the PNG is exported in your browser). Invoking it prints a disabled
27
- notice and runs nothing.
28
- - **`login` / `logout`** — identify yourself as a registered Talent (email
29
- or Google). See [Login](#login-login--logout).
30
- - **`add-role` / `change-role`** — manage your roles: add a growth role from the
31
- catalog, or switch your MAIN role to one you already hold (arrow-key pickers).
32
- The onboarding interview also ends with the same MAIN-role step. See
33
- [Command families](#command-families) for the `role`/`profile`/`add` groupings.
34
- - **`superadmin`** — a non-production, password-gated test tool for the team
35
- running this CLI against the service; not something a Talent uses. See
36
- [Superadmin](#superadmin-non-production-only).
8
+ ## Install
37
9
 
38
- **Session gating (ADR-061).** `ai-usage` is the only command a non-registered
39
- (session-less) caller can run — the anonymous AI-usage evaluation, with its
40
- consent → email → persistence flow. Every other command requires an active
41
- session: exempt are `ai-usage` and `login`; `logout` without a session is a
42
- silent no-op; `certify`/`report`/`share` require `shakers login` first
43
- (`superadmin` is its own non-prod escape hatch, exempt too). A session-less
44
- call to a gated command prints a clear error naming what is missing and both
45
- `shakers login` and `shakers register`; in non-TTY/agent mode it exits with a
46
- non-zero code. `ai-usage` is public: when no session exists it only reminds the
47
- Talent they can sign in (a Yes/No prompt on a TTY), never blocks. The former
48
- standalone `ai-footprint`/`ai-certify` binaries were retired earlier; the
49
- interactive shell that replaced them is now retired too (see
50
- [`docs/decisions.md`](docs/decisions.md): ADR-060 REPL→argv, ADR-061 gating).
10
+ Requires Node 18 or later.
51
11
 
52
- The AI usage mechanism is inspired by `darnoux/claude-code-level-up` (scan
53
- local signals and classify by level), extended to cover the main AI tools on
54
- the market (not just Claude) and to a full 8-tier ladder with per-tier roadmap
55
- content.
56
-
57
- ## What it does
58
-
59
- 1. **Scans** the current project (and relevant parts of your home
60
- directory) for known AI-tool configuration.
61
- 2. **Classifies** the setup into a tier, `T0` to `T7` ("empty bench" to
62
- "orchestrated workshop"), computed deterministically — no LLM involved
63
- in the level itself.
64
- 3. **Leads with a "why this tier" analysis**: exactly which criteria you meet,
65
- with the signal behind each one, and the single next criterion blocking
66
- progression to the next tier — shown FIRST, before the score.
67
- 4. **Evaluates your agents**: one line per agent (nested subagents drawn with
68
- stacked `↓`), each with a **definition-quality score** (0-100, how well the
69
- agent is built) and a **usage signal** (how often you've actually invoked it,
70
- read from your local Claude Code history — usage only, never session
71
- content). Full per-agent detail (rationale included) lives in the `report`
72
- HTML.
73
- 5. **Roadmap behind `--roadmap`**: current tier → next tier, with what it
74
- unlocks, steps, a copyable code snippet, community tips and common mistakes,
75
- plus a ready-to-paste implementation prompt — curated, authored content, not
76
- generated per run. Hidden from the default output to keep the terminal clean;
77
- pass `--roadmap` (alias `--next`) to see it.
78
-
79
- Everything above runs **always, locally, unconditionally** — nothing is
80
- gated behind a decision. See [Privacy & consent](#privacy--consent-model)
81
- for what happens if you choose to save your report to Shakers.
82
-
83
- ### Agent evaluation (the LLM feature)
84
-
85
- The definition-quality score is the one AI-model-backed part of `ai-usage`. As
86
- with the org-chart synthesis and roadmap personalization, the CLI never calls a
87
- model directly: it POSTs the scrubbed agent definitions to the certifications
88
- service's `agent-evaluation` endpoint (a sibling of your configured ingest
89
- endpoint) that runs the model server-side (**gemini-2.5-flash**) and returns a
90
- score + short rationale per agent. It degrades gracefully: no endpoint, a network error, or a
91
- timeout simply means no scores are shown — the rest of the report is unaffected.
92
- The **usage** signal is entirely local (no network, no model). See
93
- [Privacy & consent](#privacy--consent-model).
94
-
95
- ## Installation
96
-
97
- One line:
98
-
99
- ```bash
100
- curl -fsSL https://raw.githubusercontent.com/devShakers/ai-usage-evaluator/release/install.sh | bash
101
- ```
102
-
103
- The installer:
104
-
105
- - Requires **Node 18+** (checks and fails clearly if missing/too old).
106
- - Discovers the CLI's own `src/*.js` modules dynamically (via a local copy
107
- or the GitHub API) rather than hardcoding a file list.
108
- - Places the tool in `~/.shakers/` and drops the single `shakers`
109
- command in `~/.local/bin` (the standalone `ai-footprint`/`ai-certify`
110
- launchers are no longer created, and any legacy ones are removed on
111
- upgrade). The only third-party package is **`@livekit/rtc-node`** (the
112
- LiveKit interview engine), fetched post-install for every flavor;
113
- `SHAKERS_SKIP_NATIVE_INSTALL=1` skips that fetch (offline installs / CI).
114
- - All installer output is in English, unconditionally (it runs before
115
- Node/the CLI's own i18n layer is available).
116
-
117
- Alternative, cloning the repo first (same result, lets you review the code
118
- before installing):
119
-
120
- ```bash
121
- git clone https://github.com/devShakers/ai-usage-evaluator
122
- cd ai-usage-evaluator
123
- ./install.sh
124
- ```
125
-
126
- Uninstall: `./install.sh --uninstall`.
127
-
128
- ## Publishing (maintainers)
129
-
130
- One codebase ships in three flavors; the baked backend target is derived from
131
- the package **name** (`src/config.js#PACKAGE_NAME_ENV`), overridable per run
132
- with `SHAKERS_CLI_ENV=staging|dev|local`. Per-endpoint `SHAKERS_CLI_*_BASE`
133
- env vars and `config.json` always win over the baked default.
134
-
135
- | Flavor | Package name | Registry | Baked target | Publish |
136
- |---|---|---|---|---|
137
- | Private (current) | `@shakers/shakers-cli` | GitLab proj 201 (`publishConfig`) | dev (new-works) | `export SHAKERS_GITLAB_TOKEN=<PAT, scope write_registry on proj 201>` then `npm publish` |
138
- | Public beta | `shakers-cli-beta` | npmjs (public) | staging | bump `BETA.version` in `scripts/prepare-beta.js`, then `npm run publish:beta` |
139
- | Local | (checkout, `@shakers/shakers-cli`) | — | dev, or `SHAKERS_CLI_ENV=local` for localhost | run from the clone; no publish |
140
-
141
- Both publishes bump `version` first (the registry rejects re-publishing an
142
- existing version). The private one publishes from a checked-out `release` with the
143
- committed `@shakers/shakers-cli` manifest, unchanged. For the beta, bump
144
- `BETA.version` in `scripts/prepare-beta.js` (manual, one line), then run the
145
- single command `npm run publish:beta`: it stamps `name`/`version`/`publishConfig`,
146
- runs `npm publish --tag latest`, and restores the private manifest with git. The
147
- tag is explicit because npm refuses to publish a prerelease (`0.8.0-beta.N`) to
148
- `latest` without one; `--tag latest` still moves `latest` to the new version, so
149
- testers install `shakers-cli-beta` bare (which resolves `latest`) with no manual
150
- `npm dist-tag add` step. The npmjs account for `shakers-cli-beta` must
151
- exist and you must be `npm login`ed (or set `NODE_AUTH_TOKEN`) first — nothing
152
- here publishes automatically.
153
-
154
- `@livekit/rtc-node` is a real `dependencies` entry, so `npm i` / `npm i -g` of
155
- either package pulls it automatically (GitLab's packument keeps `dependencies`
156
- but strips `optionalDependencies`, which is why it must not be optional).
157
-
158
- ## Usage
159
-
160
- `shakers <command> [flags]` runs one command and exits. With no command it
161
- prints the usage help:
162
-
163
- ```bash
164
- shakers # print the usage help and exit
165
- shakers --lang es|en # force the CLI copy language instead of OS-locale detect
166
- ```
167
-
168
- The commands (only `ai-usage` and `login` run without a session — see
169
- [Session gating](#shakers-shakers)):
170
-
171
- ```bash
172
- shakers ai-usage # scan this project + machine, print the report (no HTML link) — anonymous
173
- shakers certify # certify a DIMENSION of your role over a LiveKit interview (needs login)
174
- shakers report # build + open the full shareable HTML report (needs login)
175
- shakers share # branded LinkedIn card (temporarily disabled)
176
- shakers login # identify yourself as a registered Talent (email or Google)
177
- shakers logout # forget the stored session (no-op if none)
178
- shakers superadmin # non-production test tool — not for Talents
179
-
180
- # Marketplace & profile (all need login):
181
- shakers alma # interactive mini-shell to chat with Alma, your AI assistant
182
- shakers find-projects # list the Projects/Positions available to you (paginated, filterable)
183
- shakers show-project # detail of one project/position (by number or id)
184
- shakers save-project # bookmark a project/position (by number or id)
185
- shakers unsave-project # remove a bookmark (by number or id)
186
- shakers applications # projects you applied to + status
187
- shakers invitations # your unread project invitations
188
- shakers availability # view (or --set) your availability
189
- shakers rate # view (or --set) your per-project rate
190
- shakers certifications# your certified / uncertified / expired role dimensions
191
- shakers add-role # add a role to your profile (a growth role) — arrow-key picker
192
- shakers change-role # switch your MAIN role to one you already have — arrow-key picker
193
- shakers me # your profile summary (alias: shakers profile)
194
- ```
195
-
196
- #### Command families
197
-
198
- The flat commands above are also grouped into **families** — a friendlier way to
199
- discover them for both humans and agents. `shakers <family> <subcommand>` runs the
200
- exact same handler; **every flat command keeps working as an alias**, so nothing
201
- breaks. Run `shakers <family>` with no subcommand to list its subcommands, and
202
- `shakers` (no args) prints the full family map.
203
-
204
- | Family | Subcommands | Flat aliases |
205
- |--------|-------------|--------------|
206
- | `add` | `skill`, `agent`, `project`, `role` | `add-skill`, `add-agent`, `add-project`, `add-role` |
207
- | `role` | `add`, `change` (`main`) | `add-role`, `change-role` |
208
- | `profile` | `show`, `rate`, `languages`, `socials`, `experiences`, `portfolios`, `availability`, `certifications` | `me`, `rate`, `lang`, `socials`, `experiences`, `portfolios`, `availability`, `certifications` |
209
- | `projects` | `find`, `show`, `save`, `unsave`, `invitations`, `applications` | `find-projects`, `show-project`, `save-project`, `unsave-project`, `invitations`, `applications` |
210
- | `usage` | `run`, `report`, `share` | `ai-usage`, `report`, `share` |
211
- | `certs` | `list`, `certify` | `certifications`, `certify` |
212
- | `account` | `login`, `logout`, `register`, `config` | `login`, `logout`, `register`, `config` |
213
-
214
- ```bash
215
- shakers role add # == shakers add-role
216
- shakers role change # == shakers change-role
217
- shakers profile rate # == shakers rate
218
- shakers projects find # == shakers find-projects
219
- shakers usage run # == shakers ai-usage
220
- shakers account login # == shakers login
221
- shakers profile # no subcommand → your profile summary (== shakers me)
222
- shakers projects # no subcommand → lists the "projects" subcommands
223
- ```
224
-
225
- Each command keeps all its flags:
226
-
227
- ```bash
228
- shakers ai-usage --json # report as JSON on stdout
229
- shakers ai-usage --root ../other # scan another directory instead of the current one
230
- shakers ai-usage --roadmap # also show the tier roadmap / next-steps (hidden by default; alias --next)
231
- shakers ai-usage --no-save # persist nothing (report only, on screen)
232
- shakers ai-usage --build-next-level # secondary path: write deterministic starter file(s) for the next tier
233
- shakers ai-usage --force # with --build-next-level, overwrite an existing file
234
- shakers ai-usage --lang es|en # force the report language instead of OS-locale detect
235
- shakers ai-usage --consent-status # view your save decision / email / last send
236
- shakers ai-usage --consent-revoke # revoke consent to save (-> denied), no more sends
237
- shakers ai-usage --consent-reset # clear the decision (-> undecided), ask again next run
238
- shakers ai-usage --consent-email E # change the email on file, without touching the decision
239
- shakers ai-usage --set-endpoint URL # persist the ingest endpoint (see "Configuration" below)
240
- shakers ai-usage --show-endpoint # show the effective endpoint and where it comes from
241
- ```
242
-
243
- `ai-usage` no longer prints a report link — its output is the clean terminal
244
- view. Use `report` to produce and open the full HTML (needs login):
245
-
246
- ```bash
247
- shakers report # materialize + open this project's HTML report in the browser
248
- shakers report --root ../other # report for another project
249
- shakers report --no-open # just print the file:// link, don't launch the browser
250
- shakers report --lang es|en # force the surrounding CLI copy + report language
251
- ```
252
-
253
- The `share` command reuses the last ai-usage stored for the project (needs login):
254
-
255
- ```bash
256
- shakers share # build the LinkedIn card for this project's ai-usage
257
- shakers share --root ../other # card for another project's ai-usage
258
- shakers share --lang es|en # force the surrounding CLI copy language (the card is English)
259
- ```
260
-
261
- ### Marketplace & profile
262
-
263
- These talk to the Shakers platform on your behalf (they use your login session,
264
- never a project scan). All need `shakers login` first.
265
-
266
- **Chat with Alma.** Open an interactive mini-shell with your AI assistant from the
267
- terminal. The conversation keeps its context across turns, and Alma can act on your
268
- profile (with an arrow-key confirmation before anything irreversible):
269
-
270
- ```bash
271
- shakers alma # opens the conversation; type "exit" to quit
272
- ```
273
-
274
- Before the first message, `alma` asks for **consent to share a code-free map of the
275
- current project** (its name, services, agents, technologies — never your source
276
- code) so Alma can answer with context. If you decline — or there is no terminal to
277
- ask — every message is sent **without** that context. The consent is CLI-side only.
278
-
279
- **Find and open projects.** `find-projects` lists the positions available to you,
280
- ordered by match, paginated and filterable server-side:
281
-
282
- ```bash
283
- shakers find-projects # first page (grouped All / Saved)
284
- shakers find-projects --page 2 --limit 20 # paginate
285
- shakers find-projects --attendance remote --country ES # filter by work mode / country
286
- shakers find-projects --tab saved # only your saved positions
287
- shakers find-projects --json # machine output (includes ids)
288
- ```
289
-
290
- **Reference a project by its number.** `find-projects` and `applications` hide the
291
- raw ids from the human listing and print a `N)` number instead. `show-project`,
292
- `save-project` and `unsave-project` accept **that number** (from the last listing)
293
- or a full id:
294
-
295
- ```bash
296
- shakers show-project 3 # detail of item 3 from the last listing
297
- shakers save-project 3 # bookmark item 3
298
- shakers unsave-project 3 # remove the bookmark
299
- shakers show-project <uuid> # a raw id also works (for scripts / --json)
300
- ```
301
-
302
- **Your applications and invitations:**
303
-
304
- ```bash
305
- shakers applications # positions you applied to + status (also refreshes the number cache)
306
- shakers invitations # your unread project invitations
307
- ```
308
-
309
- **Your profile.** View by default; the two setters (`--set`) are interactive with
310
- an explicit confirmation before writing (they change what clients see):
311
-
312
- ```bash
313
- shakers me # summary: headline, role, % complete, rate, availability, languages, skills/agents count
314
- shakers certifications # your role dimensions by state (certified / uncertified / expired) + band
315
- shakers availability # view your availability (open-to-work, hours/month, location)
316
- shakers availability --set # change it — arrow-key pickers, then confirm
317
- shakers rate # view your per-project rate
318
- shakers rate --set # change it — pick modality + currency, type the amount, then confirm
319
- ```
320
-
321
- **Your roles.** A talent has one **MAIN role** plus optional **growth roles**. Both
322
- commands use the same arrow-key picker as the rest of the CLI:
323
-
324
- ```bash
325
- shakers add-role # pick a role from the catalog and add it as a growth role
326
- shakers change-role # switch your MAIN role to one you already have
327
- ```
328
-
329
- `add-role` (alias `shakers role add`) reads the role catalog (the roles you do not
330
- already hold) and adds the one you pick. `change-role` (alias `shakers role change`)
331
- lists the roles you already hold and sets the one you pick as your MAIN role.
332
-
333
- Setting your **MAIN role** is a step of **registration** (`shakers register`): after
334
- you take or skip the interview during the alta, it offers your resolved/recommended
335
- roles and lets you set your MAIN role. Running the interview on its own
336
- (`shakers onboarding`) does **not** ask for the main role — to change it later use
337
- `shakers change-role`.
338
-
339
- **Repeat the onboarding interview.** `shakers onboarding --repeat` (alias
340
- `shakers onboarding repeat`) re-runs the **interview only**, **overwriting** the
341
- previous one (it does not touch your main role). Because the prior evaluation is
342
- discarded and it cannot be undone, it first shows a clear warning and requires an
343
- **explicit Yes/No confirmation** (arrow-key selector); on a non-TTY, pass `--yes` to
344
- confirm. Only after you confirm does it reset the interview and run it again.
345
- Declining aborts with no change. If you have no onboarding yet it tells you to run
346
- `shakers onboarding` first.
347
-
348
- ```bash
349
- shakers onboarding # the interview (+ final main-role step)
350
- shakers onboarding --repeat # warn + confirm, then overwrite and re-run
351
- shakers onboarding repeat --yes # same, pre-confirmed (non-interactive / agents)
352
- ```
353
-
354
- Every listing/detail is also available as `--json` for scripting, and every
355
- command takes `--lang es|en`.
356
-
357
- Without installing, from a copy of the repo, `shakers <cmd>` is equivalent to
358
- `node bin/shakers.js <cmd>`.
359
-
360
- ### Human vs. agent mode (dual TTY contract)
361
-
362
- Every command keeps the same dual contract it had before the shell was
363
- retired: on a real terminal it is **interactive** (prompts, masked secret
364
- input, pickers); on a non-TTY (piped stdin, CI, an agent) it runs **one-shot**
365
- and never blocks on a prompt it cannot answer. Each interactive question has a
366
- flag equivalent (`--email`, `--root`, `--skill`, `--accept-disclaimer`,
367
- `--consent-email`, …), read-heavy commands print machine-readable output with
368
- `--json` (`ai-usage --json`), and **exit codes are meaningful** — a gated
369
- command with no session, or a command that failed, exits non-zero, so an agent
370
- can branch on the result.
371
-
372
- Results are saved in `~/.config/shakers/` (a per-project cumulative HTML
373
- report plus its `report-state.json`). **Nothing is ever written to the
374
- scanned project** — the report can't slip into a commit by accident.
375
-
376
- ### MCP server (`shakers mcp`)
377
-
378
- `shakers mcp` speaks JSON-RPC over stdio so a desktop AI app (Claude / ChatGPT
379
- Desktop) can drive the same features as tools. It exposes, among others:
380
-
381
- - **AI usage**: `ai_usage`, `ai_usage_result`.
382
- - **Auth**: `social_signin_start`, `social_signin_poll`, `logout`.
383
- - **Sign-up** (from the talent's own AI, ticket 39540; copy from UX review
384
- 39574): every talent-facing text is fixed, comes from the tools in the
385
- talent's language (es/en/it/pt, fixed by their first message) and the AI shows
386
- it word for word. `signup_start` (welcome and permission to look for the CV),
387
- `signup_email` (the email they read most), `signup_draft` (the profile draft
388
- and the data notice, confirmed before the account exists),
389
- `signup_create_account` (starts the hub import of LinkedIn + CV + what the AI
390
- knows and opens the local password/Google window, which claims that profile
391
- with a code kept only in memory; if the email already has an account, the
392
- window asks the talent to sign in instead), `signup_status`,
393
- `update_existing_profile` (shows what would change in an existing profile and
394
- re-imports filling only empty fields), `save_profile_details`,
395
- `import_profile`, `open_web` (opens the web signed in through a one-time
396
- link), `open_linkedin_profile` (only when the talent does not know where to
397
- find their LinkedIn URL), plus `suggest_register_context` and `read_cv`.
398
- `ai_usage` is the step after the account exists, right after its two
399
- disclaimers.
400
- - **Onboarding interview**: `onboarding_interview_start`,
401
- `onboarding_interview_turn`, `onboarding_interview_complete` (if LiveKit
402
- cannot load, the talent is sent to the web), `repeat_onboarding_interview`
403
- (OVERWRITE-repeat — the agent must warn the talent it is irreversible before
404
- calling), `onboarding_finish` (only after a repeat; the sign-up never calls it).
405
- - **Roles**: `list_available_roles`, `add_role`, `list_my_roles`, `set_main_role`
406
- — `set_main_role` is the onboarding **final step** (after
407
- `onboarding_interview_complete`, or if the interview was skipped, offer
408
- `list_my_roles` and set the picked one).
409
- - **Closed questions** of the sign-up (AI-usage consent, which email, interview
410
- here or later, how to answer it, main role) are answered by picking an option.
411
- When the client declares the MCP `elicitation` capability (spec 2025-06-18),
412
- the tool asks in the client's own dialog (`elicitation/create`) and gets the
413
- pick directly; otherwise it returns `question` and `options` and the AI offers
414
- them as buttons or a numbered list. The legal texts are always shown in the
415
- chat before any consent dialog.
416
- - **Asked before touching this computer**: `suggest_register_context` (look for
417
- the CV), `read_cv` (read one CV file), `import_profile` with a CV file (send it)
418
- and `add_project` (send the project folder's name, web address, dates and
419
- client) each ask the talent themselves, naming exactly what they read or send,
420
- the same way as the closed questions above. Without a dialog, the answer only
421
- counts when it comes back for a question that tool asked for those exact
422
- arguments; a yes the AI sets on its own is ignored and the question is asked
423
- again. Nothing is read or sent before the yes.
424
- - **Profile / skills / agents**: `list_addable`, `add_skill`, `add_agent`,
425
- `add_project`, `get_profile`, `get_rate`, `get_languages`, `list_socials`,
426
- `list_experiences`, `list_portfolios`, `get_availability`.
427
- - **Marketplace**: `find_projects`, `show_project`, `save_project`,
428
- `unsave_project`, `list_invitations`, `list_applications`.
429
- - **Certifications**: `list_certifications`, `list_certifiable_dimensions`.
430
- - **Alma**: `alma_chat`, `alma_decision` (a change Alma proposes is applied only
431
- after the talent says yes).
432
-
433
- Each tool has two audiences. Its `title` and `description` are what the talent
434
- reads in the client: plain words saying what it does, what it reads on the
435
- machine and what it sends to Shakers. `packaging/mcpb/manifest.json` declares the
436
- same tools with the same descriptions, and a test keeps them equal. How the AI
437
- must use a tool (order, verbatim texts, internal ids) travels in the
438
- description of its input schema.
439
-
440
- MCP tool names are **stable** (renaming would break existing client configs); the
441
- role tools above were added, not renamed. `register`, `register_preview` and
442
- `register_status` were removed with the sign-up redesign, not renamed. `login`
443
- (it only pointed to `social_signin_start`) and `ask` (a copy of `alma_chat` that
444
- dropped Alma's confirmation requests) were removed to show the talent fewer
445
- tools; the `/ask` prompt now uses `alma_chat`.
446
-
447
- ## Try it
448
-
449
- Today the CLI runs from a repo checkout with `node bin/shakers.js` (the npm
450
- package is `shakers`, run with `npx shakers <command>` — e.g. `npx shakers ai-usage` — which is later work). Verified commands:
451
-
452
- ```bash
453
- node bin/shakers.js # no command → prints the usage help (exit 0)
454
- node bin/shakers.js ai-usage # anonymous AI-usage evaluation (no session needed)
455
- node bin/shakers.js ai-usage --help # the command's own flags/help
456
- node bin/shakers.js login # sign in (needs an endpoint configured)
457
- node bin/shakers.js logout # sign out (silent no-op if no session)
458
- node bin/shakers.js certify # gated: with no session → clear error, exits 1
459
- ```
460
-
461
- Gating behaviour to expect, session-less: `ai-usage` and `login` run; `logout`
462
- is a silent no-op (exit 0); `certify`/`report`/`share` print "requires an
463
- active session" naming both `shakers login` and `shakers register`, and **exit
464
- non-zero** (so an agent can branch on it). An unknown command (e.g. the removed `start`) also exits
465
- non-zero.
466
-
467
- ## Skill certification (`certify`)
468
-
469
- `certify` (run as `shakers certify`, alias `certify skills`) certifies
470
- Skills from your Shakers catalog by analyzing your local project. **It
471
- requires you to be [logged in](#login-login--logout) first** (ADR-050) — see
472
- the login gate below; there is no email-only path any more. It runs in two
473
- phases, back to back:
474
-
475
- 1. **Resolve** — detects your project technologies, asks the certifications
476
- service which map to a Skill you can certify, and shows certifiable vs
477
- non-certifiable. Only the detected **technology names** (plus an email
478
- audit hint, when one is on file) leave the machine here — the call is
479
- authenticated by your login session's bearer token, not by the email.
480
- 2. **Certify** — you pick ONE certifiable Skill to certify (interactive
481
- single-select, or `--skill <name>` / `--skill <position>` non-interactively
482
- — one Skill per run, so the mandatory interview below always has exactly
483
- one Skill to interview about); the CLI takes a deterministic **code
484
- sample** for it, runs a secret-scrub pass, sends it for a Skill assessment,
485
- and shows the result. The assessment report is **always shown**; the
486
- analyzed result is persisted to Shakers only if you granted consent up
487
- front. Skill scores are **indicative and not reproducible** — not an
488
- official qualification. This is the single most invasive payload in this
489
- repo — your **actual sampled code** — so if you granted consent, it's also
490
- the clearest case of what [Privacy & consent model](#privacy--consent-model)
491
- describes as Datadog capture: a third party retaining that code for up to
492
- three months, with no selective deletion afterwards. Right after the
493
- code-only result, a short **interview about that same Skill** starts
494
- automatically (see below) — it is no longer optional.
12
+ **Command line (npm)**
495
13
 
496
14
  ```bash
497
- shakers certify # resolve + certify a Skill for the current project
498
- shakers certify --root ../other # analyze another directory
499
- shakers certify --skill React # certify the Skill by name (no interactive select)
500
- shakers certify --skill 1 # certify the Skill at this position in the resolve report
501
- shakers certify --email you@shakers.com
502
- shakers certify --lang es|en
503
- shakers certify --accept-disclaimer # accept the legal disclaimer non-interactively
15
+ npm i -g shakers-cli
504
16
  ```
505
17
 
506
- Unlike `ai-usage` (which always produces a local report), `certify` is
507
- inherently server-side: it requires an endpoint — `SHAKERS_CLI_CERTIFY_ENDPOINT`,
508
- or (its usual case) the resolved `SHAKERS_CLI_INGEST_ENDPOINT` from which the
509
- certify route is derived as a sibling (see
510
- [Configuration](#configuration-environment-variables)) — there is no
511
- local-only certification and, since ADR-042, only ONE backend to configure. The
512
- flow is deliberately front-loaded, and checked in this order, entirely before
513
- any Skill is chosen: (1) the endpoint must be configured, (2) your project's
514
- technologies are detected locally (no egress yet), (3) the **login gate**
515
- refuses — with no egress at all — a run with no active session (a superadmin
516
- session bypasses it, see [Superadmin](#superadmin-non-production-only)), (4) a
517
- legal disclaimer is shown that you must explicitly accept (the code-egress
518
- gate), and (5) — the first time, and skipped entirely for a logged-in Talent
519
- whose session already carries an email — the save-to-Shakers consent and an
520
- email OTP verification are handled, still before you choose a Skill. The
521
- disclaimer assumes the project is your own and attributes responsibility to
522
- you, so **never run it on a third party's code** (e.g. a client under NDA).
523
- For local end-to-end testing, run the real certifications service and point
524
- the endpoint at loopback (see "Local end-to-end testing" below); the in-repo
525
- stub that used to serve this route is retired. The real implementation lives
526
- in `sh-web-works-certifications` — the CLI's only backend.
527
-
528
- ### Skill interview — starts on its own, consent still required
18
+ Or run it without installing: `npx -y shakers-cli <command>`.
529
19
 
530
- Once `certify skills` shows the code-only assessment for the Skill you
531
- certified, it goes straight into a short **interview about that same Skill**:
532
- a few questions about the sampled code (an antifraud check) and about your
533
- general command of the tool, over the same session/turn/verdict machine
534
- `certify agents` uses. There is no "do you want to try it?" prompt any more —
535
- it always reaches the interview when stdin is an interactive terminal and an
536
- interview endpoint is configured. What it does NOT skip is consent: a legal
537
- notice (what is asked, and what happens to your answers — including the
538
- third-party Datadog retention if you gave content consent) is shown and you
539
- must explicitly accept it before anything about the interview leaves the
540
- machine; declining (or answering nothing) stops there, visibly, and your
541
- code-only Skill certification is unaffected either way. Running from a
542
- pipe/CI (no TTY) cannot host an interview or a consent answer, so it is
543
- skipped with a visible message. The server combines the interview with the
544
- code score into an attested combined level (Middle/Senior/Expert), which can
545
- raise or lower what the code alone gave you.
546
-
547
- ### Agent certification (`certify agents`) — an interview, not a form
548
-
549
- `certify agents` certifies how deeply you command ONE of your own agents
550
- (`.claude/agents/*.md`). It is a real **interview**: the service opens a
551
- session, asks **one question per turn**, decides which of the five assessment
552
- areas each question probes, and decides when to stop. The CLI is the courier —
553
- it re-sends the agent **definition** (never persisted server-side, only hashed)
554
- and your answer, and it deliberately cannot choose the question or the area.
20
+ **Command line (install script)**
555
21
 
556
22
  ```bash
557
- shakers certify agents # interview + verdict for one agent
558
- shakers certify agents --root ../other
559
- shakers certify agents --email you@shakers.com
560
- shakers certify agents --lang es|en
23
+ curl -fsSL https://raw.githubusercontent.com/devShakers/ai-usage-evaluator/release/install.sh | bash
561
24
  ```
562
25
 
563
- What is worth knowing before you start:
564
-
565
- - **Either the whole flow, or nothing is asked of you.** Certifying now needs
566
- an **active [login](#login-login--logout) session** (ADR-050) — a session
567
- proves control of the account, which is a higher bar than the
568
- email+OTP check this used to be. That is checked **locally, before you are
569
- asked for anything** — no address, no agent picker, no egress — and if
570
- you're not logged in it stops right there with a distinct message for
571
- "never logged in" vs "your session expired," and tells you to run `login`.
572
- A non-production superadmin session bypasses this (see
573
- [Superadmin](#superadmin-non-production-only)). `--email` (or the address
574
- already on file) still travels as an optional audit hint the server matches
575
- against your session — it is no longer what authenticates you. The
576
- disclosure still comes first, because the login check itself sends nothing.
577
- - **You can stop and come back.** Progress lives in
578
- `~/.config/shakers/interview-session.json` (permissions `600`), written
579
- atomically after every turn. If the process dies — Ctrl-C, a dropped
580
- connection, a closed laptop — re-run `certify agents` and it offers to
581
- continue where you left off, re-sending the answer that was in flight so you
582
- never retype it. The file is deleted when the verdict arrives (or when the
583
- session expires), and it holds a **bearer token** for your interview plus the
584
- answer currently in flight, which is why it is `600` and why nothing prints
585
- it.
586
- - **There is a limit of 5 interviews per 24 hours**, and an abandoned session
587
- still counts. That is why declining a resume tells you the attempt is already
588
- spent, and why a transient network failure never silently opens a second
589
- session.
590
- - **Answers are capped at 4000 characters, counted after the secret-scrub
591
- pass.** Scrubbing can make text *longer* (a path or a key becomes
592
- `[REDACTED]`), so an answer that fits raw can be refused. You are told before
593
- the first question, and an over-long answer is refused **locally**, with the
594
- exact overshoot — never as a server error after you wrote three paragraphs.
595
- - **You see the turn number and the areas you have been ASKED ABOUT, each with
596
- how many turns it has had — not how many turns are left.** "Asked about" is not
597
- "covered": whether an area is substantiated is the grader's judgement, and one
598
- question is never it. The per-area count is there so a lopsided interview (five
599
- turns on one area, one on another) is visible instead of invisible. The service
600
- owns the stop condition; showing you its budget would turn "when does this end"
601
- into something to play against.
602
- - **Before the first question you are told what is being judged**: the reasoning
603
- behind each decision, the alternatives you discarded and why, and concrete
604
- cases where it showed. It is not a request for longer answers — a claim with no
605
- reasoning behind it does not evidence command however long it is.
606
- - **Two different lifetimes for what you write**, both stated in the disclosure
607
- you accept before anything leaves: (1) inside Shakers your free text is
608
- **deleted when the verdict is emitted**, in the same operation — only the
609
- question, the quote that was verified and each area's tag survive; (2) if you
610
- granted content consent, the copy at **Datadog LLM Observability** (a third
611
- party) runs its full retention and **cannot be deleted** — the first deletion
612
- does not reach it. And the asymmetry that matters: consent is read fresh on
613
- every call, but if it is on for the **verdict** request, the **whole**
614
- interview is captured, even if every earlier turn was sent without it.
615
- - **The verdict can take minutes.** Grading runs three samples over the full
616
- transcript, and it can outlast the CLI's own wait. When that happens the CLI
617
- polls and collects the verdict rather than reporting a failure; if you give up
618
- first, the session stays on disk and the next run picks the verdict up.
619
-
620
- Like `certify skills`, this needs an endpoint: the four interview routes are
621
- derived from `SHAKERS_CLI_INGEST_ENDPOINT`, the CLI's one backend (see
622
- [Configuration](#configuration-environment-variables)).
26
+ Uninstall with the same line ending in `| bash -s -- --uninstall`.
623
27
 
624
- ## Login (`login` / `logout`)
28
+ **Claude Code plugin**
625
29
 
626
- A registered Talent identifies themselves with `login` (issue 122 / ADR-044).
627
- Since ADR-061 a session is required by **every** command except `ai-usage` and
628
- `login` itself — `certify` (both `skills` and `agents`) also proves control of
629
- the **account**, not just of an email address (ADR-050). `login` and `logout`
630
- run without a session (that is how you obtain/drop one); `logout` with no
631
- session is a silent no-op.
632
-
633
- ```bash
634
- shakers login # no method flag: interactive picker (Email / Google / LinkedIn) on a real TTY
635
- shakers login --email you@shakers.com # skip the picker, prompt only for the password
636
- shakers login --google # skip the picker, go straight to the Google flow
637
- shakers login --linkedin # skip the picker, go straight to the LinkedIn flow
638
- shakers logout # forget the stored session (no-op if none)
639
30
  ```
640
-
641
- - **No `--password` flag, ever.** `argv` is visible to every other process on
642
- the machine (`ps`) and lands in shell history, so the password is only ever
643
- collected via a masked interactive prompt or a stdin pipe — never a flag.
644
- - **Email/password** sends `{ email, password }` to the certifications
645
- service's `POST /api/v1/auth/login/email`, which proxies the credentials to
646
- the Shakers Hub **server-side** and runs its token-exchange, returning a
647
- certifications-service JWT the CLI stores locally. The password transits
648
- CLI → certifications service → Hub, over TLS, and is never persisted by the
649
- certifications service.
650
- - **Google** is an **OAuth 2.0 Device Authorization Grant** (RFC 8628): the CLI
651
- asks the Hub for a short code, shows you a URL and a `XXXX-XXXX` code to enter
652
- in your browser, and polls until you authorize. Nothing about Google lives on
653
- your machine — no client id, no loopback server, no secret; the Hub owns all
654
- Google config and does the token exchange server-side. After you authorize, the
655
- Hub session is exchanged for the same API JWT the email flow stores.
656
- - **LinkedIn** signs in through the same device flow as Google, with
657
- `provider=linkedin`: the `login --linkedin` / `--provider linkedin` flags and
658
- the sign-in window served to AI apps (the loopback method-choice screen) both
659
- route to it. This reverses the earlier parking (ADR-041/046). Whether it
660
- completes depends on the Hub having a LinkedIn OAuth app provisioned.
661
- - The session (`{ accessToken, expiresAt, email }`) is stored **atomically**,
662
- permissions `600`, in `~/.config/shakers/auth-session.json`. **Logged in**
663
- means "an unexpired token is present" — an unparseable or missing
664
- `expiresAt` is treated as expired, never as active. `login` while a session
665
- is already active tells you so instead of silently overwriting it; run
666
- `logout` first to switch accounts.
667
-
668
- ## Superadmin (non-production only)
669
-
670
- `superadmin` is a password-gated, **non-production** test tool for the team
671
- running this CLI against a service instance — not something a Talent uses.
672
- The server 404s every superadmin route in production regardless of the
673
- password.
674
-
675
- ```bash
676
- shakers superadmin # open a session (prompts password + your own email)
677
- shakers superadmin --email you@shakers.com # same, prompts only the password
678
- shakers superadmin --inspect --email talent@example.com # read-only certification receipt (ADR-025)
679
- shakers superadmin --logout # forget the locally stored session
31
+ /plugin marketplace add devShakers/ai-usage-evaluator
32
+ /plugin install shakers@shakers-mcp
680
33
  ```
681
34
 
682
- - **Also no `--password` flag**, for the same reason as `login` — the
683
- password is only ever read from an interactive prompt or a stdin pipe.
684
- - Opening a session validates the password server-side and persists the
685
- returned token locally (`config.json`'s `superadminSession`, ADR-027).
686
- `certify` then accepts that session **instead of** a `login` session,
687
- bypassing the login/identity gates on **any** email/repo, and its results
688
- are stamped `test_origin: true`.
689
- - **A known, documented exception (ADR-050):** unlike `certify agents`
690
- (hardened to reject an unregistered email), the skill-code certification's
691
- superadmin branch still tolerates `userId: null` and lets a superadmin
692
- certify code against an unregistered email. This asymmetry is deliberate
693
- and left as-is — it's non-production, encrypted, and yields no durable
694
- credential — not a bug to fix to parity.
695
- - `--inspect` is read-only: it prints the stored authorship + rubric evidence
696
- for an email's certifications (an attribution trail, not cryptographic
697
- proof).
698
-
699
- ## The report
700
-
701
- - **Terminal output** (from `ai-usage`/`certify`) and a **self-contained HTML
702
- dashboard** (opened by `report`; Shakers branding, responsive, zero network
703
- calls — no CDN, no external script, no fetch). The terminal is the concise
704
- view; the HTML carries the full detail.
705
- - **`ai-usage`/`certify` persist their result silently** into
706
- `report-state.json` and print **no** link (ADR-016). The HTML is produced and
707
- opened only when you run **`report`** — which regenerates the per-project HTML
708
- from state, opens it in your browser (use `--no-open` to just print the link),
709
- and prints the clickable `file://` link.
710
- - **Localized to your OS locale**: a locale starting with `es` shows
711
- Spanish; anything else shows English (`src/locale.js` / `src/i18n.js`).
712
- `--lang` overrides this for a single run, including the copyable
713
- implementation prompt.
714
- - **Terminal sections (ADR-016), in order**: the "why this tier" analysis
715
- FIRST, then the score meter, detected tools, technologies, and a
716
- one-line-per-agent summary (name + model + definition-quality score + local
717
- usage, with `↓` nesting). No environment section; the roadmap / next-steps is
718
- behind `--roadmap`.
719
- - **HTML sections**: everything above at full length, plus the environment,
720
- MCP servers, the agent org chart with **per-agent detail** (score, rationale,
721
- usage), and the current→next roadmap with its implementation prompt.
722
- - **The HTML report is cumulative and scoped per project.** Each scanned
723
- project has its OWN report file (`report-<hash>.html` in
724
- `~/.config/shakers/`), keyed by the project's absolute path, and is
725
- regenerated whole from `report-state.json` each time you run `report`. It
726
- fills in over time: the usage section appears once you've run `ai-usage`
727
- in that project, and the certification section once you've run `certify`
728
- there; both appear together when both have run for the **same** project. This is
729
- intentional (skill-code-certification, reporting redesign) — the report is a
730
- persistent per-project artifact, not a per-invocation transcript. So running
731
- `certify` in a project where you previously ran `ai-usage` correctly
732
- still shows the usage section: that usage was produced for this
733
- project and is part of its cumulative record, not stale or leaked data.
734
- Different projects never mix into one document.
735
- - **Score scope (ADR-010, reverts ADR-009): the 0-100 score is computed over
736
- project ∪ home** — your whole developer AI setup (the project's signals plus
737
- your global `~/.claude` and machine-level config), not this one project in
738
- isolation. It measures the maturity of _you as a developer_, so projects that
739
- share a home tend to read similar scores. ADR-009 had briefly scoped the score
740
- to the project directory only, but that drove notes too low (project-level AI
741
- config is sparse), so ADR-010 reverted it to the earlier project ∪ home
742
- behaviour. The **tier (T0-T7)** uses the same project ∪ home scope.
743
-
744
- ## What it detects
745
-
746
- All detection is **deterministic** (no LLM) and reads only known AI-tool
747
- configuration — never your project's business logic or source code:
748
-
749
- - **Tools**: Claude Code, Cursor, GitHub Copilot, Windsurf, Aider,
750
- Continue, Cline, Gemini CLI, Codex CLI, Amazon Q Developer, Cody, Zed,
751
- Tabnine — existence of config files/directories, binaries on `PATH`,
752
- installed editor extensions.
753
- - **Depth per tool**: project instructions/rules, MCP servers configured,
754
- own skills/commands, hooks.
755
- - **MCP servers**: names and a heuristic category (data/comms/dev/browser/
756
- other) from known config locations (`.mcp.json`, `.cursor/mcp.json`,
757
- Windsurf/Gemini config, etc.) — only the top-level server-name keys are
758
- read, never the values (which can carry commands, URLs or env vars).
759
- - **Memory structure**: `@file` import count and nesting depth, section
760
- count and byte size of context files (`CLAUDE.md`, `AGENTS.md`,
761
- `GEMINI.md`) — structure only, never the file's actual text is stored.
762
- - **Automations**: npm/shell scripts that invoke a known AI CLI, JSON-piping
763
- patterns, and scheduled tasks (cron/launchd/pm2/systemd) — counts and
764
- booleans only.
765
- - **Browser tools**: Playwright/Puppeteer as a project dependency, or a
766
- browser-category MCP server.
767
- - **Agents**: your `.claude/agents/*.md` org chart (name, wired tools,
768
- model, hierarchy) — deterministic; an optional server-side LLM step can
769
- synthesize a short description per agent for nicer cards (see below).
770
- - **Technologies**: frameworks/libraries actually used in the project
771
- (React, Next.js, Express, Django...), parsed from dependency manifests
772
- (`package.json`, `requirements.txt`, `go.mod`, etc.) and filtered through
773
- a curated name map — never a raw dependency dump.
774
- - **Hooks**: hook-based automation configured for a tool.
775
-
776
- **Never** read, stored or sent: file _contents_ beyond what's needed to
777
- compute a count, absolute paths, environment variables, or credentials.
778
-
779
- ## Tier ladder (T0-T7)
780
-
781
- The tier is "the highest tier whose criteria you ALL meet, checked strictly
782
- bottom-up". The 0-4 band used elsewhere (e.g. Shakers direction views) is
783
- derived from the tier — the tier is the single source of truth.
784
-
785
- | Tier | Name | Criterion |
786
- | ---- | --------------------- | -------------------------------------------- |
787
- | T0 | Empty bench | no tool detected |
788
- | T1 | First tool | at least one tool detected |
789
- | T2 | Bench with notes | T1 + project instructions/rules/config exist |
790
- | T3 | Connected bench | T2 + at least one MCP server configured |
791
- | T4 | Own tooling | T3 + own skills/commands/rules |
792
- | T5 | Agentic operator | agentic CLI + MCP + own tooling together |
793
- | T6 | Multi-agent | T5 + 2 or more agents defined |
794
- | T7 | Orchestrated workshop | T6 + at least one hook configured |
795
-
796
- File recency (`mtime`) is informative only — it is never a gating signal
797
- for any tier.
798
-
799
- ## Optional server-side LLM layers
800
-
801
- Three capabilities are ephemeral, optional, server-side LLM calls — all run
802
- independently of the save/consent decision (they never touch the
803
- persistence payload) and all degrade gracefully (deterministic fallback, or
804
- simply no scores shown) if the endpoint is unset or the call fails for any
805
- other reason. Since ADR-042 there is a single backend to answer any of
806
- them — no second hop to retry against.
807
-
808
- "Ephemeral" here is about the SHAKERS-side persistence payload only — it does
809
- **not** mean the call's content is never stored anywhere. See
810
- [Privacy & consent model](#privacy--consent-model) for what a `granted`
811
- consent additionally authorizes a third-party observability provider to
812
- capture.
813
-
814
- - **Agent-card synthesis** (`SHAKERS_CLI_SYNTHESIS_ENDPOINT`): sends your
815
- agents' description text to synthesize a short symbolic name + "what it
816
- does" per agent, for nicer cards. Falls back to the deterministic org
817
- chart if unavailable — and, per agent, to your own raw `.claude/agents/`
818
- description (cleaned up and excerpted for card display) or a minimal
819
- name-derived line if that's missing too, so a card's description is
820
- never blank.
821
- - **Roadmap personalization** (`SHAKERS_CLI_ROADMAP_ENDPOINT`): asks the
822
- certifications service to rewrite the current tier jump's prose (what it unlocks, steps,
823
- tips, mistakes) adapted to your detected stack. The tier, the band, and
824
- the "when to upgrade" criterion are **never** touched by this call — only
825
- the curated roadmap's fallback prose can ever change. Only derived
826
- signals are sent (frameworks, tool/MCP categories, tier), never raw file
827
- content or agent descriptions.
828
- - **Agent definition-quality evaluation** (`agent-evaluation`, derived as a
829
- sibling of your ingest endpoint; overridable with
830
- `SHAKERS_CLI_AGENT_EVAL_ENDPOINT`): sends the scrubbed agent definitions and
831
- gets back a 0-100 score + short rationale per agent (**gemini-2.5-flash**
832
- server-side, prompt version `agent-eval-v1`). The definition is treated as
833
- DATA server-side (prompt-injection safe). Degradation is by omission — the
834
- server drops any agent it couldn't score, and agents with no returned score
835
- render without a number. No endpoint / failure → no scores shown.
836
-
837
- All three send only derived signals or scrubbed agent definitions — never raw
838
- file content — and a scrub pass runs before anything leaves the machine.
35
+ The plugin adds the Shakers MCP server and these slash-commands: `onboarding`, `ai_usage`,
36
+ `my_profile`, `find_projects`, `certify` and `ask`.
839
37
 
840
- Separately, `ai-usage` reads your **local Claude Code history**
841
- (`~/.claude/projects/**`) to count how often each detected agent was actually
842
- invoked on this machine. This is **usage only**: it extracts a single signal per
843
- line — the `subagent_type` of an `Agent` tool call — and never reads, stores, or
844
- transmits prompt text, tool inputs, or any session content. The counts stay
845
- strictly local (not in the persistence payload). It degrades gracefully if the
846
- history directory is absent or unreadable.
38
+ **Claude Desktop**
847
39
 
848
- ## Privacy & consent model
40
+ Download the `.mcpb` file from the latest
41
+ [GitHub Release](https://github.com/devShakers/ai-usage-evaluator/releases) and open it
42
+ with Claude Desktop.
849
43
 
850
- - **The CLI talks to ONE Shakers backend.** Every call this tool makes — the
851
- usage send, the optional LLM layers above, `login`, and everything under
852
- `certify` (resolve, certify, email verification, agent certification,
853
- skill interview) — goes to a single configured endpoint,
854
- `sh-web-works-certifications`. Until 2026-08-04 (ADR-021) there was a
855
- second hop that fell back to `shakers-hub-backend`; ADR-042 retired it once
856
- it was confirmed that hop never had the routes mounted (it only ever
857
- answered 404, which had already masked at least one real timeout in a
858
- diagnosis). There is no fallback any more: an unset or unreachable endpoint
859
- is a real, named error (timeout / connection refused / 5xx), not a silent
860
- hop to somewhere else. Nothing is deployed at a real address yet — see
861
- [Configuration](#configuration-environment-variables) — and `install.sh`
862
- writes a loopback placeholder by default, so a fresh, unconfigured install
863
- talks to nothing on the Talent's own machine.
864
- - **The report is always generated and shown locally, unconditionally.**
865
- There is no gate, no wall, no preview step before you see your own data.
866
- - **Saving (persisting) it to Shakers is opt-in, asked once.** The first
867
- time you run the tool, right **after** the report is already on screen,
868
- you're asked a short yes/no question: do you want this report saved in
869
- Shakers? Accepting asks for an email; declining persists that choice and
870
- you're never asked again. Manage the decision any time with
871
- `--consent-status` / `--consent-revoke` / `--consent-email`, without
872
- re-running the scan.
873
- - **This one yes/no now governs TWO different things (talents-ai-score,
874
- ADR-028), kept explicit rather than blurred into one vague permission —
875
- there is no separate flag for each yet, it's a single consent:**
876
- 1. **Persisting in Shakers.** Only derived signals are ever sent for
877
- saving — booleans, counts, categories, tier/band, the detected
878
- technology names, and (if it ran) the synthesized agent summaries.
879
- **Never** file contents, absolute paths, environment variables, or
880
- credentials. The email you typed travels outside this whitelisted
881
- payload, in the request body.
882
- 2. **Capturing content in a third-party observability provider.**
883
- `ai-usage`/`certify`'s optional server-side AI calls — agent-card
884
- synthesis, roadmap personalization, agent definition-quality
885
- evaluation, CERTIFY's skill-code
886
- assessment, and every call of the agent-certification **interview**
887
- (each turn, plus the verdict) — send a
888
- `traceContentConsent` flag reflecting your **current**, per-request
889
- decision. When (and only when) it's `true`, **Datadog LLM
890
- Observability**, a company **other than Shakers**, may capture and
891
- retain the prompt/output of that call — which, for CERTIFY and agent
892
- certification, includes your **actual sampled source code** and your
893
- **free-text answers**, not just derived signals. Retention is up to
894
- **three months**, configured on Datadog's side. **There is no promise
895
- of later, per-item deletion of that content** — unlike the structured
896
- payload above (governed by `--consent-revoke`/purge), Datadog's
897
- retention is the only expiry that exists for it. If you decline (or
898
- never decide), nothing is sent there — this is the safe default; the
899
- flag is only ever omitted or `true`, never inferred.
900
- - **The optional LLM layers above still run REGARDLESS of your save
901
- decision** — that's what makes the diagram, the roadmap and the agent
902
- scores "always show". What changes with consent is ONLY whether Datadog
903
- may capture what they send, per point 2 above; the call itself, and
904
- whether it's silently dropped or degraded on failure, is unaffected by
905
- consent either way. The local **usage** read (Claude Code history) is not
906
- even a network call — it never leaves the machine, consent or not.
907
- - **Registration funnel analytics.** `shakers register` and the MCP sign-up
908
- send one event per registration step to the Hub, which relays them to
909
- Amplitude. Only steps and categories travel (never an exact rate or free
910
- text), with a random device id kept in
911
- `~/.config/shakers/analytics-device.json` (permissions `600`). A failed
912
- send never affects the registration.
913
- - The consent decision lives in `~/.config/shakers/consent.json`
914
- (permissions `600`).
915
- - An **unfinished interview** (agent certification, or the skill-code
916
- interview under `certify skills`) lives in
917
- `~/.config/shakers/interview-session.json` (permissions `600`, written
918
- atomically — the two kinds share one file, discriminated by a `kind`
919
- field). It holds a bearer token for that interview and the answer
920
- currently in flight — nothing else of what you typed — and it is deleted as
921
- soon as the verdict arrives or the session expires. Delete it by hand at any
922
- time: the only consequence is losing the ability to resume that interview
923
- (the attempt it spent is already counted server-side either way).
924
- - A **login session** lives in `~/.config/shakers/auth-session.json`
925
- (permissions `600`, written atomically): the bearer token that identifies
926
- you to `certify`, plus its expiry and (when the server sent one) your
927
- email. See [Login](#login-login--logout).
928
- - **Legal**: sending data about how a person works involves personal-data
929
- processing (GDPR). This model has legal/labor sign-off reported for the
930
- current design (see `active-work/talents-ai-score/decisions.md`,
931
- ADR-011/013). **Activating sending against real Shakers talents in
932
- production is a separate deployment decision that still requires its own
933
- legal/labor go-ahead** for that rollout — this repo doesn't ship a
934
- production endpoint by default (see below).
935
- - **Legal copy across FOUR separate disclosure texts** (reviewed — the
936
- `[PENDING LEGAL/LABOR REVIEW — NOT FINAL]` markers were removed), each shown
937
- before a different kind of egress: the save-to-Shakers consent intro
938
- (`ai-usage` / `certify skills`), the `certify skills` code-egress disclaimer,
939
- the `certify agents` interview disclaimer, and the `certify skills` interview
940
- disclaimer. All four state that **you are solely responsible for owning/being
941
- authorized to analyze the code you submit, that Shakers assumes no liability
942
- for it, and that misuse may lead to penalties on your Shakers account (up to
943
- suspension)**. The skill-interview disclosure additionally names, per
944
- ADR-049, that the interview asks questions **about the code you just
945
- sampled**. And per ADR-051, that disclosure's own yes/no is a **real consent
946
- gate**, not decorative text: declining it skips the interview outright (your
947
- code-only Skill certification stands either way) — only the earlier "do you
948
- want to try the interview?" opt-in was removed, not this consent.
949
-
950
- ## Configuration (environment variables)
951
-
952
- The backend endpoints ARE baked in, per flavor, in `ENV_PROFILES`
953
- (`src/config.js`): `staging`, `dev` and `local`. The default flavor is derived
954
- from the package `name` (`shakers-cli-beta` → staging, `@shakers/shakers-cli` →
955
- dev), forceable with `SHAKERS_CLI_ENV=staging|dev|local` — see
956
- [Publishing](#publishing-maintainers) above. No secret is ever compiled in
957
- (ADR-002/007). The baked profile is only a DEFAULT: the per-endpoint
958
- `SHAKERS_CLI_*_BASE` env vars and `config.json` always win over it (env >
959
- `config.json` > baked profile), and the profile bases reach the getters by
960
- seeding a fresh `config.json` on first run. Every code path that depends on an
961
- endpoint either degrades gracefully (no send / deterministic fallback) or — for
962
- `certify`, which has no local-only product — surfaces an actionable error;
963
- neither ever breaks the local `ai-usage` report.
964
-
965
- **Since ADR-042 the CLI talks to ONE backend**, `sh-web-works-certifications`.
966
- The two-hop chain this section used to describe (a `shakers-hub-backend`
967
- fallback) is retired: it never had the routes mounted on `develop`, so every
968
- "fallback" was an instant 404 that once masked a real timeout in a
969
- diagnosis. Only ONE variable needs setting; everything else this CLI calls is
970
- **derived from it** as a sibling route (`deriveFromIngest` in `src/config.js`)
971
- — the base path's last segment (e.g. `.../usage/reports`) is swapped for the
972
- sibling's (e.g. `.../usage/skill-certification/sessions`).
973
-
974
- | Variable | Purpose |
975
- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
976
- | `SHAKERS_CLI_INGEST_ENDPOINT` | **The one endpoint to configure.** Where a saved `usage` report is sent (if consent is granted). Every other endpoint below derives from it unless it has its own override. |
977
- | `SHAKERS_CLI_CERTIFY_ENDPOINT` | Override for the `certify` skill-certification route. Unset derives from ingest. Unlike `usage`'s endpoints, a missing one here is an **actionable error**, never a silent no-op — `certify` has no local-only product. |
978
- | `SHAKERS_CLI_LOGIN_ENDPOINT` | Override for `login`'s email/password route. Unset derives from ingest (climbing out of the `usage` module: `.../api/v1/auth/login/email`). |
979
- | `SHAKERS_CLI_DEVICE_AUTHORIZE_ENDPOINT`| Override for Google device-flow authorize (`POST .../auth/device/code`). Unset derives from the hub base. |
980
- | `SHAKERS_CLI_DEVICE_TOKEN_ENDPOINT` | Override for Google device-flow token polling (`POST .../works/auth/device/token`). Unset derives from the hub base. |
981
- | `SHAKERS_CLI_SYNTHESIS_ENDPOINT` | Override for agent-card synthesis (optional feature). Unset derives from ingest. |
982
- | `SHAKERS_CLI_ROADMAP_ENDPOINT` | Override for roadmap personalization (optional feature). Unset derives from ingest. |
983
- | `SHAKERS_CLI_AGENT_EVAL_ENDPOINT` | Override for agent definition-quality evaluation (optional feature). Unset derives from ingest. |
984
- | `SHAKERS_CLI_CONFIG_DIR` | Override `~/.config/shakers/` (mainly for tests). |
985
-
986
- > **Env prefix (ADR-045):** the CLI's variables use the `SHAKERS_CLI_*` prefix
987
- > (distinct from the certifications backend's own `SHAKERS_*`). The pre-rename
988
- > `AI_FOOTPRINT_*` names are still honoured as a fallback — if the new name is
989
- > unset and the old one is set, the old one is used — so nothing breaks for
990
- > anyone who exported the old variables.
991
-
992
- Every other endpoint this CLI calls (email verification request/verify,
993
- agent-certification interview sessions, skill-certification interview
994
- sessions, and the two superadmin routes) has **no** env-var override at all —
995
- they are always derived from ingest; see `src/config.js` for the full list of
996
- `get*Endpoint` getters. The agent-certification and skill-interview session
997
- bases are derived exactly like the others, but their **per-session** URLs
998
- (`/:id`, `/:id/turns`, `/:id/verdict`) are built by string concatenation in
999
- the client, never re-derived (`deriveFromIngest` replaces the base's last
1000
- path segment, and that base already ends in `sessions`).
1001
-
1002
- ### Config file (persistent ingest endpoint)
1003
-
1004
- So you don't have to `export SHAKERS_CLI_INGEST_ENDPOINT` every session, it
1005
- can also live in a persistent file next to consent/reports:
1006
-
1007
- ```
1008
- ~/.config/shakers/config.json
1009
- {
1010
- "ingestEndpoint": "https://your-certifications-service/api/v1/usage/reports"
1011
- }
1012
- ```
1013
-
1014
- Set it without editing JSON by hand:
44
+ ## Main commands
1015
45
 
1016
46
  ```bash
1017
- shakers ai-usage --set-endpoint https://your-certifications-service/api/v1/usage/reports
1018
- shakers ai-usage --show-endpoint # prints the effective endpoint and its source
47
+ shakers ai-usage # scan this project and machine, show your AI-usage tier (no account needed)
48
+ shakers register # create your Shakers account and profile
49
+ shakers login # sign in (email or Google)
50
+ shakers logout # forget the stored session
51
+ shakers certify # certify a dimension of your role through an interview
52
+ shakers report # build and open your shareable HTML report
53
+ shakers me # your profile summary
54
+ shakers find-projects # projects and positions available to you
55
+ shakers applications # projects you applied to, and their status
56
+ shakers availability # view or set your availability
57
+ shakers rate # view or set your rate
58
+ shakers alma # chat with Alma
59
+ shakers mcp # run the MCP server for an AI desktop app
1019
60
  ```
1020
61
 
1021
- **Resolution precedence:** `SHAKERS_CLI_INGEST_ENDPOINT` (env var, the raw
1022
- developer override, legacy `AI_FOOTPRINT_INGEST_ENDPOINT` honoured too) **>**
1023
- `config.json` **>** none. There is still no compiled-in production default in
1024
- the code — only `install.sh` bakes a loopback placeholder into a FRESH config
1025
- file (see the prominent comment there; **this must change before real
1026
- distribution**). Every sibling-derived endpoint in the table above keeps
1027
- deriving from whichever value this resolves to.
1028
-
1029
- **A config file written before ADR-042 may still carry the retired
1030
- `ingestEndpointFallback` key.** `install.sh` never overwrites an existing
1031
- `config.json`, so upgrading doesn't clean it up. The policy is deliberate:
1032
- the key is **ignored** (nothing reads it any more), **never migrated** (there
1033
- is nowhere to migrate a hub URL to — the one endpoint is already configured
1034
- separately) and **never erased** (this CLI never rewrites a Talent's config
1035
- file except behind an explicit `--set-*`, and a rewrite is the one operation
1036
- that could lose it). `--show-endpoint` is the one place that says the key is
1037
- present and unused, so nobody debugging their setup mistakes it for a live
1038
- hop.
1039
-
1040
- **Endpoint safety (bounded):** because the endpoint decides where the sampled
1041
- code (`certify`) and derived signals (`ai-usage`) are sent, `--set-endpoint`
1042
- refuses to persist an `http://` URL to any host other than
1043
- `localhost`/`127.0.0.1`/`::1` — a non-local host must be `https`. There is no
1044
- domain allowlist yet (`SHAKERS_CLI_DOMAINS` in `src/config.js` is deliberately
1045
- empty — see that file's docblock for why an unverified entry would be worse
1046
- than none); a non-loopback, non-allowlisted host still requires you to type
1047
- the hostname back before `--set-endpoint` persists it. The env var is not
1048
- validated (it's the explicit developer escape hatch); a hand-edited config
1049
- file carrying an insecure remote endpoint is ignored at read time.
62
+ Run `shakers` with no command to see every command.
1050
63
 
1051
- ## Local end-to-end testing
64
+ ## Privacy
1052
65
 
1053
- **Run the real backend and point the CLI at loopback.** There used to be a
1054
- `reference-server/` stub in this repo that you could run instead; it is
1055
- **retired** (talents-ai-score, issue 044) and it is not coming back. It still
1056
- answered the `agent-certification/followups` and `/verdict` routes after those
1057
- were retired from the service, and it never had a single **interview** route, so
1058
- anyone who ran it was testing against a contract that no longer exists. That is
1059
- worse than having no stub: it fails silently and in your favour.
66
+ - The `ai-usage` scan runs on your machine and its report is shown there first.
67
+ - Saving it to Shakers is opt-in. You are asked once, after you see the report. Change
68
+ your decision any time with `shakers ai-usage --consent-status`, `--consent-revoke` or
69
+ `--consent-email`.
70
+ - What is saved is derived data (counts, categories, tier, detected technologies), never
71
+ file contents, paths, environment variables or credentials.
72
+ - Certification sends secret-scrubbed samples of your code and your interview answers to
73
+ Shakers to assess them.
74
+ - Read the full policy at <https://shakersworks.com/legal/mcp-privacy>.
1060
75
 
1061
- It was retired rather than repaired on purpose. Serving the agent-certification
1062
- interview would mean reimplementing session state, the `seq` cursor, per-turn
1063
- idempotency, the stop condition and evidence anchoring — a second implementation
1064
- of the most delicate semantics in the system, which would lie to your face the
1065
- moment it drifted from the real one. Running the real service is what the team
1066
- does, and it is the only way to get answers you can trust.
76
+ ## License
1067
77
 
1068
- This also settles a standing caveat: the old stub kept its reports in an
1069
- in-memory map, so every mention of it had to warn that production demands a real
1070
- database. That warning is **obsolete by retirement, not by oversight** — there is
1071
- no in-repo server left that anyone could mistake for the real one. Persistence is
1072
- the certifications service's business (Prisma/Postgres), and always was.
1073
-
1074
- The backend is the Shakers certifications service
1075
- (NestJS + Prisma + Postgres) — since ADR-042, the CLI's **only** backend.
1076
- Its `usage` module mounts every route this CLI calls (plus `auth/login/*`)
1077
- under the service's `api/v1` global prefix. Start it in its own checkout (it
1078
- needs its own database and secrets — see that repo's README), then:
1079
-
1080
- ```bash
1081
- # the service listens on PORT, default 3000, with global prefix /api/v1
1082
- export SHAKERS_CLI_INGEST_ENDPOINT=http://127.0.0.1:3000/api/v1/usage/reports
1083
- shakers ai-usage
1084
- ```
1085
-
1086
- `http://` is accepted **only** for loopback (`localhost`, `127.0.0.1`, `::1`);
1087
- every other host must be `https` (`src/config.js`). If you prefer not to export
1088
- a variable each session, persist it instead — the env var wins over the file:
1089
-
1090
- ```bash
1091
- shakers ai-usage --set-endpoint http://127.0.0.1:3000/api/v1/usage/reports
1092
- ```
78
+ Proprietary, source available. See [LICENSE](LICENSE).
1093
79
 
1094
- Every other URL the CLI needs (`skill-certification`, `login`, the Google
1095
- config/login pair, `email-verification/request` and `/verify`,
1096
- `agent-synthesis`, `agent-evaluation`, `graph-inference`, and the
1097
- `agent-certification/sessions…` / `skill-certification/sessions…` interview
1098
- routes) is derived as a sibling of whatever `ingestEndpoint` resolves to, so
1099
- that one variable is enough — `login` first, since `certify` refuses to run
1100
- without a session (ADR-050):
80
+ ## Support
1101
81
 
1102
- ```bash
1103
- shakers login --email you@shakers.com
1104
- ```
1105
-
1106
- Note the real OTP (for the non-login email-verification path, still used by
1107
- `ai-usage`'s save-to-Shakers consent) is emailed via HubSpot with a Redis
1108
- TTL/single-use code — there is no fixed local code any more, so read the one
1109
- you were sent. There is no fallback hop to exercise any more (ADR-042): an
1110
- unset or unreachable endpoint fails with the real cause (timeout / connection
1111
- refused / 5xx), it does not retry anywhere else.
1112
-
1113
- The CLI's own test suite does not need any of this: it wires an in-process fake
1114
- (`test-fixtures/ingest-service-fake.js`) into a throwaway server on an ephemeral
1115
- port. That fake is a **test double, not a runnable server** — it binds no port,
1116
- has no launcher, is never installed, and only implements what the assertions in
1117
- `test/` require.
1118
-
1119
- ## How to add a new tool
1120
-
1121
- Edit `src/detectors.js` and add an entry with its signals:
1122
-
1123
- ```js
1124
- {
1125
- id: 'my-tool',
1126
- name: 'My Tool',
1127
- vendor: 'Vendor',
1128
- category: CATEGORIES.AGENTIC_CLI,
1129
- signals: [
1130
- { type: 'projectPath', path: '.mytool' },
1131
- { type: 'bin', name: 'mytool' },
1132
- ],
1133
- }
1134
- ```
1135
-
1136
- If you want to measure depth, add a probe in `src/scanner.js` inside
1137
- `probes` that returns **only numbers**.
1138
-
1139
- ## Structure
1140
-
1141
- ```
1142
- bin/shakers.js Argv command dispatcher + session gate — the single entrypoint (ADR-060/061)
1143
- bin/ai-usage.js `ai-usage` command logic (run(args,{ask}))
1144
- bin/certify.js `certify` command logic — skills/agents subcommands + picker (run(args,{ask}))
1145
- bin/report-html.js `report` command — materialize + open the HTML (run(args,{ask}))
1146
- bin/share.js `share` command logic — currently disabled (run(args,{ask}))
1147
- bin/login.js `login`/`logout` command logic (run/runLogout(args,{ask}))
1148
- bin/superadmin.js `superadmin` non-production test-tool command (run(args,{ask}))
1149
-
1150
- ── ai-usage: detection & classification ──
1151
- src/detectors.js Catalog of tools and signals
1152
- src/scanner.js Scan engine -> report object
1153
- src/scan-exclusions.js Paths/dirs excluded from the scan
1154
- src/tier-engine.js T0-T7 ladder computation (single source of truth)
1155
- src/tier-analysis.js "Why this tier" deterministic breakdown
1156
- src/maturity.js 0-4 band + 0-100 score (derived from the tier)
1157
- src/mcp-detector.js MCP server name/category detector
1158
- src/memory-structure-detector.js Context-file import/structure detector
1159
- src/automations-detector.js Scripts/scheduler automation detector
1160
- src/browser-tools-detector.js Browser-automation tooling detector
1161
- src/tech-detector.js Project technologies (frameworks) detector
1162
- src/tech-extensions.js Technology name map / extensions
1163
- src/agent-org-chart.js Deterministic agent org chart parser (+ hierarchy)
1164
- src/agent-synthesis.js Optional LLM agent-card synthesis client
1165
- src/agent-evaluation.js Optional LLM agent definition-quality client (gemini-2.5-flash, server-side)
1166
- src/agent-usage.js Local Claude Code history reader (usage signal only, never content)
1167
- src/roadmap-content.js Curated per-tier roadmap content (es/en)
1168
- src/roadmap-prompt.js Ready-to-paste implementation prompt
1169
- src/roadmap-personalization.js Optional LLM roadmap-prose personalization client
1170
- src/build-next-level.js Secondary: writes deterministic starter files
1171
-
1172
- ── certify: Skill + agent certification ──
1173
- src/certify-args.js `certify` flag parsing (--skill, --accept-disclaimer, --fast…)
1174
- src/certify-client.js Resolve/certify HTTP client (discriminated results)
1175
- src/certify-disclaimer.js Legal disclaimer + explicit acceptance (egress gate, `certify skills`)
1176
- src/certify-preconditions.js LOGIN precondition for `certify agents` (ADR-050)
1177
- src/certify-render.js Resolve report renderer
1178
- src/certify-remediation-prompt.js Copyable remediation prompt per Skill
1179
- src/certify-agents.js `certify agents` interview flow
1180
- src/certify-skill-interview.js `certify skills`' mandatory-start skill interview (ADR-049/051)
1181
- src/interview-engine.js Shared turn-loop/resume/verdict engine (agents + skill interviews)
1182
- src/agent-certification-client.js HTTP client for both interview kinds' session/turn/verdict routes
1183
- src/skill-sampler.js Deterministic per-Skill code sampling (+ scrub)
1184
- src/skill-selection.js --skill selection parsing (by name or position)
1185
- src/authorship.js Git-authorship filtering/attribution of sampled code (ADR-017)
1186
- src/interactive-select.js Interactive single-/multi-select picker
1187
- src/interview-session-store.js Atomic 0600 session-in-flight store (shared by both interview kinds)
1188
- src/legal-notice.js Shared framing for the four disclosure texts
1189
- src/render-certification.js Certification report (terminal + HTML sections)
1190
- src/render-skill-interview.js Skill-interview combined-level verdict renderer
1191
-
1192
- ── login / superadmin ──
1193
- src/auth-session-store.js Atomic 0600 login-session store (`login`)
1194
- src/auth-client.js Email/password login HTTP client
1195
- src/auth-device-client.js Google device-flow HTTP client (RFC 8628: authorize/token/api-token)
1196
- src/device-login.js Google device-flow orchestration (blocking CLI loop + shared start/poll)
1197
- src/device-auth-store.js Atomic 0600 pending-device-grant store (bridges the MCP start/poll tools)
1198
-
1199
- ── share: LinkedIn card ──
1200
- src/share-card.js Builds the self-contained branded SVG/HTML card
1201
- src/shakers-wordmark.js Inlined "shakers" logotype (auto-generated from SVG)
1202
-
1203
- ── consent, identity, persistence, reporting ──
1204
- src/consent-flow.js Short, one-time "save to Shakers?" prompt
1205
- src/consent-skip.js Explicit reasons the consent prompt is/isn't shown
1206
- src/email-verification.js Email OTP verification client (gates persistence)
1207
- src/share.js Consent state + derived-payload whitelist + sending
1208
- src/report-store.js Per-project cumulative report state + HTML (persistence)
1209
- src/report-theme.js Shared Shakers HTML theme (tokens/base/copy script)
1210
- src/store.js Legacy latest/history store — UNUSED (kept on disk)
1211
- src/render-terminal.js Terminal output (why-first, one-line-per-agent; ADR-016)
1212
- src/render-html.js Self-contained HTML dashboard (full detail, per-agent scores)
1213
- src/osc-link.js OSC 8 clickable terminal links
1214
- src/open-file.js Best-effort cross-platform "open in browser" (report/login-browser)
1215
-
1216
- ── graph-inference plumbing (retained; the `map` command was removed) ──
1217
- src/repo-context.js Content-free structural repo summary (entrypoints, AI call-sites…)
1218
- src/graph-infer-client.js Optional LLM graph-inference client (gemini-2.5-pro, server-side)
1219
- src/graph-scan.js Deterministic agent-subgraph + footprint drawer (feeds the sheet)
1220
- src/graph-generator.js Deterministic graph generation
1221
-
1222
- ── shared plumbing ──
1223
- src/cli-args.js `ai-usage` flag parsing
1224
- src/config.js Endpoint configuration from env vars, never hardcoded — one backend (ADR-042)
1225
- src/config-dir.js Single source for the config dir + legacy `~/.config/ai-footprint` migration (ADR-045)
1226
- src/env-paths.js Home-directory + `SHAKERS_CLI_*`/`AI_FOOTPRINT_*` env resolution (test-overridable)
1227
- src/stdin-ask.js Injectable stdin question/answer helper
1228
- src/terminal-progress.js Status line + spinner for slow calls
1229
- src/locale.js OS locale detection
1230
- src/i18n.js Text catalogs (es/en) — report, CLI, certify, login, superadmin
1231
-
1232
- test-fixtures/ingest-service-fake.js In-process backend FAKE for tests only — not shipped, binds no port
1233
- install.sh Installer (curl | bash, or local)
1234
- ```
82
+ talent@shakersworks.com