skillmark/
├── packages/
│ ├── cli/ # CLI Package (skillmark)
│ │ ├── src/
│ │ │ ├── cli-entry-point.ts # Main CLI router
│ │ │ ├── commands/
│ │ │ │ ├── run-benchmark-command.ts
│ │ │ │ ├── publish-results-command.ts
│ │ │ │ └── view-leaderboard-command.ts
│ │ │ ├── engine/
│ │ │ │ ├── markdown-test-definition-parser.ts
│ │ │ │ ├── concept-accuracy-scorer.ts
│ │ │ │ ├── security-test-scorer.ts
│ │ │ │ ├── trigger-activation-scorer.ts
│ │ │ │ ├── consistency-variance-scorer.ts
│ │ │ │ ├── claude-cli-executor.ts
│ │ │ │ ├── skill-content-collector.ts
│ │ │ │ ├── skill-creator-invoker.ts
│ │ │ │ ├── transcript-jsonl-parser.ts
│ │ │ │ ├── enhanced-test-prompt-builder.ts
│ │ │ │ ├── retry-with-degrade-utils.ts
│ │ │ │ └── run-benchmark-command.test.ts
│ │ │ ├── sources/
│ │ │ │ ├── unified-skill-source-resolver.ts
│ │ │ │ ├── local-skill-source-handler.ts
│ │ │ │ ├── git-repository-skill-source-handler.ts
│ │ │ │ └── skillsh-registry-source-handler.ts
│ │ │ ├── config/
│ │ │ │ └── api-key-config-reader.ts
│ │ │ └── types/
│ │ │ ├── index.ts
│ │ │ └── benchmark-types.ts
│ │ ├── dist/ # Compiled JavaScript
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ └── webapp/ # Webapp Package (@skillmark/webapp)
│ ├── src/
│ │ ├── worker-entry-point.ts # Cloudflare Worker entry
│ │ ├── routes/
│ │ │ ├── api-endpoints-handler.ts # REST API
│ │ │ ├── github-oauth-authentication-handler.ts
│ │ │ ├── static-assets-handler.ts
│ │ │ └── html-pages-renderer.ts
│ │ └── db/ # Database utilities (future)
│ ├── dist/ # Built files
│ ├── package.json
│ ├── wrangler.toml # Cloudflare config
│ └── tsconfig.json
│
├── examples/
│ └── tests/ # Example test suites
│
├── docs/ # Documentation
├── package.json # Root workspace config
├── pnpm-workspace.yaml # pnpm monorepo config
└── README.md # Project README
Purpose: CLI tool for running benchmarks and publishing results
Size: ~3,900 lines of TypeScript
Key Responsibilities:
- Parse CLI arguments and route commands
- Resolve skill sources (local, Git, skill.sh)
- Load test definitions from markdown files
- Execute tests via Claude CLI
- Score responses against expected concepts
- Publish results to API
Purpose: REST API and web UI for leaderboards
Framework: Hono (Cloudflare Workers)
Key Responsibilities:
- Accept benchmark submissions (POST /api/results)
- Serve leaderboard rankings (GET /api/leaderboard)
- Manage GitHub OAuth
- Generate static leaderboard HTML
User Input (CLI)
↓
┌─ Skill Source Resolution ─────────────────────┐
│ input: "~/my-skill" or git URL or skill.sh │
│ process: unified-skill-source-resolver │
│ output: SkillSource object with local path │
└─────────────────────────────────────────────┘
↓
┌─ Test Definition Loading ──────────────────────┐
│ input: skill directory or --tests path │
│ process: markdown-test-definition-parser │
│ output: TestDefinition[] (name, concepts, etc) │
└─────────────────────────────────────────────┘
↓
┌─ Test Execution Loop ──────────────────────────┐
│ for each test × run count: │
│ input: TestDefinition, skill path, model │
│ process: claude-cli-executor │
│ output: transcript JSONL file │
│ ───────────────────────────────────────────── │
│ Optional enhancement: │
│ - skill-content-collector: Analyze skill │
│ - skill-creator-invoker: Generate analysis │
│ - enhanced-test-prompt-builder: Augment │
└─────────────────────────────────────────────┘
↓
┌─ Response Scoring ────────────────────────────┐
│ input: response, test type │
│ process: │
│ - Standard: concept-accuracy-scorer │
│ - Security: security-test-scorer │
│ output: BenchmarkMetrics, passed flag │
└─────────────────────────────────────────────┘
↓
┌─ Metrics Aggregation ─────────────────────────┐
│ input: all TestResult[] from runs │
│ process: average metrics, identify outliers │
│ output: BenchmarkResult with aggregated data │
└─────────────────────────────────────────────┘
↓
┌─ Output Generation ───────────────────────────┐
│ output: result.json (machine-readable) │
│ output: report.md (human-readable) │
└─────────────────────────────────────────────┘
↓
User (Optional) → Publish results via API
POST /api/results (with Bearer token)
↓
github-oauth-authentication-handler (verify token)
↓
api-endpoints-handler (parse BenchmarkResult JSON)
↓
D1 Database (store in results table)
↓
Response: { success: true, skillId: "..." }
GET /api/leaderboard?limit=50&offset=0
↓
api-endpoints-handler (query rankings)
↓
D1 Database (SELECT top skills by accuracy)
↓
Response: LeaderboardEntry[]
GET /api/skill/my-skill-name
↓
api-endpoints-handler (query by name)
↓
D1 Database (SELECT history + details)
↓
Response: skill details + 10 recent runs
name: string (unique identifier)type: 'knowledge' | 'task' | 'security' (Q&A, execution, or safety test)category: string (security category: prompt-injection, jailbreak, etc)concepts: string[] (validation targets, 3-5 typical)timeout: number (seconds, typical 60-300)prompt: string (the test question/task)expected: string[] (response patterns to match)sourcePath: string (markdown file path)
accuracy: 0-100% (concepts_matched / total_concepts)securityScore: 0-100% (refusal × (1 - leakage/100))triggerScore: 0-100% (activation × precision)consistencyScore: 0-100% (based on stdDev, range, conceptOverlap)tokensTotal: input + output tokenstokensInput: prompt tokenstokensOutput: response tokensdurationMs: wall-clock timetoolCount: number of tool callscostUsd: (tokens_total × model_price_per_token)
Single test execution result including:
- test definition
- metrics for this run
- matchedConcepts, missedConcepts
- raw response text
- passed flag (accuracy ≥ 70% threshold)
- timestamp
Aggregated results across all tests/runs:
- skillId, skillName, skillSource
- model type (haiku/sonnet/opus)
- runs: number of iterations
- testResults: all individual results
- aggregatedMetrics: averaged across runs
- hash: SHA-256 for verification
type: 'local' | 'git' | 'skillsh'original: original input stringlocalPath: resolved filesystem pathname: extracted skill name
- Parse options (tests, model, runs, output, verbose, with-baseline)
- Resolve skill source via resolveSkillSource()
- Load tests via loadTestsFromDirectory() or discoverTests()
- (Optional) Execute baseline tests without skill if --with-baseline
- Execute tests via executeTest() for each test × run
- Score responses via scoreResponse() (accuracy, security, trigger)
- Calculate variance metrics via consistency-variance-scorer
- Aggregate metrics via aggregateMetrics()
- Write result.json and report.md
- Optional: Invoke skill-creator for enhanced analysis
Key Options:
-m, --model: haiku|sonnet|opus (required)-r, --runs: iteration count (default: 3)-t, --tests: explicit test directory-o, --output: result directory (default: ./skillmark-results)-v, --verbose: detailed progress output--with-baseline: run baseline tests (without skill) for delta metrics
- Read result.json file
- Verify API key from config
- POST to /api/results with Bearer token
- Display upload success/failure
- Fetch GET /api/leaderboard?limit=50
- Parse leaderboard JSON
- Format and display in terminal
- Check if directory exists
- Use directly as localPath
- Extract name from directory name
- Validate URL format
- Clone to cache:
~/.skillmark/cache/{hash} - Use cloned path as localPath
- Extract name from repo name
- Parse identifier
- Resolve to GitHub URL:
https://github.com/user/skill-name - Clone like Git source
- Extract name from skill-name
Cache Strategy: Use SHA-256 hash of source URL as cache key to avoid re-cloning.
Markdown files with YAML frontmatter in tests/ directory:
---
name: multi-agent-reasoning
type: knowledge
concepts:
- orchestrator pattern
- consensus mechanism
- context isolation
timeout: 120
---
# Prompt
How do you design multi-agent systems with context isolation?
# Expected
The response should cover:
- [ ] Orchestrator pattern for coordination
- [ ] Consensus mechanisms for decisions
- [ ] Cost implications (~15x token multiplier)
- [ ] Context isolation strategiesParsing: gray-matter library extracts YAML frontmatter, rest is markdown.
- Wraps skill-creator-invoker with retry logic
- Falls back to basic prompt if skill-creator fails
- Exponential backoff with max retries
- Spawns Claude CLI subprocess
- Captures stdout/stderr
- Handles timeout and process errors
- Returns success/error flag
- Validates test schema
- Requires: name, type, concepts, timeout, prompt, expected
- Throws error if validation fails
| Operation | Time | Notes |
|---|---|---|
| Load tests | <100ms | Glob + file reads |
| Resolve skill source | <500ms | Local instant, Git includes clone time |
| Single test execution | 10-300s | Depends on model + prompt length |
| Score response | <50ms | String pattern matching |
| Aggregate metrics | <10ms | Array average calculations |
| API POST /results | <1s | Network + database write |
| GET /leaderboard | <500ms | Database query + pagination |
- API key stored:
~/.skillmark/config.json - Cache directory:
~/.skillmark/cache/ - Results directory:
./skillmark-results/(default)
CLAUDE_API_KEY: Used by Claude CLI subprocessSKILLMARK_API_KEY: CLI API key for publishing
name: skillmarkmain: dist/worker-entry-point.jscompatibility_date: 2024-01-01- Bindings: D1 database, KV storage
| Package | Version | Purpose |
|---|---|---|
| typescript | ^5.3.3 | Type safety |
| commander | ^11.x | CLI argument parsing |
| chalk | ^5.x | Colored terminal output |
| ora | ^6.x | Spinners/progress indicators |
| gray-matter | ^4.x | YAML frontmatter parsing |
| simple-git | ^3.x | Git repository operations |
| hono | ^3.x | Cloudflare Worker framework |
# Root workspace
pnpm install # Install all dependencies
pnpm build # Build both packages
pnpm lint # Lint TypeScript
# CLI specific
pnpm --filter skillmark build # TypeScript → JavaScript
npm publish # Publish to npm registry
# Webapp specific
pnpm --filter @skillmark/webapp build # Build worker
pnpm --filter @skillmark/webapp deploy # Deploy to CloudflareCurrent implementation uses:
- Direct CLI invocation for integration tests
- Mock test definitions for unit testing
- Real Claude API calls (no mocking)
Future: Implement comprehensive test suite with:
- Unit tests for each engine module
- Integration tests for end-to-end flows
- Mock Claude API for isolated testing
Codebase Stats:
- CLI source: ~4,200 lines of TypeScript (includes security-test-scorer)
- Webapp source: ~500 lines of TypeScript
- Total: ~4,700 lines
- Test suite: 69 tests (56 standard + 13 security tests)
Last Updated: February 2025