@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.
- package/README.md +1 -1
- package/dist/artifact.d.ts +1 -115
- package/dist/browser.d.ts +10 -19
- package/dist/chartRender.d.ts +46 -57
- package/dist/chartRender.js +1 -1
- package/dist/chat-memory.d.ts +26 -330
- package/dist/chat-notify.d.ts +30 -409
- package/dist/chat-notify.js +3 -3
- package/dist/chatProgress.d.ts +28 -47
- package/dist/code-scan.d.ts +52 -58
- package/dist/codeStats.d.ts +36 -136
- package/dist/codeStats.js +1 -1
- package/dist/codebaseMemory.d.ts +52 -32
- package/dist/codebaseMemory.js +2 -2
- package/dist/core-tools.d.ts +10 -131
- package/dist/datasetStore.d.ts +52 -179
- package/dist/datasetStore.js +12 -3
- package/dist/discord.d.ts +32 -68
- package/dist/figma.d.ts +5 -408
- package/dist/function-skill.d.ts +23 -135
- package/dist/function-skill.js +1 -1
- package/dist/gbrain.d.ts +46 -114
- package/dist/git-write.d.ts +45 -137
- package/dist/git-write.js +6 -6
- package/dist/git.d.ts +2 -73
- package/dist/github.d.ts +2 -1202
- package/dist/gitlab.d.ts +55 -1059
- package/dist/gitlab.js +2 -2
- package/dist/googleDocs.d.ts +39 -175
- package/dist/hubspot.d.ts +1 -381
- package/dist/index.d.ts +19 -12
- package/dist/index.js +157 -148
- package/dist/integrations.d.ts +2 -2
- package/dist/jira.d.ts +2 -532
- package/dist/jira.js +4 -4
- package/dist/kvMemory.d.ts +47 -78
- package/dist/lark.d.ts +2 -161
- package/dist/lark.js +1 -1
- package/dist/larkDocs.d.ts +35 -236
- package/dist/linear.d.ts +36 -343
- package/dist/linkedin.d.ts +10 -120
- package/dist/llm-billing.d.ts +92 -180
- package/dist/llm-billing.js +1 -1
- package/dist/memory.d.ts +11 -137
- package/dist/notion.d.ts +28 -276
- package/dist/notion.js +4 -4
- package/dist/opendesign.d.ts +24 -202
- package/dist/opendesign.js +2 -2
- package/dist/package.json +3 -2
- package/dist/plane.d.ts +40 -24
- package/dist/report.d.ts +153 -110
- package/dist/review-dedup.d.ts +8 -8
- package/dist/review.d.ts +12 -2
- package/dist/reviewMemoryIo.d.ts +37 -3
- package/dist/reviewRecord.d.ts +41 -47
- package/dist/sentry.d.ts +25 -22
- package/dist/skill-installer.d.ts +11 -86
- package/dist/slack.d.ts +1 -284
- package/dist/socialCard.d.ts +35 -89
- package/dist/test-runner.d.ts +1 -220
- package/dist/trackers/github-adapter.d.ts +39 -94
- package/dist/trackers/index.d.ts +25 -18
- package/dist/trackers/jira-adapter.d.ts +20 -88
- package/dist/trackers/linear-adapter.d.ts +24 -87
- package/dist/trackers/plane-adapter.d.ts +29 -85
- package/dist/trackers/plane-adapter.js +1 -1
- package/dist/trackers/types.d.ts +1 -186
- package/dist/triggerAgent.d.ts +26 -42
- package/dist/triggerAgent.js +1 -1
- package/dist/workflow-builder.d.ts +11 -245
- package/docs/cli-reference.md +33 -0
- package/docs/concepts/designing-agents.md +201 -0
- package/docs/self-host/backup-restore.md +52 -0
- package/docs/self-host/index.md +75 -0
- package/docs/self-host/storage.md +50 -0
- package/docs/self-host/troubleshooting.md +48 -0
- package/docs/self-host/upgrade.md +81 -0
- package/package.json +3 -2
package/dist/code-scan.d.ts
CHANGED
|
@@ -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 |
|
|
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) =>
|
|
83
|
+
detect: (dir: any) => boolean;
|
|
47
84
|
langs: string[];
|
|
48
|
-
bin: () =>
|
|
49
|
-
args: (files: any, ctx?:
|
|
85
|
+
bin: () => string;
|
|
86
|
+
args: (files: any, ctx?: any) => any[];
|
|
50
87
|
parse: typeof parseOxlint;
|
|
51
88
|
}[];
|
|
52
|
-
export
|
|
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;
|
package/dist/codeStats.d.ts
CHANGED
|
@@ -1,29 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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:
|
|
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:
|
|
26
|
-
dirs:
|
|
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
|
|
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,
|
|
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
|
|
package/dist/codebaseMemory.d.ts
CHANGED
|
@@ -1,32 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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` array — the 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;
|
package/dist/codebaseMemory.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{spawnSync as d}from"node:child_process";import{existsSync as
|
|
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=
|
|
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};
|
package/dist/core-tools.d.ts
CHANGED
|
@@ -1,131 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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;
|