vskill 1.2.0 → 1.2.2
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/agents.json +1 -1
- package/dist/api/client.js +7 -6
- package/dist/api/client.js.map +1 -1
- package/dist/blocklist/blocklist.d.ts +12 -0
- package/dist/blocklist/blocklist.js +19 -0
- package/dist/blocklist/blocklist.js.map +1 -1
- package/dist/commands/add.js +71 -43
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/auth.js +32 -1
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/diff.js +8 -0
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/eval/run.js +5 -0
- package/dist/commands/eval/run.js.map +1 -1
- package/dist/commands/info.js +7 -0
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/outdated.js +24 -7
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/pin.js +7 -2
- package/dist/commands/pin.js.map +1 -1
- package/dist/commands/submit.js +8 -0
- package/dist/commands/submit.js.map +1 -1
- package/dist/commands/update.js +14 -5
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/versions.js +11 -0
- package/dist/commands/versions.js.map +1 -1
- package/dist/discovery/github-tree.js +14 -2
- package/dist/discovery/github-tree.js.map +1 -1
- package/dist/eval/anthropic-catalog.d.ts +7 -1
- package/dist/eval/anthropic-catalog.js +81 -8
- package/dist/eval/anthropic-catalog.js.map +1 -1
- package/dist/eval/credential-resolver.js +5 -3
- package/dist/eval/credential-resolver.js.map +1 -1
- package/dist/eval/integration-runner.js +4 -4
- package/dist/eval/integration-runner.js.map +1 -1
- package/dist/eval/llm.d.ts +2 -0
- package/dist/eval/llm.js +39 -8
- package/dist/eval/llm.js.map +1 -1
- package/dist/eval/model-catalog.d.ts +27 -0
- package/dist/eval/model-catalog.js +101 -0
- package/dist/eval/model-catalog.js.map +1 -0
- package/dist/eval/pricing.d.ts +5 -0
- package/dist/eval/pricing.js +16 -2
- package/dist/eval/pricing.js.map +1 -1
- package/dist/eval/test-case-parser.js +35 -16
- package/dist/eval/test-case-parser.js.map +1 -1
- package/dist/eval-server/api-routes.d.ts +2 -10
- package/dist/eval-server/api-routes.js +35 -85
- package/dist/eval-server/api-routes.js.map +1 -1
- package/dist/eval-server/install-skill-routes.d.ts +2 -0
- package/dist/eval-server/install-skill-routes.js +7 -0
- package/dist/eval-server/install-skill-routes.js.map +1 -1
- package/dist/eval-server/model-compare-routes.js +4 -2
- package/dist/eval-server/model-compare-routes.js.map +1 -1
- package/dist/eval-server/oauth-github-routes.js +32 -2
- package/dist/eval-server/oauth-github-routes.js.map +1 -1
- package/dist/eval-server/origin-resolver.d.ts +6 -0
- package/dist/eval-server/origin-resolver.js +35 -5
- package/dist/eval-server/origin-resolver.js.map +1 -1
- package/dist/eval-server/platform-proxy.d.ts +3 -3
- package/dist/eval-server/platform-proxy.js +10 -25
- package/dist/eval-server/platform-proxy.js.map +1 -1
- package/dist/eval-server/skill-create-routes.d.ts +1 -1
- package/dist/eval-server/skill-create-routes.js +1 -71
- package/dist/eval-server/skill-create-routes.js.map +1 -1
- package/dist/eval-server/skill-md-emitter.d.ts +17 -0
- package/dist/eval-server/skill-md-emitter.js +70 -0
- package/dist/eval-server/skill-md-emitter.js.map +1 -0
- package/dist/eval-server/studio-privacy.d.ts +26 -0
- package/dist/eval-server/studio-privacy.js +129 -0
- package/dist/eval-server/studio-privacy.js.map +1 -0
- package/dist/eval-ui/assets/{AdvancedTab-DOgbx7u0.js → AdvancedTab-CSWhj_MZ.js} +1 -1
- package/dist/eval-ui/assets/{CreateSkillPage-ENMve2K8.js → CreateSkillPage-BJzNKgad.js} +1 -1
- package/dist/eval-ui/assets/{FindSkillsPalette-BMVKCk6E.js → FindSkillsPalette-XckIggJi.js} +2 -2
- package/dist/eval-ui/assets/{GeneralTab-AwK9sIkP.js → GeneralTab-Gbc-K6UI.js} +1 -1
- package/dist/eval-ui/assets/{PrivacyTab-BtNrxpVV.js → PrivacyTab-BXCIX8cQ.js} +1 -1
- package/dist/eval-ui/assets/SearchPaletteCore-CTZ8CI14.js +14 -0
- package/dist/eval-ui/assets/SkillDetailPanel-NPnDnA3H.js +1 -0
- package/dist/eval-ui/assets/{UpdateDropdown-C4BH7W_M.js → UpdateDropdown-CPP1t9LD.js} +1 -1
- package/dist/eval-ui/assets/{UpdatesTab-DTmo-vVb.js → UpdatesTab-BFGUaUtu.js} +1 -1
- package/dist/eval-ui/assets/{main-tzMA8J07.js → main-jiMosYzo.js} +40 -41
- package/dist/eval-ui/assets/{preferences-DCdw0Kvu.js → preferences-D2BPT0OT.js} +2 -2
- package/dist/eval-ui/assets/useDesktopBridge-BKz-gcRg.js +2 -0
- package/dist/eval-ui/index.html +2 -2
- package/dist/eval-ui/preferences.html +2 -2
- package/dist/lib/frontmatter.d.ts +2 -5
- package/dist/lib/frontmatter.js +15 -40
- package/dist/lib/frontmatter.js.map +1 -1
- package/dist/lib/github-fetch.d.ts +2 -0
- package/dist/lib/github-fetch.js +27 -1
- package/dist/lib/github-fetch.js.map +1 -1
- package/dist/lib/keychain.js +8 -1
- package/dist/lib/keychain.js.map +1 -1
- package/dist/lib/private-source.d.ts +77 -0
- package/dist/lib/private-source.js +392 -0
- package/dist/lib/private-source.js.map +1 -0
- package/dist/lib/repo-visibility.d.ts +16 -0
- package/dist/lib/repo-visibility.js +43 -3
- package/dist/lib/repo-visibility.js.map +1 -1
- package/dist/utils/version.d.ts +5 -10
- package/dist/utils/version.js +82 -40
- package/dist/utils/version.js.map +1 -1
- package/package.json +1 -1
- package/dist/eval-ui/assets/SearchPaletteCore-C9G-ySXc.js +0 -14
- package/dist/eval-ui/assets/SkillDetailPanel-BCJj8p79.js +0 -1
- package/dist/eval-ui/assets/useDesktopBridge-9oZFQsrw.js +0 -2
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Shared provider picker catalog. Explicit new IDs do not change saved/default choices.
|
|
2
|
+
import { ANTHROPIC_CATALOG_SNAPSHOT, findAnthropicModel } from "./anthropic-catalog.js";
|
|
3
|
+
// Verified 2026-10-09 against https://developers.openai.com/api/docs/models/
|
|
4
|
+
// gpt-6.1-sol, gpt-6-astra and gpt-6-luna. Standard short-context pricing;
|
|
5
|
+
// above 272K input tokens, the full request costs 2x input and 1.5x output.
|
|
6
|
+
export const CURRENT_OPENAI_MODELS = [
|
|
7
|
+
{ id: "gpt-6.1-sol", displayName: "GPT-6.1 Sol", inputPerMillion: 2, outputPerMillion: 10 },
|
|
8
|
+
{ id: "gpt-6-astra", displayName: "GPT-6 Astra", inputPerMillion: 10, outputPerMillion: 50 },
|
|
9
|
+
{ id: "gpt-6-luna", displayName: "GPT-6 Luna", inputPerMillion: 0.1, outputPerMillion: 0.5 },
|
|
10
|
+
];
|
|
11
|
+
// 0711 — Anthropic models + pricing now derive from the dated catalog
|
|
12
|
+
// snapshot at `src/eval/anthropic-catalog.ts`. Manual maintenance of this
|
|
13
|
+
// list led to stale prices (Opus 4.7 shown at $15/$75 instead of $5/$25)
|
|
14
|
+
// because three different files held copies of the same fact. The catalog
|
|
15
|
+
// file is the single source of truth; CI fails if its snapshotDate is
|
|
16
|
+
// older than 6 months.
|
|
17
|
+
function buildAnthropicProviderModels() {
|
|
18
|
+
return ANTHROPIC_CATALOG_SNAPSHOT.models
|
|
19
|
+
.filter((m) => m.status === "active")
|
|
20
|
+
.map((m) => ({
|
|
21
|
+
id: m.id,
|
|
22
|
+
label: `${m.displayName} (API)${m.pricing.longContext ? " · base rate ≤100K input" : ""}`,
|
|
23
|
+
pricing: {
|
|
24
|
+
prompt: m.pricing.promptUsdPer1M,
|
|
25
|
+
completion: m.pricing.completionUsdPer1M,
|
|
26
|
+
},
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
function aliasInfo(alias, fallbackLabel) {
|
|
30
|
+
const entry = findAnthropicModel(alias);
|
|
31
|
+
if (!entry)
|
|
32
|
+
return { label: fallbackLabel };
|
|
33
|
+
return { label: entry.displayName, resolvedId: entry.id };
|
|
34
|
+
}
|
|
35
|
+
export const PROVIDER_MODELS = {
|
|
36
|
+
// Opus first so it is the default when no override is set
|
|
37
|
+
// (getEffectiveRawModel returns models[0]). Labels come from the catalog so
|
|
38
|
+
// the picker shows the exact dated version (e.g. "Claude Opus 4.7"), not the
|
|
39
|
+
// bare family name — keeps the Studio truthful when a model is bumped.
|
|
40
|
+
"claude-cli": [
|
|
41
|
+
{ id: "opus", ...aliasInfo("opus", "Claude Opus") },
|
|
42
|
+
{ id: "sonnet", ...aliasInfo("sonnet", "Claude Sonnet") },
|
|
43
|
+
{ id: "haiku", ...aliasInfo("haiku", "Claude Haiku") },
|
|
44
|
+
...ANTHROPIC_CATALOG_SNAPSHOT.models
|
|
45
|
+
.filter((m) => m.capabilities.includes("modern_thinking_budget"))
|
|
46
|
+
.map((m) => ({ id: m.id, label: m.displayName, resolvedId: m.id })),
|
|
47
|
+
],
|
|
48
|
+
"anthropic": buildAnthropicProviderModels(),
|
|
49
|
+
// Ollama's model list is dynamic — populated by probeOllama() from GET
|
|
50
|
+
// /api/tags. Empty by default (parity with "lm-studio") so an unreachable
|
|
51
|
+
// or timed-out probe surfaces zero models instead of leaking a hardcoded
|
|
52
|
+
// fallback that isn't actually installed (0876 US-001).
|
|
53
|
+
"ollama": [],
|
|
54
|
+
"gemini-cli": [
|
|
55
|
+
{ id: "gemini-2.5-pro", label: "Gemini 2.5 Pro" },
|
|
56
|
+
{ id: "gemini-2.5-flash", label: "Gemini 2.5 Flash" },
|
|
57
|
+
],
|
|
58
|
+
"codex-cli": [
|
|
59
|
+
{ id: "o3", label: "OpenAI o3" },
|
|
60
|
+
{ id: "o4-mini", label: "OpenAI o4-mini" },
|
|
61
|
+
...CURRENT_OPENAI_MODELS.map((m) => ({ id: m.id, label: m.displayName })),
|
|
62
|
+
],
|
|
63
|
+
"openai": [
|
|
64
|
+
{ id: "gpt-4o-mini", label: "GPT-4o mini (API)", pricing: { prompt: 0.15, completion: 0.60 } },
|
|
65
|
+
{ id: "gpt-4o", label: "GPT-4o (API)", pricing: { prompt: 2.50, completion: 10 } },
|
|
66
|
+
{ id: "gpt-4.1", label: "GPT-4.1 (API)", pricing: { prompt: 2, completion: 8 } },
|
|
67
|
+
{ id: "gpt-4.1-mini", label: "GPT-4.1 mini (API)", pricing: { prompt: 0.40, completion: 1.60 } },
|
|
68
|
+
{ id: "o4-mini", label: "o4-mini (API)", pricing: { prompt: 1.10, completion: 4.40 } },
|
|
69
|
+
...CURRENT_OPENAI_MODELS.map((m) => ({
|
|
70
|
+
id: m.id, label: `${m.displayName} (API) · base rate ≤272K input`,
|
|
71
|
+
pricing: { prompt: m.inputPerMillion, completion: m.outputPerMillion },
|
|
72
|
+
})),
|
|
73
|
+
],
|
|
74
|
+
"openrouter": [
|
|
75
|
+
// Anthropic via OpenRouter
|
|
76
|
+
{ id: "anthropic/claude-opus-4", label: "Claude Opus 4 (via OpenRouter)" },
|
|
77
|
+
{ id: "anthropic/claude-sonnet-4", label: "Claude Sonnet 4 (via OpenRouter)" },
|
|
78
|
+
{ id: "anthropic/claude-haiku-4", label: "Claude Haiku 4 (via OpenRouter)" },
|
|
79
|
+
// OpenAI via OpenRouter (0698 polish — Anton wants OpenAI first-class)
|
|
80
|
+
{ id: "openai/gpt-5", label: "GPT-5 (via OpenRouter)" },
|
|
81
|
+
{ id: "openai/gpt-5-mini", label: "GPT-5 mini (via OpenRouter)" },
|
|
82
|
+
{ id: "openai/o4-mini", label: "o4-mini (via OpenRouter)" },
|
|
83
|
+
{ id: "openai/o3", label: "OpenAI o3 (via OpenRouter)" },
|
|
84
|
+
{ id: "openai/gpt-4.1", label: "GPT-4.1 (via OpenRouter)" },
|
|
85
|
+
// Google + Meta
|
|
86
|
+
{ id: "google/gemini-2.5-pro", label: "Gemini 2.5 Pro (via OpenRouter)" },
|
|
87
|
+
{ id: "google/gemini-2.5-flash", label: "Gemini 2.5 Flash (via OpenRouter)" },
|
|
88
|
+
{ id: "meta-llama/llama-3.3-70b-instruct", label: "Llama 3.3 70B (via OpenRouter)" },
|
|
89
|
+
],
|
|
90
|
+
// LM Studio's default model list is empty because the actual list depends on
|
|
91
|
+
// what models the user has loaded. The probe at probeLmStudio() populates
|
|
92
|
+
// this dynamically from GET /v1/models.
|
|
93
|
+
"lm-studio": [],
|
|
94
|
+
// 0857: `stub` is a deterministic TEST SEAM (src/eval/llm.ts createStubClient),
|
|
95
|
+
// NOT a user-facing provider. This empty list exists only to satisfy the
|
|
96
|
+
// `Record<ProviderName, ModelOption[]>` exhaustiveness check — `stub` is
|
|
97
|
+
// deliberately excluded from `detectAvailableProviders()` and
|
|
98
|
+
// `KNOWN_PROVIDER_NAMES`, so it never reaches /api/config or the picker.
|
|
99
|
+
"stub": [],
|
|
100
|
+
};
|
|
101
|
+
//# sourceMappingURL=model-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-catalog.js","sourceRoot":"","sources":["../../src/eval/model-catalog.ts"],"names":[],"mappings":"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"}
|
package/dist/eval/pricing.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ export interface ModelPricing {
|
|
|
3
3
|
inputPerMillion: number;
|
|
4
4
|
outputPerMillion: number;
|
|
5
5
|
updatedAt: string;
|
|
6
|
+
longContext?: {
|
|
7
|
+
aboveInputTokens: number;
|
|
8
|
+
inputPerMillion: number;
|
|
9
|
+
outputPerMillion: number;
|
|
10
|
+
};
|
|
6
11
|
}
|
|
7
12
|
/**
|
|
8
13
|
* Get the billing mode for a provider.
|
package/dist/eval/pricing.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// catalog (tracked in 0711 follow-ups).
|
|
8
8
|
// ---------------------------------------------------------------------------
|
|
9
9
|
import { ANTHROPIC_CATALOG_SNAPSHOT } from "./anthropic-catalog.js";
|
|
10
|
+
import { CURRENT_OPENAI_MODELS } from "./model-catalog.js";
|
|
10
11
|
// ---------------------------------------------------------------------------
|
|
11
12
|
// Pricing table — update rates here when providers change pricing
|
|
12
13
|
// ---------------------------------------------------------------------------
|
|
@@ -17,6 +18,11 @@ function buildAnthropicPricing() {
|
|
|
17
18
|
inputPerMillion: m.pricing.promptUsdPer1M,
|
|
18
19
|
outputPerMillion: m.pricing.completionUsdPer1M,
|
|
19
20
|
updatedAt: ANTHROPIC_CATALOG_SNAPSHOT.snapshotDate,
|
|
21
|
+
...(m.pricing.longContext ? { longContext: {
|
|
22
|
+
aboveInputTokens: m.pricing.longContext.aboveInputTokens,
|
|
23
|
+
inputPerMillion: m.pricing.longContext.promptUsdPer1M,
|
|
24
|
+
outputPerMillion: m.pricing.longContext.completionUsdPer1M,
|
|
25
|
+
} } : {}),
|
|
20
26
|
};
|
|
21
27
|
}
|
|
22
28
|
return out;
|
|
@@ -24,6 +30,12 @@ function buildAnthropicPricing() {
|
|
|
24
30
|
const PRICING = {
|
|
25
31
|
anthropic: buildAnthropicPricing(),
|
|
26
32
|
openai: {
|
|
33
|
+
...Object.fromEntries(CURRENT_OPENAI_MODELS.map((m) => [m.id, {
|
|
34
|
+
inputPerMillion: m.inputPerMillion,
|
|
35
|
+
outputPerMillion: m.outputPerMillion,
|
|
36
|
+
updatedAt: "2026-10-09",
|
|
37
|
+
longContext: { aboveInputTokens: 272_000, inputPerMillion: 2 * m.inputPerMillion, outputPerMillion: 1.5 * m.outputPerMillion },
|
|
38
|
+
}])),
|
|
27
39
|
"o4-mini": { inputPerMillion: 1.10, outputPerMillion: 4.40, updatedAt: "2025-05-01" },
|
|
28
40
|
"gpt-4.1": { inputPerMillion: 2, outputPerMillion: 8, updatedAt: "2025-05-01" },
|
|
29
41
|
"gpt-4.1-mini": { inputPerMillion: 0.40, outputPerMillion: 1.60, updatedAt: "2025-05-01" },
|
|
@@ -125,8 +137,10 @@ export function calculateCost(provider, model, inputTokens, outputTokens) {
|
|
|
125
137
|
const pricing = getProviderPricing(provider, model);
|
|
126
138
|
if (!pricing)
|
|
127
139
|
return null;
|
|
128
|
-
const
|
|
129
|
-
|
|
140
|
+
const rates = pricing.longContext && inputTokens > pricing.longContext.aboveInputTokens
|
|
141
|
+
? pricing.longContext : pricing;
|
|
142
|
+
const inputCost = (inputTokens / 1_000_000) * rates.inputPerMillion;
|
|
143
|
+
const outputCost = (outputTokens / 1_000_000) * rates.outputPerMillion;
|
|
130
144
|
return inputCost + outputCost;
|
|
131
145
|
}
|
|
132
146
|
/**
|
package/dist/eval/pricing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../src/eval/pricing.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,8EAA8E;AAC9E,EAAE;AACF,yEAAyE;AACzE,0EAA0E;AAC1E,qEAAqE;AACrE,wCAAwC;AACxC,8EAA8E;AAE9E,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../src/eval/pricing.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
//
|
|
9
9
|
// See increment 0776 for the why.
|
|
10
10
|
// ---------------------------------------------------------------------------
|
|
11
|
-
const
|
|
11
|
+
const HEADING_RE = /^## Test Cases[ \t]*\r?\n/im;
|
|
12
12
|
const PAIR_RE = /-\s*Prompt:\s*"([^"]+)"\s*\n\s*Expected:\s*"([^"]+)"/gi;
|
|
13
13
|
export function parseTestCases(content) {
|
|
14
14
|
if (!content)
|
|
15
15
|
return [];
|
|
16
|
-
const
|
|
17
|
-
if (!
|
|
16
|
+
const bounds = findSection(content);
|
|
17
|
+
if (!bounds)
|
|
18
18
|
return [];
|
|
19
|
-
const section =
|
|
19
|
+
const section = content.slice(bounds.bodyStart, bounds.end);
|
|
20
20
|
const cases = [];
|
|
21
21
|
// Reset lastIndex via a fresh regex each call to keep this function pure
|
|
22
22
|
const pair = new RegExp(PAIR_RE.source, "gi");
|
|
@@ -36,25 +36,44 @@ export function serializeTestCases(prompts) {
|
|
|
36
36
|
// section entirely (keeps SKILL.md clean when the author clears fixtures).
|
|
37
37
|
export function upsertTestCasesIntoSkillMd(content, prompts) {
|
|
38
38
|
const trimmed = content.replace(/\s+$/, "");
|
|
39
|
-
const
|
|
39
|
+
const section = findSection(trimmed);
|
|
40
40
|
if (prompts.length === 0) {
|
|
41
|
-
if (!
|
|
41
|
+
if (!section)
|
|
42
42
|
return content;
|
|
43
|
-
return
|
|
43
|
+
return (trimmed.slice(0, section.start) + trimmed.slice(section.end))
|
|
44
|
+
.replace(/\n{3,}/g, "\n\n").trimEnd() + "\n";
|
|
44
45
|
}
|
|
45
46
|
const block = serializeTestCases(prompts).trimEnd();
|
|
46
|
-
if (
|
|
47
|
-
|
|
47
|
+
if (section) {
|
|
48
|
+
// Slices preserve literal $&, $` and $' in user-authored prompts.
|
|
49
|
+
return trimmed.slice(0, section.start) + block + trimmed.slice(section.end) + "\n";
|
|
48
50
|
}
|
|
49
51
|
return trimmed + "\n\n" + block + "\n";
|
|
50
52
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
/** Locate real section boundaries, ignoring headings inside a quoted prompt.
|
|
54
|
+
* Keep raw prompt text for compatibility with existing published SKILL.md files.
|
|
55
|
+
*/
|
|
56
|
+
function findSection(content) {
|
|
57
|
+
const heading = HEADING_RE.exec(content);
|
|
58
|
+
if (!heading)
|
|
59
|
+
return null;
|
|
60
|
+
const bodyStart = heading.index + heading[0].length;
|
|
61
|
+
const body = content.slice(bodyStart);
|
|
62
|
+
const pairs = [...body.matchAll(new RegExp(PAIR_RE.source, "gi"))];
|
|
63
|
+
const boundaries = body.matchAll(/^##[ \t]+|^---[ \t]*(?:\r?$)/gm);
|
|
64
|
+
for (const boundary of boundaries) {
|
|
65
|
+
const index = boundary.index;
|
|
66
|
+
if (pairs.some((pair) => index >= pair.index && index < pair.index + pair[0].length))
|
|
67
|
+
continue;
|
|
68
|
+
// Leave the newline before the next heading intact when replacing.
|
|
69
|
+
let end = bodyStart + index;
|
|
70
|
+
if (content[end - 1] === "\n")
|
|
71
|
+
end--;
|
|
72
|
+
if (content[end - 1] === "\r")
|
|
73
|
+
end--;
|
|
74
|
+
return { start: heading.index, bodyStart, end };
|
|
75
|
+
}
|
|
76
|
+
return { start: heading.index, bodyStart, end: content.length };
|
|
58
77
|
}
|
|
59
78
|
function textToExpected(raw) {
|
|
60
79
|
const norm = raw.trim().toLowerCase();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-case-parser.js","sourceRoot":"","sources":["../../src/eval/test-case-parser.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6EAA6E;AAC7E,EAAE;AACF,0DAA0D;AAC1D,2EAA2E;AAC3E,+EAA+E;AAC/E,mEAAmE;AACnE,EAAE;AACF,kCAAkC;AAClC,8EAA8E;AAS9E,MAAM,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"test-case-parser.js","sourceRoot":"","sources":["../../src/eval/test-case-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Router } from "./router.js";
|
|
2
2
|
import type { SkillInfo } from "../eval/skill-scanner.js";
|
|
3
|
+
import { type ModelOption } from "../eval/model-catalog.js";
|
|
4
|
+
export { PROVIDER_MODELS } from "../eval/model-catalog.js";
|
|
3
5
|
import type { ProviderName } from "../eval/llm.js";
|
|
4
6
|
import type { AgentDefinition } from "../agents/agents-registry.js";
|
|
5
7
|
export interface InstalledAgentEntry {
|
|
@@ -159,16 +161,6 @@ export declare function buildSkillMetadata(skillDir: string, origin: "source" |
|
|
|
159
161
|
* vitest can simulate a fresh server boot per-case.
|
|
160
162
|
*/
|
|
161
163
|
export declare function resetStudioRestoreState(): void;
|
|
162
|
-
interface ModelOption {
|
|
163
|
-
id: string;
|
|
164
|
-
label: string;
|
|
165
|
-
pricing?: {
|
|
166
|
-
prompt: number;
|
|
167
|
-
completion: number;
|
|
168
|
-
};
|
|
169
|
-
resolvedId?: string;
|
|
170
|
-
}
|
|
171
|
-
export declare const PROVIDER_MODELS: Record<ProviderName, ModelOption[]>;
|
|
172
164
|
type OpenRouterCacheEntry = {
|
|
173
165
|
value: Array<{
|
|
174
166
|
id: string;
|
|
@@ -12,6 +12,8 @@ import { classifyError } from "./error-classifier.js";
|
|
|
12
12
|
import { readLockfile, writeLockfile } from "../lockfile/lockfile.js";
|
|
13
13
|
import { resolveSkillApiName as resolveSkillApiNameImpl } from "./skill-name-resolver.js";
|
|
14
14
|
import { resolveSkillOrigin } from "./origin-resolver.js";
|
|
15
|
+
import { isPrivateOrUnknownRepo } from "../lib/private-source.js";
|
|
16
|
+
import { isPrivateStudioSkill, isPrivateStudioSkillAt, readStudioLocks } from "./studio-privacy.js";
|
|
15
17
|
import { runBenchmarkSSE, runSingleCaseSSE } from "./benchmark-runner.js";
|
|
16
18
|
import { getSkillSemaphore } from "./concurrency.js";
|
|
17
19
|
import { resolveSkillDir, resolveAllowedSkillDir } from "./skill-resolver.js";
|
|
@@ -26,7 +28,8 @@ import { classifyOrigin, scanSkillsTriScope, dedupeByDir } from "../eval/skill-s
|
|
|
26
28
|
import { scanInstalledPluginSkills, scanAuthoredPluginSkills, } from "../eval/plugin-scanner.js";
|
|
27
29
|
import { resolveGlobalSkillsDir } from "../eval/path-utils.js";
|
|
28
30
|
import { loadAndValidateEvals, EvalValidationError } from "../eval/schema.js";
|
|
29
|
-
import {
|
|
31
|
+
import { PROVIDER_MODELS } from "../eval/model-catalog.js";
|
|
32
|
+
export { PROVIDER_MODELS } from "../eval/model-catalog.js";
|
|
30
33
|
import { readBenchmark } from "../eval/benchmark.js";
|
|
31
34
|
import { writeHistoryEntry, listHistory, readHistoryEntry, computeRegressions, deleteHistoryEntry, getCaseHistory, computeStats } from "../eval/benchmark-history.js";
|
|
32
35
|
import { judgeAssertion } from "../eval/judge.js";
|
|
@@ -856,88 +859,6 @@ function computeBenchmarkStatus(benchmark, evalIds, hasEvals) {
|
|
|
856
859
|
// Use overall_pass_rate as single source of truth
|
|
857
860
|
return (benchmark.overall_pass_rate ?? 0) >= 1 ? "pass" : "fail";
|
|
858
861
|
}
|
|
859
|
-
// 0711 — Anthropic models + pricing now derive from the dated catalog
|
|
860
|
-
// snapshot at `src/eval/anthropic-catalog.ts`. Manual maintenance of this
|
|
861
|
-
// list led to stale prices (Opus 4.7 shown at $15/$75 instead of $5/$25)
|
|
862
|
-
// because three different files held copies of the same fact. The catalog
|
|
863
|
-
// file is the single source of truth; CI fails if its snapshotDate is
|
|
864
|
-
// older than 6 months.
|
|
865
|
-
function buildAnthropicProviderModels() {
|
|
866
|
-
return ANTHROPIC_CATALOG_SNAPSHOT.models
|
|
867
|
-
.filter((m) => m.status === "active")
|
|
868
|
-
.map((m) => ({
|
|
869
|
-
id: m.id,
|
|
870
|
-
label: `${m.displayName} (API)`,
|
|
871
|
-
pricing: {
|
|
872
|
-
prompt: m.pricing.promptUsdPer1M,
|
|
873
|
-
completion: m.pricing.completionUsdPer1M,
|
|
874
|
-
},
|
|
875
|
-
}));
|
|
876
|
-
}
|
|
877
|
-
function aliasInfo(alias, fallbackLabel) {
|
|
878
|
-
const entry = findAnthropicModel(alias);
|
|
879
|
-
if (!entry)
|
|
880
|
-
return { label: fallbackLabel };
|
|
881
|
-
return { label: entry.displayName, resolvedId: entry.id };
|
|
882
|
-
}
|
|
883
|
-
export const PROVIDER_MODELS = {
|
|
884
|
-
// Opus first so it is the default when no override is set
|
|
885
|
-
// (getEffectiveRawModel returns models[0]). Labels come from the catalog so
|
|
886
|
-
// the picker shows the exact dated version (e.g. "Claude Opus 4.7"), not the
|
|
887
|
-
// bare family name — keeps the Studio truthful when a model is bumped.
|
|
888
|
-
"claude-cli": [
|
|
889
|
-
{ id: "opus", ...aliasInfo("opus", "Claude Opus") },
|
|
890
|
-
{ id: "sonnet", ...aliasInfo("sonnet", "Claude Sonnet") },
|
|
891
|
-
{ id: "haiku", ...aliasInfo("haiku", "Claude Haiku") },
|
|
892
|
-
],
|
|
893
|
-
"anthropic": buildAnthropicProviderModels(),
|
|
894
|
-
// Ollama's model list is dynamic — populated by probeOllama() from GET
|
|
895
|
-
// /api/tags. Empty by default (parity with "lm-studio") so an unreachable
|
|
896
|
-
// or timed-out probe surfaces zero models instead of leaking a hardcoded
|
|
897
|
-
// fallback that isn't actually installed (0876 US-001).
|
|
898
|
-
"ollama": [],
|
|
899
|
-
"gemini-cli": [
|
|
900
|
-
{ id: "gemini-2.5-pro", label: "Gemini 2.5 Pro" },
|
|
901
|
-
{ id: "gemini-2.5-flash", label: "Gemini 2.5 Flash" },
|
|
902
|
-
],
|
|
903
|
-
"codex-cli": [
|
|
904
|
-
{ id: "o3", label: "OpenAI o3" },
|
|
905
|
-
{ id: "o4-mini", label: "OpenAI o4-mini" },
|
|
906
|
-
],
|
|
907
|
-
"openai": [
|
|
908
|
-
{ id: "gpt-4o-mini", label: "GPT-4o mini (API)", pricing: { prompt: 0.15, completion: 0.60 } },
|
|
909
|
-
{ id: "gpt-4o", label: "GPT-4o (API)", pricing: { prompt: 2.50, completion: 10 } },
|
|
910
|
-
{ id: "gpt-4.1", label: "GPT-4.1 (API)", pricing: { prompt: 2, completion: 8 } },
|
|
911
|
-
{ id: "gpt-4.1-mini", label: "GPT-4.1 mini (API)", pricing: { prompt: 0.40, completion: 1.60 } },
|
|
912
|
-
{ id: "o4-mini", label: "o4-mini (API)", pricing: { prompt: 1.10, completion: 4.40 } },
|
|
913
|
-
],
|
|
914
|
-
"openrouter": [
|
|
915
|
-
// Anthropic via OpenRouter
|
|
916
|
-
{ id: "anthropic/claude-opus-4", label: "Claude Opus 4 (via OpenRouter)" },
|
|
917
|
-
{ id: "anthropic/claude-sonnet-4", label: "Claude Sonnet 4 (via OpenRouter)" },
|
|
918
|
-
{ id: "anthropic/claude-haiku-4", label: "Claude Haiku 4 (via OpenRouter)" },
|
|
919
|
-
// OpenAI via OpenRouter (0698 polish — Anton wants OpenAI first-class)
|
|
920
|
-
{ id: "openai/gpt-5", label: "GPT-5 (via OpenRouter)" },
|
|
921
|
-
{ id: "openai/gpt-5-mini", label: "GPT-5 mini (via OpenRouter)" },
|
|
922
|
-
{ id: "openai/o4-mini", label: "o4-mini (via OpenRouter)" },
|
|
923
|
-
{ id: "openai/o3", label: "OpenAI o3 (via OpenRouter)" },
|
|
924
|
-
{ id: "openai/gpt-4.1", label: "GPT-4.1 (via OpenRouter)" },
|
|
925
|
-
// Google + Meta
|
|
926
|
-
{ id: "google/gemini-2.5-pro", label: "Gemini 2.5 Pro (via OpenRouter)" },
|
|
927
|
-
{ id: "google/gemini-2.5-flash", label: "Gemini 2.5 Flash (via OpenRouter)" },
|
|
928
|
-
{ id: "meta-llama/llama-3.3-70b-instruct", label: "Llama 3.3 70B (via OpenRouter)" },
|
|
929
|
-
],
|
|
930
|
-
// LM Studio's default model list is empty because the actual list depends on
|
|
931
|
-
// what models the user has loaded. The probe at probeLmStudio() populates
|
|
932
|
-
// this dynamically from GET /v1/models.
|
|
933
|
-
"lm-studio": [],
|
|
934
|
-
// 0857: `stub` is a deterministic TEST SEAM (src/eval/llm.ts createStubClient),
|
|
935
|
-
// NOT a user-facing provider. This empty list exists only to satisfy the
|
|
936
|
-
// `Record<ProviderName, ModelOption[]>` exhaustiveness check — `stub` is
|
|
937
|
-
// deliberately excluded from `detectAvailableProviders()` and
|
|
938
|
-
// `KNOWN_PROVIDER_NAMES`, so it never reaches /api/config or the picker.
|
|
939
|
-
"stub": [],
|
|
940
|
-
};
|
|
941
862
|
// ---------------------------------------------------------------------------
|
|
942
863
|
// Local provider detection caches — avoid 500ms+ probes on every /api/config
|
|
943
864
|
// request. Without the caches, page load blocks on the timeout when the
|
|
@@ -1561,6 +1482,10 @@ export function registerRoutes(router, rootArg, projectName) {
|
|
|
1561
1482
|
// overwrites currentVersion. Stamping it server-side from the lockfile
|
|
1562
1483
|
// collapses the race so badges render their final source on first paint.
|
|
1563
1484
|
const lockForCurrentVersion = readLockfile(root);
|
|
1485
|
+
// Skills from a private repo (or one GitHub does not confirm is public)
|
|
1486
|
+
// are flagged so the Studio never sends them to the platform; see
|
|
1487
|
+
// studio-privacy.ts for how installed, plugin and authored skills map.
|
|
1488
|
+
const studioLocks = readStudioLocks(root);
|
|
1564
1489
|
const enriched = await Promise.all(skills.map(async (s) => {
|
|
1565
1490
|
let evalCount = 0;
|
|
1566
1491
|
let assertionCount = 0;
|
|
@@ -1583,9 +1508,11 @@ export function registerRoutes(router, rootArg, projectName) {
|
|
|
1583
1508
|
// currentVersion=null — the resolver then falls through to frontmatter,
|
|
1584
1509
|
// preserving non-italic styling for author-declared versions.
|
|
1585
1510
|
const currentVersion = lockForCurrentVersion?.skills?.[s.skill]?.version ?? null;
|
|
1511
|
+
const sourcePrivate = await isPrivateStudioSkill({ ...s, origin }, studioLocks);
|
|
1586
1512
|
return {
|
|
1587
1513
|
...s,
|
|
1588
1514
|
origin,
|
|
1515
|
+
...(sourcePrivate ? { sourcePrivate: true } : {}),
|
|
1589
1516
|
scope: s.scope ?? (origin === "installed" ? "installed" : "own"),
|
|
1590
1517
|
isSymlink: s.isSymlink ?? false,
|
|
1591
1518
|
symlinkTarget: s.symlinkTarget ?? null,
|
|
@@ -1740,6 +1667,12 @@ export function registerRoutes(router, rootArg, projectName) {
|
|
|
1740
1667
|
// `/versions/diff` as needed.
|
|
1741
1668
|
async function buildSkillApiPath(skill, plugin) {
|
|
1742
1669
|
const origin = await resolveSkillOrigin(skill, plugin, getRoot());
|
|
1670
|
+
// Private (or unconfirmed) skills never reach the platform: lockfile
|
|
1671
|
+
// entries (incl. plugin installs), authored skills in private checkouts,
|
|
1672
|
+
// and installed skills nobody recorded.
|
|
1673
|
+
if (origin.private || (await isPrivateStudioSkillAt(skill, plugin, getRoot()))) {
|
|
1674
|
+
return { apiPathRoot: null, origin };
|
|
1675
|
+
}
|
|
1743
1676
|
if (origin.owner && origin.repo) {
|
|
1744
1677
|
return {
|
|
1745
1678
|
apiPathRoot: `/api/v1/skills/${encodeURIComponent(origin.owner)}/${encodeURIComponent(origin.repo)}/${encodeURIComponent(skill)}`,
|
|
@@ -1750,6 +1683,9 @@ export function registerRoutes(router, rootArg, projectName) {
|
|
|
1750
1683
|
// whose origin comes from a git remote, not a lockfile.
|
|
1751
1684
|
const fullName = await resolveSkillApiName(skill, plugin);
|
|
1752
1685
|
const parts = fullName.split("/");
|
|
1686
|
+
if (parts.length === 3 && (await isPrivateOrUnknownRepo(parts[0], parts[1]))) {
|
|
1687
|
+
return { apiPathRoot: null, origin };
|
|
1688
|
+
}
|
|
1753
1689
|
const apiPathRoot = parts.length === 3
|
|
1754
1690
|
? `/api/v1/skills/${parts.map(encodeURIComponent).join("/")}`
|
|
1755
1691
|
: `/api/v1/skills/${encodeURIComponent(fullName)}`;
|
|
@@ -1759,7 +1695,6 @@ export function registerRoutes(router, rootArg, projectName) {
|
|
|
1759
1695
|
const root = getRoot();
|
|
1760
1696
|
// 0823: comprehensive origin resolver via shared buildSkillApiPath.
|
|
1761
1697
|
const { apiPathRoot, origin } = await buildSkillApiPath(params.skill, params.plugin);
|
|
1762
|
-
const apiPath = `${apiPathRoot}/versions`;
|
|
1763
1698
|
const emptyEnvelope = () => {
|
|
1764
1699
|
res.setHeader("X-Skill-VCS", "unavailable");
|
|
1765
1700
|
sendJson(res, {
|
|
@@ -1770,6 +1705,13 @@ export function registerRoutes(router, rootArg, projectName) {
|
|
|
1770
1705
|
trackedForUpdates: false,
|
|
1771
1706
|
}, 200, req);
|
|
1772
1707
|
};
|
|
1708
|
+
// A skill from a private (or unconfirmed) repo has no platform history,
|
|
1709
|
+
// and its name and repo must not be sent there.
|
|
1710
|
+
if (apiPathRoot === null) {
|
|
1711
|
+
emptyEnvelope();
|
|
1712
|
+
return;
|
|
1713
|
+
}
|
|
1714
|
+
const apiPath = `${apiPathRoot}/versions`;
|
|
1773
1715
|
let fetchResp;
|
|
1774
1716
|
try {
|
|
1775
1717
|
fetchResp = await fetch(`${PLATFORM_BASE}${apiPath}`, {
|
|
@@ -1859,6 +1801,10 @@ export function registerRoutes(router, rootArg, projectName) {
|
|
|
1859
1801
|
// so Anthropic-shipped skills (slack-messaging, pptx, etc.) get the
|
|
1860
1802
|
// matching upstream URL for diff requests, not the legacy bare-name path.
|
|
1861
1803
|
const { apiPathRoot } = await buildSkillApiPath(params.skill, params.plugin);
|
|
1804
|
+
if (apiPathRoot === null) {
|
|
1805
|
+
sendJson(res, { error: "This skill comes from a private repository; version diffs are not available from verified-skill.com." }, 404, req);
|
|
1806
|
+
return;
|
|
1807
|
+
}
|
|
1862
1808
|
const basePath = `${apiPathRoot}/versions/diff`;
|
|
1863
1809
|
try {
|
|
1864
1810
|
const resp = await fetch(`${PLATFORM_BASE}${basePath}?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`, { signal: AbortSignal.timeout(10_000) });
|
|
@@ -1964,7 +1910,11 @@ export function registerRoutes(router, rootArg, projectName) {
|
|
|
1964
1910
|
let versions = [];
|
|
1965
1911
|
try {
|
|
1966
1912
|
const origin = await resolveSkillOrigin(skill, plugin, root);
|
|
1967
|
-
|
|
1913
|
+
// Private (or unconfirmed) skills never reach the platform.
|
|
1914
|
+
if (!origin.private &&
|
|
1915
|
+
origin.owner &&
|
|
1916
|
+
origin.repo &&
|
|
1917
|
+
!(await isPrivateStudioSkillAt(skill, plugin, root))) {
|
|
1968
1918
|
const apiPath = `/api/v1/skills/${encodeURIComponent(origin.owner)}/${encodeURIComponent(origin.repo)}/${encodeURIComponent(skill)}/versions`;
|
|
1969
1919
|
try {
|
|
1970
1920
|
const fetchResp = await fetch(`${PLATFORM_BASE}${apiPath}`, {
|