@zibby/skills 0.1.95 → 0.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.
Files changed (78) hide show
  1. package/README.md +1 -1
  2. package/dist/artifact.d.ts +1 -115
  3. package/dist/browser.d.ts +10 -19
  4. package/dist/chartRender.d.ts +46 -57
  5. package/dist/chartRender.js +1 -1
  6. package/dist/chat-memory.d.ts +26 -330
  7. package/dist/chat-notify.d.ts +30 -409
  8. package/dist/chat-notify.js +3 -3
  9. package/dist/chatProgress.d.ts +28 -47
  10. package/dist/code-scan.d.ts +52 -58
  11. package/dist/codeStats.d.ts +36 -136
  12. package/dist/codeStats.js +1 -1
  13. package/dist/codebaseMemory.d.ts +52 -32
  14. package/dist/codebaseMemory.js +2 -2
  15. package/dist/core-tools.d.ts +10 -131
  16. package/dist/datasetStore.d.ts +52 -179
  17. package/dist/datasetStore.js +12 -3
  18. package/dist/discord.d.ts +32 -68
  19. package/dist/figma.d.ts +5 -408
  20. package/dist/function-skill.d.ts +23 -135
  21. package/dist/function-skill.js +1 -1
  22. package/dist/gbrain.d.ts +46 -114
  23. package/dist/git-write.d.ts +45 -137
  24. package/dist/git-write.js +6 -6
  25. package/dist/git.d.ts +2 -73
  26. package/dist/github.d.ts +2 -1202
  27. package/dist/gitlab.d.ts +55 -1059
  28. package/dist/gitlab.js +2 -2
  29. package/dist/googleDocs.d.ts +39 -175
  30. package/dist/hubspot.d.ts +1 -381
  31. package/dist/index.d.ts +19 -12
  32. package/dist/index.js +157 -148
  33. package/dist/integrations.d.ts +2 -2
  34. package/dist/jira.d.ts +2 -532
  35. package/dist/jira.js +4 -4
  36. package/dist/kvMemory.d.ts +47 -78
  37. package/dist/lark.d.ts +2 -161
  38. package/dist/lark.js +1 -1
  39. package/dist/larkDocs.d.ts +35 -236
  40. package/dist/linear.d.ts +36 -343
  41. package/dist/linkedin.d.ts +10 -120
  42. package/dist/llm-billing.d.ts +92 -180
  43. package/dist/llm-billing.js +1 -1
  44. package/dist/memory.d.ts +11 -137
  45. package/dist/notion.d.ts +28 -276
  46. package/dist/notion.js +4 -4
  47. package/dist/opendesign.d.ts +24 -202
  48. package/dist/opendesign.js +2 -2
  49. package/dist/package.json +3 -2
  50. package/dist/plane.d.ts +40 -24
  51. package/dist/report.d.ts +153 -110
  52. package/dist/review-dedup.d.ts +8 -8
  53. package/dist/review.d.ts +12 -2
  54. package/dist/reviewMemoryIo.d.ts +37 -3
  55. package/dist/reviewRecord.d.ts +41 -47
  56. package/dist/sentry.d.ts +25 -22
  57. package/dist/skill-installer.d.ts +11 -86
  58. package/dist/slack.d.ts +1 -284
  59. package/dist/socialCard.d.ts +35 -89
  60. package/dist/test-runner.d.ts +1 -220
  61. package/dist/trackers/github-adapter.d.ts +39 -94
  62. package/dist/trackers/index.d.ts +25 -18
  63. package/dist/trackers/jira-adapter.d.ts +20 -88
  64. package/dist/trackers/linear-adapter.d.ts +24 -87
  65. package/dist/trackers/plane-adapter.d.ts +29 -85
  66. package/dist/trackers/plane-adapter.js +1 -1
  67. package/dist/trackers/types.d.ts +1 -186
  68. package/dist/triggerAgent.d.ts +26 -42
  69. package/dist/triggerAgent.js +1 -1
  70. package/dist/workflow-builder.d.ts +11 -245
  71. package/docs/cli-reference.md +33 -0
  72. package/docs/concepts/designing-agents.md +201 -0
  73. package/docs/self-host/backup-restore.md +52 -0
  74. package/docs/self-host/index.md +75 -0
  75. package/docs/self-host/storage.md +50 -0
  76. package/docs/self-host/troubleshooting.md +48 -0
  77. package/docs/self-host/upgrade.md +81 -0
  78. package/package.json +3 -2
@@ -1,3 +1,47 @@
1
+ /**
2
+ * code-scan.js — AGENT-DRIVEN, stack-smart deterministic code scanner (tier ①:
3
+ * fully local — the code never leaves the box; no API, no OAuth, no browser).
4
+ *
5
+ * WHAT IT IS
6
+ * ──────────
7
+ * A hand-written single-tool skill (same shape as chartRender.js / kvMemory.js):
8
+ * `serverName`, `allowedTools`, `tools[]`, `handleToolCall`, and a `resolve()`
9
+ * that spawns the GENERIC bin/mcp-skill.mjs. The ONE tool — `scan_code` — is
10
+ * called by the AGENT after it has a repo on disk (a clone). It AUTO-DETECTS the
11
+ * stack and runs the matching deterministic linter(s), returning structured
12
+ * findings the agent triages.
13
+ *
14
+ * WHY A SKILL, NOT A FLOOR PROBE
15
+ * ──────────────────────────────
16
+ * The code-review agent is GENERAL-PURPOSE (Go, Python, Rust, Java, JS/TS, …).
17
+ * A language-specific linter therefore CANNOT be an always-run deterministic
18
+ * floor step — that's wrong for a Go/Python repo and doesn't scale. Instead the
19
+ * AGENT decides: it looks at the repo, calls scan_code, and the tool picks the
20
+ * right scanner(s) by stack detection. This is exactly what a skill is for.
21
+ *
22
+ * NO HARDCODING — the SCANNERS registry is the single extension point
23
+ * ──────────────────────────────────────────────────────────────────
24
+ * Every scanner is ONE entry in the SCANNERS array: { id, detect, langs, bin,
25
+ * args, parse }. Adding a tool (tsc, semgrep, eslint, clippy…) = one more entry,
26
+ * no changes to scan_code itself. scan_code runs EVERY scanner whose detect(dir)
27
+ * is true, scoped to files matching its `langs`, and merges the results.
28
+ *
29
+ * TWO scanners are WIRED + VERIFIED TODAY, both self-vendored (no image bake, no
30
+ * upstream-npm binary trust):
31
+ * - oxlint (JS/TS) via @zibby/bin-oxlint — a single static binary; see
32
+ * resolveOxlintBin.
33
+ * - semgrep (Java, Python, Go, Ruby, PHP) via @zibby/bin-semgrep — the OSS
34
+ * Semgrep engine `semgrep-core` (LGPL-2.1), spawned DIRECTLY (no Python, no
35
+ * `semgrep` CLI, no network, no telemetry, no registry) with a VENDORED curated
36
+ * ruleset + a generated local targets file; see resolveSemgrepBin. It scans ALL
37
+ * its languages in ONE invocation via a `-targets` file. JS/TS is intentionally
38
+ * left to oxlint (semgrep EXCLUDES it) to avoid double-scanning.
39
+ * ruff (Python) + staticcheck (Go) remain SCAFFOLD entries (registry + parser
40
+ * present, clearly marked TODO) — semgrep now covers Python/Go for BREADTH; ruff/
41
+ * staticcheck can still be wired later for DEPTH. Best-effort throughout: a missing
42
+ * binary (spawn ENOENT), an unreadable file, or a parser hiccup NEVER throws — the
43
+ * scanner is skipped with a note and the others still run.
44
+ */
1
45
  /**
2
46
  * Build the semgrep-core `-targets` document for a set of RELATIVE file paths. This
3
47
  * is the internal ATD wire format semgrep-core expects (verified against the pinned
@@ -5,14 +49,7 @@
5
49
  * analyzer, products }], … ]]. One entry per file we can map to a language; files
6
50
  * of other languages are dropped. EXPORTED for unit-testing the shape.
7
51
  */
8
- export function buildSemgrepTargets(relFiles: any): (string | (string | {
9
- path: {
10
- fpath: string;
11
- ppath: string;
12
- };
13
- analyzer: any;
14
- products: string[];
15
- })[][])[];
52
+ export declare function buildSemgrepTargets(relFiles: any): (string | any[])[];
16
53
  /**
17
54
  * Parse `semgrep-core … -json` output into the SAME finding shape as parseOxlint
18
55
  * ({ file, line, severity, rule, message }). The engine prints progress DOTS
@@ -21,7 +58,7 @@ export function buildSemgrepTargets(relFiles: any): (string | (string | {
21
58
  * end, extra:{ message, severity? } } ], errors, paths }. Best-effort: empty /
22
59
  * unparseable → []. EXPORTED for direct unit-testing of the shape assumption.
23
60
  */
24
- export function parseSemgrep(stdout: any): any;
61
+ export declare function parseSemgrep(stdout: any): any;
25
62
  /**
26
63
  * Parse `oxlint --format json` output. oxlint emits ONE JSON object:
27
64
  * { diagnostics: [ { message, code:"eslint(no-cond-assign)", severity:"warning"|"error",
@@ -30,7 +67,7 @@ export function parseSemgrep(stdout: any): any;
30
67
  * The line comes from the first label's span. VERIFIED against oxlint 1.73.0.
31
68
  * EXPORTED for direct unit-testing of the shape assumption.
32
69
  */
33
- export function parseOxlint(stdout: any): any;
70
+ export declare function parseOxlint(stdout: any): any;
34
71
  /**
35
72
  * THE EXTENSION POINT. Each scanner is one self-contained entry:
36
73
  * id stable scanner id (labels its findings block)
@@ -41,55 +78,12 @@ export function parseOxlint(stdout: any): any;
41
78
  * parse (stdout, stderr, code) => [{ file, line, severity, rule, message }]
42
79
  * Adding a tool = ONE more entry here. NOTHING scanner-specific lives elsewhere.
43
80
  */
44
- export const SCANNERS: {
81
+ export declare const SCANNERS: {
45
82
  id: string;
46
- detect: (dir: any) => any;
83
+ detect: (dir: any) => boolean;
47
84
  langs: string[];
48
- bin: () => any;
49
- args: (files: any, ctx?: {}) => any[];
85
+ bin: () => string;
86
+ args: (files: any, ctx?: any) => any[];
50
87
  parse: typeof parseOxlint;
51
88
  }[];
52
- export namespace codeScanSkill {
53
- let id: string;
54
- let serverName: string;
55
- let meta: any;
56
- let allowedTools: string[];
57
- let description: string;
58
- let promptFragment: string;
59
- function resolve(): {
60
- command: any;
61
- args: any[];
62
- env: {};
63
- description: string;
64
- type?: undefined;
65
- alwaysLoad?: undefined;
66
- } | {
67
- type: string;
68
- command: string;
69
- args: any[];
70
- env: {};
71
- description: string;
72
- alwaysLoad: boolean;
73
- };
74
- function handleToolCall(name: any, args: any): Promise<string>;
75
- let tools: {
76
- name: string;
77
- description: string;
78
- input_schema: {
79
- type: string;
80
- properties: {
81
- dir: {
82
- type: string;
83
- description: string;
84
- };
85
- files: {
86
- type: string;
87
- items: {
88
- type: string;
89
- };
90
- description: string;
91
- };
92
- };
93
- };
94
- }[];
95
- }
89
+ export declare const codeScanSkill: any;
@@ -1,29 +1,44 @@
1
- export function sizeBucket(added: any, deleted: any): string;
2
- export function fileExtension(path: any): string;
3
- export function extKind(ext: any): any;
1
+ /**
2
+ * code-stats — a PURE, DETERMINISTIC code-statistics skill (zero LLM, zero
3
+ * network, zero env). Same input → same output, ALWAYS. This is the
4
+ * reproducible "骨架" beneath any semantic scoring: the numbers a performance
5
+ * report cites that must survive being challenged (LinearB's one real
6
+ * advantage is that its metadata metrics are reproducible — these match that
7
+ * bar while adding per-file / per-path facts LinearB's metadata layer never
8
+ * sees).
9
+ *
10
+ * Design contract:
11
+ * - EVERY tool is a pure function of its arguments. No fetch, no env, no
12
+ * clock, no randomness → byte-identical results on every run, unit-testable.
13
+ * - Distinct from code-scan (linters/scanners, which DO run a tool) — this
14
+ * only COUNTS/CLASSIFIES structured facts the caller already has (a
15
+ * commit's changed-file list, a column of numbers).
16
+ * - Used TWO ways (see engineering-insights): the collect node calls
17
+ * `commit_facts` per commit to persist deterministic raw facts (file paths,
18
+ * extension mix, size bucket) that would otherwise be thrown away; the
19
+ * report agent calls `glob_hit` / `percentile` ON-DEMAND to compute
20
+ * core-path coverage against the customer's own globs and to rank people
21
+ * within a cohort (percentiles are reproducible and cross-team comparable —
22
+ * the "universal" property a raw score lacks).
23
+ */
24
+ export declare function sizeBucket(added: any, deleted: any): string;
25
+ export declare function fileExtension(path: any): string;
26
+ export declare function extKind(ext: any): any;
4
27
  /**
5
28
  * commit_facts — deterministic per-commit facts from its changed-file list.
6
29
  * `files` is [{ path|newPath|filename, additions?, deletions? }] (the shapes
7
30
  * gitlab_get_commit / github_get_commit already return). Pure.
8
31
  */
9
- export function commitFacts(files: any, opts?: {}): {
32
+ export declare function commitFacts(files: any, opts?: any): {
10
33
  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
- };
34
+ filePaths: any[];
35
+ extCounts: any;
36
+ kindCounts: any;
22
37
  additions: number;
23
38
  deletions: number;
24
39
  sizeBucket: string;
25
- largestFile: string;
26
- dirs: string[];
40
+ largestFile: any;
41
+ dirs: any[];
27
42
  };
28
43
  /**
29
44
  * glob_hit — how many of `paths` match ANY of `globs`. Deterministic. Supports
@@ -31,8 +46,8 @@ export function commitFacts(files: any, opts?: {}): {
31
46
  * own core-path globs (e.g. "src/payment/**") are passed at REPORT time — this
32
47
  * makes "who works in the core" a reproducible number, not an LLM guess.
33
48
  */
34
- export function globToRegExp(glob: any): RegExp;
35
- export function globHit(paths: any, globs: any): {
49
+ export declare function globToRegExp(glob: any): RegExp;
50
+ export declare function globHit(paths: any, globs: any): {
36
51
  total: number;
37
52
  hits: number;
38
53
  ratio: number;
@@ -43,121 +58,6 @@ export function globHit(paths: any, globs: any): {
43
58
  * `values` (0-100, "% of the cohort at or below value"). Ties count at-or-below
44
59
  * (the standard cumulative rank). Empty cohort → null (undefined, not a lie).
45
60
  */
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
- }
61
+ export declare function percentileRank(values: any, value: any): number;
62
+ export declare const codeStatsSkill: any;
163
63
  export default codeStatsSkill;
package/dist/codeStats.js CHANGED
@@ -1,4 +1,4 @@
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)
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,y=Number(r.deletions??r.del??0)||0;a+=g,m+=y;let d=T(l);i[d||"(none)"]=(i[d||"(none)"]||0)+1,n[j(d)]+=1;let b=g+y;b>c.changed&&(c={path:l,changed:b})}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
2
  These tools COMPUTE reproducible facts from data you already have. Use them so
3
3
  your numbers are auditable and survive challenge (same input \u2192 same output).
4
4
 
@@ -1,32 +1,52 @@
1
- export namespace codebaseMemorySkill {
2
- let id: string;
3
- let serverName: string;
4
- let meta: any;
5
- let allowedTools: string[];
6
- let description: string;
7
- let promptFragment: string;
8
- /**
9
- * stdio MCP server = the BARE binary with NO subcommand (verified for
10
- * v0.8.1). Never returns { command: null } — the binary is baked into the
11
- * image; if it's somehow absent the server simply fails to spawn and its
12
- * tools are unavailable, which does not crash the run.
13
- */
14
- function resolve(): {
15
- type: string;
16
- command: any;
17
- args: any[];
18
- env: {
19
- CBM_CACHE_DIR: any;
20
- };
21
- description: string;
22
- alwaysLoad: boolean;
23
- };
24
- /**
25
- * Pre-run hook (graph.js calls this for every skill declared on the node,
26
- * before the agent runs). Index the checked-out repo ONCE per run with the
27
- * imperative `cli index_repository` path. Idempotent via a per-repo marker
28
- * under CBM_CACHE_DIR; fully wrapped so it NEVER throws into the run.
29
- * Returns {}it contributes no agent-visible options.
30
- */
31
- function invokeAgentOptions(): {};
32
- }
1
+ /**
2
+ * codebaseMemory.js — code-graph + semantic codebase memory skill, backed by
3
+ * the DeusData/codebase-memory-mcp binary BAKED INTO the agent image.
4
+ *
5
+ * WHAT IT IS
6
+ * ──────────
7
+ * A hand-written stdio MCP skill (same shape as kvMemory.js) that points the
8
+ * agent at the `codebase-memory-mcp` server binary already on the image PATH
9
+ * (/usr/local/bin/codebase-memory-mcp see agent-ops/Dockerfile and
10
+ * backend/lib/docker/zibby-agent/Dockerfile, which fetch the v0.8.1 portable
11
+ * static build at build time, sha256-verified, multi-arch). The server indexes
12
+ * a checked-out repository into a code graph + embeddings (Apache-2.0 nomic
13
+ * embeddings) and exposes architecture / search / trace tools over it.
14
+ *
15
+ * RELATIONSHIP TO THE BINARY (VERIFIED GROUND TRUTH for v0.8.1)
16
+ * ─────────────────────────────────────────────────────────────
17
+ * - stdio MCP server = the BARE binary, NO subcommand → command + args:[].
18
+ * - imperative one-shot = `codebase-memory-mcp cli <tool> '<json>'`.
19
+ * Indexing = `cli index_repository '{"repo_path":"<absDir>"}'`.
20
+ * - DB / cache dir env = CBM_CACHE_DIR (we point it at a writable workspace
21
+ * dir so a read-only / ephemeral HOME never wedges the server).
22
+ *
23
+ * WHY UNGATED (no integration token)
24
+ * ──────────────────────────────────
25
+ * Fully local no API, no OAuth, no paste-token. It is therefore deliberately
26
+ * LEFT OUT of backend/src/services/skill-integrations.js
27
+ * (REQUIRED_/OPTIONAL_INTEGRATION_MAP). Leaving it out = ungated = correct.
28
+ * The skill ACTIVATES ONLY when a node declares 'codebase-memory' in its
29
+ * `skills` arraythe registry never auto-loads it, so existing agents are
30
+ * unaffected (this is what makes the integration additive). `alwaysLoad: true`
31
+ * (matching every other skill) only means: once a node HAS declared it, its
32
+ * MCP tools load eagerly rather than lazily — it does NOT make the skill
33
+ * global.
34
+ *
35
+ * INDEX-AT-START HOOK
36
+ * ───────────────────
37
+ * invokeAgentOptions() runs ONCE per run (idempotent via a per-repo marker
38
+ * file under CBM_CACHE_DIR) to index the checked-out repo with the imperative
39
+ * `cli index_repository` path BEFORE the node's agent runs, so the graph/search
40
+ * tools have data on the very first tool call. It is wrapped in try/catch and
41
+ * NEVER throws — a failed index degrades to "tools return empty", not a crashed
42
+ * run. The hook returns {} (it contributes no agent-visible options); its only
43
+ * job is the side-effect of building the index.
44
+ *
45
+ * It only helps agents whose repo is ALREADY checked out when the node starts.
46
+ * An agent that clones INSIDE its own run has nothing to index at hook time —
47
+ * the hook then NO-OPS (see repoDirToIndex) and that agent must call
48
+ * index_repository itself right after cloning. Do NOT "fix" the empty case by
49
+ * falling back to the workspace root: that indexes the agent's own template
50
+ * source, which is worse than no index at all.
51
+ */
52
+ export declare const codebaseMemorySkill: any;
@@ -1,4 +1,4 @@
1
- import{spawnSync as d}from"node:child_process";import{existsSync as n,mkdirSync as c,readdirSync as h,writeFileSync as m}from"node:fs";import{createHash as u}from"node:crypto";import{join as s}from"node:path";import{SKILL_META as y}from"@zibby/skill-ids";function i(){return process.env.CBM_BIN||"/usr/local/bin/codebase-memory-mcp"}function a(){if(process.env.CBM_CACHE_DIR)return process.env.CBM_CACHE_DIR;let e=process.env.WORKSPACE||process.env.ZIBBY_WORKSPACE;return e?s(e,".zibby","cbm-cache"):"/tmp/zibby-cbm-cache"}function l(){let e=process.env.WORKSPACE||process.env.ZIBBY_WORKSPACE||"/workspace",r=s(e,".zibby","repos");try{if(n(r)){let t=h(r,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>s(r,o.name));if(t.length===1)return t[0];if(t.length>1)return r}}catch{}return null}function _(e){return u("sha256").update(e).digest("hex").slice(0,16)}var x={id:"codebase-memory",serverName:"codebase_memory",meta:y["codebase-memory"],allowedTools:["mcp__codebase_memory__*"],description:"Codebase memory \u2014 code-graph + semantic index over the checked-out repo (architecture, graph search, dependency trace, change detection)",promptFragment:`## Codebase Memory (code-graph + semantic index over THIS repo)
1
+ import{spawnSync as d}from"node:child_process";import{existsSync as s,mkdirSync as c,readdirSync as h,writeFileSync as m}from"node:fs";import{createHash as u}from"node:crypto";import{join as n}from"node:path";import{SKILL_META as y}from"@zibby/skill-ids";function i(){return process.env.CBM_BIN||"/usr/local/bin/codebase-memory-mcp"}function a(){if(process.env.CBM_CACHE_DIR)return process.env.CBM_CACHE_DIR;let e=process.env.WORKSPACE||process.env.ZIBBY_WORKSPACE;return e?n(e,".zibby","cbm-cache"):"/tmp/zibby-cbm-cache"}function l(){let e=process.env.WORKSPACE||process.env.ZIBBY_WORKSPACE||"/workspace",r=n(e,".zibby","repos");try{if(s(r)){let t=h(r,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>n(r,o.name));if(t.length===1)return t[0];if(t.length>1)return r}}catch{}return null}function _(e){return u("sha256").update(e).digest("hex").slice(0,16)}var x={id:"codebase-memory",serverName:"codebase_memory",meta:y["codebase-memory"],allowedTools:["mcp__codebase_memory__*"],description:"Codebase memory \u2014 code-graph + semantic index over the checked-out repo (architecture, graph search, dependency trace, change detection)",promptFragment:`## Codebase Memory (code-graph + semantic index over THIS repo)
2
2
  The checked-out repository is indexed into a queryable code graph + semantic
3
3
  index. Reach for these instead of blindly grepping when you need structure,
4
4
  relationships, or "where does X live / what depends on Y":
@@ -10,5 +10,5 @@ relationships, or "where does X live / what depends on Y":
10
10
  - get_code_snippet / search_code: pull the exact code for a node / text match.
11
11
  - index_status / list_projects: confirm the index is present before querying.
12
12
  The repo is indexed for you at the start of the run; if a query comes back
13
- empty, call index_status, and only re-index (index_repository) if needed.`,resolve(){let e=a();try{c(e,{recursive:!0})}catch{}let r={CBM_CACHE_DIR:e};return process.env.WORKSPACE&&(r.WORKSPACE=process.env.WORKSPACE),{type:"stdio",command:i(),args:[],env:r,description:this.description,alwaysLoad:!0}},invokeAgentOptions(){try{let e=l();if(!e)return{};let r=a();try{c(r,{recursive:!0})}catch{}let t=s(r,`.cbm-indexed-${_(e)}`);if(n(t))return{};let o=i();if(!n(o)&&!process.env.CBM_BIN)return{};let p=d(o,["cli","index_repository",JSON.stringify({repo_path:e})],{env:{...process.env,CBM_CACHE_DIR:r},encoding:"utf-8",timeout:300*1e3,maxBuffer:32*1024*1024});try{m(t,`${new Date().toISOString()} status=${p.status}
13
+ empty, call index_status, and only re-index (index_repository) if needed.`,resolve(){let e=a();try{c(e,{recursive:!0})}catch{}let r={CBM_CACHE_DIR:e};return process.env.WORKSPACE&&(r.WORKSPACE=process.env.WORKSPACE),{type:"stdio",command:i(),args:[],env:r,description:this.description,alwaysLoad:!0}},invokeAgentOptions(){try{let e=l();if(!e)return{};let r=a();try{c(r,{recursive:!0})}catch{}let t=n(r,`.cbm-indexed-${_(e)}`);if(s(t))return{};let o=i();if(!s(o)&&!process.env.CBM_BIN)return{};let p=d(o,["cli","index_repository",JSON.stringify({repo_path:e})],{env:{...process.env,CBM_CACHE_DIR:r},encoding:"utf-8",timeout:300*1e3,maxBuffer:32*1024*1024});try{m(t,`${new Date().toISOString()} status=${p.status}
14
14
  `)}catch{}}catch{}return{}}};export{x as codebaseMemorySkill};
@@ -1,131 +1,10 @@
1
- export namespace coreToolsSkill {
2
- let id: string;
3
- let description: string;
4
- let envKeys: any[];
5
- let tools: ({
6
- name: string;
7
- description: string;
8
- input_schema: {
9
- type: string;
10
- properties: {
11
- path: {
12
- type: string;
13
- description: string;
14
- };
15
- content?: undefined;
16
- command?: undefined;
17
- cwd?: undefined;
18
- url?: undefined;
19
- seconds?: undefined;
20
- reason?: undefined;
21
- };
22
- required: string[];
23
- };
24
- } | {
25
- name: string;
26
- description: string;
27
- input_schema: {
28
- type: string;
29
- properties: {
30
- path: {
31
- type: string;
32
- description: string;
33
- };
34
- content: {
35
- type: string;
36
- description: string;
37
- };
38
- command?: undefined;
39
- cwd?: undefined;
40
- url?: undefined;
41
- seconds?: undefined;
42
- reason?: undefined;
43
- };
44
- required: string[];
45
- };
46
- } | {
47
- name: string;
48
- description: string;
49
- input_schema: {
50
- type: string;
51
- properties: {
52
- path: {
53
- type: string;
54
- description: string;
55
- };
56
- content?: undefined;
57
- command?: undefined;
58
- cwd?: undefined;
59
- url?: undefined;
60
- seconds?: undefined;
61
- reason?: undefined;
62
- };
63
- required?: undefined;
64
- };
65
- } | {
66
- name: string;
67
- description: string;
68
- input_schema: {
69
- type: string;
70
- properties: {
71
- command: {
72
- type: string;
73
- description: string;
74
- };
75
- cwd: {
76
- type: string;
77
- description: string;
78
- };
79
- path?: undefined;
80
- content?: undefined;
81
- url?: undefined;
82
- seconds?: undefined;
83
- reason?: undefined;
84
- };
85
- required: string[];
86
- };
87
- } | {
88
- name: string;
89
- description: string;
90
- input_schema: {
91
- type: string;
92
- properties: {
93
- url: {
94
- type: string;
95
- description: string;
96
- };
97
- path?: undefined;
98
- content?: undefined;
99
- command?: undefined;
100
- cwd?: undefined;
101
- seconds?: undefined;
102
- reason?: undefined;
103
- };
104
- required: string[];
105
- };
106
- } | {
107
- name: string;
108
- description: string;
109
- input_schema: {
110
- type: string;
111
- properties: {
112
- seconds: {
113
- type: string;
114
- description: string;
115
- };
116
- reason: {
117
- type: string;
118
- description: string;
119
- };
120
- path?: undefined;
121
- content?: undefined;
122
- command?: undefined;
123
- cwd?: undefined;
124
- url?: undefined;
125
- };
126
- required?: undefined;
127
- };
128
- })[];
129
- function handleToolCall(name: any, args: any, context: any): Promise<any>;
130
- function resolve(): any;
131
- }
1
+ /**
2
+ * Core Tools Skill
3
+ *
4
+ * Provides baseline local capabilities for the chat agent:
5
+ * file read, directory listing, shell execution, and URL opening.
6
+ *
7
+ * These are the equivalent of what Cursor/Claude agents get natively.
8
+ * All handlers run locally in the Node.js process — no MCP server needed.
9
+ */
10
+ export declare const coreToolsSkill: any;