vibecheck-score 0.1.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 (87) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +217 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/output/confirm.d.ts +3 -0
  6. package/dist/output/confirm.d.ts.map +1 -0
  7. package/dist/output/confirm.js +37 -0
  8. package/dist/output/confirm.js.map +1 -0
  9. package/dist/output/narrative.d.ts +3 -0
  10. package/dist/output/narrative.d.ts.map +1 -0
  11. package/dist/output/narrative.js +94 -0
  12. package/dist/output/narrative.js.map +1 -0
  13. package/dist/output/terminal.d.ts +4 -0
  14. package/dist/output/terminal.d.ts.map +1 -0
  15. package/dist/output/terminal.js +95 -0
  16. package/dist/output/terminal.js.map +1 -0
  17. package/dist/scanners/agents.d.ts +7 -0
  18. package/dist/scanners/agents.d.ts.map +1 -0
  19. package/dist/scanners/agents.js +95 -0
  20. package/dist/scanners/agents.js.map +1 -0
  21. package/dist/scanners/deploy.d.ts +7 -0
  22. package/dist/scanners/deploy.d.ts.map +1 -0
  23. package/dist/scanners/deploy.js +139 -0
  24. package/dist/scanners/deploy.js.map +1 -0
  25. package/dist/scanners/environment.d.ts +7 -0
  26. package/dist/scanners/environment.d.ts.map +1 -0
  27. package/dist/scanners/environment.js +110 -0
  28. package/dist/scanners/environment.js.map +1 -0
  29. package/dist/scanners/index.d.ts +7 -0
  30. package/dist/scanners/index.d.ts.map +1 -0
  31. package/dist/scanners/index.js +23 -0
  32. package/dist/scanners/index.js.map +1 -0
  33. package/dist/scanners/mcp.d.ts +7 -0
  34. package/dist/scanners/mcp.d.ts.map +1 -0
  35. package/dist/scanners/mcp.js +138 -0
  36. package/dist/scanners/mcp.js.map +1 -0
  37. package/dist/scanners/memory.d.ts +7 -0
  38. package/dist/scanners/memory.d.ts.map +1 -0
  39. package/dist/scanners/memory.js +131 -0
  40. package/dist/scanners/memory.js.map +1 -0
  41. package/dist/scanners/orchestration.d.ts +7 -0
  42. package/dist/scanners/orchestration.d.ts.map +1 -0
  43. package/dist/scanners/orchestration.js +99 -0
  44. package/dist/scanners/orchestration.js.map +1 -0
  45. package/dist/scanners/repositories.d.ts +7 -0
  46. package/dist/scanners/repositories.d.ts.map +1 -0
  47. package/dist/scanners/repositories.js +301 -0
  48. package/dist/scanners/repositories.js.map +1 -0
  49. package/dist/scanners/security.d.ts +7 -0
  50. package/dist/scanners/security.d.ts.map +1 -0
  51. package/dist/scanners/security.js +113 -0
  52. package/dist/scanners/security.js.map +1 -0
  53. package/dist/scanners/social.d.ts +7 -0
  54. package/dist/scanners/social.d.ts.map +1 -0
  55. package/dist/scanners/social.js +68 -0
  56. package/dist/scanners/social.js.map +1 -0
  57. package/dist/scanners/universal-file.d.ts +10 -0
  58. package/dist/scanners/universal-file.d.ts.map +1 -0
  59. package/dist/scanners/universal-file.js +526 -0
  60. package/dist/scanners/universal-file.js.map +1 -0
  61. package/dist/scanners/utils.d.ts +6 -0
  62. package/dist/scanners/utils.d.ts.map +1 -0
  63. package/dist/scanners/utils.js +51 -0
  64. package/dist/scanners/utils.js.map +1 -0
  65. package/dist/scanners/workspace.d.ts +3 -0
  66. package/dist/scanners/workspace.d.ts.map +1 -0
  67. package/dist/scanners/workspace.js +59 -0
  68. package/dist/scanners/workspace.js.map +1 -0
  69. package/dist/scoring/engine.d.ts +11 -0
  70. package/dist/scoring/engine.d.ts.map +1 -0
  71. package/dist/scoring/engine.js +85 -0
  72. package/dist/scoring/engine.js.map +1 -0
  73. package/dist/scoring/tiers.d.ts +11 -0
  74. package/dist/scoring/tiers.d.ts.map +1 -0
  75. package/dist/scoring/tiers.js +20 -0
  76. package/dist/scoring/tiers.js.map +1 -0
  77. package/dist/taxonomy/classifier.d.ts +9 -0
  78. package/dist/taxonomy/classifier.d.ts.map +1 -0
  79. package/dist/taxonomy/classifier.js +44 -0
  80. package/dist/taxonomy/classifier.js.map +1 -0
  81. package/dist/taxonomy/registry.json +189 -0
  82. package/dist/types.d.ts +109 -0
  83. package/dist/types.d.ts.map +1 -0
  84. package/dist/types.js +58 -0
  85. package/dist/types.js.map +1 -0
  86. package/package.json +44 -0
  87. package/src/taxonomy/registry.json +189 -0
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs } from "node:util";
3
+ import { platform, homedir } from "node:os";
4
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
5
+ import { fileURLToPath } from "node:url";
6
+ import { dirname, join } from "node:path";
7
+ import { randomUUID } from "node:crypto";
8
+ import { computeScore } from "./scoring/engine.js";
9
+ import { runAllScanners } from "./scanners/index.js";
10
+ import { EnvironmentScanner } from "./scanners/environment.js";
11
+ import { McpScanner } from "./scanners/mcp.js";
12
+ import { AgentsScanner } from "./scanners/agents.js";
13
+ import { OrchestrationScanner } from "./scanners/orchestration.js";
14
+ import { RepositoriesScanner } from "./scanners/repositories.js";
15
+ import { MemoryScanner } from "./scanners/memory.js";
16
+ import { SecurityScanner } from "./scanners/security.js";
17
+ import { DeployScanner } from "./scanners/deploy.js";
18
+ import { SocialScanner } from "./scanners/social.js";
19
+ import { UniversalFileScanner, getSupersededIds } from "./scanners/universal-file.js";
20
+ import { renderResults, createSpinner } from "./output/terminal.js";
21
+ function getVersion() {
22
+ try {
23
+ const __dirname = dirname(fileURLToPath(import.meta.url));
24
+ const pkgPath = join(__dirname, "..", "package.json");
25
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
26
+ return pkg.version ?? "0.1.0";
27
+ }
28
+ catch {
29
+ return "0.1.0";
30
+ }
31
+ }
32
+ const HANDLE_RE = /^[a-z0-9_-]{3,39}$/;
33
+ function printHelp() {
34
+ console.log(`
35
+ vibecheck — scan your AI coding setup
36
+
37
+ Usage:
38
+ vibecheck [options]
39
+
40
+ Options:
41
+ --help Show this help message
42
+ --json Output raw ProbeResult as JSON
43
+ --merge <file> Merge detections from another scan (JSON file)
44
+ --deep Scan home directory for global AI config (crontab, launchd)
45
+ --submit Submit results to vibecheck.dev
46
+ --handle <id> Your handle (3-39 chars, lowercase, hyphens, underscores)
47
+ --url <url> Override submit URL (default: https://vibecheck.dev)
48
+ --yes Skip submit confirmation prompt
49
+ `);
50
+ }
51
+ async function main() {
52
+ const { values } = parseArgs({
53
+ options: {
54
+ help: { type: "boolean", default: false },
55
+ json: { type: "boolean", default: false },
56
+ deep: { type: "boolean", default: false },
57
+ merge: { type: "string" },
58
+ submit: { type: "boolean", default: false },
59
+ handle: { type: "string" },
60
+ url: { type: "string" },
61
+ yes: { type: "boolean", default: false },
62
+ },
63
+ strict: true,
64
+ });
65
+ if (values.help) {
66
+ printHelp();
67
+ process.exit(0);
68
+ }
69
+ const isJson = values.json ?? false;
70
+ const isDeep = values.deep ?? false;
71
+ const scanners = [
72
+ new EnvironmentScanner(),
73
+ new McpScanner(),
74
+ new AgentsScanner(),
75
+ new OrchestrationScanner(),
76
+ new RepositoriesScanner(),
77
+ new MemoryScanner(),
78
+ new SecurityScanner(),
79
+ new DeployScanner(),
80
+ new SocialScanner(),
81
+ new UniversalFileScanner(isDeep), // must be last — supersedes v2 for shared artifacts
82
+ ];
83
+ const spinner = isJson ? null : createSpinner("Scanning your AI setup...");
84
+ spinner?.start();
85
+ const scanResults = await runAllScanners(scanners);
86
+ spinner?.stop();
87
+ // Flatten and deduplicate detections by id
88
+ // UFS runs last — collect its detections to know which v2 IDs to suppress
89
+ const supersededV2Ids = getSupersededIds();
90
+ const ufsResult = scanResults.find((r) => r.scanner === "universal-file");
91
+ const ufsDetectionIds = new Set(ufsResult?.detections.map((d) => d.id) ?? []);
92
+ // Build set of v2 IDs that UFS actually covered (supersedes + UFS emitted something)
93
+ const suppressedV2Ids = new Set();
94
+ for (const v2Id of supersededV2Ids) {
95
+ // Check if any UFS detection declares it supersedes this v2 ID
96
+ const hasUfsReplacement = ufsResult?.detections.some((d) => d.id.startsWith("ufs:"));
97
+ if (hasUfsReplacement)
98
+ suppressedV2Ids.add(v2Id);
99
+ }
100
+ const seen = new Set();
101
+ const detections = [];
102
+ for (const result of scanResults) {
103
+ for (const d of result.detections) {
104
+ if (seen.has(d.id))
105
+ continue;
106
+ // Skip v2 detections when UFS supersedes them
107
+ if (result.scanner !== "universal-file" && suppressedV2Ids.has(d.id))
108
+ continue;
109
+ seen.add(d.id);
110
+ detections.push(d);
111
+ }
112
+ }
113
+ // --merge: fold in detections from an external scan
114
+ if (values.merge) {
115
+ try {
116
+ const external = JSON.parse(readFileSync(values.merge, "utf-8"));
117
+ for (const d of external.detections) {
118
+ if (!seen.has(d.id)) {
119
+ seen.add(d.id);
120
+ detections.push(d);
121
+ }
122
+ }
123
+ }
124
+ catch (err) {
125
+ console.error(`\x1b[31m Failed to read --merge file: ${values.merge}\x1b[0m`);
126
+ process.exit(1);
127
+ }
128
+ }
129
+ const score = computeScore(detections);
130
+ const version = getVersion();
131
+ const result = {
132
+ version,
133
+ timestamp: new Date().toISOString(),
134
+ platform: platform(),
135
+ scanResults,
136
+ detections,
137
+ score,
138
+ };
139
+ if (isJson) {
140
+ console.log(JSON.stringify(result, null, 2));
141
+ }
142
+ else {
143
+ renderResults(score, detections);
144
+ // Hint about --merge when autonomy is empty and no merge was used
145
+ const autonomyScore = score.categories.find((c) => c.category === "autonomy");
146
+ if (autonomyScore?.score === 0 && !values.merge) {
147
+ console.log(" \x1b[2m💡 Run agents on a separate machine? Export with --json there,");
148
+ console.log(" then pass it here with --merge <file> to combine scores.\x1b[0m\n");
149
+ }
150
+ }
151
+ // --submit flow
152
+ if (values.submit) {
153
+ const handle = values.handle;
154
+ if (!handle || !HANDLE_RE.test(handle)) {
155
+ console.error("\x1b[31m --handle is required for --submit (3-39 chars, lowercase alphanumeric/hyphens/underscores)\x1b[0m");
156
+ process.exit(1);
157
+ }
158
+ // Token management: ~/.vibecheck/token
159
+ const tokenDir = join(homedir(), ".vibecheck");
160
+ const tokenPath = join(tokenDir, "token");
161
+ let submissionToken;
162
+ if (existsSync(tokenPath)) {
163
+ submissionToken = readFileSync(tokenPath, "utf-8").trim();
164
+ }
165
+ else {
166
+ submissionToken = randomUUID();
167
+ mkdirSync(tokenDir, { recursive: true });
168
+ writeFileSync(tokenPath, submissionToken, { mode: 0o600 });
169
+ }
170
+ // Confirmation unless --yes
171
+ if (!values.yes && !isJson) {
172
+ const rl = await import("node:readline/promises").then((m) => m.createInterface({ input: process.stdin, output: process.stdout }));
173
+ const answer = await rl.question(`\n Submit results as \x1b[1m${handle}\x1b[0m to vibecheck.dev? [Y/n] `);
174
+ rl.close();
175
+ if (answer.trim().toLowerCase() === "n") {
176
+ console.log(" Submission skipped.");
177
+ return;
178
+ }
179
+ }
180
+ const submitUrl = values.url ?? "https://vibecheck.dev";
181
+ try {
182
+ const res = await fetch(`${submitUrl}/api/submit`, {
183
+ method: "POST",
184
+ headers: { "Content-Type": "application/json" },
185
+ body: JSON.stringify({ handle, probeResult: result, submissionToken }),
186
+ });
187
+ if (res.ok) {
188
+ const body = (await res.json());
189
+ const url = body.url;
190
+ const inner = ` \x1b[32m✓\x1b[0m Published! Share your score:`;
191
+ const urlLine = ` ${url}`;
192
+ const width = Math.max(inner.length - 9, urlLine.length) + 4; // -9 for ANSI codes
193
+ const border = "─".repeat(width);
194
+ console.log(`\n \x1b[32m┌${border}┐\x1b[0m`);
195
+ console.log(` \x1b[32m│\x1b[0m ${inner.padEnd(width - 2)} \x1b[32m│\x1b[0m`);
196
+ console.log(` \x1b[32m│\x1b[0m ${urlLine.padEnd(width - 2)} \x1b[32m│\x1b[0m`);
197
+ console.log(` \x1b[32m└${border}┘\x1b[0m\n`);
198
+ }
199
+ else if (res.status === 403) {
200
+ console.error("\n \x1b[31m✗ This handle is owned by a different machine.\x1b[0m");
201
+ console.error(" If this is your handle, restore ~/.vibecheck/token from the original machine.\n");
202
+ }
203
+ else {
204
+ const body = (await res.json().catch(() => ({})));
205
+ console.error(`\n \x1b[31m✗ Submit failed: ${body.error ?? res.statusText}\x1b[0m\n`);
206
+ }
207
+ }
208
+ catch (err) {
209
+ console.error(`\n \x1b[33m⚠ Could not reach ${submitUrl} — results saved locally only.\x1b[0m\n`);
210
+ }
211
+ }
212
+ }
213
+ main().catch((err) => {
214
+ console.error("Fatal error:", err);
215
+ process.exit(1);
216
+ });
217
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Detection } from "../types.js";
2
+ export declare function confirmDetections(detections: Detection[]): Promise<Detection[]>;
3
+ //# sourceMappingURL=confirm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../../src/output/confirm.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,SAAS,EAAE,GACtB,OAAO,CAAC,SAAS,EAAE,CAAC,CAoDtB"}
@@ -0,0 +1,37 @@
1
+ import { createInterface } from "node:readline/promises";
2
+ import { stdin, stdout } from "node:process";
3
+ import chalk from "chalk";
4
+ export async function confirmDetections(detections) {
5
+ const rl = createInterface({ input: stdin, output: stdout });
6
+ try {
7
+ console.log(chalk.bold("\n Detected items:"));
8
+ for (let i = 0; i < detections.length; i++) {
9
+ const d = detections[i];
10
+ const innovation = d.taxonomyMatch === null ? chalk.yellow(" *") : "";
11
+ console.log(` ${chalk.dim(`${i + 1}.`)} ${d.name}${innovation} ${chalk.dim(`(${d.source})`)}`);
12
+ }
13
+ console.log();
14
+ const answer = await rl.question(chalk.bold(" Confirm detections? [Y/n/edit] "));
15
+ const normalized = answer.trim().toLowerCase();
16
+ if (normalized === "n" || normalized === "no") {
17
+ console.log(chalk.dim(" Scan cancelled."));
18
+ return [];
19
+ }
20
+ if (normalized === "edit" || normalized === "e") {
21
+ const removeStr = await rl.question(chalk.dim(" Enter numbers to remove (comma-separated): "));
22
+ const toRemove = new Set(removeStr
23
+ .split(",")
24
+ .map((s) => parseInt(s.trim(), 10) - 1)
25
+ .filter((n) => !isNaN(n) && n >= 0 && n < detections.length));
26
+ const filtered = detections.filter((_, i) => !toRemove.has(i));
27
+ console.log(chalk.dim(` Removed ${toRemove.size} item(s). ${filtered.length} remaining.`));
28
+ return filtered;
29
+ }
30
+ // Y or empty = confirm all
31
+ return detections;
32
+ }
33
+ finally {
34
+ rl.close();
35
+ }
36
+ }
37
+ //# sourceMappingURL=confirm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm.js","sourceRoot":"","sources":["../../src/output/confirm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAAuB;IAEvB,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAE7D,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,UAAU,GAAG,CAAC,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,OAAO,CAAC,GAAG,CACT,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,UAAU,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CACnF,CAAC;QACJ,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC9B,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAChD,CAAC;QAEF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE/C,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;YAC5C,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;YAChD,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,QAAQ,CACjC,KAAK,CAAC,GAAG,CACP,+CAA+C,CAChD,CACF,CAAC;YACF,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,SAAS;iBACN,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;iBACtC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAC/D,CAAC;YAEF,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAC3B,CAAC;YACF,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CAAC,aAAa,QAAQ,CAAC,IAAI,aAAa,QAAQ,CAAC,MAAM,aAAa,CAAC,CAC/E,CAAC;YACF,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,2BAA2B;QAC3B,OAAO,UAAU,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ScoreResult, Detection } from "../types.js";
2
+ export declare function generateNarrative(score: ScoreResult, detections: Detection[]): string;
3
+ //# sourceMappingURL=narrative.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narrative.d.ts","sourceRoot":"","sources":["../../src/output/narrative.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAmE5E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,SAAS,EAAE,GACtB,MAAM,CA8CR"}
@@ -0,0 +1,94 @@
1
+ // TODO: extract to @vibecheck/core — duplicated from packages/web/src/lib/narrative-templates.ts
2
+ // Types and scoring are already duplicated between probe and web.
3
+ // When a third consumer appears, extract the shared package.
4
+ import { CATEGORY_LABELS } from "../types.js";
5
+ const DIMENSION_COMMENTARY = {
6
+ intelligence: {
7
+ low: "Single model, default config. The foundation is there — just needs breadth.",
8
+ mid: "Solid model strategy. You're making deliberate choices about which AI handles what.",
9
+ high: "Multi-model mastery with routing logic. You treat models like a portfolio, not a monogamy.",
10
+ },
11
+ tooling: {
12
+ low: "Light on tools. There's a whole ecosystem of MCP servers waiting to supercharge your setup.",
13
+ mid: "Good tool coverage. Your MCP servers extend the AI's reach meaningfully.",
14
+ high: "Deep tool ecosystem. Custom MCP servers, comprehensive coverage — you're a producer, not just a consumer.",
15
+ },
16
+ continuity: {
17
+ low: "No memory system. Your AI starts fresh every session — a brilliant goldfish.",
18
+ mid: "You've solved basic continuity. The AI remembers what matters across sessions.",
19
+ high: "Multi-layer memory architecture. Daily logs, curated long-term, active work tracking — this is institutional memory.",
20
+ },
21
+ autonomy: {
22
+ low: "Purely reactive. The AI waits for your every command.",
23
+ mid: "Your agents have some independence. Subagents and scheduled tasks are in play.",
24
+ high: "Full agent workforce. Proactive work loops, specialized roles, agents that find their own tasks.",
25
+ },
26
+ ship: {
27
+ low: "Manual deploy or basic push-to-deploy. The pipeline needs work.",
28
+ mid: "CI/CD with tests and automated deploy. Professional-grade shipping.",
29
+ high: "AI-integrated pipeline. Agent-opened PRs, merge queues, quality gates — a shipping machine.",
30
+ },
31
+ security: {
32
+ low: "Security gaps visible. Secrets management and agent permissions need attention.",
33
+ mid: "Good hygiene. Gitignored secrets, environment variables, some permission scoping.",
34
+ high: "Comprehensive security model. Canary tokens, permission governance, prompt injection defense.",
35
+ },
36
+ ops: {
37
+ low: "Minimal operational infrastructure. Documentation and project management are informal.",
38
+ mid: "Task tracking and good docs. The operational backbone is solid.",
39
+ high: "AI-integrated operations. Maintenance agents, monitoring, automated documentation.",
40
+ },
41
+ social: {
42
+ low: "Solo setup. No community integration or multi-channel presence.",
43
+ mid: "Some community engagement. Communication channels or shared configs.",
44
+ high: "Full social integration. Published tools, multi-channel AI presence, community builder.",
45
+ },
46
+ };
47
+ const IMPROVEMENT_HINTS = {
48
+ ship: "Add a GitHub Actions workflow or deploy config to level up.",
49
+ tooling: "Try connecting an MCP server — filesystem or GitHub are great starters.",
50
+ continuity: "Add a CLAUDE.md to your project root so the AI remembers your conventions.",
51
+ security: "Make sure .env is in your .gitignore and review agent permissions.",
52
+ ops: "Add build/dev/lint scripts to package.json for a quick ops boost.",
53
+ };
54
+ function commentaryForScore(cat, score) {
55
+ const c = DIMENSION_COMMENTARY[cat];
56
+ if (score >= 60)
57
+ return c.high;
58
+ if (score >= 30)
59
+ return c.mid;
60
+ return c.low;
61
+ }
62
+ export function generateNarrative(score, detections) {
63
+ const sorted = [...score.categories].sort((a, b) => b.score - a.score);
64
+ const strongest = sorted[0];
65
+ // Find weakest category with score < 50 (last in sorted = lowest score)
66
+ const weakCandidates = sorted.filter((c) => c.score < 50);
67
+ const weakest = weakCandidates.length > 0
68
+ ? weakCandidates[weakCandidates.length - 1]
69
+ : undefined;
70
+ const sentences = [];
71
+ // Strongest category commentary
72
+ sentences.push(commentaryForScore(strongest.category, strongest.score));
73
+ // Weakest category suggestion (with guardrail)
74
+ if (weakest && weakest.category !== strongest.category) {
75
+ const hint = IMPROVEMENT_HINTS[weakest.category];
76
+ if (hint && weakest.score < 30) {
77
+ sentences.push(hint);
78
+ }
79
+ else {
80
+ sentences.push(`${CATEGORY_LABELS[weakest.category]} is your biggest growth area.`);
81
+ }
82
+ }
83
+ // MCP count mention
84
+ const mcpCount = detections.filter((d) => d.id.startsWith("mcp-")).length;
85
+ if (mcpCount > 3) {
86
+ sentences.push(`${mcpCount} MCP servers connected — that's serious tool integration.`);
87
+ }
88
+ // Pioneer mention
89
+ if (score.pioneer.isPioneer) {
90
+ sentences.push("Pioneer badge earned — you're building what the taxonomy hasn't seen yet.");
91
+ }
92
+ return sentences.join(" ");
93
+ }
94
+ //# sourceMappingURL=narrative.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narrative.js","sourceRoot":"","sources":["../../src/output/narrative.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ScoreResult, Detection } from "../types.js";
2
+ export declare function createSpinner(text: string): import("ora").Ora;
3
+ export declare function renderResults(score: ScoreResult, detections: Detection[]): void;
4
+ //# sourceMappingURL=terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/output/terminal.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EAGV,MAAM,aAAa,CAAC;AAqBrB,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,qBAEzC;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,SAAS,EAAE,GACtB,IAAI,CAyGN"}
@@ -0,0 +1,95 @@
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ import { CATEGORY_EMOJI, CATEGORY_LABELS, TAXONOMY_CATEGORIES } from "../types.js";
4
+ import { getNextTier } from "../scoring/tiers.js";
5
+ import { generateNarrative } from "./narrative.js";
6
+ function scoreColor(score) {
7
+ if (score >= 50)
8
+ return chalk.green;
9
+ if (score >= 25)
10
+ return chalk.yellow;
11
+ return chalk.red;
12
+ }
13
+ function tierBadge(tier) {
14
+ const badges = {
15
+ basic: chalk.gray("[basic]"),
16
+ intermediate: chalk.cyan("[inter]"),
17
+ advanced: chalk.magenta("[adv]"),
18
+ elite: chalk.yellow("[elite]"),
19
+ };
20
+ return badges[tier] ?? chalk.gray(`[${tier}]`);
21
+ }
22
+ export function createSpinner(text) {
23
+ return ora({ text, spinner: "dots" });
24
+ }
25
+ export function renderResults(score, detections) {
26
+ console.log();
27
+ // Header
28
+ const levelStr = chalk.bold.white(`Level ${score.level}`);
29
+ const tierStr = chalk.bold.cyan(score.tier.title);
30
+ const typeStr = chalk.dim(`[${score.typeCode.code}]`);
31
+ console.log(` ${levelStr} ${tierStr} ${typeStr}`);
32
+ console.log(` ${chalk.dim(score.tier.tagline)}`);
33
+ console.log();
34
+ // Narrative summary
35
+ const narrative = generateNarrative(score, detections);
36
+ console.log(` ${chalk.italic(narrative)}`);
37
+ console.log();
38
+ // Category bar chart
39
+ const catMap = new Map(score.categories.map((c) => [c.category, c]));
40
+ for (const cat of TAXONOMY_CATEGORIES) {
41
+ const cs = catMap.get(cat);
42
+ const label = CATEGORY_LABELS[cat].padEnd(12);
43
+ const filled = Math.round(cs.score / 10);
44
+ const empty = 10 - filled;
45
+ const bar = scoreColor(cs.score)("█".repeat(filled)) + chalk.dim("░".repeat(empty));
46
+ const scoreStr = scoreColor(cs.score)(String(cs.score).padStart(3));
47
+ console.log(` ${label} ${bar} ${scoreStr}`);
48
+ }
49
+ console.log();
50
+ // Detection list grouped by category
51
+ console.log(chalk.bold(" Detections"));
52
+ console.log(chalk.dim(" " + "-".repeat(52)));
53
+ for (const cat of TAXONOMY_CATEGORIES) {
54
+ const catDetections = detections.filter((d) => d.category === cat);
55
+ if (catDetections.length === 0)
56
+ continue;
57
+ console.log(` ${CATEGORY_EMOJI[cat]} ${chalk.bold(CATEGORY_LABELS[cat])}`);
58
+ for (const d of catDetections) {
59
+ const badge = tierBadge(d.tier);
60
+ const innovation = d.taxonomyMatch === null ? chalk.yellow(" *") : "";
61
+ const conf = d.confidence === "low" ? chalk.dim(" (low)") : "";
62
+ console.log(` ${badge} ${d.name}${innovation}${conf}`);
63
+ console.log(` ${chalk.dim(d.source)}`);
64
+ }
65
+ }
66
+ console.log();
67
+ // Pioneer badge
68
+ if (score.pioneer.isPioneer) {
69
+ console.log(chalk.yellow.bold(" ★ Pioneer Badge"));
70
+ console.log(chalk.yellow(` ${score.pioneer.innovations.length} innovation(s) detected`));
71
+ for (const inn of score.pioneer.innovations) {
72
+ console.log(chalk.yellow(` → ${inn.name} (${inn.source})`));
73
+ }
74
+ console.log();
75
+ }
76
+ // Improvement hints
77
+ const weakest = [...score.categories]
78
+ .filter((c) => c.score < 50)
79
+ .sort((a, b) => a.score - b.score)
80
+ .slice(0, 3);
81
+ if (weakest.length > 0) {
82
+ console.log(chalk.bold(" Growth areas"));
83
+ for (const w of weakest) {
84
+ console.log(` ${chalk.dim("→")} ${CATEGORY_LABELS[w.category]}: ${w.score}/100`);
85
+ }
86
+ console.log();
87
+ }
88
+ // Next tier hint
89
+ const next = getNextTier(score.tier.title);
90
+ if (next) {
91
+ console.log(chalk.dim(` Next tier: ${next.title} (level ${next.minLevel}+)`));
92
+ console.log();
93
+ }
94
+ }
95
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/output/terminal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { ScanResult } from "../types.js";
2
+ import type { Scanner } from "./index.js";
3
+ export declare class AgentsScanner implements Scanner {
4
+ name: string;
5
+ scan(): Promise<ScanResult>;
6
+ }
7
+ //# sourceMappingURL=agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/scanners/agents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAS1C,qBAAa,aAAc,YAAW,OAAO;IAC3C,IAAI,SAAY;IAEV,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;CA6FlC"}
@@ -0,0 +1,95 @@
1
+ import { readdir } from "node:fs/promises";
2
+ import { classify } from "../taxonomy/classifier.js";
3
+ import { fileExists, readJsonIfExists } from "./utils.js";
4
+ export class AgentsScanner {
5
+ name = "agents";
6
+ async scan() {
7
+ const start = performance.now();
8
+ const findings = [];
9
+ // Check .claude/agents/ directory for subagents
10
+ try {
11
+ const agents = await readdir(".claude/agents");
12
+ if (agents.length > 0) {
13
+ findings.push({
14
+ id: "subagents",
15
+ source: ".claude/agents/",
16
+ confidence: "high",
17
+ details: { count: agents.length },
18
+ });
19
+ }
20
+ }
21
+ catch {
22
+ // directory doesn't exist
23
+ }
24
+ // Check for AGENTS.md, SOUL.md, EVOLVE.md — CWD first, then home dir
25
+ const specialFiles = [
26
+ { file: "AGENTS.md", id: "agents-md" },
27
+ { file: "SOUL.md", id: "soul-md" },
28
+ { file: "EVOLVE.md", id: "evolve-md" },
29
+ ];
30
+ for (const { file, id } of specialFiles) {
31
+ if (await fileExists(file)) {
32
+ findings.push({
33
+ id,
34
+ source: file,
35
+ confidence: "high",
36
+ });
37
+ }
38
+ else if (await fileExists(`~/${file}`)) {
39
+ findings.push({
40
+ id,
41
+ source: `~/${file}`,
42
+ confidence: "medium",
43
+ });
44
+ }
45
+ }
46
+ // Check hooks in settings
47
+ const settings = await readJsonIfExists(".claude/settings.json");
48
+ if (settings?.hooks && Object.keys(settings.hooks).length > 0) {
49
+ findings.push({
50
+ id: "hooks",
51
+ source: ".claude/settings.json",
52
+ confidence: "high",
53
+ details: {
54
+ hookCount: Object.keys(settings.hooks).length,
55
+ },
56
+ });
57
+ }
58
+ // Check .claude/skills/ directory
59
+ try {
60
+ const skills = await readdir(".claude/skills");
61
+ if (skills.length > 0) {
62
+ findings.push({
63
+ id: "claude-skills",
64
+ source: ".claude/skills/",
65
+ confidence: "high",
66
+ details: { count: skills.length },
67
+ });
68
+ }
69
+ }
70
+ catch {
71
+ // directory doesn't exist
72
+ }
73
+ // Check .claude/commands/ directory
74
+ try {
75
+ const commands = await readdir(".claude/commands");
76
+ if (commands.length > 0) {
77
+ findings.push({
78
+ id: "claude-commands",
79
+ source: ".claude/commands/",
80
+ confidence: "high",
81
+ details: { count: commands.length },
82
+ });
83
+ }
84
+ }
85
+ catch {
86
+ // directory doesn't exist
87
+ }
88
+ return {
89
+ scanner: this.name,
90
+ detections: classify(findings),
91
+ duration: Math.round(performance.now() - start),
92
+ };
93
+ }
94
+ }
95
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/scanners/agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { ScanResult } from "../types.js";
2
+ import type { Scanner } from "./index.js";
3
+ export declare class DeployScanner implements Scanner {
4
+ name: string;
5
+ scan(): Promise<ScanResult>;
6
+ }
7
+ //# sourceMappingURL=deploy.d.ts.map