shakers-cli-beta 0.8.0-beta.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 (218) hide show
  1. package/LICENSE +59 -0
  2. package/README.md +1175 -0
  3. package/bin/add-agent.js +88 -0
  4. package/bin/add-project.js +88 -0
  5. package/bin/add-role.js +61 -0
  6. package/bin/add-skill.js +88 -0
  7. package/bin/ai-usage.js +81 -0
  8. package/bin/alma.js +99 -0
  9. package/bin/applications.js +69 -0
  10. package/bin/availability.js +70 -0
  11. package/bin/certifications.js +69 -0
  12. package/bin/certify.js +73 -0
  13. package/bin/change-role.js +61 -0
  14. package/bin/config.js +120 -0
  15. package/bin/experiences.js +69 -0
  16. package/bin/find-projects.js +89 -0
  17. package/bin/invitations.js +69 -0
  18. package/bin/lang.js +70 -0
  19. package/bin/login.js +283 -0
  20. package/bin/mcp.js +98 -0
  21. package/bin/me.js +69 -0
  22. package/bin/onboarding.js +134 -0
  23. package/bin/portfolios.js +69 -0
  24. package/bin/rate.js +70 -0
  25. package/bin/register.js +325 -0
  26. package/bin/report-html.js +134 -0
  27. package/bin/save.js +77 -0
  28. package/bin/shakers.js +344 -0
  29. package/bin/share.js +72 -0
  30. package/bin/show-project.js +72 -0
  31. package/bin/socials.js +70 -0
  32. package/bin/superadmin.js +351 -0
  33. package/package.json +40 -0
  34. package/src/agent-category.js +13 -0
  35. package/src/agent-evaluation.js +177 -0
  36. package/src/agent-org-chart.js +355 -0
  37. package/src/agent-synthesis.js +132 -0
  38. package/src/agent-usage.js +118 -0
  39. package/src/agents-client.js +165 -0
  40. package/src/ai-fluency-cell.js +72 -0
  41. package/src/ai-profile-client.js +45 -0
  42. package/src/ai-profile-preview.js +154 -0
  43. package/src/ai.js +66 -0
  44. package/src/alma-client.js +123 -0
  45. package/src/alma-flow.js +32 -0
  46. package/src/alma-repo-context.js +47 -0
  47. package/src/alma-shell.js +161 -0
  48. package/src/ansi.js +62 -0
  49. package/src/applications-client.js +79 -0
  50. package/src/applications-flow.js +58 -0
  51. package/src/auth-client.js +144 -0
  52. package/src/auth-device-client.js +118 -0
  53. package/src/auth-method-picker.js +44 -0
  54. package/src/auth-methods.js +35 -0
  55. package/src/auth-session-store.js +214 -0
  56. package/src/authorship.js +203 -0
  57. package/src/automations-detector.js +170 -0
  58. package/src/availability-client.js +92 -0
  59. package/src/availability-flow.js +105 -0
  60. package/src/backend-request.js +170 -0
  61. package/src/blind-approval-extract.js +48 -0
  62. package/src/brand-ansi.js +14 -0
  63. package/src/brand-svg.js +9 -0
  64. package/src/browser-tools-detector.js +21 -0
  65. package/src/build-next-level.js +56 -0
  66. package/src/certifications-client.js +89 -0
  67. package/src/certifications-flow.js +75 -0
  68. package/src/certify-dimension-client.js +217 -0
  69. package/src/certify-dimension-flow.js +193 -0
  70. package/src/certify-disclaimer.js +51 -0
  71. package/src/certify-remediation-prompt.js +23 -0
  72. package/src/cli-args.js +83 -0
  73. package/src/config-dir.js +120 -0
  74. package/src/config.js +778 -0
  75. package/src/consent-flow.js +115 -0
  76. package/src/consent-skip.js +27 -0
  77. package/src/decisions-extract.js +43 -0
  78. package/src/detect-repos.js +145 -0
  79. package/src/detected-tools.js +15 -0
  80. package/src/detection-evidence.js +105 -0
  81. package/src/detection-noise.js +132 -0
  82. package/src/detectors.js +221 -0
  83. package/src/device-auth-store.js +100 -0
  84. package/src/device-login.js +118 -0
  85. package/src/email-verification.js +152 -0
  86. package/src/env-paths.js +16 -0
  87. package/src/find-projects-cache.js +89 -0
  88. package/src/find-projects-client.js +138 -0
  89. package/src/find-projects-flow.js +164 -0
  90. package/src/git-activity.js +123 -0
  91. package/src/graph-certs.js +58 -0
  92. package/src/graph-generator.js +230 -0
  93. package/src/graph-scan.js +239 -0
  94. package/src/i18n.js +3264 -0
  95. package/src/inter-fonts.js +6 -0
  96. package/src/interactive-select.js +183 -0
  97. package/src/interview-client.js +226 -0
  98. package/src/interview-transcript.js +56 -0
  99. package/src/inventory-client.js +90 -0
  100. package/src/invitations-client.js +66 -0
  101. package/src/invitations-flow.js +50 -0
  102. package/src/lang-client.js +147 -0
  103. package/src/lang-codes.js +14 -0
  104. package/src/lang-flow.js +85 -0
  105. package/src/legal-notice.js +53 -0
  106. package/src/locale.js +51 -0
  107. package/src/markdown-ansi.js +50 -0
  108. package/src/maturity.js +111 -0
  109. package/src/mcp-ai-usage-result-tool.js +109 -0
  110. package/src/mcp-ai-usage-tool.js +333 -0
  111. package/src/mcp-alma-tools.js +91 -0
  112. package/src/mcp-applications-tools.js +42 -0
  113. package/src/mcp-ask-tools.js +50 -0
  114. package/src/mcp-auth-form.js +282 -0
  115. package/src/mcp-availability-tools.js +43 -0
  116. package/src/mcp-certifications-tools.js +42 -0
  117. package/src/mcp-certify-dimension-tools.js +58 -0
  118. package/src/mcp-detector.js +223 -0
  119. package/src/mcp-device-login-tools.js +173 -0
  120. package/src/mcp-find-projects-tools.js +67 -0
  121. package/src/mcp-install.js +245 -0
  122. package/src/mcp-invitations-tools.js +42 -0
  123. package/src/mcp-lang-tools.js +39 -0
  124. package/src/mcp-onboarding-tools.js +388 -0
  125. package/src/mcp-portfolios-tools.js +46 -0
  126. package/src/mcp-profile-tools.js +46 -0
  127. package/src/mcp-rate-tools.js +42 -0
  128. package/src/mcp-register-tools.js +517 -0
  129. package/src/mcp-report-tools.js +101 -0
  130. package/src/mcp-role-tools.js +112 -0
  131. package/src/mcp-saved-positions-tools.js +55 -0
  132. package/src/mcp-server.js +170 -0
  133. package/src/mcp-show-project-tools.js +50 -0
  134. package/src/mcp-socials-tools.js +39 -0
  135. package/src/memory-structure-detector.js +108 -0
  136. package/src/model-call-record.js +198 -0
  137. package/src/onboarding-availability.js +26 -0
  138. package/src/onboarding-client.js +364 -0
  139. package/src/onboarding-flow.js +1078 -0
  140. package/src/onboarding-livekit-client.js +102 -0
  141. package/src/onboarding-status-client.js +42 -0
  142. package/src/open-file.js +32 -0
  143. package/src/osc-link.js +16 -0
  144. package/src/portfolio-client.js +164 -0
  145. package/src/portfolio-git-info.js +61 -0
  146. package/src/portfolios-client.js +85 -0
  147. package/src/portfolios-flow.js +79 -0
  148. package/src/profile-client.js +125 -0
  149. package/src/profile-flow.js +115 -0
  150. package/src/profile-switch.js +46 -0
  151. package/src/prompt-select.js +29 -0
  152. package/src/rate-client.js +82 -0
  153. package/src/rate-flow.js +137 -0
  154. package/src/render-ai-fluency.js +266 -0
  155. package/src/render-certification.js +177 -0
  156. package/src/render-html.js +140 -0
  157. package/src/render-report-text.js +27 -0
  158. package/src/render-sheet.js +261 -0
  159. package/src/render-terminal.js +109 -0
  160. package/src/render-usage-report-text.js +155 -0
  161. package/src/repo-context.js +215 -0
  162. package/src/report-gating.js +49 -0
  163. package/src/report-store.js +226 -0
  164. package/src/report-theme.js +177 -0
  165. package/src/report-view-client.js +50 -0
  166. package/src/reveal-output.js +29 -0
  167. package/src/roadmap-content.js +453 -0
  168. package/src/roadmap-personalization.js +132 -0
  169. package/src/roadmap-prompt.js +154 -0
  170. package/src/roles-client.js +114 -0
  171. package/src/roles-flow.js +192 -0
  172. package/src/sanitize-network-text.js +36 -0
  173. package/src/saved-positions-client.js +71 -0
  174. package/src/saved-positions-flow.js +50 -0
  175. package/src/scan-exclusions.js +50 -0
  176. package/src/scanner.js +612 -0
  177. package/src/scope-signals.js +148 -0
  178. package/src/secret-prompt.js +72 -0
  179. package/src/session-gate.js +30 -0
  180. package/src/session-refresh.js +51 -0
  181. package/src/session-scan.js +336 -0
  182. package/src/session-signals.js +36 -0
  183. package/src/shakers-wordmark.js +17 -0
  184. package/src/share-card.js +362 -0
  185. package/src/share-certification.js +111 -0
  186. package/src/share-consent-state.js +157 -0
  187. package/src/share-payload.js +300 -0
  188. package/src/share.js +184 -0
  189. package/src/show-project-client.js +58 -0
  190. package/src/show-project-flow.js +119 -0
  191. package/src/signup-client.js +91 -0
  192. package/src/skills-client.js +102 -0
  193. package/src/socials-client.js +91 -0
  194. package/src/socials-flow.js +83 -0
  195. package/src/specificity-extract.js +41 -0
  196. package/src/start-add-agents.js +306 -0
  197. package/src/start-add-portfolio.js +388 -0
  198. package/src/start-add-skills.js +260 -0
  199. package/src/stdin-ask.js +129 -0
  200. package/src/steering-extract.js +43 -0
  201. package/src/strip-internal-comments.js +45 -0
  202. package/src/tech-detector.js +295 -0
  203. package/src/templates/report-sheet.html +572 -0
  204. package/src/terminal-agents.js +199 -0
  205. package/src/terminal-format.js +85 -0
  206. package/src/terminal-progress.js +106 -0
  207. package/src/terminal-sections.js +219 -0
  208. package/src/tier-analysis.js +126 -0
  209. package/src/tier-engine.js +114 -0
  210. package/src/tier-projection.js +117 -0
  211. package/src/transcript-turns.js +49 -0
  212. package/src/translations-client.js +84 -0
  213. package/src/typewriter.js +154 -0
  214. package/src/usage-model-calls.js +119 -0
  215. package/src/usage-oneshot-commands.js +180 -0
  216. package/src/usage-repo-scope.js +162 -0
  217. package/src/usage-run-steps.js +338 -0
  218. package/src/work-streams.js +74 -0
@@ -0,0 +1,295 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const {
7
+ EXCLUDED_DIRS,
8
+ MAX_WALK_DEPTH,
9
+ isRefusedWalkRoot,
10
+ isExcludedWalkPath,
11
+ } = require('./scan-exclusions');
12
+
13
+ // Monorepo support (skill-code-certification, issue 008): manifests are discovered RECURSIVELY under `root`, not just at the top level.
14
+
15
+ // Exact dependency-name -> canonical framework/library name (npm + pip).
16
+ const EXACT_FRAMEWORK_MAP = {
17
+ // JS/TS — frontend
18
+ react: 'React',
19
+ 'react-dom': 'React',
20
+ next: 'Next.js',
21
+ vue: 'Vue',
22
+ nuxt: 'Nuxt',
23
+ '@angular/core': 'Angular',
24
+ svelte: 'Svelte',
25
+ '@sveltejs/kit': 'SvelteKit',
26
+ 'solid-js': 'SolidJS',
27
+ // JS/TS — backend
28
+ express: 'Express',
29
+ fastify: 'Fastify',
30
+ koa: 'Koa',
31
+ '@nestjs/core': 'NestJS',
32
+ hapi: 'Hapi',
33
+ '@hapi/hapi': 'Hapi',
34
+ // JS/TS — meta-frameworks
35
+ astro: 'Astro',
36
+ remix: 'Remix',
37
+ '@remix-run/react': 'Remix',
38
+ '@remix-run/node': 'Remix',
39
+ '@remix-run/server-runtime': 'Remix',
40
+ // JS/TS — state management
41
+ zustand: 'Zustand',
42
+ redux: 'Redux',
43
+ 'react-redux': 'Redux',
44
+ '@reduxjs/toolkit': 'Redux Toolkit',
45
+ // JS/TS — TanStack family (each product is its own Skill)
46
+ '@tanstack/react-query': 'TanStack Query',
47
+ '@tanstack/vue-query': 'TanStack Query',
48
+ '@tanstack/solid-query': 'TanStack Query',
49
+ '@tanstack/svelte-query': 'TanStack Query',
50
+ 'react-query': 'TanStack Query', // pre-rename package, same Skill
51
+ '@tanstack/react-router': 'TanStack Router',
52
+ '@tanstack/router': 'TanStack Router',
53
+ '@tanstack/react-table': 'TanStack Table',
54
+ '@tanstack/vue-table': 'TanStack Table',
55
+ '@tanstack/table-core': 'TanStack Table',
56
+ '@tanstack/react-form': 'TanStack Form',
57
+ '@tanstack/form-core': 'TanStack Form',
58
+ // JS/TS — data / API layer
59
+ prisma: 'Prisma',
60
+ '@prisma/client': 'Prisma',
61
+ graphql: 'GraphQL',
62
+ '@apollo/client': 'Apollo',
63
+ '@apollo/server': 'Apollo',
64
+ 'apollo-server': 'Apollo',
65
+ '@trpc/server': 'tRPC',
66
+ '@trpc/client': 'tRPC',
67
+ zod: 'Zod',
68
+ // JS/TS — styling. Code-certified via its CONFIG file surface
69
+ // (tailwind.config.*) — see tech-extensions.js.
70
+ tailwindcss: 'Tailwind CSS',
71
+ // JS/TS — build tools & test runners.
72
+ vite: 'Vite',
73
+ webpack: 'Webpack',
74
+ jest: 'Jest',
75
+ vitest: 'Vitest',
76
+ // Python
77
+ django: 'Django',
78
+ flask: 'Flask',
79
+ fastapi: 'FastAPI',
80
+ pyramid: 'Pyramid',
81
+ tornado: 'Tornado',
82
+ sqlalchemy: 'SQLAlchemy',
83
+ pydantic: 'Pydantic',
84
+ };
85
+
86
+ // Go module paths recognized by prefix (module paths carry version suffixes
87
+ // like "/v4" and full import sub-paths, so exact match isn't reliable).
88
+ const GO_FRAMEWORK_PREFIXES = [
89
+ { prefix: 'github.com/gin-gonic/gin', name: 'Gin' },
90
+ { prefix: 'github.com/labstack/echo', name: 'Echo' },
91
+ { prefix: 'github.com/gofiber/fiber', name: 'Fiber' },
92
+ { prefix: 'github.com/gorilla/mux', name: 'Gorilla Mux' },
93
+ { prefix: 'github.com/beego/beego', name: 'Beego' },
94
+ { prefix: 'gorm.io/gorm', name: 'GORM' },
95
+ { prefix: 'github.com/jinzhu/gorm', name: 'GORM' }, // pre-move import path, same Skill
96
+ ];
97
+
98
+ // Maps a raw dependency/module name to its canonical framework/library display name, or null if unrecognized.
99
+ function canonicalFrameworkName(rawName) {
100
+ if (typeof rawName !== 'string' || !rawName) return null;
101
+ if (Object.prototype.hasOwnProperty.call(EXACT_FRAMEWORK_MAP, rawName)) {
102
+ return EXACT_FRAMEWORK_MAP[rawName];
103
+ }
104
+ for (const { prefix, name } of GO_FRAMEWORK_PREFIXES) {
105
+ if (rawName === prefix || rawName.startsWith(`${prefix}/`)) {
106
+ return name;
107
+ }
108
+ }
109
+ return null;
110
+ }
111
+
112
+ function readFileSafe(p) {
113
+ try {
114
+ return fs.readFileSync(p, 'utf8');
115
+ } catch {
116
+ return null;
117
+ }
118
+ }
119
+
120
+ function fromPackageJsonFile(filePath) {
121
+ const raw = readFileSafe(filePath);
122
+ if (!raw) return [];
123
+ let pkg;
124
+ try {
125
+ pkg = JSON.parse(raw);
126
+ } catch {
127
+ return [];
128
+ }
129
+ const groups = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'];
130
+ const names = [];
131
+ for (const group of groups) {
132
+ if (pkg[group] && typeof pkg[group] === 'object') {
133
+ names.push(...Object.keys(pkg[group]));
134
+ }
135
+ }
136
+ return names;
137
+ }
138
+
139
+ function fromRequirementsTxtFile(filePath) {
140
+ const raw = readFileSafe(filePath);
141
+ if (!raw) return [];
142
+ const names = [];
143
+ for (const rawLine of raw.split(/\r?\n/)) {
144
+ const line = rawLine.trim();
145
+ if (!line || line.startsWith('#') || line.startsWith('-')) continue;
146
+ const match = line.match(/^([A-Za-z0-9_.-]+)/);
147
+ if (match) names.push(match[1].toLowerCase());
148
+ }
149
+ return names;
150
+ }
151
+
152
+ function fromGoModFile(filePath) {
153
+ const raw = readFileSafe(filePath);
154
+ if (!raw) return [];
155
+ const names = [];
156
+ const blockMatch = raw.match(/require\s*\(([\s\S]*?)\)/);
157
+ if (blockMatch) {
158
+ for (const rawLine of blockMatch[1].split(/\r?\n/)) {
159
+ const line = rawLine.trim();
160
+ if (!line || line.startsWith('//')) continue;
161
+ const match = line.match(/^(\S+)/);
162
+ if (match) names.push(match[1]);
163
+ }
164
+ }
165
+ const singleLineRe = /^require\s+(\S+)\s+\S+/gm;
166
+ let m;
167
+ while ((m = singleLineRe.exec(raw)) !== null) {
168
+ if (m[1] === '(') continue; // the block-opening "require (" line, not a single-line require
169
+ names.push(m[1]);
170
+ }
171
+ return names;
172
+ }
173
+
174
+ function fromPyprojectTomlFile(filePath) {
175
+ const raw = readFileSafe(filePath);
176
+ if (!raw) return [];
177
+ const names = [];
178
+
179
+ const sectionRe = /^\[tool\.poetry\.(?:dependencies|dev-dependencies|group\.[^\]]+\.dependencies)\]\s*$/gm;
180
+ const lines = raw.split(/\r?\n/);
181
+ let inDepsSection = false;
182
+ for (const line of lines) {
183
+ if (/^\[.*\]\s*$/.test(line)) {
184
+ inDepsSection = sectionRe.test(line);
185
+ sectionRe.lastIndex = 0;
186
+ continue;
187
+ }
188
+ if (!inDepsSection) continue;
189
+ const kv = line.match(/^([A-Za-z0-9_.-]+)\s*=/);
190
+ if (kv && kv[1].toLowerCase() !== 'python') names.push(kv[1].toLowerCase());
191
+ }
192
+
193
+ const depsArrayMatch = raw.match(/\bdependencies\s*=\s*\[([\s\S]*?)\]/);
194
+ if (depsArrayMatch) {
195
+ const itemRe = /["']([A-Za-z0-9_.-]+)/g;
196
+ let m;
197
+ while ((m = itemRe.exec(depsArrayMatch[1])) !== null) {
198
+ names.push(m[1].toLowerCase());
199
+ }
200
+ }
201
+
202
+ return names;
203
+ }
204
+
205
+ // Manifest filename -> reader (skill-code-certification, issue 008).
206
+ const MANIFEST_READERS = {
207
+ 'package.json': fromPackageJsonFile,
208
+ 'requirements.txt': fromRequirementsTxtFile,
209
+ 'go.mod': fromGoModFile,
210
+ 'pyproject.toml': fromPyprojectTomlFile,
211
+ };
212
+
213
+ function findManifestFiles(root) {
214
+ const found = [];
215
+ if (isRefusedWalkRoot(root)) return found;
216
+
217
+ function walk(dir, depth) {
218
+ if (depth > MAX_WALK_DEPTH) return;
219
+ let entries;
220
+ try {
221
+ entries = fs.readdirSync(dir, { withFileTypes: true });
222
+ } catch {
223
+ return;
224
+ }
225
+ for (const entry of entries) {
226
+ const abs = path.join(dir, entry.name);
227
+ if (entry.isDirectory()) {
228
+ if (EXCLUDED_DIRS.has(entry.name)) continue;
229
+ if (isExcludedWalkPath(abs)) continue;
230
+ walk(abs, depth + 1);
231
+ } else if (entry.isFile() && Object.prototype.hasOwnProperty.call(MANIFEST_READERS, entry.name)) {
232
+ found.push(abs);
233
+ }
234
+ }
235
+ }
236
+
237
+ walk(root, 0);
238
+ return found.sort();
239
+ }
240
+
241
+ // Merges every discovered manifest's output, deduped, sorted, WITHOUT filtering through the canonical framework map.
242
+ function detectRawDependencyNames(root) {
243
+ const rawNames = [];
244
+ for (const filePath of findManifestFiles(root)) {
245
+ const reader = MANIFEST_READERS[path.basename(filePath)];
246
+ if (reader) rawNames.push(...reader(filePath));
247
+ }
248
+ return [...new Set(rawNames)].sort();
249
+ }
250
+
251
+ // Maps the merged raw dependency names through canonicalFrameworkName, keeps only recognized names, dedupes, sorts.
252
+ function detectTechnologies(root) {
253
+ const rawNames = detectRawDependencyNames(root);
254
+ const canonical = new Set();
255
+ for (const rawName of rawNames) {
256
+ const name = canonicalFrameworkName(rawName);
257
+ if (name) canonical.add(name);
258
+ }
259
+ return [...canonical].sort();
260
+ }
261
+
262
+ function detectTechnologyManifests(root) {
263
+ const byTech = new Map();
264
+ for (const filePath of findManifestFiles(root)) {
265
+ const reader = MANIFEST_READERS[path.basename(filePath)];
266
+ if (!reader) continue;
267
+ const rel = path.relative(root, filePath).split(path.sep).join('/');
268
+ const seenInFile = new Set();
269
+ for (const rawName of reader(filePath)) {
270
+ const tech = canonicalFrameworkName(rawName);
271
+ if (!tech || seenInFile.has(tech)) continue;
272
+ seenInFile.add(tech);
273
+ let set = byTech.get(tech);
274
+ if (!set) {
275
+ set = new Set();
276
+ byTech.set(tech, set);
277
+ }
278
+ set.add(rel);
279
+ }
280
+ }
281
+ return [...byTech.entries()]
282
+ .map(([tech, set]) => ({ tech, manifestPaths: [...set].sort() }))
283
+ .sort((a, b) => a.tech.localeCompare(b.tech));
284
+ }
285
+
286
+ module.exports = {
287
+ detectTechnologies,
288
+ detectTechnologyManifests,
289
+ detectRawDependencyNames,
290
+ canonicalFrameworkName,
291
+ findManifestFiles,
292
+ // Exported as the SOURCE OF TRUTH for the complete set of canonical technologies the detector can ever emit.
293
+ EXACT_FRAMEWORK_MAP,
294
+ GO_FRAMEWORK_PREFIXES,
295
+ };