@michaelfromyeg/weft-index 1.0.0 → 1.2.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/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -134,7 +134,7 @@ interface PublishResult {
|
|
|
134
134
|
*/
|
|
135
135
|
declare function publishCheck(pluginDir: string, opts: {
|
|
136
136
|
registry: AdapterRegistry;
|
|
137
|
-
drivers: Record<Target, HarnessDriver
|
|
137
|
+
drivers: Partial<Record<Target, HarnessDriver>>;
|
|
138
138
|
/** Snapshot each harness's score into evals/.baselines/ for the next release. */
|
|
139
139
|
snapshot?: boolean;
|
|
140
140
|
}): Promise<PublishResult>;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/badges.ts","../src/build.ts","../src/client.ts","../src/federation.ts","../src/from-dirs.ts","../src/scan.ts","../src/publish.ts","../src/telemetry.ts"],"names":["lint"],"mappings":"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","file":"index.js","sourcesContent":["import type { EvalReport } from \"@michaelfromyeg/weft-eval\";\nimport type { Badge, Target } from \"@michaelfromyeg/weft-schema\";\n\nexport interface BadgeInputs {\n /** Static validation (the valid badge) passed. */\n validPassed: boolean;\n /** Reports from running the deterministic eval tier (trace + output). */\n evalReports?: EvalReport[];\n /** Security scan found nothing (the scanned badge). */\n scanClean?: boolean;\n /** A valid signature over the lockfile-hashed artifacts (the signed badge). */\n signatureValid?: boolean;\n /** Publisher namespace ownership proven (the verified badge). */\n ownershipVerified?: boolean;\n}\n\nexport interface BadgeResult {\n badges: Badge[];\n /** Harnesses with a passing deterministic run. */\n harnessCoverage: Target[];\n}\n\n/**\n * Compute the Phase 2 badges from validation + eval results (spec §10).\n * - `valid`: static/lint passes.\n * - `tested`: eval cases exist AND the deterministic tier passes on >= 1 harness;\n * `harnessCoverage` is the set of harnesses with a passing run. An UNTESTED\n * harness never counts -- honest coverage.\n * (`verified`/`scanned`/`signed` are computed in Phase 3.)\n */\nexport function computeBadges(input: BadgeInputs): BadgeResult {\n const badges: Badge[] = [];\n if (input.validPassed) badges.push(\"valid\");\n\n const coverage = new Set<Target>();\n let anyCases = false;\n let anyTestedPass = false;\n for (const report of input.evalReports ?? []) {\n for (const h of report.harnesses) {\n if (h.cases.length > 0) anyCases = true;\n if (h.status === \"tested\" && h.pass) {\n coverage.add(h.harness);\n anyTestedPass = true;\n }\n }\n }\n if (anyCases && anyTestedPass) badges.push(\"tested\");\n if (input.ownershipVerified) badges.push(\"verified\");\n if (input.scanClean) badges.push(\"scanned\");\n if (input.signatureValid) badges.push(\"signed\");\n\n return { badges, harnessCoverage: [...coverage] };\n}\n","import type { Badge, IndexEntry, IndexFile, Target } from \"@michaelfromyeg/weft-schema\";\n\nexport interface IndexPluginInput {\n id: string;\n source: string;\n version: string;\n ref: string;\n sha: string;\n badges: Badge[];\n harnessCoverage: Target[];\n telemetry?: { installs: number; activeUsage: number };\n}\n\n/**\n * Build a `weft.index/1` from per-version plugin metadata (spec §10). Entries are\n * grouped by id and accumulate versions; the index is metadata only -- it never\n * hosts plugin contents.\n */\nexport function buildIndex(\n plugins: IndexPluginInput[],\n federated?: IndexFile[\"federated\"],\n): IndexFile {\n const byId = new Map<string, IndexEntry>();\n for (const p of plugins) {\n const entry = byId.get(p.id) ?? { id: p.id, source: p.source, versions: [] };\n entry.versions.push({\n version: p.version,\n ref: p.ref,\n sha: p.sha,\n badges: p.badges,\n harnessCoverage: p.harnessCoverage,\n });\n if (p.telemetry) entry.telemetry = p.telemetry;\n byId.set(p.id, entry);\n }\n return {\n schema: \"weft.index/1\",\n plugins: [...byId.values()],\n ...(federated && federated.length > 0 ? { federated } : {}),\n };\n}\n\nexport function serializeIndex(index: IndexFile): string {\n return `${JSON.stringify(index, null, 2)}\\n`;\n}\n","import {\n type Badge,\n type IndexEntry,\n IndexFile,\n type IndexVersion,\n} from \"@michaelfromyeg/weft-schema\";\n\n/** Parse + validate a serialized index. */\nexport function loadIndex(text: string): IndexFile {\n return IndexFile.parse(JSON.parse(text));\n}\n\nexport function findPlugin(index: IndexFile, id: string): IndexEntry | undefined {\n return index.plugins.find((p) => p.id === id);\n}\n\n/** The last-listed version of an entry (publish order); undefined when none. */\nexport function latestVersion(entry: IndexEntry): IndexVersion | undefined {\n return entry.versions.at(-1);\n}\n\n/** Entries whose latest version carries a given badge. */\nexport function pluginsWithBadge(index: IndexFile, badge: Badge): IndexEntry[] {\n return index.plugins.filter((p) => latestVersion(p)?.badges.includes(badge));\n}\n","import type { IndexEntry, IndexFile } from \"@michaelfromyeg/weft-schema\";\n\n/** The inline server.json shape the MCP Registry serves (subset; spec §10). */\nexport interface McpServerJson {\n name: string;\n description?: string;\n version: string;\n repository?: { url?: string };\n}\nexport interface McpServerResponse {\n server: McpServerJson;\n _meta?: unknown;\n}\n\ntype FetchLike = (url: string) => Promise<{ json(): Promise<unknown> }>;\n\n/**\n * Fetch the official MCP Registry's `GET /v0.1/servers` (spec §10). `fetchImpl` is\n * injectable so tests run offline; the live default uses global fetch. We ingest\n * the registry's own scheme rather than reinventing it.\n */\nexport async function fetchMcpRegistry(\n opts: { baseUrl?: string; limit?: number; fetchImpl?: FetchLike } = {},\n): Promise<McpServerResponse[]> {\n const base = opts.baseUrl ?? \"https://registry.modelcontextprotocol.io\";\n const f = opts.fetchImpl ?? (globalThis.fetch as unknown as FetchLike);\n const res = await f(`${base}/v0.1/servers?limit=${opts.limit ?? 30}`);\n const data = (await res.json()) as { servers?: McpServerResponse[] };\n return data.servers ?? [];\n}\n\n/** Map MCP Registry servers into MCP-only index entries. */\nexport function mcpServersToEntries(servers: McpServerResponse[]): IndexEntry[] {\n return servers.map(({ server }) => ({\n id: server.name,\n source: server.repository?.url ?? \"mcp-registry\",\n versions: [\n {\n version: server.version,\n ref: server.version,\n sha: \"\",\n badges: [\"valid\"],\n harnessCoverage: [],\n },\n ],\n }));\n}\n\n/** Merge federated MCP entries into an index and stamp the ingestion. */\nexport function federate(\n index: IndexFile,\n servers: McpServerResponse[],\n ingestedAt: string,\n): IndexFile {\n const federated = [...(index.federated ?? []), { source: \"mcp-registry\", ingestedAt }];\n return { ...index, plugins: [...index.plugins, ...mcpServersToEntries(servers)], federated };\n}\n","import { gitInfo, lint } from \"@michaelfromyeg/weft-core\";\nimport type { IndexFile } from \"@michaelfromyeg/weft-schema\";\nimport { buildIndex, type IndexPluginInput } from \"./build\";\n\n/**\n * Build a metadata index from a set of plugin directories (spec §10, Phase 2\n * \"index builds from a set of plugins\"). Each plugin is statically validated for\n * the `valid` badge and stamped with its git ref/SHA. The richer `tested` badge\n * comes from the publish gate (which runs evals).\n */\nexport async function indexFromPluginDirs(\n dirs: string[],\n opts: { sourceFor?: (dir: string) => string } = {},\n): Promise<IndexFile> {\n const inputs: IndexPluginInput[] = [];\n for (const dir of dirs) {\n const linted = lint(dir);\n const { ref, sha } = await gitInfo(dir);\n inputs.push({\n id: linted.id,\n source: opts.sourceFor?.(dir) ?? dir,\n version: linted.plugin.version,\n ref,\n sha,\n badges: linted.diagnostics.hasErrors ? [] : [\"valid\"],\n harnessCoverage: [],\n });\n }\n return buildIndex(inputs);\n}\n","import { loadPluginDir } from \"@michaelfromyeg/weft-core\";\nimport { kindOf, refOf } from \"@michaelfromyeg/weft-schema\";\n\nexport interface ScanFinding {\n file: string;\n pattern: string;\n line: number;\n}\nexport interface ScanResult {\n clean: boolean;\n findings: ScanFinding[];\n}\n\n/**\n * A small built-in heuristic scanner for the `scanned` badge. It flags obviously\n * dangerous patterns in executable/hook/passthrough artifacts. Production would\n * also run garak / AI-Infra-Guard-style scanners; this is the offline default.\n */\nconst DANGEROUS: Array<{ re: RegExp; name: string }> = [\n { re: /rm\\s+-rf?\\s+[/~]/, name: \"recursive force delete of root/home\" },\n { re: /curl\\s+[^|]*\\|\\s*(sudo\\s+)?(ba)?sh/, name: \"curl-pipe-to-shell\" },\n { re: /wget\\s+[^|]*\\|\\s*(ba)?sh/, name: \"wget-pipe-to-shell\" },\n { re: /:\\(\\)\\s*\\{\\s*:\\s*\\|\\s*:&\\s*\\}\\s*;\\s*:/, name: \"fork bomb\" },\n { re: /\\b(AKIA[0-9A-Z]{16}|aws_secret_access_key)/i, name: \"embedded AWS credential\" },\n];\n\nexport function scanText(file: string, text: string): ScanFinding[] {\n const findings: ScanFinding[] = [];\n text.split(\"\\n\").forEach((line, i) => {\n for (const d of DANGEROUS) {\n if (d.re.test(line)) findings.push({ file, pattern: d.name, line: i + 1 });\n }\n });\n return findings;\n}\n\n/** Scan a plugin's executable/hook/passthrough artifacts (the `scanned` badge, §10). */\nexport function scanPlugin(pluginDir: string): ScanResult {\n const loaded = loadPluginDir(pluginDir);\n if (!loaded.ok) {\n return {\n clean: false,\n findings: [{ file: pluginDir, pattern: \"could not load plugin\", line: 0 }],\n };\n }\n const findings: ScanFinding[] = [];\n for (const c of loaded.value.plugin.components) {\n const kind = kindOf(c);\n if (kind !== \"hook\" && kind !== \"passthrough\") continue;\n const ref = refOf(c);\n const files = loaded.value.list(ref);\n for (const f of files.length > 0 ? files : [ref]) {\n try {\n findings.push(...scanText(f, loaded.value.read(f).toString(\"utf8\")));\n } catch {\n // unreadable artifact -- skip\n }\n }\n }\n return { clean: findings.length === 0, findings };\n}\n","import type { HarnessDriver } from \"@michaelfromyeg/weft-adapter-kit\";\nimport { type AdapterRegistry, type Diagnostic, lint } from \"@michaelfromyeg/weft-core\";\nimport { discoverEvals, type EvalReport, runEval } from \"@michaelfromyeg/weft-eval\";\nimport type { Badge, Target } from \"@michaelfromyeg/weft-schema\";\nimport { computeBadges } from \"./badges\";\nimport { type ScanResult, scanPlugin } from \"./scan\";\n\nexport interface PublishResult {\n id: string;\n version: string;\n /** The deterministic gate (spec §12): static valid + no failing trace/output runs. */\n ok: boolean;\n validPassed: boolean;\n evalFailed: boolean;\n badges: Badge[];\n harnessCoverage: Target[];\n diagnostics: Diagnostic[];\n evalReports: EvalReport[];\n scan: ScanResult;\n}\n\n/**\n * The deterministic publish gate (spec §9.1 step 9, §12): static validation always\n * runs and must pass; then every component's evals run against available harnesses,\n * and any FAILED trace/output run blocks the publish. Judge/differential are\n * advisory (reported `skipped`), and UNTESTED harnesses never block -- honest.\n */\nexport async function publishCheck(\n pluginDir: string,\n opts: {\n registry: AdapterRegistry;\n drivers: Record<Target, HarnessDriver>;\n /** Snapshot each harness's score into evals/.baselines/ for the next release. */\n snapshot?: boolean;\n },\n): Promise<PublishResult> {\n const linted = lint(pluginDir);\n const validPassed = !linted.diagnostics.hasErrors;\n\n const evalReports: EvalReport[] = [];\n if (validPassed) {\n for (const d of discoverEvals(pluginDir)) {\n evalReports.push(\n await runEval({\n evalFile: d.evalFile,\n pluginDir,\n componentLeaf: d.componentLeaf,\n registry: opts.registry,\n drivers: opts.drivers,\n snapshotBaselines: opts.snapshot,\n }),\n );\n }\n }\n\n const evalFailed = evalReports.some((r) =>\n r.harnesses.some((h) => h.status === \"tested\" && !h.pass),\n );\n const scan = validPassed ? scanPlugin(pluginDir) : { clean: false, findings: [] };\n const { badges, harnessCoverage } = computeBadges({\n validPassed,\n evalReports,\n scanClean: scan.clean,\n });\n\n return {\n id: linted.id,\n version: linted.plugin.version,\n ok: validPassed && !evalFailed,\n validPassed,\n evalFailed,\n badges,\n harnessCoverage,\n diagnostics: linted.diagnostics.items,\n evalReports,\n scan,\n };\n}\n","import type { IndexFile } from \"@michaelfromyeg/weft-schema\";\n\n/**\n * Opt-in, aggregate-only install record (spec §2, §10): increments an entry's\n * `installs`. There is no per-user data -- telemetry is a count, never identity.\n */\nexport function recordInstall(index: IndexFile, id: string): IndexFile {\n return {\n ...index,\n plugins: index.plugins.map((p) =>\n p.id === id\n ? {\n ...p,\n telemetry: {\n installs: (p.telemetry?.installs ?? 0) + 1,\n activeUsage: p.telemetry?.activeUsage ?? 0,\n },\n }\n : p,\n ),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/badges.ts","../src/build.ts","../src/client.ts","../src/federation.ts","../src/from-dirs.ts","../src/scan.ts","../src/publish.ts","../src/telemetry.ts"],"names":["lint"],"mappings":"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","file":"index.js","sourcesContent":["import type { EvalReport } from \"@michaelfromyeg/weft-eval\";\nimport type { Badge, Target } from \"@michaelfromyeg/weft-schema\";\n\nexport interface BadgeInputs {\n /** Static validation (the valid badge) passed. */\n validPassed: boolean;\n /** Reports from running the deterministic eval tier (trace + output). */\n evalReports?: EvalReport[];\n /** Security scan found nothing (the scanned badge). */\n scanClean?: boolean;\n /** A valid signature over the lockfile-hashed artifacts (the signed badge). */\n signatureValid?: boolean;\n /** Publisher namespace ownership proven (the verified badge). */\n ownershipVerified?: boolean;\n}\n\nexport interface BadgeResult {\n badges: Badge[];\n /** Harnesses with a passing deterministic run. */\n harnessCoverage: Target[];\n}\n\n/**\n * Compute the Phase 2 badges from validation + eval results (spec §10).\n * - `valid`: static/lint passes.\n * - `tested`: eval cases exist AND the deterministic tier passes on >= 1 harness;\n * `harnessCoverage` is the set of harnesses with a passing run. An UNTESTED\n * harness never counts -- honest coverage.\n * (`verified`/`scanned`/`signed` are computed in Phase 3.)\n */\nexport function computeBadges(input: BadgeInputs): BadgeResult {\n const badges: Badge[] = [];\n if (input.validPassed) badges.push(\"valid\");\n\n const coverage = new Set<Target>();\n let anyCases = false;\n let anyTestedPass = false;\n for (const report of input.evalReports ?? []) {\n for (const h of report.harnesses) {\n if (h.cases.length > 0) anyCases = true;\n if (h.status === \"tested\" && h.pass) {\n coverage.add(h.harness);\n anyTestedPass = true;\n }\n }\n }\n if (anyCases && anyTestedPass) badges.push(\"tested\");\n if (input.ownershipVerified) badges.push(\"verified\");\n if (input.scanClean) badges.push(\"scanned\");\n if (input.signatureValid) badges.push(\"signed\");\n\n return { badges, harnessCoverage: [...coverage] };\n}\n","import type { Badge, IndexEntry, IndexFile, Target } from \"@michaelfromyeg/weft-schema\";\n\nexport interface IndexPluginInput {\n id: string;\n source: string;\n version: string;\n ref: string;\n sha: string;\n badges: Badge[];\n harnessCoverage: Target[];\n telemetry?: { installs: number; activeUsage: number };\n}\n\n/**\n * Build a `weft.index/1` from per-version plugin metadata (spec §10). Entries are\n * grouped by id and accumulate versions; the index is metadata only -- it never\n * hosts plugin contents.\n */\nexport function buildIndex(\n plugins: IndexPluginInput[],\n federated?: IndexFile[\"federated\"],\n): IndexFile {\n const byId = new Map<string, IndexEntry>();\n for (const p of plugins) {\n const entry = byId.get(p.id) ?? { id: p.id, source: p.source, versions: [] };\n entry.versions.push({\n version: p.version,\n ref: p.ref,\n sha: p.sha,\n badges: p.badges,\n harnessCoverage: p.harnessCoverage,\n });\n if (p.telemetry) entry.telemetry = p.telemetry;\n byId.set(p.id, entry);\n }\n return {\n schema: \"weft.index/1\",\n plugins: [...byId.values()],\n ...(federated && federated.length > 0 ? { federated } : {}),\n };\n}\n\nexport function serializeIndex(index: IndexFile): string {\n return `${JSON.stringify(index, null, 2)}\\n`;\n}\n","import {\n type Badge,\n type IndexEntry,\n IndexFile,\n type IndexVersion,\n} from \"@michaelfromyeg/weft-schema\";\n\n/** Parse + validate a serialized index. */\nexport function loadIndex(text: string): IndexFile {\n return IndexFile.parse(JSON.parse(text));\n}\n\nexport function findPlugin(index: IndexFile, id: string): IndexEntry | undefined {\n return index.plugins.find((p) => p.id === id);\n}\n\n/** The last-listed version of an entry (publish order); undefined when none. */\nexport function latestVersion(entry: IndexEntry): IndexVersion | undefined {\n return entry.versions.at(-1);\n}\n\n/** Entries whose latest version carries a given badge. */\nexport function pluginsWithBadge(index: IndexFile, badge: Badge): IndexEntry[] {\n return index.plugins.filter((p) => latestVersion(p)?.badges.includes(badge));\n}\n","import type { IndexEntry, IndexFile } from \"@michaelfromyeg/weft-schema\";\n\n/** The inline server.json shape the MCP Registry serves (subset; spec §10). */\nexport interface McpServerJson {\n name: string;\n description?: string;\n version: string;\n repository?: { url?: string };\n}\nexport interface McpServerResponse {\n server: McpServerJson;\n _meta?: unknown;\n}\n\ntype FetchLike = (url: string) => Promise<{ json(): Promise<unknown> }>;\n\n/**\n * Fetch the official MCP Registry's `GET /v0.1/servers` (spec §10). `fetchImpl` is\n * injectable so tests run offline; the live default uses global fetch. We ingest\n * the registry's own scheme rather than reinventing it.\n */\nexport async function fetchMcpRegistry(\n opts: { baseUrl?: string; limit?: number; fetchImpl?: FetchLike } = {},\n): Promise<McpServerResponse[]> {\n const base = opts.baseUrl ?? \"https://registry.modelcontextprotocol.io\";\n const f = opts.fetchImpl ?? (globalThis.fetch as unknown as FetchLike);\n const res = await f(`${base}/v0.1/servers?limit=${opts.limit ?? 30}`);\n const data = (await res.json()) as { servers?: McpServerResponse[] };\n return data.servers ?? [];\n}\n\n/** Map MCP Registry servers into MCP-only index entries. */\nexport function mcpServersToEntries(servers: McpServerResponse[]): IndexEntry[] {\n return servers.map(({ server }) => ({\n id: server.name,\n source: server.repository?.url ?? \"mcp-registry\",\n versions: [\n {\n version: server.version,\n ref: server.version,\n sha: \"\",\n badges: [\"valid\"],\n harnessCoverage: [],\n },\n ],\n }));\n}\n\n/** Merge federated MCP entries into an index and stamp the ingestion. */\nexport function federate(\n index: IndexFile,\n servers: McpServerResponse[],\n ingestedAt: string,\n): IndexFile {\n const federated = [...(index.federated ?? []), { source: \"mcp-registry\", ingestedAt }];\n return { ...index, plugins: [...index.plugins, ...mcpServersToEntries(servers)], federated };\n}\n","import { gitInfo, lint } from \"@michaelfromyeg/weft-core\";\nimport type { IndexFile } from \"@michaelfromyeg/weft-schema\";\nimport { buildIndex, type IndexPluginInput } from \"./build\";\n\n/**\n * Build a metadata index from a set of plugin directories (spec §10, Phase 2\n * \"index builds from a set of plugins\"). Each plugin is statically validated for\n * the `valid` badge and stamped with its git ref/SHA. The richer `tested` badge\n * comes from the publish gate (which runs evals).\n */\nexport async function indexFromPluginDirs(\n dirs: string[],\n opts: { sourceFor?: (dir: string) => string } = {},\n): Promise<IndexFile> {\n const inputs: IndexPluginInput[] = [];\n for (const dir of dirs) {\n const linted = lint(dir);\n const { ref, sha } = await gitInfo(dir);\n inputs.push({\n id: linted.id,\n source: opts.sourceFor?.(dir) ?? dir,\n version: linted.plugin.version,\n ref,\n sha,\n badges: linted.diagnostics.hasErrors ? [] : [\"valid\"],\n harnessCoverage: [],\n });\n }\n return buildIndex(inputs);\n}\n","import { loadPluginDir } from \"@michaelfromyeg/weft-core\";\nimport { kindOf, refOf } from \"@michaelfromyeg/weft-schema\";\n\nexport interface ScanFinding {\n file: string;\n pattern: string;\n line: number;\n}\nexport interface ScanResult {\n clean: boolean;\n findings: ScanFinding[];\n}\n\n/**\n * A small built-in heuristic scanner for the `scanned` badge. It flags obviously\n * dangerous patterns in executable/hook/passthrough artifacts. Production would\n * also run garak / AI-Infra-Guard-style scanners; this is the offline default.\n */\nconst DANGEROUS: Array<{ re: RegExp; name: string }> = [\n { re: /rm\\s+-rf?\\s+[/~]/, name: \"recursive force delete of root/home\" },\n { re: /curl\\s+[^|]*\\|\\s*(sudo\\s+)?(ba)?sh/, name: \"curl-pipe-to-shell\" },\n { re: /wget\\s+[^|]*\\|\\s*(ba)?sh/, name: \"wget-pipe-to-shell\" },\n { re: /:\\(\\)\\s*\\{\\s*:\\s*\\|\\s*:&\\s*\\}\\s*;\\s*:/, name: \"fork bomb\" },\n { re: /\\b(AKIA[0-9A-Z]{16}|aws_secret_access_key)/i, name: \"embedded AWS credential\" },\n];\n\nexport function scanText(file: string, text: string): ScanFinding[] {\n const findings: ScanFinding[] = [];\n text.split(\"\\n\").forEach((line, i) => {\n for (const d of DANGEROUS) {\n if (d.re.test(line)) findings.push({ file, pattern: d.name, line: i + 1 });\n }\n });\n return findings;\n}\n\n/** Scan a plugin's executable/hook/passthrough artifacts (the `scanned` badge, §10). */\nexport function scanPlugin(pluginDir: string): ScanResult {\n const loaded = loadPluginDir(pluginDir);\n if (!loaded.ok) {\n return {\n clean: false,\n findings: [{ file: pluginDir, pattern: \"could not load plugin\", line: 0 }],\n };\n }\n const findings: ScanFinding[] = [];\n for (const c of loaded.value.plugin.components) {\n const kind = kindOf(c);\n if (kind !== \"hook\" && kind !== \"passthrough\") continue;\n const ref = refOf(c);\n const files = loaded.value.list(ref);\n for (const f of files.length > 0 ? files : [ref]) {\n try {\n findings.push(...scanText(f, loaded.value.read(f).toString(\"utf8\")));\n } catch {\n // unreadable artifact -- skip\n }\n }\n }\n return { clean: findings.length === 0, findings };\n}\n","import type { HarnessDriver } from \"@michaelfromyeg/weft-adapter-kit\";\nimport { type AdapterRegistry, type Diagnostic, lint } from \"@michaelfromyeg/weft-core\";\nimport { discoverEvals, type EvalReport, runEval } from \"@michaelfromyeg/weft-eval\";\nimport type { Badge, Target } from \"@michaelfromyeg/weft-schema\";\nimport { computeBadges } from \"./badges\";\nimport { type ScanResult, scanPlugin } from \"./scan\";\n\nexport interface PublishResult {\n id: string;\n version: string;\n /** The deterministic gate (spec §12): static valid + no failing trace/output runs. */\n ok: boolean;\n validPassed: boolean;\n evalFailed: boolean;\n badges: Badge[];\n harnessCoverage: Target[];\n diagnostics: Diagnostic[];\n evalReports: EvalReport[];\n scan: ScanResult;\n}\n\n/**\n * The deterministic publish gate (spec §9.1 step 9, §12): static validation always\n * runs and must pass; then every component's evals run against available harnesses,\n * and any FAILED trace/output run blocks the publish. Judge/differential are\n * advisory (reported `skipped`), and UNTESTED harnesses never block -- honest.\n */\nexport async function publishCheck(\n pluginDir: string,\n opts: {\n registry: AdapterRegistry;\n drivers: Partial<Record<Target, HarnessDriver>>;\n /** Snapshot each harness's score into evals/.baselines/ for the next release. */\n snapshot?: boolean;\n },\n): Promise<PublishResult> {\n const linted = lint(pluginDir);\n const validPassed = !linted.diagnostics.hasErrors;\n\n const evalReports: EvalReport[] = [];\n if (validPassed) {\n for (const d of discoverEvals(pluginDir)) {\n evalReports.push(\n await runEval({\n evalFile: d.evalFile,\n pluginDir,\n componentLeaf: d.componentLeaf,\n registry: opts.registry,\n drivers: opts.drivers,\n snapshotBaselines: opts.snapshot,\n }),\n );\n }\n }\n\n const evalFailed = evalReports.some((r) =>\n r.harnesses.some((h) => h.status === \"tested\" && !h.pass),\n );\n const scan = validPassed ? scanPlugin(pluginDir) : { clean: false, findings: [] };\n const { badges, harnessCoverage } = computeBadges({\n validPassed,\n evalReports,\n scanClean: scan.clean,\n });\n\n return {\n id: linted.id,\n version: linted.plugin.version,\n ok: validPassed && !evalFailed,\n validPassed,\n evalFailed,\n badges,\n harnessCoverage,\n diagnostics: linted.diagnostics.items,\n evalReports,\n scan,\n };\n}\n","import type { IndexFile } from \"@michaelfromyeg/weft-schema\";\n\n/**\n * Opt-in, aggregate-only install record (spec §2, §10): increments an entry's\n * `installs`. There is no per-user data -- telemetry is a count, never identity.\n */\nexport function recordInstall(index: IndexFile, id: string): IndexFile {\n return {\n ...index,\n plugins: index.plugins.map((p) =>\n p.id === id\n ? {\n ...p,\n telemetry: {\n installs: (p.telemetry?.installs ?? 0) + 1,\n activeUsage: p.telemetry?.activeUsage ?? 0,\n },\n }\n : p,\n ),\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michaelfromyeg/weft-index",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Weft metadata index: builder, client, MCP-Registry federation, badges, publish gate.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@michaelfromyeg/weft-
|
|
20
|
-
"@michaelfromyeg/weft-
|
|
21
|
-
"@michaelfromyeg/weft-
|
|
22
|
-
"@michaelfromyeg/weft-
|
|
19
|
+
"@michaelfromyeg/weft-adapter-kit": "1.2.0",
|
|
20
|
+
"@michaelfromyeg/weft-schema": "1.2.0",
|
|
21
|
+
"@michaelfromyeg/weft-eval": "1.2.0",
|
|
22
|
+
"@michaelfromyeg/weft-core": "1.2.0"
|
|
23
23
|
},
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"author": "Michael DeMarco",
|