memory-journal-mcp 7.1.0 → 7.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 +59 -51
- package/dist/{chunk-GW5DYUQJ.js → chunk-GR4T3SRW.js} +139 -100
- package/dist/{chunk-37BQOJDZ.js → chunk-IWKLHSPU.js} +81 -2
- package/dist/{chunk-JEGRDY6W.js → chunk-ORV7ZZOE.js} +357 -51
- package/dist/cli.js +30 -4
- package/dist/github-integration-2TFMXHIJ.js +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +3 -3
- package/dist/{tools-O44Q52RD.js → tools-CXR2FEB2.js} +2 -2
- package/package.json +1 -1
- package/skills/README.md +77 -0
- package/skills/autonomous-dev/SKILL.md +56 -0
- package/skills/bin/sync.js +50 -0
- package/skills/bun/SKILL.md +156 -0
- package/skills/github-commander/SKILL.md +1 -1
- package/skills/github-commander/workflows/code-quality-audit.md +7 -5
- package/skills/github-commander/workflows/issue-triage.md +13 -4
- package/skills/github-commander/workflows/milestone-sprint.md +9 -1
- package/skills/github-commander/workflows/perf-audit.md +2 -0
- package/skills/github-commander/workflows/pr-review.md +9 -3
- package/skills/github-commander/workflows/roadmap-kickoff.md +79 -0
- package/skills/github-commander/workflows/security-audit.md +3 -3
- package/skills/github-commander/workflows/update-deps.md +2 -2
- package/skills/gitlab/SKILL.md +115 -0
- package/skills/gitlab/package-lock.json +392 -0
- package/skills/gitlab/package.json +14 -0
- package/skills/gitlab/scripts/gitlab-client.ts +125 -0
- package/skills/gitlab/scripts/gitlab-helper.ts +80 -0
- package/skills/golang/SKILL.md +54 -0
- package/skills/mysql/SKILL.md +30 -0
- package/skills/package.json +48 -0
- package/skills/playwright-standard/SKILL.md +58 -0
- package/skills/playwright-standard/examples/fixtures.ts +66 -0
- package/skills/playwright-standard/examples/type-stubs.d.ts +10 -0
- package/skills/playwright-standard/references/advanced-scenarios.md +59 -0
- package/skills/playwright-standard/references/infrastructure.md +43 -0
- package/skills/postgres/SKILL.md +33 -0
- package/skills/react-best-practices/AGENTS.md +2883 -0
- package/skills/react-best-practices/README.md +127 -0
- package/skills/react-best-practices/SKILL.md +138 -0
- package/skills/react-best-practices/metadata.json +17 -0
- package/skills/react-best-practices/rules/_sections.md +46 -0
- package/skills/react-best-practices/rules/_template.md +28 -0
- package/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/skills/react-best-practices/rules/advanced-init-once.md +42 -0
- package/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/skills/react-best-practices/rules/async-api-routes.md +35 -0
- package/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/skills/react-best-practices/rules/async-dependencies.md +48 -0
- package/skills/react-best-practices/rules/async-parallel.md +24 -0
- package/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/skills/react-best-practices/rules/bundle-conditional.md +37 -0
- package/skills/react-best-practices/rules/bundle-defer-third-party.md +48 -0
- package/skills/react-best-practices/rules/bundle-dynamic-imports.md +34 -0
- package/skills/react-best-practices/rules/bundle-preload.md +44 -0
- package/skills/react-best-practices/rules/client-event-listeners.md +78 -0
- package/skills/react-best-practices/rules/client-localstorage-schema.md +74 -0
- package/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/skills/react-best-practices/rules/js-batch-dom-css.md +110 -0
- package/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/skills/react-best-practices/rules/js-cache-storage.md +68 -0
- package/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/skills/react-best-practices/rules/js-length-check-first.md +50 -0
- package/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/skills/react-best-practices/rules/rendering-activity.md +24 -0
- package/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +38 -0
- package/skills/react-best-practices/rules/rendering-conditional-render.md +32 -0
- package/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/skills/react-best-practices/rules/rendering-hoist-jsx.md +36 -0
- package/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +72 -0
- package/skills/react-best-practices/rules/rendering-hydration-suppress-warning.md +26 -0
- package/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/skills/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/skills/react-best-practices/rules/rerender-functional-setstate.md +77 -0
- package/skills/react-best-practices/rules/rerender-lazy-state-init.md +56 -0
- package/skills/react-best-practices/rules/rerender-memo-with-default-value.md +36 -0
- package/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/skills/react-best-practices/rules/server-auth-actions.md +96 -0
- package/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/skills/react-best-practices/rules/server-dedup-props.md +65 -0
- package/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/skills/rust/SKILL.md +86 -0
- package/skills/shadcn-ui/SKILL.md +72 -0
- package/skills/skill-builder/SKILL.md +457 -0
- package/skills/skill-builder/checklist.md +65 -0
- package/skills/sqlite/SKILL.md +38 -0
- package/skills/typescript/SKILL.md +453 -0
- package/skills/typescript/assets/eslint-template.js +102 -0
- package/skills/typescript/assets/tsconfig-template.json +45 -0
- package/skills/typescript/references/enterprise-patterns.md +531 -0
- package/skills/typescript/references/generics.md +493 -0
- package/skills/typescript/references/nestjs-integration.md +579 -0
- package/skills/typescript/references/react-integration.md +616 -0
- package/skills/typescript/references/toolchain.md +547 -0
- package/skills/typescript/references/type-system.md +481 -0
- package/skills/vitest-standard/SKILL.md +82 -0
- package/skills/vitest-standard/examples/service-mock.ts +60 -0
- package/skills/vitest-standard/examples/tdd-calculator.ts +41 -0
- package/skills/vitest-standard/examples/type-stubs.d.ts +18 -0
- package/skills/vitest-standard/references/async-and-errors.md +58 -0
- package/skills/vitest-standard/references/coverage-and-config.md +53 -0
- package/skills/vitest-standard/references/mocking.md +61 -0
- package/skills/vitest-standard/references/tdd-patterns.md +60 -0
- package/dist/github-integration-FOJ4U6I5.js +0 -1
- package/skills/github-commander/workflows/full-audit.md +0 -134
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { transformAutoReturn } from './chunk-OKOVZ5QE.js';
|
|
2
|
-
import { GitHubIntegration, resolveAuthor, logger, assertSafeDirectoryPath, MemoryJournalMcpError, matchSuggestion, ConfigurationError } from './chunk-
|
|
2
|
+
import { GitHubIntegration, resolveAuthor, logger, ValidationError, ResourceNotFoundError, assertSafeDirectoryPath, MemoryJournalMcpError, matchSuggestion, ConfigurationError } from './chunk-IWKLHSPU.js';
|
|
3
3
|
import { z, ZodError } from 'zod';
|
|
4
4
|
import { open, stat, mkdir, rename, appendFile, readdir, readFile } from 'fs/promises';
|
|
5
5
|
import { tmpdir } from 'os';
|
|
@@ -59,7 +59,7 @@ async function resolveIssueUrl(context, projectNumber, issueNumber, existingUrl)
|
|
|
59
59
|
([_, v]) => v.project_number === projectNumber
|
|
60
60
|
);
|
|
61
61
|
if (entry) {
|
|
62
|
-
const { GitHubIntegration: GitHubIntegration2 } = await import('./github-integration-
|
|
62
|
+
const { GitHubIntegration: GitHubIntegration2 } = await import('./github-integration-2TFMXHIJ.js');
|
|
63
63
|
const targetGithub = new GitHubIntegration2(entry[1].path);
|
|
64
64
|
const repoInfo = await targetGithub.getRepoInfo();
|
|
65
65
|
if (repoInfo.owner && repoInfo.repo) {
|
|
@@ -114,6 +114,7 @@ var SIGNIFICANCE_TYPES = [
|
|
|
114
114
|
"release"
|
|
115
115
|
];
|
|
116
116
|
var MAX_CONTENT_LENGTH = 5e4;
|
|
117
|
+
var MAX_QUERY_LIMIT = 500;
|
|
117
118
|
var DATE_MIN_SENTINEL = "1970-01-01";
|
|
118
119
|
var DATE_MAX_SENTINEL = "2999-12-31";
|
|
119
120
|
var DATE_FORMAT_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
@@ -215,7 +216,7 @@ var GetEntryByIdSchemaMcp = z.object({
|
|
|
215
216
|
include_relationships: z.boolean().optional().default(true)
|
|
216
217
|
});
|
|
217
218
|
var GetRecentEntriesSchema = z.object({
|
|
218
|
-
limit: z.number().max(
|
|
219
|
+
limit: z.number().min(1).max(MAX_QUERY_LIMIT).optional().default(5),
|
|
219
220
|
is_personal: z.boolean().optional()
|
|
220
221
|
});
|
|
221
222
|
var GetRecentEntriesSchemaMcp = z.object({
|
|
@@ -452,7 +453,6 @@ function getCoreTools(context) {
|
|
|
452
453
|
}
|
|
453
454
|
|
|
454
455
|
// src/handlers/tools/search/helpers.ts
|
|
455
|
-
var MAX_QUERY_LIMIT = 500;
|
|
456
456
|
var DEDUP_KEY_LENGTH = 200;
|
|
457
457
|
function calcPerDbLimit(limit, hasTeamDb) {
|
|
458
458
|
return hasTeamDb ? Math.min(limit * 2, MAX_QUERY_LIMIT) : limit;
|
|
@@ -730,11 +730,23 @@ function getSearchTools(context) {
|
|
|
730
730
|
handler: async (params) => {
|
|
731
731
|
try {
|
|
732
732
|
const input = SearchEntriesSchema.parse(params);
|
|
733
|
-
const query = input.query || "";
|
|
733
|
+
const query = input.query?.trim() || "";
|
|
734
734
|
const mode = input.mode;
|
|
735
|
-
const { resolvedMode, isAuto } = resolveSearchMode(mode, query);
|
|
736
735
|
const hasFilters = input.project_number !== void 0 || input.issue_number !== void 0 || input.pr_number !== void 0 || input.pr_status !== void 0 || input.workflow_run_id !== void 0 || input.is_personal !== void 0 || input.tags !== void 0 || input.entry_type !== void 0 || input.start_date !== void 0 || input.end_date !== void 0;
|
|
737
|
-
|
|
736
|
+
if (!query && !hasFilters) {
|
|
737
|
+
return {
|
|
738
|
+
...formatHandlerError(
|
|
739
|
+
new ValidationError(
|
|
740
|
+
"Search requires either a query string or at least one filter",
|
|
741
|
+
{ suggestion: "Provide a search query or use get_recent_entries instead" }
|
|
742
|
+
)
|
|
743
|
+
),
|
|
744
|
+
entries: [],
|
|
745
|
+
count: 0
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
const { resolvedMode, isAuto } = resolveSearchMode(mode, query);
|
|
749
|
+
const effectiveMode = resolvedMode;
|
|
738
750
|
const searchOptions = {
|
|
739
751
|
limit: input.limit,
|
|
740
752
|
isPersonal: input.is_personal,
|
|
@@ -1320,10 +1332,10 @@ function getRelationshipTools(context) {
|
|
|
1320
1332
|
const input = LinkEntriesSchema.parse(params);
|
|
1321
1333
|
if (input.from_entry_id === input.to_entry_id) {
|
|
1322
1334
|
return {
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1335
|
+
...formatHandlerError(
|
|
1336
|
+
new ValidationError("Cannot link an entry to itself")
|
|
1337
|
+
),
|
|
1338
|
+
success: false
|
|
1327
1339
|
};
|
|
1328
1340
|
}
|
|
1329
1341
|
const existingRelationships = db.getRelationships(input.from_entry_id);
|
|
@@ -1358,12 +1370,13 @@ function getRelationshipTools(context) {
|
|
|
1358
1370
|
const isFkError = errMsg.includes("FOREIGN KEY constraint failed");
|
|
1359
1371
|
if (isFkError) {
|
|
1360
1372
|
return {
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1373
|
+
...formatHandlerError(
|
|
1374
|
+
new ResourceNotFoundError(
|
|
1375
|
+
"Entry",
|
|
1376
|
+
`from: ${String(input.from_entry_id)}, to: ${String(input.to_entry_id)}`
|
|
1377
|
+
)
|
|
1378
|
+
),
|
|
1379
|
+
success: false
|
|
1367
1380
|
};
|
|
1368
1381
|
}
|
|
1369
1382
|
}
|
|
@@ -2098,11 +2111,7 @@ ${e.content}
|
|
|
2098
2111
|
tags: e.tags,
|
|
2099
2112
|
significance: e.significanceType ?? void 0
|
|
2100
2113
|
}));
|
|
2101
|
-
const result = await exportEntriesToMarkdown(
|
|
2102
|
-
exportable,
|
|
2103
|
-
input.output_dir,
|
|
2104
|
-
db
|
|
2105
|
-
);
|
|
2114
|
+
const result = await exportEntriesToMarkdown(exportable, input.output_dir, db);
|
|
2106
2115
|
await sendProgress(progress, 3, 3, "Export complete");
|
|
2107
2116
|
return result;
|
|
2108
2117
|
} catch (err) {
|
|
@@ -2439,6 +2448,8 @@ var GitHubIssueOutputSchema = z.object({
|
|
|
2439
2448
|
}).extend(ErrorFieldsMixin.shape);
|
|
2440
2449
|
var GitHubIssueDetailsOutputSchema = GitHubIssueOutputSchema.extend({
|
|
2441
2450
|
body: z.string().nullable(),
|
|
2451
|
+
bodyTruncated: z.boolean().optional(),
|
|
2452
|
+
bodyFullLength: z.number().optional(),
|
|
2442
2453
|
labels: z.array(z.string()),
|
|
2443
2454
|
assignees: z.array(z.string()),
|
|
2444
2455
|
createdAt: z.string(),
|
|
@@ -2459,6 +2470,14 @@ var GitHubIssuesListOutputSchema = z.object({
|
|
|
2459
2470
|
}).extend(ErrorFieldsMixin.shape);
|
|
2460
2471
|
var GitHubIssueResultOutputSchema = z.object({
|
|
2461
2472
|
issue: GitHubIssueDetailsOutputSchema.optional(),
|
|
2473
|
+
comments: z.array(
|
|
2474
|
+
z.object({
|
|
2475
|
+
author: z.string(),
|
|
2476
|
+
body: z.string(),
|
|
2477
|
+
createdAt: z.string()
|
|
2478
|
+
})
|
|
2479
|
+
).optional(),
|
|
2480
|
+
commentCount: z.number().optional(),
|
|
2462
2481
|
owner: z.string().optional(),
|
|
2463
2482
|
repo: z.string().optional(),
|
|
2464
2483
|
detectedOwner: z.string().nullable().optional(),
|
|
@@ -2475,6 +2494,8 @@ var GitHubPullRequestOutputSchema = z.object({
|
|
|
2475
2494
|
}).extend(ErrorFieldsMixin.shape);
|
|
2476
2495
|
var GitHubPRDetailsOutputSchema = GitHubPullRequestOutputSchema.extend({
|
|
2477
2496
|
body: z.string().nullable(),
|
|
2497
|
+
bodyTruncated: z.boolean().optional(),
|
|
2498
|
+
bodyFullLength: z.number().optional(),
|
|
2478
2499
|
draft: z.boolean(),
|
|
2479
2500
|
headBranch: z.string(),
|
|
2480
2501
|
baseBranch: z.string(),
|
|
@@ -2539,7 +2560,9 @@ var StatusOptionOutputSchema = z.object({
|
|
|
2539
2560
|
var KanbanColumnOutputSchema = z.object({
|
|
2540
2561
|
status: z.string(),
|
|
2541
2562
|
statusOptionId: z.string(),
|
|
2542
|
-
items: z.array(KanbanItemOutputSchema)
|
|
2563
|
+
items: z.array(KanbanItemOutputSchema).optional(),
|
|
2564
|
+
itemCount: z.number().optional(),
|
|
2565
|
+
truncated: z.boolean().optional()
|
|
2543
2566
|
});
|
|
2544
2567
|
var KanbanBoardOutputSchema = z.object({
|
|
2545
2568
|
projectId: z.string().optional(),
|
|
@@ -2549,6 +2572,14 @@ var KanbanBoardOutputSchema = z.object({
|
|
|
2549
2572
|
statusOptions: z.array(StatusOptionOutputSchema).optional(),
|
|
2550
2573
|
columns: z.array(KanbanColumnOutputSchema).optional(),
|
|
2551
2574
|
totalItems: z.number().optional(),
|
|
2575
|
+
itemDirectory: z.array(
|
|
2576
|
+
z.object({
|
|
2577
|
+
id: z.string(),
|
|
2578
|
+
title: z.string(),
|
|
2579
|
+
status: z.string().nullable()
|
|
2580
|
+
})
|
|
2581
|
+
).optional(),
|
|
2582
|
+
summaryOnly: z.boolean().optional(),
|
|
2552
2583
|
owner: z.string().optional(),
|
|
2553
2584
|
detectedOwner: z.string().nullable().optional(),
|
|
2554
2585
|
detectedRepo: z.string().nullable().optional(),
|
|
@@ -2558,16 +2589,19 @@ var KanbanBoardOutputSchema = z.object({
|
|
|
2558
2589
|
instruction: z.string().optional()
|
|
2559
2590
|
}).extend(ErrorFieldsMixin.shape);
|
|
2560
2591
|
var MoveKanbanItemOutputSchema = z.object({
|
|
2561
|
-
success: z.boolean().optional(),
|
|
2562
2592
|
itemId: z.string().optional(),
|
|
2563
2593
|
newStatus: z.string().optional(),
|
|
2564
2594
|
projectNumber: z.number().optional(),
|
|
2565
|
-
message: z.string().optional(),
|
|
2566
|
-
error: z.string().optional(),
|
|
2567
|
-
requiresUserInput: z.boolean().optional(),
|
|
2568
|
-
hint: z.string().optional(),
|
|
2569
2595
|
availableStatuses: z.array(z.string()).optional()
|
|
2570
2596
|
}).extend(ErrorFieldsMixin.shape);
|
|
2597
|
+
var AddKanbanItemOutputSchema = z.object({
|
|
2598
|
+
itemId: z.string().optional(),
|
|
2599
|
+
projectNumber: z.number().optional()
|
|
2600
|
+
}).extend(ErrorFieldsMixin.shape);
|
|
2601
|
+
var DeleteKanbanItemOutputSchema = z.object({
|
|
2602
|
+
itemId: z.string().optional(),
|
|
2603
|
+
projectNumber: z.number().optional()
|
|
2604
|
+
}).extend(ErrorFieldsMixin.shape);
|
|
2571
2605
|
var CreateGitHubIssueWithEntryOutputSchema = z.object({
|
|
2572
2606
|
success: z.boolean().optional(),
|
|
2573
2607
|
issue: z.object({
|
|
@@ -2858,7 +2892,7 @@ function getGitHubReadTools(context) {
|
|
|
2858
2892
|
owner: z.string().optional(),
|
|
2859
2893
|
repo: z.string().optional(),
|
|
2860
2894
|
state: z.enum(["open", "closed", "all"]).optional().default("open"),
|
|
2861
|
-
limit: z.number().optional().default(20)
|
|
2895
|
+
limit: z.number().max(MAX_QUERY_LIMIT).optional().default(20)
|
|
2862
2896
|
}).parse(params);
|
|
2863
2897
|
const resolved = await resolveOwnerRepo(
|
|
2864
2898
|
context,
|
|
@@ -2908,7 +2942,7 @@ function getGitHubReadTools(context) {
|
|
|
2908
2942
|
owner: z.string().optional(),
|
|
2909
2943
|
repo: z.string().optional(),
|
|
2910
2944
|
state: z.enum(["open", "closed", "all"]).optional().default("open"),
|
|
2911
|
-
limit: z.number().optional().default(20)
|
|
2945
|
+
limit: z.number().max(MAX_QUERY_LIMIT).optional().default(20)
|
|
2912
2946
|
}).parse(params);
|
|
2913
2947
|
const resolved = await resolveOwnerRepo(
|
|
2914
2948
|
context,
|
|
@@ -2943,7 +2977,11 @@ function getGitHubReadTools(context) {
|
|
|
2943
2977
|
inputSchema: z.object({
|
|
2944
2978
|
issue_number: z.number(),
|
|
2945
2979
|
owner: z.string().optional().describe("LEAVE EMPTY to auto-detect from git"),
|
|
2946
|
-
repo: z.string().optional().describe("LEAVE EMPTY to auto-detect from git")
|
|
2980
|
+
repo: z.string().optional().describe("LEAVE EMPTY to auto-detect from git"),
|
|
2981
|
+
truncate_body: relaxedNumber().optional().default(800).describe(
|
|
2982
|
+
"Max characters for body text (0 = full body, default 800). Reduces token usage."
|
|
2983
|
+
),
|
|
2984
|
+
include_comments: z.boolean().optional().default(false).describe("Include issue comments (default false). Each comment adds tokens.")
|
|
2947
2985
|
}),
|
|
2948
2986
|
outputSchema: GitHubIssueResultOutputSchema,
|
|
2949
2987
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
@@ -2952,7 +2990,9 @@ function getGitHubReadTools(context) {
|
|
|
2952
2990
|
const input = z.object({
|
|
2953
2991
|
issue_number: z.number(),
|
|
2954
2992
|
owner: z.string().optional(),
|
|
2955
|
-
repo: z.string().optional()
|
|
2993
|
+
repo: z.string().optional(),
|
|
2994
|
+
truncate_body: z.number().optional().default(800),
|
|
2995
|
+
include_comments: z.boolean().optional().default(false)
|
|
2956
2996
|
}).parse(params);
|
|
2957
2997
|
const resolved = await resolveOwnerRepo(context, input, "is this issue from");
|
|
2958
2998
|
if ("error" in resolved) return resolved.response;
|
|
@@ -2975,8 +3015,30 @@ function getGitHubReadTools(context) {
|
|
|
2975
3015
|
detectedRepo: resolved.detectedRepo
|
|
2976
3016
|
};
|
|
2977
3017
|
}
|
|
3018
|
+
const truncateBody = input.truncate_body;
|
|
3019
|
+
let bodyTruncated = false;
|
|
3020
|
+
let bodyFullLength;
|
|
3021
|
+
if (truncateBody > 0 && issue.body && issue.body.length > truncateBody) {
|
|
3022
|
+
bodyFullLength = issue.body.length;
|
|
3023
|
+
const remaining = issue.body.length - truncateBody;
|
|
3024
|
+
issue.body = issue.body.slice(0, truncateBody) + `
|
|
3025
|
+
[Truncated. Re-run with truncate_body: 0 to view remaining ${String(remaining)} chars]`;
|
|
3026
|
+
bodyTruncated = true;
|
|
3027
|
+
}
|
|
3028
|
+
let comments;
|
|
3029
|
+
if (input.include_comments) {
|
|
3030
|
+
comments = await resolved.github.getIssueComments(
|
|
3031
|
+
resolved.owner,
|
|
3032
|
+
resolved.repo,
|
|
3033
|
+
input.issue_number
|
|
3034
|
+
);
|
|
3035
|
+
}
|
|
2978
3036
|
return {
|
|
2979
|
-
issue
|
|
3037
|
+
issue: {
|
|
3038
|
+
...issue,
|
|
3039
|
+
...bodyTruncated ? { bodyTruncated: true, bodyFullLength } : {}
|
|
3040
|
+
},
|
|
3041
|
+
...comments ? { comments, commentCount: comments.length } : {},
|
|
2980
3042
|
owner: resolved.owner,
|
|
2981
3043
|
repo: resolved.repo,
|
|
2982
3044
|
detectedOwner: resolved.detectedOwner,
|
|
@@ -2995,7 +3057,10 @@ function getGitHubReadTools(context) {
|
|
|
2995
3057
|
inputSchema: z.object({
|
|
2996
3058
|
pr_number: z.number(),
|
|
2997
3059
|
owner: z.string().optional().describe("LEAVE EMPTY to auto-detect from git"),
|
|
2998
|
-
repo: z.string().optional().describe("LEAVE EMPTY to auto-detect from git")
|
|
3060
|
+
repo: z.string().optional().describe("LEAVE EMPTY to auto-detect from git"),
|
|
3061
|
+
truncate_body: relaxedNumber().optional().default(800).describe(
|
|
3062
|
+
"Max characters for body text (0 = full body, default 800). Reduces token usage."
|
|
3063
|
+
)
|
|
2999
3064
|
}),
|
|
3000
3065
|
outputSchema: GitHubPRResultOutputSchema,
|
|
3001
3066
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
@@ -3004,7 +3069,8 @@ function getGitHubReadTools(context) {
|
|
|
3004
3069
|
const input = z.object({
|
|
3005
3070
|
pr_number: z.number(),
|
|
3006
3071
|
owner: z.string().optional(),
|
|
3007
|
-
repo: z.string().optional()
|
|
3072
|
+
repo: z.string().optional(),
|
|
3073
|
+
truncate_body: z.number().optional().default(800)
|
|
3008
3074
|
}).parse(params);
|
|
3009
3075
|
const resolved = await resolveOwnerRepo(context, input, "is this PR from");
|
|
3010
3076
|
if ("error" in resolved) return resolved.response;
|
|
@@ -3027,8 +3093,21 @@ function getGitHubReadTools(context) {
|
|
|
3027
3093
|
detectedRepo: resolved.detectedRepo
|
|
3028
3094
|
};
|
|
3029
3095
|
}
|
|
3096
|
+
const truncateBody = input.truncate_body;
|
|
3097
|
+
let bodyTruncated = false;
|
|
3098
|
+
let bodyFullLength;
|
|
3099
|
+
if (truncateBody > 0 && pullRequest.body && pullRequest.body.length > truncateBody) {
|
|
3100
|
+
bodyFullLength = pullRequest.body.length;
|
|
3101
|
+
const remaining = pullRequest.body.length - truncateBody;
|
|
3102
|
+
pullRequest.body = pullRequest.body.slice(0, truncateBody) + `
|
|
3103
|
+
[Truncated. Re-run with truncate_body: 0 to view remaining ${String(remaining)} chars]`;
|
|
3104
|
+
bodyTruncated = true;
|
|
3105
|
+
}
|
|
3030
3106
|
return {
|
|
3031
|
-
pullRequest
|
|
3107
|
+
pullRequest: {
|
|
3108
|
+
...pullRequest,
|
|
3109
|
+
...bodyTruncated ? { bodyTruncated: true, bodyFullLength } : {}
|
|
3110
|
+
},
|
|
3032
3111
|
owner: resolved.owner,
|
|
3033
3112
|
repo: resolved.repo,
|
|
3034
3113
|
detectedOwner: resolved.detectedOwner,
|
|
@@ -3096,7 +3175,13 @@ function getKanbanTools(context) {
|
|
|
3096
3175
|
inputSchema: z.object({
|
|
3097
3176
|
project_number: z.number().optional().describe("GitHub Project number (optional if repo is registered)"),
|
|
3098
3177
|
owner: z.string().optional().describe("Project owner - LEAVE EMPTY to auto-detect"),
|
|
3099
|
-
repo: z.string().optional().describe("Repository name - LEAVE EMPTY to auto-detect")
|
|
3178
|
+
repo: z.string().optional().describe("Repository name - LEAVE EMPTY to auto-detect"),
|
|
3179
|
+
summary_only: z.boolean().optional().default(false).describe(
|
|
3180
|
+
"Return column summaries only (name + itemCount), omitting individual items. Saves ~80% tokens."
|
|
3181
|
+
),
|
|
3182
|
+
item_limit: relaxedNumber().optional().default(25).describe(
|
|
3183
|
+
"Maximum items per column (default 25, max 100). Set to 0 for summary_only behavior."
|
|
3184
|
+
)
|
|
3100
3185
|
}),
|
|
3101
3186
|
outputSchema: KanbanBoardOutputSchema,
|
|
3102
3187
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
@@ -3105,7 +3190,9 @@ function getKanbanTools(context) {
|
|
|
3105
3190
|
const input = z.object({
|
|
3106
3191
|
project_number: z.number().optional(),
|
|
3107
3192
|
owner: z.string().optional(),
|
|
3108
|
-
repo: z.string().optional()
|
|
3193
|
+
repo: z.string().optional(),
|
|
3194
|
+
summary_only: z.boolean().optional().default(false),
|
|
3195
|
+
item_limit: z.number().max(100).optional().default(25)
|
|
3109
3196
|
}).parse(params);
|
|
3110
3197
|
const resolved = await resolveOwner(context, input.owner);
|
|
3111
3198
|
if ("error" in resolved) return resolved.response;
|
|
@@ -3144,7 +3231,44 @@ function getKanbanTools(context) {
|
|
|
3144
3231
|
recoverable: true
|
|
3145
3232
|
};
|
|
3146
3233
|
}
|
|
3147
|
-
|
|
3234
|
+
const summaryOnly = input.summary_only || input.item_limit === 0;
|
|
3235
|
+
if (summaryOnly) {
|
|
3236
|
+
const summaryColumns = board.columns.map((col) => ({
|
|
3237
|
+
status: col.status,
|
|
3238
|
+
statusOptionId: col.statusOptionId,
|
|
3239
|
+
items: [],
|
|
3240
|
+
itemCount: col.items.length
|
|
3241
|
+
}));
|
|
3242
|
+
const itemDirectory = board.columns.flatMap(
|
|
3243
|
+
(col) => col.items.map((item) => ({
|
|
3244
|
+
id: item.id,
|
|
3245
|
+
title: item.title,
|
|
3246
|
+
status: item.status
|
|
3247
|
+
}))
|
|
3248
|
+
);
|
|
3249
|
+
return {
|
|
3250
|
+
...board,
|
|
3251
|
+
columns: summaryColumns,
|
|
3252
|
+
summaryOnly: true,
|
|
3253
|
+
itemDirectory
|
|
3254
|
+
};
|
|
3255
|
+
}
|
|
3256
|
+
const itemLimit = input.item_limit;
|
|
3257
|
+
const truncatedColumns = board.columns.map((col) => {
|
|
3258
|
+
if (col.items.length <= itemLimit) {
|
|
3259
|
+
return { ...col, itemCount: col.items.length };
|
|
3260
|
+
}
|
|
3261
|
+
return {
|
|
3262
|
+
...col,
|
|
3263
|
+
items: col.items.slice(0, itemLimit),
|
|
3264
|
+
itemCount: col.items.length,
|
|
3265
|
+
truncated: true
|
|
3266
|
+
};
|
|
3267
|
+
});
|
|
3268
|
+
return {
|
|
3269
|
+
...board,
|
|
3270
|
+
columns: truncatedColumns
|
|
3271
|
+
};
|
|
3148
3272
|
} catch (err) {
|
|
3149
3273
|
return formatHandlerError(err);
|
|
3150
3274
|
}
|
|
@@ -3237,6 +3361,155 @@ function getKanbanTools(context) {
|
|
|
3237
3361
|
return formatHandlerError(err);
|
|
3238
3362
|
}
|
|
3239
3363
|
}
|
|
3364
|
+
},
|
|
3365
|
+
{
|
|
3366
|
+
name: "add_kanban_item",
|
|
3367
|
+
title: "Add Kanban Item",
|
|
3368
|
+
description: "Add an existing GitHub Issue or Pull Request to a Kanban board (GitHub Project v2). Returns the project item ID on success.",
|
|
3369
|
+
group: "github",
|
|
3370
|
+
inputSchema: z.object({
|
|
3371
|
+
project_number: z.number().optional().describe("GitHub Project number (optional if repo is registered)"),
|
|
3372
|
+
issue_number: z.number().describe("The number of the issue or PR to add"),
|
|
3373
|
+
owner: z.string().optional().describe("Repository owner - LEAVE EMPTY to auto-detect"),
|
|
3374
|
+
repo: z.string().optional().describe("Repository name - LEAVE EMPTY to auto-detect")
|
|
3375
|
+
}),
|
|
3376
|
+
outputSchema: AddKanbanItemOutputSchema,
|
|
3377
|
+
annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: true },
|
|
3378
|
+
handler: async (params) => {
|
|
3379
|
+
try {
|
|
3380
|
+
const input = z.object({
|
|
3381
|
+
project_number: z.number().optional(),
|
|
3382
|
+
issue_number: z.number(),
|
|
3383
|
+
owner: z.string().optional(),
|
|
3384
|
+
repo: z.string().optional()
|
|
3385
|
+
}).parse(params);
|
|
3386
|
+
const resolved = await resolveOwnerRepo(context, input);
|
|
3387
|
+
if ("error" in resolved) return resolved.response;
|
|
3388
|
+
const projectNum = resolveProjectNumber(
|
|
3389
|
+
context,
|
|
3390
|
+
resolved.repo,
|
|
3391
|
+
input.project_number
|
|
3392
|
+
);
|
|
3393
|
+
if (projectNum === void 0) {
|
|
3394
|
+
return {
|
|
3395
|
+
success: false,
|
|
3396
|
+
error: "project_number is required and could not be resolved from registry. Please supply it explicitly.",
|
|
3397
|
+
code: "VALIDATION_ERROR",
|
|
3398
|
+
category: "validation",
|
|
3399
|
+
recoverable: true
|
|
3400
|
+
};
|
|
3401
|
+
}
|
|
3402
|
+
const issueDetails = await resolved.github.getIssue(
|
|
3403
|
+
resolved.owner,
|
|
3404
|
+
resolved.repo,
|
|
3405
|
+
input.issue_number
|
|
3406
|
+
);
|
|
3407
|
+
if (!issueDetails?.nodeId) {
|
|
3408
|
+
return {
|
|
3409
|
+
success: false,
|
|
3410
|
+
error: `Issue or PR #${String(input.issue_number)} not found or lacks a nodeId`,
|
|
3411
|
+
code: "RESOURCE_NOT_FOUND",
|
|
3412
|
+
category: "resource",
|
|
3413
|
+
recoverable: true
|
|
3414
|
+
};
|
|
3415
|
+
}
|
|
3416
|
+
const board = await resolved.github.getProjectKanban(
|
|
3417
|
+
resolved.owner,
|
|
3418
|
+
projectNum,
|
|
3419
|
+
resolved.repo
|
|
3420
|
+
);
|
|
3421
|
+
if (!board) {
|
|
3422
|
+
return {
|
|
3423
|
+
success: false,
|
|
3424
|
+
error: `Project #${String(projectNum)} not found`,
|
|
3425
|
+
code: "RESOURCE_NOT_FOUND",
|
|
3426
|
+
category: "resource",
|
|
3427
|
+
recoverable: true
|
|
3428
|
+
};
|
|
3429
|
+
}
|
|
3430
|
+
const result = await resolved.github.addProjectItem(
|
|
3431
|
+
board.projectId,
|
|
3432
|
+
issueDetails.nodeId
|
|
3433
|
+
);
|
|
3434
|
+
return {
|
|
3435
|
+
success: result.success,
|
|
3436
|
+
itemId: result.itemId,
|
|
3437
|
+
projectNumber: projectNum,
|
|
3438
|
+
message: result.success ? `Added Issue/PR #${String(input.issue_number)} to Project #${projectNum}` : void 0,
|
|
3439
|
+
error: result.error
|
|
3440
|
+
};
|
|
3441
|
+
} catch (err) {
|
|
3442
|
+
return formatHandlerError(err);
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3445
|
+
},
|
|
3446
|
+
{
|
|
3447
|
+
name: "delete_kanban_item",
|
|
3448
|
+
title: "Delete Kanban Item",
|
|
3449
|
+
description: "Remove an item from a GitHub Kanban board cleanly. This untethers it from the project but does NOT close or delete the underlying Issue/PR.",
|
|
3450
|
+
group: "github",
|
|
3451
|
+
inputSchema: z.object({
|
|
3452
|
+
project_number: z.number().optional().describe("GitHub Project number (optional if repo is registered)"),
|
|
3453
|
+
item_id: z.string().describe("The project item ID to remove (from get_kanban_board)"),
|
|
3454
|
+
owner: z.string().optional().describe("Project owner - LEAVE EMPTY to auto-detect"),
|
|
3455
|
+
repo: z.string().optional().describe("Repository name - LEAVE EMPTY to auto-detect")
|
|
3456
|
+
}),
|
|
3457
|
+
outputSchema: DeleteKanbanItemOutputSchema,
|
|
3458
|
+
annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: true },
|
|
3459
|
+
handler: async (params) => {
|
|
3460
|
+
try {
|
|
3461
|
+
const input = z.object({
|
|
3462
|
+
project_number: z.number().optional(),
|
|
3463
|
+
item_id: z.string(),
|
|
3464
|
+
owner: z.string().optional(),
|
|
3465
|
+
repo: z.string().optional()
|
|
3466
|
+
}).parse(params);
|
|
3467
|
+
const resolved = await resolveOwner(context, input.owner);
|
|
3468
|
+
if ("error" in resolved) return resolved.response;
|
|
3469
|
+
const effectiveRepo = input.repo ?? resolved.repo;
|
|
3470
|
+
const projectNum = resolveProjectNumber(
|
|
3471
|
+
context,
|
|
3472
|
+
effectiveRepo,
|
|
3473
|
+
input.project_number
|
|
3474
|
+
);
|
|
3475
|
+
if (projectNum === void 0) {
|
|
3476
|
+
return {
|
|
3477
|
+
success: false,
|
|
3478
|
+
error: "project_number is required and could not be resolved from registry. Please supply it explicitly.",
|
|
3479
|
+
code: "VALIDATION_ERROR",
|
|
3480
|
+
category: "validation",
|
|
3481
|
+
recoverable: true
|
|
3482
|
+
};
|
|
3483
|
+
}
|
|
3484
|
+
const board = await resolved.github.getProjectKanban(
|
|
3485
|
+
resolved.owner,
|
|
3486
|
+
projectNum,
|
|
3487
|
+
effectiveRepo
|
|
3488
|
+
);
|
|
3489
|
+
if (!board) {
|
|
3490
|
+
return {
|
|
3491
|
+
success: false,
|
|
3492
|
+
error: `Project #${String(projectNum)} not found`,
|
|
3493
|
+
code: "RESOURCE_NOT_FOUND",
|
|
3494
|
+
category: "resource",
|
|
3495
|
+
recoverable: true
|
|
3496
|
+
};
|
|
3497
|
+
}
|
|
3498
|
+
const result = await resolved.github.deleteProjectItem(
|
|
3499
|
+
board.projectId,
|
|
3500
|
+
input.item_id
|
|
3501
|
+
);
|
|
3502
|
+
return {
|
|
3503
|
+
success: result.success,
|
|
3504
|
+
itemId: input.item_id,
|
|
3505
|
+
projectNumber: projectNum,
|
|
3506
|
+
message: result.success ? `Deleted item ${input.item_id} from Project #${projectNum}` : void 0,
|
|
3507
|
+
error: result.error
|
|
3508
|
+
};
|
|
3509
|
+
} catch (err) {
|
|
3510
|
+
return formatHandlerError(err);
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3240
3513
|
}
|
|
3241
3514
|
];
|
|
3242
3515
|
}
|
|
@@ -3294,7 +3567,11 @@ function getGitHubIssueTools(context) {
|
|
|
3294
3567
|
if (!issue) {
|
|
3295
3568
|
return {
|
|
3296
3569
|
success: false,
|
|
3297
|
-
error: "Failed to create GitHub issue. Check GITHUB_TOKEN permissions."
|
|
3570
|
+
error: "Failed to create GitHub issue. Check GITHUB_TOKEN permissions.",
|
|
3571
|
+
code: "API_ERROR",
|
|
3572
|
+
category: "api",
|
|
3573
|
+
suggestion: "Verify GitHub token has write access to issues.",
|
|
3574
|
+
recoverable: true
|
|
3298
3575
|
};
|
|
3299
3576
|
}
|
|
3300
3577
|
const projectNumber = resolveProjectNumber(
|
|
@@ -3453,13 +3730,21 @@ Description: ${input.body.slice(0, 200)}${input.body.length > 200 ? "..." : ""}`
|
|
|
3453
3730
|
if (!issueDetails) {
|
|
3454
3731
|
return {
|
|
3455
3732
|
success: false,
|
|
3456
|
-
error: `Issue #${String(input.issue_number)} not found
|
|
3733
|
+
error: `Issue #${String(input.issue_number)} not found`,
|
|
3734
|
+
code: "RESOURCE_NOT_FOUND",
|
|
3735
|
+
category: "resource",
|
|
3736
|
+
suggestion: "Verify the issue number exists in this repository.",
|
|
3737
|
+
recoverable: true
|
|
3457
3738
|
};
|
|
3458
3739
|
}
|
|
3459
3740
|
if (issueDetails.state === "CLOSED") {
|
|
3460
3741
|
return {
|
|
3461
|
-
|
|
3462
|
-
|
|
3742
|
+
...formatHandlerError(
|
|
3743
|
+
new ValidationError(
|
|
3744
|
+
`Issue #${String(input.issue_number)} is already closed`
|
|
3745
|
+
)
|
|
3746
|
+
),
|
|
3747
|
+
success: false
|
|
3463
3748
|
};
|
|
3464
3749
|
}
|
|
3465
3750
|
const result = await resolved.github.closeIssue(
|
|
@@ -3471,7 +3756,11 @@ Description: ${input.body.slice(0, 200)}${input.body.length > 200 ? "..." : ""}`
|
|
|
3471
3756
|
if (!result) {
|
|
3472
3757
|
return {
|
|
3473
3758
|
success: false,
|
|
3474
|
-
error: "Failed to close GitHub issue. Check GITHUB_TOKEN permissions."
|
|
3759
|
+
error: "Failed to close GitHub issue. Check GITHUB_TOKEN permissions.",
|
|
3760
|
+
code: "API_ERROR",
|
|
3761
|
+
category: "api",
|
|
3762
|
+
suggestion: "Verify GitHub token has write access to issues.",
|
|
3763
|
+
recoverable: true
|
|
3475
3764
|
};
|
|
3476
3765
|
}
|
|
3477
3766
|
let kanbanResult;
|
|
@@ -3630,10 +3919,12 @@ function isResourceError(result) {
|
|
|
3630
3919
|
}
|
|
3631
3920
|
var DEFAULT_BRIEFING_CONFIG = {
|
|
3632
3921
|
entryCount: 3,
|
|
3922
|
+
summaryCount: 1,
|
|
3633
3923
|
includeTeam: false,
|
|
3634
3924
|
issueCount: 0,
|
|
3635
3925
|
prCount: 0,
|
|
3636
3926
|
prStatusBreakdown: false,
|
|
3927
|
+
milestoneCount: 3,
|
|
3637
3928
|
workflowCount: 0,
|
|
3638
3929
|
workflowStatusBreakdown: false,
|
|
3639
3930
|
copilotReviews: false
|
|
@@ -4373,7 +4664,7 @@ var TeamCreateEntrySchemaMcp = z.object({
|
|
|
4373
4664
|
author: z.string().optional()
|
|
4374
4665
|
});
|
|
4375
4666
|
var TeamGetRecentSchema = z.object({
|
|
4376
|
-
limit: z.number().max(500).optional().default(10)
|
|
4667
|
+
limit: z.number().min(1).max(500).optional().default(10)
|
|
4377
4668
|
});
|
|
4378
4669
|
var TeamGetRecentSchemaMcp = z.object({
|
|
4379
4670
|
limit: relaxedNumber().optional().default(10)
|
|
@@ -6021,6 +6312,8 @@ var METHOD_ALIASES = {
|
|
|
6021
6312
|
context: "getGithubContext",
|
|
6022
6313
|
kanban: "getKanbanBoard",
|
|
6023
6314
|
moveKanban: "moveKanbanItem",
|
|
6315
|
+
addKanban: "addKanbanItem",
|
|
6316
|
+
deleteKanban: "deleteKanbanItem",
|
|
6024
6317
|
milestones: "getGithubMilestones",
|
|
6025
6318
|
milestone: "getGithubMilestone",
|
|
6026
6319
|
createMilestone: "createGithubMilestone",
|
|
@@ -6095,6 +6388,7 @@ var GROUP_EXAMPLES = {
|
|
|
6095
6388
|
'mj.github.getGithubIssues({ state: "open" })',
|
|
6096
6389
|
'mj.github.getGithubPrs({ state: "open" })',
|
|
6097
6390
|
"mj.github.getKanbanBoard({ project_number: 1 })",
|
|
6391
|
+
"mj.github.addKanbanItem({ project_number: 1, issue_number: 123 })",
|
|
6098
6392
|
"mj.github.getGithubMilestones()",
|
|
6099
6393
|
"mj.github.getRepoInsights()"
|
|
6100
6394
|
],
|
|
@@ -6143,7 +6437,9 @@ var POSITIONAL_PARAM_MAP = {
|
|
|
6143
6437
|
getGithubIssue: "issue_number",
|
|
6144
6438
|
getGithubPr: "pr_number",
|
|
6145
6439
|
getKanbanBoard: "project_number",
|
|
6146
|
-
moveKanbanItem: ["item_id", "
|
|
6440
|
+
moveKanbanItem: ["item_id", "target_status"],
|
|
6441
|
+
addKanbanItem: "issue_number",
|
|
6442
|
+
deleteKanbanItem: "item_id",
|
|
6147
6443
|
getGithubMilestone: "milestone_number",
|
|
6148
6444
|
createGithubMilestone: "title",
|
|
6149
6445
|
updateGithubMilestone: "milestone_number",
|
|
@@ -6377,8 +6673,8 @@ var DEFAULT_SECURITY_CONFIG = {
|
|
|
6377
6673
|
maxCodeLength: 50 * 1024,
|
|
6378
6674
|
// 50KB
|
|
6379
6675
|
maxExecutionsPerMinute: 60,
|
|
6380
|
-
maxResultSize:
|
|
6381
|
-
//
|
|
6676
|
+
maxResultSize: 100 * 1024,
|
|
6677
|
+
// 100KB — context window protection (configurable via CODE_MODE_MAX_RESULT_SIZE)
|
|
6382
6678
|
blockedPatterns: [
|
|
6383
6679
|
/\brequire\s*\(/,
|
|
6384
6680
|
// No require()
|
|
@@ -6493,9 +6789,12 @@ var CodeModeSecurityManager = class {
|
|
|
6493
6789
|
const errors = [];
|
|
6494
6790
|
try {
|
|
6495
6791
|
const serialized = JSON.stringify(result);
|
|
6496
|
-
|
|
6792
|
+
const actualBytes = Buffer.byteLength(serialized, "utf-8");
|
|
6793
|
+
if (actualBytes > this.config.maxResultSize) {
|
|
6794
|
+
const actualKb = Math.ceil(actualBytes / 1024);
|
|
6795
|
+
const limitKb = Math.ceil(this.config.maxResultSize / 1024);
|
|
6497
6796
|
errors.push(
|
|
6498
|
-
`Result exceeds maximum size of ${String(
|
|
6797
|
+
`Result exceeds maximum size of ${String(limitKb)} KB (${String(actualKb)} KB returned). Extract specific fields or aggregate data before returning. Example: instead of \`return await mj.github.getKanbanBoard(5)\`, use \`const b = await mj.github.getKanbanBoard(5); return { columns: b.columns?.length ?? 0, totalItems: b.totalItems }\``
|
|
6499
6798
|
);
|
|
6500
6799
|
}
|
|
6501
6800
|
} catch (error) {
|
|
@@ -6871,7 +7170,12 @@ var ExecuteCodeSchemaMcp = z.object({
|
|
|
6871
7170
|
var securityManager = null;
|
|
6872
7171
|
var sandboxPool = null;
|
|
6873
7172
|
function getSecurityManager() {
|
|
6874
|
-
|
|
7173
|
+
if (!securityManager) {
|
|
7174
|
+
const envMaxSize = process.env["CODE_MODE_MAX_RESULT_SIZE"];
|
|
7175
|
+
const parsedMaxSize = envMaxSize && /^\d+$/.test(envMaxSize) ? parseInt(envMaxSize, 10) : void 0;
|
|
7176
|
+
const overrides = parsedMaxSize !== void 0 && Number.isFinite(parsedMaxSize) && Number.isInteger(parsedMaxSize) && parsedMaxSize > 0 ? { maxResultSize: parsedMaxSize } : void 0;
|
|
7177
|
+
securityManager = new CodeModeSecurityManager(overrides);
|
|
7178
|
+
}
|
|
6875
7179
|
return securityManager;
|
|
6876
7180
|
}
|
|
6877
7181
|
function getSandboxPool() {
|
|
@@ -7343,6 +7647,8 @@ var TOOL_GROUPS = {
|
|
|
7343
7647
|
"get_github_context",
|
|
7344
7648
|
"get_kanban_board",
|
|
7345
7649
|
"move_kanban_item",
|
|
7650
|
+
"add_kanban_item",
|
|
7651
|
+
"delete_kanban_item",
|
|
7346
7652
|
"create_github_issue_with_entry",
|
|
7347
7653
|
"close_github_issue_with_entry",
|
|
7348
7654
|
"get_github_milestones",
|