@agllama/mcp 0.6.27 → 0.7.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 (37) hide show
  1. package/dist/api-client.d.ts +30 -2
  2. package/dist/api-client.d.ts.map +1 -1
  3. package/dist/api-client.js +28 -4
  4. package/dist/api-client.js.map +1 -1
  5. package/dist/server.d.ts.map +1 -1
  6. package/dist/server.js +60 -1
  7. package/dist/server.js.map +1 -1
  8. package/dist/tools/__tests__/prScorer.test.d.ts +2 -0
  9. package/dist/tools/__tests__/prScorer.test.d.ts.map +1 -0
  10. package/dist/tools/__tests__/prScorer.test.js +537 -0
  11. package/dist/tools/__tests__/prScorer.test.js.map +1 -0
  12. package/dist/tools/devLinks.d.ts +5 -22
  13. package/dist/tools/devLinks.d.ts.map +1 -1
  14. package/dist/tools/devLinks.js +15 -110
  15. package/dist/tools/devLinks.js.map +1 -1
  16. package/dist/tools/help.d.ts.map +1 -1
  17. package/dist/tools/help.js +74 -0
  18. package/dist/tools/help.js.map +1 -1
  19. package/dist/tools/index.d.ts +3 -0
  20. package/dist/tools/index.d.ts.map +1 -1
  21. package/dist/tools/index.js +3 -0
  22. package/dist/tools/index.js.map +1 -1
  23. package/dist/tools/prScorer.d.ts +41 -0
  24. package/dist/tools/prScorer.d.ts.map +1 -0
  25. package/dist/tools/prScorer.js +182 -0
  26. package/dist/tools/prScorer.js.map +1 -0
  27. package/dist/tools/prScorerHistory.d.ts +53 -0
  28. package/dist/tools/prScorerHistory.d.ts.map +1 -0
  29. package/dist/tools/prScorerHistory.js +251 -0
  30. package/dist/tools/prScorerHistory.js.map +1 -0
  31. package/dist/tools/prScorerSchema.d.ts +9 -0
  32. package/dist/tools/prScorerSchema.d.ts.map +1 -0
  33. package/dist/tools/prScorerSchema.js +217 -0
  34. package/dist/tools/prScorerSchema.js.map +1 -0
  35. package/dist/types.d.ts +19 -0
  36. package/dist/types.d.ts.map +1 -1
  37. package/package.json +2 -2
@@ -0,0 +1,53 @@
1
+ import { z } from 'zod';
2
+ export declare const testPrScorerToolName = "llama_test_pr_scorer";
3
+ export declare const testPrScorerToolDescription: string;
4
+ export declare const testPrScorerToolSchema: z.ZodObject<{
5
+ orgSlug: z.ZodOptional<z.ZodString>;
6
+ projectKey: z.ZodOptional<z.ZodString>;
7
+ source: z.ZodString;
8
+ prId: z.ZodString;
9
+ }, "strip", z.ZodTypeAny, {
10
+ source: string;
11
+ prId: string;
12
+ orgSlug?: string | undefined;
13
+ projectKey?: string | undefined;
14
+ }, {
15
+ source: string;
16
+ prId: string;
17
+ orgSlug?: string | undefined;
18
+ projectKey?: string | undefined;
19
+ }>;
20
+ export type TestPrScorerToolInput = z.infer<typeof testPrScorerToolSchema>;
21
+ export declare function executeTestPrScorer(input: TestPrScorerToolInput): Promise<string>;
22
+ export declare const listPrScorerHistoryToolName = "llama_list_pr_scorer_history";
23
+ export declare const listPrScorerHistoryToolDescription: string;
24
+ export declare const listPrScorerHistoryToolSchema: z.ZodObject<{
25
+ orgSlug: z.ZodOptional<z.ZodString>;
26
+ projectKey: z.ZodOptional<z.ZodString>;
27
+ }, "strip", z.ZodTypeAny, {
28
+ orgSlug?: string | undefined;
29
+ projectKey?: string | undefined;
30
+ }, {
31
+ orgSlug?: string | undefined;
32
+ projectKey?: string | undefined;
33
+ }>;
34
+ export type ListPrScorerHistoryToolInput = z.infer<typeof listPrScorerHistoryToolSchema>;
35
+ export declare function executeListPrScorerHistory(input: ListPrScorerHistoryToolInput): Promise<string>;
36
+ export declare const revertPrScorerToolName = "llama_revert_pr_scorer";
37
+ export declare const revertPrScorerToolDescription: string;
38
+ export declare const revertPrScorerToolSchema: z.ZodObject<{
39
+ orgSlug: z.ZodOptional<z.ZodString>;
40
+ projectKey: z.ZodOptional<z.ZodString>;
41
+ historyIndex: z.ZodNumber;
42
+ }, "strip", z.ZodTypeAny, {
43
+ historyIndex: number;
44
+ orgSlug?: string | undefined;
45
+ projectKey?: string | undefined;
46
+ }, {
47
+ historyIndex: number;
48
+ orgSlug?: string | undefined;
49
+ projectKey?: string | undefined;
50
+ }>;
51
+ export type RevertPrScorerToolInput = z.infer<typeof revertPrScorerToolSchema>;
52
+ export declare function executeRevertPrScorer(input: RevertPrScorerToolInput): Promise<string>;
53
+ //# sourceMappingURL=prScorerHistory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prScorerHistory.d.ts","sourceRoot":"","sources":["../../src/tools/prScorerHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiCxB,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D,eAAO,MAAM,2BAA2B,QAQwF,CAAC;AAEjI,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;EAoBjC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAgB3E,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAqEjB;AAMD,eAAO,MAAM,2BAA2B,iCAAiC,CAAC;AAE1E,eAAO,MAAM,kCAAkC,QAIwC,CAAC;AAExF,eAAO,MAAM,6BAA6B;;;;;;;;;EASxC,CAAC;AAEH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAUzF,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,MAAM,CAAC,CAwDjB;AAMD,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAE/D,eAAO,MAAM,6BAA6B,QAIkD,CAAC;AAE7F,eAAO,MAAM,wBAAwB;;;;;;;;;;;;EAgBnC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE/E,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAgDjB"}
@@ -0,0 +1,251 @@
1
+ import { z } from 'zod';
2
+ import { getApiClient, LlamaApiError } from '../api-client.js';
3
+ import { getSessionDefaults } from './session.js';
4
+ // ============================================
5
+ // Shared context helper
6
+ // ============================================
7
+ async function resolveContext(orgSlug, projectKey) {
8
+ const session = await getSessionDefaults();
9
+ const resolvedOrg = orgSlug ?? session?.orgSlug;
10
+ const resolvedProject = projectKey ?? session?.projectKey;
11
+ if (!resolvedOrg) {
12
+ return {
13
+ error: 'orgSlug is required. Either provide it or set session context with llama_set_context first.',
14
+ };
15
+ }
16
+ if (!resolvedProject) {
17
+ return {
18
+ error: 'projectKey is required. Either provide it or set session context with llama_set_context first.',
19
+ };
20
+ }
21
+ return { orgSlug: resolvedOrg, projectKey: resolvedProject };
22
+ }
23
+ // ============================================
24
+ // llama_test_pr_scorer
25
+ // ============================================
26
+ export const testPrScorerToolName = 'llama_test_pr_scorer';
27
+ export const testPrScorerToolDescription = 'Dry-run a PR Scorer ruleset against a real PR without saving the rules. ' +
28
+ 'Returns the full evaluation result including score, grade, reasons, flags, and a per-rule trace. ' +
29
+ 'Use this to validate new or edited rules before calling llama_set_pr_scorer_rules.\n\n' +
30
+ 'prId format: "<adoRepoId>:<prNumber>" (e.g. "abc123-def-456:42"). ' +
31
+ 'These composite IDs are returned by the GET /pr-scorer/recent-prs endpoint that the editor dry-run pane uses; ' +
32
+ 'they are NOT the DevLink UUID and NOT the bare ADO PR number.\n\n' +
33
+ 'trace[] contains one entry per rule: { ruleIndex, matched, delta, reason?, flag? }. ' +
34
+ 'Use trace to explain why a specific rule fired or did not fire (e.g. delta=0 + matched=false means the condition was false).';
35
+ export const testPrScorerToolSchema = z.object({
36
+ orgSlug: z
37
+ .string()
38
+ .optional()
39
+ .describe('Organization slug (session default)'),
40
+ projectKey: z
41
+ .string()
42
+ .optional()
43
+ .describe('Project key (session default)'),
44
+ source: z
45
+ .string()
46
+ .describe('DSL rules to test. May differ from the currently saved ruleset — this is a dry run.'),
47
+ prId: z
48
+ .string()
49
+ .describe('Composite ADO PR id in the format "<adoRepoId>:<prNumber>" (e.g. "abc123-def-456:42"). ' +
50
+ 'Obtain from GET /pr-scorer/recent-prs. NOT the DevLink UUID.'),
51
+ });
52
+ export async function executeTestPrScorer(input) {
53
+ try {
54
+ const ctx = await resolveContext(input.orgSlug, input.projectKey);
55
+ if ('error' in ctx) {
56
+ return JSON.stringify({ success: false, error: ctx.error });
57
+ }
58
+ const client = getApiClient();
59
+ try {
60
+ await client.recordToolCall('llama_test_pr_scorer', {
61
+ orgSlug: ctx.orgSlug,
62
+ projectKey: ctx.projectKey,
63
+ prId: input.prId,
64
+ sourceLength: input.source.length,
65
+ });
66
+ }
67
+ catch {
68
+ // Ignore recording errors
69
+ }
70
+ const data = await client.postPrScorerTest(ctx.orgSlug, ctx.projectKey, input.source, input.prId);
71
+ return JSON.stringify({
72
+ success: true,
73
+ orgSlug: ctx.orgSlug,
74
+ projectKey: ctx.projectKey,
75
+ prId: input.prId,
76
+ score: data.score,
77
+ grade: data.grade,
78
+ reasons: data.reasons ?? [],
79
+ flags: data.flags ?? [],
80
+ trace: (data.trace ?? []),
81
+ });
82
+ }
83
+ catch (error) {
84
+ // Surface parse errors the same way as llama_set_pr_scorer_rules
85
+ if (error instanceof LlamaApiError && error.statusCode === 400) {
86
+ if (Array.isArray(error.details)) {
87
+ const parseErrors = error.details.map((d) => ({
88
+ line: typeof d.line === 'number' ? d.line : 0,
89
+ column: typeof d.column === 'number' ? d.column : 0,
90
+ message: typeof d.message === 'string' ? d.message : String(d.message ?? ''),
91
+ }));
92
+ return JSON.stringify({ success: false, parseErrors });
93
+ }
94
+ return JSON.stringify({
95
+ success: false,
96
+ error: `PR scorer test failed: ${error.message}`,
97
+ statusCode: error.statusCode,
98
+ });
99
+ }
100
+ if (error instanceof LlamaApiError) {
101
+ return JSON.stringify({
102
+ success: false,
103
+ error: `PR scorer test failed: ${error.message}`,
104
+ statusCode: error.statusCode,
105
+ });
106
+ }
107
+ return JSON.stringify({
108
+ success: false,
109
+ error: error instanceof Error ? error.message : 'Unknown error',
110
+ });
111
+ }
112
+ }
113
+ // ============================================
114
+ // llama_list_pr_scorer_history
115
+ // ============================================
116
+ export const listPrScorerHistoryToolName = 'llama_list_pr_scorer_history';
117
+ export const listPrScorerHistoryToolDescription = 'List the save history for a project\'s PR Scorer ruleset. ' +
118
+ 'Returns metadata only (timestamps + updatedById); full rule bodies are stripped to keep token cost low. ' +
119
+ 'Entries are ordered most-recent-first; the index of each entry corresponds to the historyIndex ' +
120
+ 'accepted by llama_revert_pr_scorer (0 = most recent save before the current state).';
121
+ export const listPrScorerHistoryToolSchema = z.object({
122
+ orgSlug: z
123
+ .string()
124
+ .optional()
125
+ .describe('Organization slug (session default)'),
126
+ projectKey: z
127
+ .string()
128
+ .optional()
129
+ .describe('Project key (session default)'),
130
+ });
131
+ export async function executeListPrScorerHistory(input) {
132
+ try {
133
+ const ctx = await resolveContext(input.orgSlug, input.projectKey);
134
+ if ('error' in ctx) {
135
+ return JSON.stringify({ success: false, error: ctx.error });
136
+ }
137
+ const client = getApiClient();
138
+ try {
139
+ await client.recordToolCall('llama_list_pr_scorer_history', {
140
+ orgSlug: ctx.orgSlug,
141
+ projectKey: ctx.projectKey,
142
+ });
143
+ }
144
+ catch {
145
+ // Ignore recording errors
146
+ }
147
+ const raw = await client.getPrScorerHistory(ctx.orgSlug, ctx.projectKey);
148
+ // Strip source + ast fields — return metadata only per spec
149
+ const entries = (raw ?? []).map((entry, index) => {
150
+ const meta = {
151
+ index,
152
+ savedAt: entry.savedAt,
153
+ };
154
+ if (entry.updatedById !== undefined) {
155
+ meta.updatedById = entry.updatedById;
156
+ }
157
+ if (typeof entry.source === 'string') {
158
+ meta.sourceLineCount = entry.source.split('\n').length;
159
+ meta.sourceLength = entry.source.length;
160
+ }
161
+ return meta;
162
+ });
163
+ return JSON.stringify({
164
+ success: true,
165
+ orgSlug: ctx.orgSlug,
166
+ projectKey: ctx.projectKey,
167
+ count: entries.length,
168
+ entries,
169
+ });
170
+ }
171
+ catch (error) {
172
+ if (error instanceof LlamaApiError) {
173
+ return JSON.stringify({
174
+ success: false,
175
+ error: `Failed to list PR scorer history: ${error.message}`,
176
+ statusCode: error.statusCode,
177
+ });
178
+ }
179
+ return JSON.stringify({
180
+ success: false,
181
+ error: error instanceof Error ? error.message : 'Unknown error',
182
+ });
183
+ }
184
+ }
185
+ // ============================================
186
+ // llama_revert_pr_scorer
187
+ // ============================================
188
+ export const revertPrScorerToolName = 'llama_revert_pr_scorer';
189
+ export const revertPrScorerToolDescription = 'Revert the PR Scorer ruleset to a previous saved version. ' +
190
+ 'historyIndex is 0-indexed from most-recent-first (i.e. 0 = the most recent save before the current state). ' +
191
+ 'Call llama_list_pr_scorer_history first to see available indices and their timestamps. ' +
192
+ 'After a successful revert, call llama_get_pr_scorer_rules to confirm the active ruleset.';
193
+ export const revertPrScorerToolSchema = z.object({
194
+ orgSlug: z
195
+ .string()
196
+ .optional()
197
+ .describe('Organization slug (session default)'),
198
+ projectKey: z
199
+ .string()
200
+ .optional()
201
+ .describe('Project key (session default)'),
202
+ historyIndex: z
203
+ .number()
204
+ .int()
205
+ .min(0)
206
+ .describe('0-indexed position from most-recent-first history. Use llama_list_pr_scorer_history to find available indices.'),
207
+ });
208
+ export async function executeRevertPrScorer(input) {
209
+ try {
210
+ const ctx = await resolveContext(input.orgSlug, input.projectKey);
211
+ if ('error' in ctx) {
212
+ return JSON.stringify({ success: false, error: ctx.error });
213
+ }
214
+ const client = getApiClient();
215
+ try {
216
+ await client.recordToolCall('llama_revert_pr_scorer', {
217
+ orgSlug: ctx.orgSlug,
218
+ projectKey: ctx.projectKey,
219
+ historyIndex: input.historyIndex,
220
+ });
221
+ }
222
+ catch {
223
+ // Ignore recording errors
224
+ }
225
+ const data = await client.postPrScorerRevert(ctx.orgSlug, ctx.projectKey, input.historyIndex);
226
+ return JSON.stringify({
227
+ success: true,
228
+ orgSlug: ctx.orgSlug,
229
+ projectKey: ctx.projectKey,
230
+ historyIndex: input.historyIndex,
231
+ source: data?.rules?.source ?? '',
232
+ enabled: data?.enabled ?? true,
233
+ updatedById: data?.updatedById ?? null,
234
+ message: `PR Scorer ruleset reverted to history index ${input.historyIndex}.`,
235
+ });
236
+ }
237
+ catch (error) {
238
+ if (error instanceof LlamaApiError) {
239
+ return JSON.stringify({
240
+ success: false,
241
+ error: `Failed to revert PR scorer: ${error.message}`,
242
+ statusCode: error.statusCode,
243
+ });
244
+ }
245
+ return JSON.stringify({
246
+ success: false,
247
+ error: error instanceof Error ? error.message : 'Unknown error',
248
+ });
249
+ }
250
+ }
251
+ //# sourceMappingURL=prScorerHistory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prScorerHistory.js","sourceRoot":"","sources":["../../src/tools/prScorerHistory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Full DSL reference for the PR Scorer rule language.
3
+ * Exported as a string so it can be embedded in the llama_get_pr_scorer_schema
4
+ * tool description AND returned as the handler response.
5
+ *
6
+ * Spec: LLAMA-1283
7
+ */
8
+ export declare const PR_SCORER_DSL_REFERENCE = "# PR Scorer Rule Language \u2014 Full DSL Reference\n\nPR Scorer rules let you automatically adjust the quality score of a pull\nrequest based on its content, metadata, and linked issues. Each rule is a\nsingle line that conditionally adds or subtracts points and optionally\nattaches a human-readable reason and flag label.\n\n---\n\n## Grammar (EBNF)\n\n```\nruleset := rule*\nrule := 'when' expr 'then' SignedInt ( 'reason' STRING )? ( 'flag' STRING )?\nSignedInt := ( '+' | '-' ) INTEGER // range: [-10, +10] inclusive\nSTRING := '\"' [^\"]* '\"'\n```\n\nBlank lines and lines beginning with `#` are treated as comments and are\nsilently ignored. Rules are evaluated in order; all matching rules fire\n(scores accumulate \u2014 there is no early-exit).\n\n### Hard limits\n\n| Constraint | Value |\n|---|---|\n| Maximum rules per ruleset | 100 |\n| Maximum nested any() / all() depth | 8 |\n| Score per rule action | [-10, +10] |\n\n---\n\n## Evaluation Context \u2014 Variables\n\nEvery rule's `expr` can reference the following variables. All property\naccesses are null-safe: accessing a missing property returns `null` (which\nis falsy).\n\n### Top-level PR fields\n\n| Variable | Type | Description |\n|---|---|---|\n| `pr.id` | string | Unique PR identifier |\n| `pr.title` | string | Pull request title |\n| `pr.description` | string | PR body / description |\n| `pr.author` | string | Username of the PR author |\n| `pr.lastUpdated` | ISO-8601 string | Timestamp of last update |\n| `pr.isDraft` | boolean | `true` when the PR is in draft state |\n\n### Files\n\n`files` is an array of file-change objects.\n\n| Property | Type | Description |\n|---|---|---|\n| `path` | string | File path relative to repo root |\n| `additions` | number | Lines added in this file |\n| `deletions` | number | Lines deleted in this file |\n| `status` | string | `\"added\"` | `\"modified\"` | `\"deleted\"` | `\"renamed\"` |\n\n### Commits\n\n`commits` is an array of commit objects.\n\n| Property | Type | Description |\n|---|---|---|\n| `sha` | string | Commit hash |\n| `message` | string | Commit message |\n| `author` | string | Commit author username |\n| `timestamp` | ISO-8601 string | Commit timestamp |\n\n### Labels\n\n`labels` is an array of strings (the label names applied to the PR).\n\n### Reviewers\n\n`reviewers` is an array of reviewer objects.\n\n| Property | Type | Description |\n|---|---|---|\n| `username` | string | Reviewer username |\n| `state` | string | `\"approved\"` | `\"changes_requested\"` | `\"pending\"` |\n\n### Issue link fields\n\n| Variable | Type | Description |\n|---|---|---|\n| `hasLinkedIssue` | boolean | `true` when at least one issue is linked |\n| `linkedIssueKeys` | string[] | Array of linked issue keys (e.g. `[\"PROJ-42\"]`) |\n\n---\n\n## Operators\n\n### Comparison\n\n| Operator | Meaning | Example |\n|---|---|---|\n| `==` | Equal | `pr.isDraft == true` |\n| `!=` | Not equal | `pr.author != \"bot\"` |\n| `>` | Greater than | `files.count() > 20` |\n| `>=` | Greater than or equal | `files.count() >= 10` |\n| `<` | Less than | `commits.count() < 3` |\n| `<=` | Less than or equal | `reviewers.count() <= 1` |\n| `in` | Array membership | `\"bug\" in labels` |\n\n### Logical\n\n| Operator | Precedence (lower = binds tighter) |\n|---|---|\n| `!` (unary not) | 1 |\n| `&&` (and) | 2 |\n| `||` (or) | 3 |\n\nParentheses may be used to override precedence: `(a || b) && c`.\n\n---\n\n## Built-in Functions\n\n### Collection functions\n\nThese are called on an array variable followed by a lambda `x -> expr`.\n\n| Function | Signature | Description |\n|---|---|---|\n| `any()` | `array.any(x -> expr)` | Returns `true` if **any** element satisfies `expr` |\n| `all()` | `array.all(x -> expr)` | Returns `true` if **all** elements satisfy `expr` |\n| `count()` | `array.count()` or `array.count(x -> expr)` | Returns element count; with predicate, counts matching elements |\n\nWhen called without a predicate on an array, `count()` returns the length.\n\n### Path matching\n\n| Function | Signature | Description |\n|---|---|---|\n| `pathMatches(path, pattern)` | `pathMatches(string, string)` | Returns `true` if `path` matches the glob `pattern`. Uses `**` for recursive directory wildcard and `*` for single-segment wildcard. |\n\n### String methods\n\nCalled on a string variable with dot notation.\n\n| Method | Signature | Description |\n|---|---|---|\n| `.matches(re)` | `str.matches(string)` | Returns `true` if `str` matches the RE2 regular-expression string `re`. **Note: uses RE2 syntax, NOT JavaScript regex.** |\n| `.startsWith(prefix)` | `str.startsWith(string)` | Returns `true` if `str` begins with `prefix` |\n| `.endsWith(suffix)` | `str.endsWith(string)` | Returns `true` if `str` ends with `suffix` |\n\n> **RE2 note:** RE2 does not support lookaheads (`(?=...)`), lookbehinds\n> (`(?<=...)`), or backreferences (`\\1`). Use character classes and\n> quantifiers instead.\n\n---\n\n## Runnable Examples\n\n### Example 1 \u2014 Reward test coverage, penalise env-file touches\n\n```\n# +1 if the PR includes any test files\nwhen files.any(f -> pathMatches(f.path, \"**/*.test.ts\")) then +1 reason \"has tests\"\n\n# -5 and flag when .env files are touched (security risk)\nwhen files.any(f -> pathMatches(f.path, \".env\")) then -5 reason \"touches env\" flag \"env-file\"\n```\n\n### Example 2 \u2014 Multi-condition ruleset\n\n```\n# Draft PRs get a small penalty\nwhen pr.isDraft == true then -1 reason \"draft PR\"\n\n# Large PRs are harder to review\nwhen files.count() > 30 then -2 reason \"large diff \u2014 consider splitting\"\n\n# Bonus for linking an issue\nwhen hasLinkedIssue == true then +1 reason \"linked to tracked issue\"\n\n# All reviewers approved \u2192 bonus\nwhen reviewers.count() > 0 && reviewers.all(r -> r.state == \"approved\") then +2 reason \"all reviewers approved\"\n\n# Commits with WIP in message are a warning\nwhen commits.any(c -> c.message.startsWith(\"WIP\")) then -1 reason \"contains WIP commit\"\n\n# Title check \u2014 must not be a bare word (RE2 syntax)\nwhen pr.title.matches(\"^fix$\") then -1 reason \"title too vague\"\n```\n\n---\n\n## Return Type for Parse Errors\n\nWhen `llama_set_pr_scorer_rules` receives a syntactically invalid ruleset,\nit returns a **structured** parse-error array \u2014 not a flattened string \u2014 so\nClaude can identify and fix individual lines:\n\n```json\n{\n \"success\": false,\n \"parseErrors\": [\n { \"line\": 3, \"column\": 12, \"message\": \"Expected 'then' keyword\" },\n { \"line\": 7, \"column\": 1, \"message\": \"Score +15 exceeds maximum of +10\" }\n ]\n}\n```\n\nFix each error by its `line` + `column` and resubmit.\n";
9
+ //# sourceMappingURL=prScorerSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prScorerSchema.d.ts","sourceRoot":"","sources":["../../src/tools/prScorerSchema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,uBAAuB,yjNAgNnC,CAAC"}
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Full DSL reference for the PR Scorer rule language.
3
+ * Exported as a string so it can be embedded in the llama_get_pr_scorer_schema
4
+ * tool description AND returned as the handler response.
5
+ *
6
+ * Spec: LLAMA-1283
7
+ */
8
+ export const PR_SCORER_DSL_REFERENCE = `# PR Scorer Rule Language — Full DSL Reference
9
+
10
+ PR Scorer rules let you automatically adjust the quality score of a pull
11
+ request based on its content, metadata, and linked issues. Each rule is a
12
+ single line that conditionally adds or subtracts points and optionally
13
+ attaches a human-readable reason and flag label.
14
+
15
+ ---
16
+
17
+ ## Grammar (EBNF)
18
+
19
+ \`\`\`
20
+ ruleset := rule*
21
+ rule := 'when' expr 'then' SignedInt ( 'reason' STRING )? ( 'flag' STRING )?
22
+ SignedInt := ( '+' | '-' ) INTEGER // range: [-10, +10] inclusive
23
+ STRING := '"' [^"]* '"'
24
+ \`\`\`
25
+
26
+ Blank lines and lines beginning with \`#\` are treated as comments and are
27
+ silently ignored. Rules are evaluated in order; all matching rules fire
28
+ (scores accumulate — there is no early-exit).
29
+
30
+ ### Hard limits
31
+
32
+ | Constraint | Value |
33
+ |---|---|
34
+ | Maximum rules per ruleset | 100 |
35
+ | Maximum nested any() / all() depth | 8 |
36
+ | Score per rule action | [-10, +10] |
37
+
38
+ ---
39
+
40
+ ## Evaluation Context — Variables
41
+
42
+ Every rule's \`expr\` can reference the following variables. All property
43
+ accesses are null-safe: accessing a missing property returns \`null\` (which
44
+ is falsy).
45
+
46
+ ### Top-level PR fields
47
+
48
+ | Variable | Type | Description |
49
+ |---|---|---|
50
+ | \`pr.id\` | string | Unique PR identifier |
51
+ | \`pr.title\` | string | Pull request title |
52
+ | \`pr.description\` | string | PR body / description |
53
+ | \`pr.author\` | string | Username of the PR author |
54
+ | \`pr.lastUpdated\` | ISO-8601 string | Timestamp of last update |
55
+ | \`pr.isDraft\` | boolean | \`true\` when the PR is in draft state |
56
+
57
+ ### Files
58
+
59
+ \`files\` is an array of file-change objects.
60
+
61
+ | Property | Type | Description |
62
+ |---|---|---|
63
+ | \`path\` | string | File path relative to repo root |
64
+ | \`additions\` | number | Lines added in this file |
65
+ | \`deletions\` | number | Lines deleted in this file |
66
+ | \`status\` | string | \`"added"\` \| \`"modified"\` \| \`"deleted"\` \| \`"renamed"\` |
67
+
68
+ ### Commits
69
+
70
+ \`commits\` is an array of commit objects.
71
+
72
+ | Property | Type | Description |
73
+ |---|---|---|
74
+ | \`sha\` | string | Commit hash |
75
+ | \`message\` | string | Commit message |
76
+ | \`author\` | string | Commit author username |
77
+ | \`timestamp\` | ISO-8601 string | Commit timestamp |
78
+
79
+ ### Labels
80
+
81
+ \`labels\` is an array of strings (the label names applied to the PR).
82
+
83
+ ### Reviewers
84
+
85
+ \`reviewers\` is an array of reviewer objects.
86
+
87
+ | Property | Type | Description |
88
+ |---|---|---|
89
+ | \`username\` | string | Reviewer username |
90
+ | \`state\` | string | \`"approved"\` \| \`"changes_requested"\` \| \`"pending"\` |
91
+
92
+ ### Issue link fields
93
+
94
+ | Variable | Type | Description |
95
+ |---|---|---|
96
+ | \`hasLinkedIssue\` | boolean | \`true\` when at least one issue is linked |
97
+ | \`linkedIssueKeys\` | string[] | Array of linked issue keys (e.g. \`["PROJ-42"]\`) |
98
+
99
+ ---
100
+
101
+ ## Operators
102
+
103
+ ### Comparison
104
+
105
+ | Operator | Meaning | Example |
106
+ |---|---|---|
107
+ | \`==\` | Equal | \`pr.isDraft == true\` |
108
+ | \`!=\` | Not equal | \`pr.author != "bot"\` |
109
+ | \`>\` | Greater than | \`files.count() > 20\` |
110
+ | \`>=\` | Greater than or equal | \`files.count() >= 10\` |
111
+ | \`<\` | Less than | \`commits.count() < 3\` |
112
+ | \`<=\` | Less than or equal | \`reviewers.count() <= 1\` |
113
+ | \`in\` | Array membership | \`"bug" in labels\` |
114
+
115
+ ### Logical
116
+
117
+ | Operator | Precedence (lower = binds tighter) |
118
+ |---|---|
119
+ | \`!\` (unary not) | 1 |
120
+ | \`&&\` (and) | 2 |
121
+ | \`||\` (or) | 3 |
122
+
123
+ Parentheses may be used to override precedence: \`(a || b) && c\`.
124
+
125
+ ---
126
+
127
+ ## Built-in Functions
128
+
129
+ ### Collection functions
130
+
131
+ These are called on an array variable followed by a lambda \`x -> expr\`.
132
+
133
+ | Function | Signature | Description |
134
+ |---|---|---|
135
+ | \`any()\` | \`array.any(x -> expr)\` | Returns \`true\` if **any** element satisfies \`expr\` |
136
+ | \`all()\` | \`array.all(x -> expr)\` | Returns \`true\` if **all** elements satisfy \`expr\` |
137
+ | \`count()\` | \`array.count()\` or \`array.count(x -> expr)\` | Returns element count; with predicate, counts matching elements |
138
+
139
+ When called without a predicate on an array, \`count()\` returns the length.
140
+
141
+ ### Path matching
142
+
143
+ | Function | Signature | Description |
144
+ |---|---|---|
145
+ | \`pathMatches(path, pattern)\` | \`pathMatches(string, string)\` | Returns \`true\` if \`path\` matches the glob \`pattern\`. Uses \`**\` for recursive directory wildcard and \`*\` for single-segment wildcard. |
146
+
147
+ ### String methods
148
+
149
+ Called on a string variable with dot notation.
150
+
151
+ | Method | Signature | Description |
152
+ |---|---|---|
153
+ | \`.matches(re)\` | \`str.matches(string)\` | Returns \`true\` if \`str\` matches the RE2 regular-expression string \`re\`. **Note: uses RE2 syntax, NOT JavaScript regex.** |
154
+ | \`.startsWith(prefix)\` | \`str.startsWith(string)\` | Returns \`true\` if \`str\` begins with \`prefix\` |
155
+ | \`.endsWith(suffix)\` | \`str.endsWith(string)\` | Returns \`true\` if \`str\` ends with \`suffix\` |
156
+
157
+ > **RE2 note:** RE2 does not support lookaheads (\`(?=...)\`), lookbehinds
158
+ > (\`(?<=...)\`), or backreferences (\`\\1\`). Use character classes and
159
+ > quantifiers instead.
160
+
161
+ ---
162
+
163
+ ## Runnable Examples
164
+
165
+ ### Example 1 — Reward test coverage, penalise env-file touches
166
+
167
+ \`\`\`
168
+ # +1 if the PR includes any test files
169
+ when files.any(f -> pathMatches(f.path, "**/*.test.ts")) then +1 reason "has tests"
170
+
171
+ # -5 and flag when .env files are touched (security risk)
172
+ when files.any(f -> pathMatches(f.path, ".env")) then -5 reason "touches env" flag "env-file"
173
+ \`\`\`
174
+
175
+ ### Example 2 — Multi-condition ruleset
176
+
177
+ \`\`\`
178
+ # Draft PRs get a small penalty
179
+ when pr.isDraft == true then -1 reason "draft PR"
180
+
181
+ # Large PRs are harder to review
182
+ when files.count() > 30 then -2 reason "large diff — consider splitting"
183
+
184
+ # Bonus for linking an issue
185
+ when hasLinkedIssue == true then +1 reason "linked to tracked issue"
186
+
187
+ # All reviewers approved → bonus
188
+ when reviewers.count() > 0 && reviewers.all(r -> r.state == "approved") then +2 reason "all reviewers approved"
189
+
190
+ # Commits with WIP in message are a warning
191
+ when commits.any(c -> c.message.startsWith("WIP")) then -1 reason "contains WIP commit"
192
+
193
+ # Title check — must not be a bare word (RE2 syntax)
194
+ when pr.title.matches("^fix$") then -1 reason "title too vague"
195
+ \`\`\`
196
+
197
+ ---
198
+
199
+ ## Return Type for Parse Errors
200
+
201
+ When \`llama_set_pr_scorer_rules\` receives a syntactically invalid ruleset,
202
+ it returns a **structured** parse-error array — not a flattened string — so
203
+ Claude can identify and fix individual lines:
204
+
205
+ \`\`\`json
206
+ {
207
+ "success": false,
208
+ "parseErrors": [
209
+ { "line": 3, "column": 12, "message": "Expected 'then' keyword" },
210
+ { "line": 7, "column": 1, "message": "Score +15 exceeds maximum of +10" }
211
+ ]
212
+ }
213
+ \`\`\`
214
+
215
+ Fix each error by its \`line\` + \`column\` and resubmit.
216
+ `;
217
+ //# sourceMappingURL=prScorerSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prScorerSchema.js","sourceRoot":"","sources":["../../src/tools/prScorerSchema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgNtC,CAAC"}
package/dist/types.d.ts CHANGED
@@ -903,4 +903,23 @@ export interface MCPRoadmapDetail {
903
903
  items: MCPRoadmapItem[];
904
904
  milestones: MCPMilestone[];
905
905
  }
906
+ export type DevLinkProvider = 'AZURE_DEVOPS';
907
+ export type DevLinkType = 'PULL_REQUEST' | 'COMMIT';
908
+ export type DevLinkStatus = 'OPEN' | 'MERGED' | 'CLOSED' | 'LINKED';
909
+ export interface MCPDevLink {
910
+ id: string;
911
+ issueId: string;
912
+ projectId: string;
913
+ organizationId: string;
914
+ integrationId: string | null;
915
+ provider: DevLinkProvider;
916
+ type: DevLinkType;
917
+ status: DevLinkStatus;
918
+ externalId: string;
919
+ externalUrl: string;
920
+ title: string | null;
921
+ metadata: Record<string, unknown> | null;
922
+ createdAt: string;
923
+ updatedAt: string;
924
+ }
906
925
  //# sourceMappingURL=types.d.ts.map