@zibby/skills 0.1.90 → 0.1.91

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.
@@ -0,0 +1,163 @@
1
+ export function sizeBucket(added: any, deleted: any): string;
2
+ export function fileExtension(path: any): string;
3
+ export function extKind(ext: any): any;
4
+ /**
5
+ * commit_facts — deterministic per-commit facts from its changed-file list.
6
+ * `files` is [{ path|newPath|filename, additions?, deletions? }] (the shapes
7
+ * gitlab_get_commit / github_get_commit already return). Pure.
8
+ */
9
+ export function commitFacts(files: any, opts?: {}): {
10
+ filesChanged: number;
11
+ filePaths: string[];
12
+ extCounts: {};
13
+ kindCounts: {
14
+ code: number;
15
+ test: number;
16
+ docs: number;
17
+ config: number;
18
+ style: number;
19
+ data: number;
20
+ other: number;
21
+ };
22
+ additions: number;
23
+ deletions: number;
24
+ sizeBucket: string;
25
+ largestFile: string;
26
+ dirs: string[];
27
+ };
28
+ /**
29
+ * glob_hit — how many of `paths` match ANY of `globs`. Deterministic. Supports
30
+ * `**` (any depth), `*` (one segment, no slash), `?` (one char). The customer's
31
+ * own core-path globs (e.g. "src/payment/**") are passed at REPORT time — this
32
+ * makes "who works in the core" a reproducible number, not an LLM guess.
33
+ */
34
+ export function globToRegExp(glob: any): RegExp;
35
+ export function globHit(paths: any, globs: any): {
36
+ total: number;
37
+ hits: number;
38
+ ratio: number;
39
+ matched: string[];
40
+ };
41
+ /**
42
+ * percentile — the reproducible, cross-team-comparable rank of `value` within
43
+ * `values` (0-100, "% of the cohort at or below value"). Ties count at-or-below
44
+ * (the standard cumulative rank). Empty cohort → null (undefined, not a lie).
45
+ */
46
+ export function percentileRank(values: any, value: any): number;
47
+ export namespace codeStatsSkill {
48
+ let id: string;
49
+ let serverName: string;
50
+ let allowedTools: string[];
51
+ let description: string;
52
+ let promptFragment: string;
53
+ function resolve(): {
54
+ command: any;
55
+ args: any[];
56
+ env: {};
57
+ description: string;
58
+ type?: undefined;
59
+ alwaysLoad?: undefined;
60
+ } | {
61
+ type: string;
62
+ command: string;
63
+ args: any[];
64
+ env: {};
65
+ description: string;
66
+ alwaysLoad: boolean;
67
+ };
68
+ function handleToolCall(name: any, args: any): Promise<string>;
69
+ let tools: ({
70
+ name: string;
71
+ description: string;
72
+ input_schema: {
73
+ type: string;
74
+ properties: {
75
+ files: {
76
+ type: string;
77
+ description: string;
78
+ items: {
79
+ type: string;
80
+ properties: {
81
+ path: {
82
+ type: string;
83
+ };
84
+ additions: {
85
+ type: string;
86
+ };
87
+ deletions: {
88
+ type: string;
89
+ };
90
+ };
91
+ };
92
+ };
93
+ additions: {
94
+ type: string;
95
+ description: string;
96
+ };
97
+ deletions: {
98
+ type: string;
99
+ description: string;
100
+ };
101
+ paths?: undefined;
102
+ globs?: undefined;
103
+ values?: undefined;
104
+ value?: undefined;
105
+ };
106
+ required: string[];
107
+ };
108
+ } | {
109
+ name: string;
110
+ description: string;
111
+ input_schema: {
112
+ type: string;
113
+ properties: {
114
+ paths: {
115
+ type: string;
116
+ items: {
117
+ type: string;
118
+ };
119
+ description: string;
120
+ };
121
+ globs: {
122
+ type: string;
123
+ items: {
124
+ type: string;
125
+ };
126
+ description: string;
127
+ };
128
+ files?: undefined;
129
+ additions?: undefined;
130
+ deletions?: undefined;
131
+ values?: undefined;
132
+ value?: undefined;
133
+ };
134
+ required: string[];
135
+ };
136
+ } | {
137
+ name: string;
138
+ description: string;
139
+ input_schema: {
140
+ type: string;
141
+ properties: {
142
+ values: {
143
+ type: string;
144
+ items: {
145
+ type: string;
146
+ };
147
+ description: string;
148
+ };
149
+ value: {
150
+ type: string;
151
+ description: string;
152
+ };
153
+ files?: undefined;
154
+ additions?: undefined;
155
+ deletions?: undefined;
156
+ paths?: undefined;
157
+ globs?: undefined;
158
+ };
159
+ required: string[];
160
+ };
161
+ })[];
162
+ }
163
+ export default codeStatsSkill;
@@ -0,0 +1,19 @@
1
+ import{existsSync as _}from"fs";import{fileURLToPath as v}from"url";import{dirname as x,resolve as k}from"path";function w(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let s=x(v(import.meta.url)),e=k(s,"..","bin","mcp-skill.mjs");return _(e)?e:null}var S=[{name:"trivial",max:5},{name:"small",max:30},{name:"medium",max:150},{name:"large",max:600},{name:"huge",max:1/0}];function N(s,e){let t=(Number(s)||0)+(Number(e)||0);for(let o of S)if(t<=o.max)return o.name;return"huge"}function T(s){let t=String(s||"").toLowerCase().split("/").pop()||"",o=t.match(/\.(test|spec)\.[a-z0-9]+$/);if(o)return`.${o[1]}`;let i=t.lastIndexOf(".");return i<=0?/^(dockerfile|makefile|jenkinsfile|procfile|gemfile|rakefile)$/i.test(t)?t.toLowerCase():"":t.slice(i)}var C={code:[".js",".jsx",".ts",".tsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".rb",".php",".c",".cc",".cpp",".h",".hpp",".cs",".swift",".scala",".m",".dart",".ex",".exs",".clj",".sh",".bash"],test:[".test",".spec"],docs:[".md",".mdx",".rst",".txt",".adoc"],config:[".json",".yml",".yaml",".toml",".ini",".env",".cfg",".conf",".lock",".xml",".properties","dockerfile","makefile","jenkinsfile","procfile",".tf",".gradle"],style:[".css",".scss",".sass",".less",".styl"],data:[".csv",".tsv",".sql",".parquet",".proto",".graphql",".gql"]},P=(()=>{let s={};for(let[e,t]of Object.entries(C))for(let o of t)s[o]=e;return s})();function j(s){return P[String(s||"").toLowerCase()]||"other"}function E(s,e={}){let t=Array.isArray(s)?s:[],o=[],i={},n={code:0,test:0,docs:0,config:0,style:0,data:0,other:0},a=0,m=0,c={path:"",changed:-1};for(let r of t){if(!r||typeof r!="object")continue;let l=String(r.path||r.newPath||r.filename||r.new_path||"").trim();if(!l)continue;o.push(l);let g=Number(r.additions??r.add??0)||0,b=Number(r.deletions??r.del??0)||0;a+=g,m+=b;let d=T(l);i[d||"(none)"]=(i[d||"(none)"]||0)+1,n[j(d)]+=1;let y=g+b;y>c.changed&&(c={path:l,changed:y})}let p=Number(e.additions),u=Number(e.deletions),h=Number.isFinite(p)?p:a,f=Number.isFinite(u)?u:m;return{filesChanged:o.length,filePaths:o,extCounts:i,kindCounts:n,additions:h,deletions:f,sizeBucket:N(h,f),largestFile:c.path||null,dirs:[...new Set(o.map(r=>r.includes("/")?r.split("/")[0]:"(root)"))].sort()}}function O(s){let e="",t=String(s||"");for(let o=0;o<t.length;o++){let i=t[o];i==="*"?t[o+1]==="*"?(e+=".*",o++,t[o+1]==="/"&&o++):e+="[^/]*":i==="?"?e+="[^/]":"\\^$.|+()[]{}".includes(i)?e+=`\\${i}`:e+=i}return new RegExp(`^${e}$`)}function A(s,e){let t=Array.isArray(s)?s.map(String):[],o=(Array.isArray(e)?e:[]).filter(Boolean).map(O);if(!o.length)return{total:t.length,hits:0,ratio:0,matched:[]};let i=t.filter(n=>o.some(a=>a.test(n)));return{total:t.length,hits:i.length,ratio:t.length?Number((i.length/t.length).toFixed(4)):0,matched:i}}function L(s,e){let t=(Array.isArray(s)?s:[]).map(Number).filter(n=>Number.isFinite(n)),o=Number(e);if(!t.length||!Number.isFinite(o))return null;let i=t.filter(n=>n<=o).length;return Number((i/t.length*100).toFixed(1))}var R={id:"code-stats",serverName:"code_stats",allowedTools:["mcp__code_stats__*"],description:"Deterministic code statistics \u2014 pure, reproducible facts from changed-file lists + numbers (extension/work-kind mix, size bucket, core-path glob coverage, percentile rank). Zero LLM, zero network.",promptFragment:`## Code Stats (DETERMINISTIC facts \u2014 pure, reproducible, zero-LLM)
2
+ These tools COMPUTE reproducible facts from data you already have. Use them so
3
+ your numbers are auditable and survive challenge (same input \u2192 same output).
4
+
5
+ Tools:
6
+ - code_stats_commit_facts: Given a commit's changed \`files\` list
7
+ ([{path, additions, deletions}] \u2014 exactly what gitlab_get_commit /
8
+ github_get_commit return), returns { filePaths, extCounts, kindCounts
9
+ (code/test/docs/config/style/data/other), additions, deletions, sizeBucket,
10
+ largestFile, dirs }. Call this for EVERY commit you meter and PERSIST the raw
11
+ facts (filePaths as JSON, kindCounts, sizeBucket) \u2014 they're free now and let
12
+ any later analysis run without re-fetching.
13
+ - code_stats_glob_hit: Given \`paths\` + \`globs\` (e.g. ["src/payment/**",
14
+ "auth/**"]), returns { hits, ratio, matched }. Use at REPORT time to compute
15
+ each person's CORE-PATH coverage against the caller's own core globs \u2014 a
16
+ reproducible "works in the core vs the edges" number.
17
+ - code_stats_percentile: Given \`values\` (a cohort's numbers) + a \`value\`,
18
+ returns the 0-100 percentile rank. Use to express every metric as a rank
19
+ within the team (reproducible + comparable across teams), not a raw number.`,resolve(){let s=w();return s?{type:"stdio",command:"node",args:[s,"../dist/codeStats.js","codeStatsSkill"],env:{},description:this.description,alwaysLoad:!0}:{command:null,args:[],env:{},description:this.description}},async handleToolCall(s,e){try{switch(s){case"code_stats_commit_facts":return JSON.stringify(E(e?.files,{additions:e?.additions,deletions:e?.deletions}));case"code_stats_glob_hit":return JSON.stringify(A(e?.paths,e?.globs));case"code_stats_percentile":return JSON.stringify({percentile:L(e?.values,e?.value)});default:return JSON.stringify({error:`Unknown tool: ${s}`})}}catch(t){return JSON.stringify({error:t.message})}},tools:[{name:"code_stats_commit_facts",description:"Deterministic per-commit facts from its changed-file list. Pass files: [{path, additions, deletions}] (gitlab_get_commit / github_get_commit shape). Returns filePaths, extCounts, kindCounts (code/test/docs/config/style/data/other), additions, deletions, sizeBucket (trivial/small/medium/large/huge), largestFile, dirs. Pure \u2014 same input always same output.",input_schema:{type:"object",properties:{files:{type:"array",description:"Changed files. Each { path (or newPath/filename), additions?, deletions? }.",items:{type:"object",properties:{path:{type:"string"},additions:{type:"number"},deletions:{type:"number"}}}},additions:{type:"number",description:"Optional commit-level total additions override (else summed from files)."},deletions:{type:"number",description:"Optional commit-level total deletions override."}},required:["files"]}},{name:"code_stats_glob_hit",description:"How many of paths match ANY of globs (supports **, *, ?). Returns { total, hits, ratio, matched }. Use for reproducible core-path coverage against the caller's own core globs.",input_schema:{type:"object",properties:{paths:{type:"array",items:{type:"string"},description:"File paths to test."},globs:{type:"array",items:{type:"string"},description:'Glob patterns, e.g. ["src/payment/**", "auth/**"].'}},required:["paths","globs"]}},{name:"code_stats_percentile",description:'The 0-100 percentile rank of value within values (cumulative "% at or below"). Reproducible + cross-team comparable. Empty cohort \u2192 null.',input_schema:{type:"object",properties:{values:{type:"array",items:{type:"number"},description:"The cohort's numbers."},value:{type:"number",description:"The value to rank."}},required:["values","value"]}}]},B=R;export{R as codeStatsSkill,E as commitFacts,B as default,j as extKind,T as fileExtension,A as globHit,O as globToRegExp,L as percentileRank,N as sizeBucket};
package/dist/index.d.ts CHANGED
@@ -25,6 +25,7 @@ import { kvMemorySkill } from './kvMemory.js';
25
25
  import { datasetStoreSkill } from './datasetStore.js';
26
26
  import { artifactSkill } from './artifact.js';
27
27
  import { chartRenderSkill } from './chartRender.js';
28
+ import { codeStatsSkill } from './codeStats.js';
28
29
  import { socialCardSkill } from './socialCard.js';
29
30
  import { codeScanSkill } from './code-scan.js';
30
31
  import { codebaseMemorySkill } from './codebaseMemory.js';
@@ -33,7 +34,7 @@ import { testRunnerSkill } from './test-runner.js';
33
34
  import { skillInstallerSkill } from './skill-installer.js';
34
35
  import { coreToolsSkill } from './core-tools.js';
35
36
  import { workflowBuilderSkill } from './workflow-builder.js';
36
- export { browserSkill, jiraSkill, githubSkill, gitlabSkill, figmaSkill, hubspotSkill, linearSkill, planeSkill, opendesignSkill, gitSkill, gitWriteSkill, slackSkill, larkSkill, discordSkill, notionSkill, linkedinSkill, googleDocsSkill, larkDocsSkill, chatNotifySkill, sentrySkill, memorySkill, chatMemorySkill, kvMemorySkill, datasetStoreSkill, artifactSkill, chartRenderSkill, socialCardSkill, codeScanSkill, codebaseMemorySkill, gbrainSkill, testRunnerSkill, testRunnerSkill as runnerSkill, skillInstallerSkill, coreToolsSkill, workflowBuilderSkill };
37
+ export { browserSkill, jiraSkill, githubSkill, gitlabSkill, figmaSkill, hubspotSkill, linearSkill, planeSkill, opendesignSkill, gitSkill, gitWriteSkill, slackSkill, larkSkill, discordSkill, notionSkill, linkedinSkill, googleDocsSkill, larkDocsSkill, chatNotifySkill, sentrySkill, memorySkill, chatMemorySkill, kvMemorySkill, datasetStoreSkill, artifactSkill, chartRenderSkill, codeStatsSkill, socialCardSkill, codeScanSkill, codebaseMemorySkill, gbrainSkill, testRunnerSkill, testRunnerSkill as runnerSkill, skillInstallerSkill, coreToolsSkill, workflowBuilderSkill };
37
38
  export { openaiBillingSkill, anthropicBillingSkill, cursorAdminSkill, fetchOpenAICosts, fetchOpenAIProjects, fetchAnthropicCosts, fetchAnthropicWorkspaces, fetchCursorSpend, fetchAllProviders, groupByKey, meanStddev } from "./llm-billing.js";
38
39
  export { reportObjectSchema, reportToBlockKit, reportToLarkCard, reportToNotionBlocks, reportToMarkdown, SEVERITIES as REPORT_SEVERITIES } from "./report.js";
39
40
  export { skill, functionSkill } from "./function-skill.js";