botvisibility 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-flow/data/pending-insights.jsonl +2 -0
- package/.next/trace +1 -0
- package/.next/trace-build +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +362 -0
- package/dist/index.js.map +1 -0
- package/dist/repo-scanner.d.ts +21 -0
- package/dist/repo-scanner.d.ts.map +1 -0
- package/dist/repo-scanner.js +690 -0
- package/dist/repo-scanner.js.map +1 -0
- package/dist/scanner.d.ts +48 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +868 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scoring.d.ts +32 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +100 -0
- package/dist/scoring.js.map +1 -0
- package/dist/types.d.ts +54 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/package.json +39 -0
- package/src/index.ts +402 -0
- package/src/repo-scanner.ts +718 -0
- package/src/scanner.ts +918 -0
- package/src/scoring.ts +105 -0
- package/src/types.ts +61 -0
- package/tsconfig.json +19 -0
package/src/scoring.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { CheckResult, Level, LevelProgress, CliCheck } from './types.js';
|
|
2
|
+
|
|
3
|
+
export const LEVELS: Level[] = [
|
|
4
|
+
{ number: 1, name: 'Discoverable', description: 'Bots can find you via machine-readable metadata.', color: 'red' },
|
|
5
|
+
{ number: 2, name: 'Usable', description: 'Your API works for agents — auth, errors, and core operations.', color: 'yellow' },
|
|
6
|
+
{ number: 3, name: 'Optimized', description: 'Your API minimizes token cost and handles scale.', color: 'green' },
|
|
7
|
+
{ number: 4, name: 'Agent-Native', description: 'Your platform treats AI agents as first-class users.', color: 'blue' },
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
// 26 web-scanned check definitions
|
|
11
|
+
export const CHECK_DEFINITIONS = [
|
|
12
|
+
// Level 1: Discoverable (11)
|
|
13
|
+
{ id: '1.1', name: 'llms.txt', level: 1 as const, category: 'Discoverable' },
|
|
14
|
+
{ id: '1.2', name: 'Agent Card', level: 1 as const, category: 'Discoverable' },
|
|
15
|
+
{ id: '1.3', name: 'OpenAPI Spec', level: 1 as const, category: 'Discoverable' },
|
|
16
|
+
{ id: '1.4', name: 'robots.txt AI Policy', level: 1 as const, category: 'Discoverable' },
|
|
17
|
+
{ id: '1.5', name: 'Documentation Accessibility', level: 1 as const, category: 'Discoverable' },
|
|
18
|
+
{ id: '1.6', name: 'CORS Headers', level: 1 as const, category: 'Discoverable' },
|
|
19
|
+
{ id: '1.7', name: 'AI Meta Tags', level: 1 as const, category: 'Discoverable' },
|
|
20
|
+
{ id: '1.8', name: 'Skill File', level: 1 as const, category: 'Discoverable' },
|
|
21
|
+
{ id: '1.9', name: 'AI Site Profile', level: 1 as const, category: 'Discoverable' },
|
|
22
|
+
{ id: '1.10', name: 'Skills Index', level: 1 as const, category: 'Discoverable' },
|
|
23
|
+
{ id: '1.11', name: 'Link Headers', level: 1 as const, category: 'Discoverable' },
|
|
24
|
+
|
|
25
|
+
// Level 2: Usable (9)
|
|
26
|
+
{ id: '2.1', name: 'API Read Operations', level: 2 as const, category: 'Usable' },
|
|
27
|
+
{ id: '2.2', name: 'API Write Operations', level: 2 as const, category: 'Usable' },
|
|
28
|
+
{ id: '2.3', name: 'API Primary Action', level: 2 as const, category: 'Usable' },
|
|
29
|
+
{ id: '2.4', name: 'API Key Authentication', level: 2 as const, category: 'Usable' },
|
|
30
|
+
{ id: '2.5', name: 'Scoped API Keys', level: 2 as const, category: 'Usable' },
|
|
31
|
+
{ id: '2.6', name: 'OpenID Configuration', level: 2 as const, category: 'Usable' },
|
|
32
|
+
{ id: '2.7', name: 'Structured Error Responses', level: 2 as const, category: 'Usable' },
|
|
33
|
+
{ id: '2.8', name: 'Async Operations', level: 2 as const, category: 'Usable' },
|
|
34
|
+
{ id: '2.9', name: 'Idempotency Support', level: 2 as const, category: 'Usable' },
|
|
35
|
+
|
|
36
|
+
// Level 3: Optimized (7)
|
|
37
|
+
{ id: '3.1', name: 'Sparse Fields', level: 3 as const, category: 'Optimized' },
|
|
38
|
+
{ id: '3.2', name: 'Cursor Pagination', level: 3 as const, category: 'Optimized' },
|
|
39
|
+
{ id: '3.3', name: 'Search & Filtering', level: 3 as const, category: 'Optimized' },
|
|
40
|
+
{ id: '3.4', name: 'Bulk Operations', level: 3 as const, category: 'Optimized' },
|
|
41
|
+
{ id: '3.5', name: 'Rate Limit Headers', level: 3 as const, category: 'Optimized' },
|
|
42
|
+
{ id: '3.6', name: 'Caching Headers', level: 3 as const, category: 'Optimized' },
|
|
43
|
+
{ id: '3.7', name: 'MCP Tool Quality', level: 3 as const, category: 'Optimized' },
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
export const CLI_CHECKS: CliCheck[] = [
|
|
47
|
+
{ id: '4.1', name: 'Intent-Based Endpoints', level: 4, category: 'Agent-Native', description: 'High-level intent endpoints alongside CRUD', whyCliOnly: 'Requires understanding API design intent' },
|
|
48
|
+
{ id: '4.2', name: 'Agent Sessions', level: 4, category: 'Agent-Native', description: 'Persistent sessions with context', whyCliOnly: 'Requires inspecting session implementation' },
|
|
49
|
+
{ id: '4.3', name: 'Scoped Agent Tokens', level: 4, category: 'Agent-Native', description: 'Agent-specific tokens with capability limits', whyCliOnly: 'Requires reviewing auth configuration' },
|
|
50
|
+
{ id: '4.4', name: 'Agent Audit Logs', level: 4, category: 'Agent-Native', description: 'API actions logged with agent identifiers', whyCliOnly: 'Requires inspecting logging infrastructure' },
|
|
51
|
+
{ id: '4.5', name: 'Sandbox Environment', level: 4, category: 'Agent-Native', description: 'Sandbox for agent testing', whyCliOnly: 'Requires verifying separate environment' },
|
|
52
|
+
{ id: '4.6', name: 'Consequence Labels', level: 4, category: 'Agent-Native', description: 'Marks consequential/irreversible actions', whyCliOnly: 'Requires reviewing docs/schema annotations' },
|
|
53
|
+
{ id: '4.7', name: 'Native Tool Schemas', level: 4, category: 'Agent-Native', description: 'Ready-to-use tool definitions', whyCliOnly: 'Requires checking for tool definition files' },
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
export function calculateLevelProgress(checks: CheckResult[]): LevelProgress[] {
|
|
57
|
+
return LEVELS.map((level) => {
|
|
58
|
+
const levelChecks = checks.filter((c) => c.level === level.number);
|
|
59
|
+
const passed = levelChecks.filter((c) => c.status === 'pass').length;
|
|
60
|
+
const na = levelChecks.filter((c) => c.status === 'na').length;
|
|
61
|
+
const total = levelChecks.length;
|
|
62
|
+
const failed = total - passed - na;
|
|
63
|
+
const applicable = total - na;
|
|
64
|
+
return { level, passed, failed, na, total, complete: applicable > 0 && passed === applicable };
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Weighted cross-level algorithm for determining achieved level.
|
|
70
|
+
*
|
|
71
|
+
* Rather than requiring 100% of each level in strict order, this rewards sites
|
|
72
|
+
* that invest in higher-level capabilities even if some lower-level items are missing.
|
|
73
|
+
*
|
|
74
|
+
* - L1 (Discoverable): achieved when L1 rate >= 50%
|
|
75
|
+
* - L2 (Usable): L1 >= 50% AND L2 >= 50%, OR L1 >= 35% AND L2 >= 75%
|
|
76
|
+
* - L3 (Optimized): L2 achieved AND L3 >= 50%, OR L2 >= 35% AND L3 >= 75%
|
|
77
|
+
*/
|
|
78
|
+
export function getCurrentLevel(levelProgress: LevelProgress[]): number {
|
|
79
|
+
const rate = (lp: LevelProgress | undefined): number => {
|
|
80
|
+
if (!lp) return 0;
|
|
81
|
+
const applicable = lp.total - lp.na;
|
|
82
|
+
return applicable > 0 ? lp.passed / applicable : 0;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const l1 = levelProgress.find((lp) => lp.level.number === 1);
|
|
86
|
+
const l2 = levelProgress.find((lp) => lp.level.number === 2);
|
|
87
|
+
const l3 = levelProgress.find((lp) => lp.level.number === 3);
|
|
88
|
+
|
|
89
|
+
const r1 = rate(l1);
|
|
90
|
+
const r2 = rate(l2);
|
|
91
|
+
const r3 = rate(l3);
|
|
92
|
+
|
|
93
|
+
const l2Achieved =
|
|
94
|
+
(r1 >= 0.50 && r2 >= 0.50) ||
|
|
95
|
+
(r1 >= 0.35 && r2 >= 0.75);
|
|
96
|
+
const l3Achieved =
|
|
97
|
+
(l2Achieved && r3 >= 0.50) ||
|
|
98
|
+
(r2 >= 0.35 && r3 >= 0.75);
|
|
99
|
+
|
|
100
|
+
if (l3Achieved) return 3;
|
|
101
|
+
if (l2Achieved) return 2;
|
|
102
|
+
if (r1 >= 0.50) return 1;
|
|
103
|
+
|
|
104
|
+
return 0;
|
|
105
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Core types for agent-readiness scanning — 4-level model
|
|
2
|
+
|
|
3
|
+
export interface Level {
|
|
4
|
+
number: 1 | 2 | 3 | 4;
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
color: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface LevelProgress {
|
|
11
|
+
level: Level;
|
|
12
|
+
passed: number;
|
|
13
|
+
failed: number;
|
|
14
|
+
na: number;
|
|
15
|
+
total: number;
|
|
16
|
+
complete: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface CheckResult {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
passed: boolean;
|
|
23
|
+
status: 'pass' | 'fail' | 'partial' | 'na';
|
|
24
|
+
level: 1 | 2 | 3 | 4;
|
|
25
|
+
category: string;
|
|
26
|
+
autoDetectable: boolean;
|
|
27
|
+
message: string;
|
|
28
|
+
details?: string;
|
|
29
|
+
recommendation?: string;
|
|
30
|
+
foundAt?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface CliCheck {
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
level: 4;
|
|
37
|
+
category: 'Agent-Native';
|
|
38
|
+
description: string;
|
|
39
|
+
whyCliOnly: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ScanResult {
|
|
43
|
+
url: string;
|
|
44
|
+
timestamp: string;
|
|
45
|
+
currentLevel: number;
|
|
46
|
+
levels: LevelProgress[];
|
|
47
|
+
checks: CheckResult[];
|
|
48
|
+
cliChecks: CliCheck[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface RepoCheckResult extends CheckResult {
|
|
52
|
+
filePath?: string;
|
|
53
|
+
lineNumber?: number;
|
|
54
|
+
codeSnippet?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface RepoScanResult {
|
|
58
|
+
repoPath: string;
|
|
59
|
+
timestamp: string;
|
|
60
|
+
checks: RepoCheckResult[];
|
|
61
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"declaration": true,
|
|
14
|
+
"declarationMap": true,
|
|
15
|
+
"sourceMap": true
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*"],
|
|
18
|
+
"exclude": ["node_modules", "dist"]
|
|
19
|
+
}
|