@sx4im/skillcheck 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 (61) hide show
  1. package/LICENSE +21 -0
  2. package/METHODOLOGY.md +91 -0
  3. package/README.md +159 -0
  4. package/dist/bin/skillcheck.d.ts +2 -0
  5. package/dist/bin/skillcheck.js +8 -0
  6. package/dist/bin/skillcheck.js.map +1 -0
  7. package/dist/src/adapters/nvidia-nim.d.ts +30 -0
  8. package/dist/src/adapters/nvidia-nim.js +165 -0
  9. package/dist/src/adapters/nvidia-nim.js.map +1 -0
  10. package/dist/src/cache.d.ts +5 -0
  11. package/dist/src/cache.js +27 -0
  12. package/dist/src/cache.js.map +1 -0
  13. package/dist/src/cli.d.ts +1 -0
  14. package/dist/src/cli.js +146 -0
  15. package/dist/src/cli.js.map +1 -0
  16. package/dist/src/corpus.d.ts +43 -0
  17. package/dist/src/corpus.js +233 -0
  18. package/dist/src/corpus.js.map +1 -0
  19. package/dist/src/deterministic.d.ts +7 -0
  20. package/dist/src/deterministic.js +25 -0
  21. package/dist/src/deterministic.js.map +1 -0
  22. package/dist/src/env.d.ts +12 -0
  23. package/dist/src/env.js +39 -0
  24. package/dist/src/env.js.map +1 -0
  25. package/dist/src/eval.d.ts +13 -0
  26. package/dist/src/eval.js +155 -0
  27. package/dist/src/eval.js.map +1 -0
  28. package/dist/src/generate.d.ts +9 -0
  29. package/dist/src/generate.js +94 -0
  30. package/dist/src/generate.js.map +1 -0
  31. package/dist/src/grade.d.ts +5 -0
  32. package/dist/src/grade.js +112 -0
  33. package/dist/src/grade.js.map +1 -0
  34. package/dist/src/hash.d.ts +2 -0
  35. package/dist/src/hash.js +8 -0
  36. package/dist/src/hash.js.map +1 -0
  37. package/dist/src/m0/hardcoded.d.ts +7 -0
  38. package/dist/src/m0/hardcoded.js +51 -0
  39. package/dist/src/m0/hardcoded.js.map +1 -0
  40. package/dist/src/m0/run.d.ts +38 -0
  41. package/dist/src/m0/run.js +102 -0
  42. package/dist/src/m0/run.js.map +1 -0
  43. package/dist/src/normalize.d.ts +2 -0
  44. package/dist/src/normalize.js +109 -0
  45. package/dist/src/normalize.js.map +1 -0
  46. package/dist/src/rot.d.ts +62 -0
  47. package/dist/src/rot.js +156 -0
  48. package/dist/src/rot.js.map +1 -0
  49. package/dist/src/run.d.ts +5 -0
  50. package/dist/src/run.js +47 -0
  51. package/dist/src/run.js.map +1 -0
  52. package/dist/src/score.d.ts +14 -0
  53. package/dist/src/score.js +59 -0
  54. package/dist/src/score.js.map +1 -0
  55. package/dist/src/types.d.ts +41 -0
  56. package/dist/src/types.js +2 -0
  57. package/dist/src/types.js.map +1 -0
  58. package/dist/src/verify.d.ts +5 -0
  59. package/dist/src/verify.js +71 -0
  60. package/dist/src/verify.js.map +1 -0
  61. package/package.json +64 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Saim Shafique
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/METHODOLOGY.md ADDED
@@ -0,0 +1,91 @@
1
+ # Methodology
2
+
3
+ This document describes how `skillcheck` measures skill effectiveness in v1.
4
+
5
+ ## What Is Measured
6
+
7
+ `skillcheck` measures the value of skill instructions under forced injection. The skill body is always injected into the runner model's context for the `with_skill` arm and omitted for the `no_skill` arm.
8
+
9
+ This is intentionally narrower than real agent behavior. It answers: "Does this skill content help when the model receives it?" It does not answer: "Will an agent trigger this skill at the right time?" Trigger-respecting evaluation is out of scope for v1.
10
+
11
+ ## Skill Normalization
12
+
13
+ Supported input formats:
14
+
15
+ - `SKILL.md`
16
+ - `AGENTS.md`
17
+ - `.cursorrules`
18
+ - `CLAUDE.md` for the accessible `awesome-claude-md` seed corpus
19
+
20
+ Each skill is normalized into:
21
+
22
+ - `instructions`: full injected content
23
+ - `domain`: declared scope from front matter or inferred text
24
+ - `format`: source format
25
+ - `assets`: recorded sibling files, not executed in v1
26
+ - `commit_hash`: SHA-256 hash of the instruction body
27
+
28
+ ## Task Generation
29
+
30
+ The task generator receives only the normalized `domain`. It never receives the instruction body.
31
+
32
+ For each run, the generator creates `2N` tasks and `skillcheck` deterministically samples `N` tasks. This reduces dependence on a single generation order while preserving reproducibility for the same domain and generator model.
33
+
34
+ ## A/B Runner
35
+
36
+ For each task, the runner model is called in two arms:
37
+
38
+ - `with_skill`: system context includes the skill instructions
39
+ - `no_skill`: task prompt only
40
+
41
+ Each arm runs `K` trials. The default is `K=3`; single-trial results are not accepted as launch-quality evidence.
42
+
43
+ ## Grading
44
+
45
+ Deterministic assertions run first when a task has one. Otherwise, the grader model receives the output and the criterion, but not the arm label. This keeps grading blind to whether an answer came from the skill-injected arm.
46
+
47
+ The generator, runner, and grader model IDs are separate environment variables so they can be swapped independently.
48
+
49
+ ## Scoring
50
+
51
+ `effect_pp` is:
52
+
53
+ ```text
54
+ mean(with_skill_pass_rate) - mean(no_skill_pass_rate)
55
+ ```
56
+
57
+ The confidence interval is a paired bootstrap over task/trial observations. Verdicts are:
58
+
59
+ - `helps`: the full CI is above zero
60
+ - `placebo`: the CI overlaps zero
61
+ - `harms`: the full CI is below zero
62
+
63
+ Results also report token overhead and value per 1k extra prompt tokens.
64
+
65
+ ## Reproducibility
66
+
67
+ Every published result records:
68
+
69
+ - skill source
70
+ - skill instruction hash
71
+ - task suite path
72
+ - runner, grader, and generator model IDs
73
+ - trial count and task count
74
+ - transcript hashes
75
+ - run date
76
+
77
+ `skillcheck verify <result.json>` reruns a sample of tasks and checks whether the measured effect remains inside the published confidence interval.
78
+
79
+ ## Rot Detection
80
+
81
+ Rot detection groups result history by normalized skill name plus instruction hash. A skill is flagged as rot only when a previous result was `helps` and the latest result is `placebo` or `harms`.
82
+
83
+ The leaderboard renders the latest rot status and the per-skill history timeline.
84
+
85
+ ## Known Limitations
86
+
87
+ - Forced injection does not measure trigger reliability.
88
+ - LLM-graded tasks inherit the limitations of the grader model, even with blind labels.
89
+ - Assets are recorded but not executed in v1.
90
+ - The v1 launch seed corpus is intentionally capped at 20 skills; it is launch evidence, not a comprehensive public corpus.
91
+ - NVIDIA NIM availability affects live corpus completion. Failed or interrupted runs are recorded separately from gate-passing evidence, and the M5 launch findings use only the completed Qwen Next launch run.
package/README.md ADDED
@@ -0,0 +1,159 @@
1
+ # skillcheck
2
+
3
+ Measure whether an agent skill actually improves task performance.
4
+
5
+ `skillcheck` runs a forced-injection A/B evaluation: the runner model solves generated tasks with and without the skill instructions, then the result is scored as an effect in percentage points with a bootstrap confidence interval.
6
+
7
+ ## Status
8
+
9
+ - M0-M4 gates have passed and are recorded in `BUILD-LOG.md`.
10
+ - M5 completed a 20-skill launch corpus in `results/launch/20260605T110514Z-qwen-next`.
11
+ - The launch used `qwen/qwen3-next-80b-a3b-instruct` for generator, grader, and runner after direct NVIDIA diagnostics showed the original StepFun, DeepSeek, and Mistral stack was not reliable enough to complete the corpus.
12
+ - Do not publish to npm until `RELEASE-CHECKLIST.md` is complete.
13
+
14
+ ## Run
15
+
16
+ After npm publication, users can run the CLI with one command and no global install:
17
+
18
+ ```bash
19
+ npx --yes @sx4im/skillcheck@latest --help
20
+ ```
21
+
22
+ Or install it globally:
23
+
24
+ ```bash
25
+ npm install -g @sx4im/skillcheck
26
+ skillcheck --help
27
+ ```
28
+
29
+ Before npm publication, install the CLI from this GitHub repo for testing:
30
+
31
+ ```bash
32
+ npm install -g git+ssh://git@github.com/sx4im/skillcheck.git
33
+ ```
34
+
35
+ Remove the pre-publish GitHub install with:
36
+
37
+ ```bash
38
+ npm uninstall -g skillcheck
39
+ ```
40
+
41
+ If `npm install -g @sx4im/skillcheck` returns `404 Not Found`, the package has not been published to npm yet. The first successful `npm publish` registers the package name; there is no separate manual package-registration step.
42
+
43
+ Requires Node.js 20 or newer.
44
+
45
+ ## Local Development
46
+
47
+ ```bash
48
+ npm ci
49
+ npm run build
50
+ node dist/bin/skillcheck.js --help
51
+ ```
52
+
53
+ You can also run the compiled CLI directly:
54
+
55
+ ```bash
56
+ node dist/bin/skillcheck.js eval fixtures/m2/strong-skill/SKILL.md --task-suite fixtures/m2/deterministic-tasks.json --tasks 3 --trials 3 --output /tmp/skillcheck-result.json
57
+ ```
58
+
59
+ ## Environment
60
+
61
+ Copy `.env.example` to `.env` and set `NVIDIA_API_KEY`.
62
+
63
+ Required for live NVIDIA NIM calls:
64
+
65
+ ```bash
66
+ NVIDIA_API_KEY=...
67
+ NVIDIA_BASE_URL=https://integrate.api.nvidia.com/v1
68
+ NVIDIA_GENERATOR_MODEL=qwen/qwen3-next-80b-a3b-instruct
69
+ NVIDIA_GRADER_MODEL=qwen/qwen3-next-80b-a3b-instruct
70
+ NVIDIA_RUNNER_MODEL=qwen/qwen3-next-80b-a3b-instruct
71
+ ```
72
+
73
+ Recommended launch-run provider controls:
74
+
75
+ ```bash
76
+ NVIDIA_TIMEOUT_MS=120000
77
+ NVIDIA_REQUEST_DELAY_MS=5000
78
+ NVIDIA_MAX_ATTEMPTS=8
79
+ NVIDIA_MAX_RETRY_DELAY_MS=60000
80
+ ```
81
+
82
+ The final M5 run used `--concurrency 1` and a 5 second process-wide request delay. The completed run had 75 recovered NVIDIA connection retries and no `429` rate-limit lines.
83
+
84
+ ## Commands
85
+
86
+ Evaluate one skill:
87
+
88
+ ```bash
89
+ skillcheck eval path/to/SKILL.md --tasks 10 --trials 3 --output results/my-run.json
90
+ ```
91
+
92
+ Verify a published result:
93
+
94
+ ```bash
95
+ skillcheck verify results/my-run.json --sample 3
96
+ ```
97
+
98
+ Run the launch corpus:
99
+
100
+ ```bash
101
+ skillcheck corpus run --corpus corpus/launch-20.json --results results/launch/$(date -u +%Y%m%dT%H%M%SZ) --tasks 10 --trials 3 --concurrency 1
102
+ ```
103
+
104
+ Regenerate the launch-only rot report used by the leaderboard:
105
+
106
+ ```bash
107
+ skillcheck rot --results results/launch/20260605T110514Z-qwen-next --output results/rot/report.json
108
+ ```
109
+
110
+ Build the static leaderboard:
111
+
112
+ ```bash
113
+ npm run site:build
114
+ ```
115
+
116
+ By default, the leaderboard reads the launch directory pointed to by `results/launch/latest-qwen-next-dir.txt`. Override with `SKILLCHECK_RESULTS_DIR` when you want to render a different result set.
117
+
118
+ ## Methodology
119
+
120
+ The generator receives only the declared skill domain, never the full skill body. The runner is evaluated with and without forced skill injection. The grader is blind to arm labels, and deterministic assertions run before LLM grading when available.
121
+
122
+ Forced injection is the v1 default. It measures whether the skill content helps when injected; it does not test trigger reliability. See `METHODOLOGY.md`.
123
+
124
+ ## Launch Findings
125
+
126
+ The M5 launch corpus measured 20 pinned seed skills:
127
+
128
+ - `helps`: 3 / 20, 15%.
129
+ - `placebo`: 11 / 20, 55%.
130
+ - `harms`: 6 / 20, 30%.
131
+
132
+ See `FINDINGS-DRAFT.md` for the current draft write-up and caveats.
133
+
134
+ ## Release
135
+
136
+ Do not publish from this repo until `RELEASE-CHECKLIST.md` is complete and M5 final verification has passed.
137
+
138
+ To publish the public npm package, log in with the npm account that should own `skillcheck`, then run one of the publish flows below.
139
+
140
+ With npm WebAuthn/security-key 2FA enabled:
141
+
142
+ ```bash
143
+ npm login
144
+ npm publish --access public
145
+ npm view @sx4im/skillcheck version
146
+ npx --yes @sx4im/skillcheck@latest --help
147
+ ```
148
+
149
+ With an authenticator-app OTP:
150
+
151
+ ```bash
152
+ npm publish --access public --otp=123456
153
+ ```
154
+
155
+ Replace `123456` with the current 6-digit npm two-factor authentication code.
156
+
157
+ Without account 2FA, create a granular access token on npm with `Bypass two-factor authentication` enabled and `Read and write` access to all packages, then publish with that token.
158
+
159
+ If the package name is still free, `npm publish` creates/registers `@sx4im/skillcheck` automatically.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../src/cli.js';
3
+ main(process.argv).catch((error) => {
4
+ const message = error instanceof Error ? error.message : String(error);
5
+ console.error(message);
6
+ process.exitCode = 1;
7
+ });
8
+ //# sourceMappingURL=skillcheck.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skillcheck.js","sourceRoot":"","sources":["../../packages/cli/bin/skillcheck.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC1C,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { ChatCompletionMessageParam } from 'openai/resources/chat/completions';
2
+ import type { NvidiaConfig } from '../env.js';
3
+ export interface CompletionRequest {
4
+ model: string;
5
+ messages: ChatCompletionMessageParam[];
6
+ temperature: number;
7
+ maxTokens: number;
8
+ responseFormat?: 'json_object';
9
+ chatTemplateKwargs?: Record<string, unknown>;
10
+ }
11
+ export interface CompletionResponse {
12
+ content: string;
13
+ model: string;
14
+ usage?: {
15
+ promptTokens?: number;
16
+ completionTokens?: number;
17
+ totalTokens?: number;
18
+ };
19
+ }
20
+ export declare class NvidiaNimClient {
21
+ private static requestQueue;
22
+ private static lastRequestAt;
23
+ private readonly client;
24
+ private readonly requestDelayMs;
25
+ private readonly maxAttempts;
26
+ private readonly maxRetryDelayMs;
27
+ constructor(config: NvidiaConfig);
28
+ private runSerializedRequest;
29
+ complete(request: CompletionRequest): Promise<CompletionResponse>;
30
+ }
@@ -0,0 +1,165 @@
1
+ import OpenAI from 'openai';
2
+ const RETRYABLE_STATUSES = new Set([408, 409, 429, 500, 502, 503, 504]);
3
+ function extractTextContent(content) {
4
+ if (typeof content === 'string') {
5
+ return content;
6
+ }
7
+ if (Array.isArray(content)) {
8
+ const parts = content
9
+ .map((part) => {
10
+ if (typeof part === 'string') {
11
+ return part;
12
+ }
13
+ if (typeof part === 'object' && part !== null && 'text' in part) {
14
+ const text = part.text;
15
+ return typeof text === 'string' ? text : '';
16
+ }
17
+ return '';
18
+ })
19
+ .join('');
20
+ return parts || undefined;
21
+ }
22
+ return undefined;
23
+ }
24
+ function extractMessageText(message) {
25
+ if (typeof message !== 'object' || message === null) {
26
+ return undefined;
27
+ }
28
+ const record = message;
29
+ return (extractTextContent(record.content) ??
30
+ extractTextContent(record.reasoning_content) ??
31
+ extractTextContent(record.refusal));
32
+ }
33
+ function sleep(ms) {
34
+ return new Promise((resolve) => setTimeout(resolve, ms));
35
+ }
36
+ function getStatus(error) {
37
+ if (typeof error === 'object' && error !== null && 'status' in error) {
38
+ const status = error.status;
39
+ return typeof status === 'number' ? status : undefined;
40
+ }
41
+ return undefined;
42
+ }
43
+ function getRetryAfterMs(error) {
44
+ if (typeof error !== 'object' || error === null || !('headers' in error)) {
45
+ return undefined;
46
+ }
47
+ const headers = error.headers;
48
+ const retryAfter = headers instanceof Headers
49
+ ? headers.get('retry-after')
50
+ : typeof headers === 'object' && headers !== null && 'retry-after' in headers
51
+ ? headers['retry-after']
52
+ : undefined;
53
+ if (typeof retryAfter !== 'string') {
54
+ return undefined;
55
+ }
56
+ const seconds = Number(retryAfter);
57
+ if (Number.isFinite(seconds) && seconds > 0) {
58
+ return seconds * 1000;
59
+ }
60
+ const dateMs = Date.parse(retryAfter);
61
+ if (Number.isFinite(dateMs)) {
62
+ return Math.max(0, dateMs - Date.now());
63
+ }
64
+ return undefined;
65
+ }
66
+ function describeRetry(error, attempt, waitMs, maxAttempts) {
67
+ const status = getStatus(error);
68
+ const label = status === undefined ? 'connection' : `status ${status}`;
69
+ console.error(`[nim] retry ${attempt + 1}/${maxAttempts} after ${label}; waiting ${waitMs} ms`);
70
+ }
71
+ export class NvidiaNimClient {
72
+ static requestQueue = Promise.resolve();
73
+ static lastRequestAt = 0;
74
+ client;
75
+ requestDelayMs;
76
+ maxAttempts;
77
+ maxRetryDelayMs;
78
+ constructor(config) {
79
+ this.requestDelayMs = config.requestDelayMs;
80
+ this.maxAttempts = config.maxAttempts;
81
+ this.maxRetryDelayMs = config.maxRetryDelayMs;
82
+ this.client = new OpenAI({
83
+ apiKey: config.apiKey,
84
+ baseURL: config.baseUrl,
85
+ maxRetries: 0,
86
+ timeout: config.timeoutMs
87
+ });
88
+ }
89
+ async runSerializedRequest(operation) {
90
+ const previousRequest = NvidiaNimClient.requestQueue;
91
+ let releaseCurrentRequest = () => undefined;
92
+ NvidiaNimClient.requestQueue = new Promise((resolve) => {
93
+ releaseCurrentRequest = resolve;
94
+ });
95
+ await previousRequest;
96
+ try {
97
+ if (this.requestDelayMs > 0) {
98
+ const elapsedMs = Date.now() - NvidiaNimClient.lastRequestAt;
99
+ const waitMs = Math.max(0, this.requestDelayMs - elapsedMs);
100
+ if (waitMs > 0) {
101
+ await sleep(waitMs);
102
+ }
103
+ }
104
+ NvidiaNimClient.lastRequestAt = Date.now();
105
+ return await operation();
106
+ }
107
+ finally {
108
+ releaseCurrentRequest();
109
+ }
110
+ }
111
+ async complete(request) {
112
+ let lastError;
113
+ for (let attempt = 0; attempt < this.maxAttempts; attempt += 1) {
114
+ try {
115
+ const extraBody = request.chatTemplateKwargs
116
+ ? {
117
+ chat_template_kwargs: request.chatTemplateKwargs
118
+ }
119
+ : undefined;
120
+ const requestBody = {
121
+ model: request.model,
122
+ messages: request.messages,
123
+ temperature: request.temperature,
124
+ max_tokens: request.maxTokens,
125
+ response_format: request.responseFormat ? { type: request.responseFormat } : undefined,
126
+ chat_template_kwargs: request.chatTemplateKwargs,
127
+ extra_body: extraBody,
128
+ stream: false
129
+ };
130
+ const response = (await this.runSerializedRequest(() => this.client.chat.completions.create(requestBody)));
131
+ const message = response.choices[0]?.message;
132
+ const content = extractMessageText(message);
133
+ if (content === undefined) {
134
+ const keys = message ? Object.keys(message).sort().join(',') : 'none';
135
+ throw new Error(`NVIDIA NIM response did not include text content; message keys: ${keys}`);
136
+ }
137
+ return {
138
+ content,
139
+ model: response.model,
140
+ usage: {
141
+ promptTokens: response.usage?.prompt_tokens,
142
+ completionTokens: response.usage?.completion_tokens,
143
+ totalTokens: response.usage?.total_tokens
144
+ }
145
+ };
146
+ }
147
+ catch (error) {
148
+ lastError = error;
149
+ const status = getStatus(error);
150
+ const retryable = status === undefined || RETRYABLE_STATUSES.has(status);
151
+ if (!retryable || attempt === this.maxAttempts - 1) {
152
+ break;
153
+ }
154
+ const retryAfterMs = getRetryAfterMs(error);
155
+ const baseDelayMs = status === 429 ? 5000 : 500;
156
+ const jitter = Math.floor(Math.random() * 500);
157
+ const waitMs = retryAfterMs ?? Math.min(this.maxRetryDelayMs, baseDelayMs * 2 ** attempt + jitter);
158
+ describeRetry(error, attempt, waitMs, this.maxAttempts);
159
+ await sleep(waitMs);
160
+ }
161
+ }
162
+ throw lastError instanceof Error ? lastError : new Error(String(lastError));
163
+ }
164
+ }
165
+ //# sourceMappingURL=nvidia-nim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nvidia-nim.js","sourceRoot":"","sources":["../../../packages/cli/src/adapters/nvidia-nim.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAuB5B,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAExE,SAAS,kBAAkB,CAAC,OAAgB;IAC1C,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,OAAO;aAClB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBAChE,MAAM,IAAI,GAAI,IAA2B,CAAC,IAAI,CAAC;gBAC/C,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9C,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;aACD,IAAI,CAAC,EAAE,CAAC,CAAC;QACZ,OAAO,KAAK,IAAI,SAAS,CAAC;IAC5B,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAgB;IAC1C,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACpD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,OAAgF,CAAC;IAChG,OAAO,CACL,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC;QAClC,kBAAkB,CAAC,MAAM,CAAC,iBAAiB,CAAC;QAC5C,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CACnC,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;QACrE,MAAM,MAAM,GAAI,KAA8B,CAAC,MAAM,CAAC;QACtD,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IACzD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAI,KAA+B,CAAC,OAAO,CAAC;IACzD,MAAM,UAAU,GACd,OAAO,YAAY,OAAO;QACxB,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QAC5B,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,aAAa,IAAI,OAAO;YAC3E,CAAC,CAAE,OAAuC,CAAC,aAAa,CAAC;YACzD,CAAC,CAAC,SAAS,CAAC;IAElB,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAC5C,OAAO,OAAO,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACtC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAE,OAAe,EAAE,MAAc,EAAE,WAAmB;IACzF,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,MAAM,EAAE,CAAC;IACvE,OAAO,CAAC,KAAK,CAAC,eAAe,OAAO,GAAG,CAAC,IAAI,WAAW,UAAU,KAAK,aAAa,MAAM,KAAK,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,OAAO,eAAe;IAClB,MAAM,CAAC,YAAY,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IACvD,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;IAEhB,MAAM,CAAS;IACf,cAAc,CAAS;IACvB,WAAW,CAAS;IACpB,eAAe,CAAS;IAEzC,YAAY,MAAoB;QAC9B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QAC5C,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;QAC9C,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,UAAU,EAAE,CAAC;YACb,OAAO,EAAE,MAAM,CAAC,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAI,SAA2B;QAC/D,MAAM,eAAe,GAAG,eAAe,CAAC,YAAY,CAAC;QACrD,IAAI,qBAAqB,GAAe,GAAG,EAAE,CAAC,SAAS,CAAC;QACxD,eAAe,CAAC,YAAY,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC3D,qBAAqB,GAAG,OAAO,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,MAAM,eAAe,CAAC;QACtB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;gBAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,CAAC,aAAa,CAAC;gBAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;gBAC5D,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;oBACf,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;YACD,eAAe,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3C,OAAO,MAAM,SAAS,EAAE,CAAC;QAC3B,CAAC;gBAAS,CAAC;YACT,qBAAqB,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAA0B;QACvC,IAAI,SAAkB,CAAC;QAEvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;YAC/D,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,OAAO,CAAC,kBAAkB;oBAC1C,CAAC,CAAC;wBACE,oBAAoB,EAAE,OAAO,CAAC,kBAAkB;qBACjD;oBACH,CAAC,CAAC,SAAS,CAAC;gBACd,MAAM,WAAW,GAAG;oBAClB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,UAAU,EAAE,OAAO,CAAC,SAAS;oBAC7B,eAAe,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,SAAS;oBACtF,oBAAoB,EAAE,OAAO,CAAC,kBAAkB;oBAChD,UAAU,EAAE,SAAS;oBACrB,MAAM,EAAE,KAAK;iBACd,CAAC;gBACF,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE,CACrD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CACjD,CAAmB,CAAC;gBAErB,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;gBAC7C,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;gBAC5C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;oBACtE,MAAM,IAAI,KAAK,CAAC,mEAAmE,IAAI,EAAE,CAAC,CAAC;gBAC7F,CAAC;gBAED,OAAO;oBACL,OAAO;oBACP,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,KAAK,EAAE;wBACL,YAAY,EAAE,QAAQ,CAAC,KAAK,EAAE,aAAa;wBAC3C,gBAAgB,EAAE,QAAQ,CAAC,KAAK,EAAE,iBAAiB;wBACnD,WAAW,EAAE,QAAQ,CAAC,KAAK,EAAE,YAAY;qBAC1C;iBACF,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,SAAS,GAAG,KAAK,CAAC;gBAClB,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;gBAChC,MAAM,SAAS,GAAG,MAAM,KAAK,SAAS,IAAI,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACzE,IAAI,CAAC,SAAS,IAAI,OAAO,KAAK,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;oBACnD,MAAM;gBACR,CAAC;gBAED,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;gBAC5C,MAAM,WAAW,GAAG,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;gBAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;gBAC/C,MAAM,MAAM,GAAG,YAAY,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,CAAC,IAAI,OAAO,GAAG,MAAM,CAAC,CAAC;gBACnG,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBACxD,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QAED,MAAM,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9E,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare class JsonCache {
2
+ private readonly rootDir;
3
+ constructor(rootDir?: string);
4
+ getOrSet<T>(namespace: string, keyParts: unknown, factory: () => Promise<T>): Promise<T>;
5
+ }
@@ -0,0 +1,27 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { hashJson } from './hash.js';
4
+ export class JsonCache {
5
+ rootDir;
6
+ constructor(rootDir = '.cache/skillcheck') {
7
+ this.rootDir = rootDir;
8
+ }
9
+ async getOrSet(namespace, keyParts, factory) {
10
+ const key = hashJson(keyParts);
11
+ const dir = path.join(this.rootDir, namespace);
12
+ const file = path.join(dir, `${key}.json`);
13
+ try {
14
+ return JSON.parse(await readFile(file, 'utf8'));
15
+ }
16
+ catch (error) {
17
+ if (error.code !== 'ENOENT') {
18
+ throw error;
19
+ }
20
+ }
21
+ const value = await factory();
22
+ await mkdir(dir, { recursive: true });
23
+ await writeFile(file, JSON.stringify(value, null, 2));
24
+ return value;
25
+ }
26
+ }
27
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../packages/cli/src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,OAAO,SAAS;IACS;IAA7B,YAA6B,UAAU,mBAAmB;QAA7B,YAAO,GAAP,OAAO,CAAsB;IAAG,CAAC;IAE9D,KAAK,CAAC,QAAQ,CAAI,SAAiB,EAAE,QAAiB,EAAE,OAAyB;QAC/E,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC;QAE3C,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAM,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,OAAO,EAAE,CAAC;QAC9B,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
@@ -0,0 +1 @@
1
+ export declare function main(argv: string[]): Promise<void>;