@selfagency/beans-mcp 0.4.2 → 0.5.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 +86 -12
- package/beans-mcp-server.cjs +451 -124
- package/index.cjs +451 -124
- package/index.d.ts +99 -0
- package/index.js +451 -124
- package/package.json +7 -6
package/beans-mcp-server.cjs
CHANGED
|
@@ -14433,7 +14433,7 @@ var init_v4 = __esm({
|
|
|
14433
14433
|
}
|
|
14434
14434
|
});
|
|
14435
14435
|
|
|
14436
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
14436
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
14437
14437
|
function assertCompleteRequestPrompt(request) {
|
|
14438
14438
|
if (request.params.ref.type !== "ref/prompt") {
|
|
14439
14439
|
throw new TypeError(`Expected CompleteRequestPrompt, but got ${request.params.ref.type}`);
|
|
@@ -14448,7 +14448,7 @@ function assertCompleteRequestResourceTemplate(request) {
|
|
|
14448
14448
|
}
|
|
14449
14449
|
var LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, RELATED_TASK_META_KEY, JSONRPC_VERSION, AssertObjectSchema, ProgressTokenSchema, CursorSchema, TaskCreationParamsSchema, TaskMetadataSchema, RelatedTaskMetadataSchema, RequestMetaSchema, BaseRequestParamsSchema, TaskAugmentedRequestParamsSchema, isTaskAugmentedRequestParams, RequestSchema, NotificationsParamsSchema, NotificationSchema, ResultSchema, RequestIdSchema, JSONRPCRequestSchema, isJSONRPCRequest, JSONRPCNotificationSchema, isJSONRPCNotification, JSONRPCResultResponseSchema, isJSONRPCResultResponse, ErrorCode, JSONRPCErrorResponseSchema, isJSONRPCErrorResponse, JSONRPCMessageSchema, JSONRPCResponseSchema, EmptyResultSchema, CancelledNotificationParamsSchema, CancelledNotificationSchema, IconSchema, IconsSchema, BaseMetadataSchema, ImplementationSchema, FormElicitationCapabilitySchema, ElicitationCapabilitySchema, ClientTasksCapabilitySchema, ServerTasksCapabilitySchema, ClientCapabilitiesSchema, InitializeRequestParamsSchema, InitializeRequestSchema, ServerCapabilitiesSchema, InitializeResultSchema, InitializedNotificationSchema, PingRequestSchema, ProgressSchema, ProgressNotificationParamsSchema, ProgressNotificationSchema, PaginatedRequestParamsSchema, PaginatedRequestSchema, PaginatedResultSchema, TaskStatusSchema, TaskSchema, CreateTaskResultSchema, TaskStatusNotificationParamsSchema, TaskStatusNotificationSchema, GetTaskRequestSchema, GetTaskResultSchema, GetTaskPayloadRequestSchema, GetTaskPayloadResultSchema, ListTasksRequestSchema, ListTasksResultSchema, CancelTaskRequestSchema, CancelTaskResultSchema, ResourceContentsSchema, TextResourceContentsSchema, Base64Schema, BlobResourceContentsSchema, RoleSchema, AnnotationsSchema, ResourceSchema, ResourceTemplateSchema, ListResourcesRequestSchema, ListResourcesResultSchema, ListResourceTemplatesRequestSchema, ListResourceTemplatesResultSchema, ResourceRequestParamsSchema, ReadResourceRequestParamsSchema, ReadResourceRequestSchema, ReadResourceResultSchema, ResourceListChangedNotificationSchema, SubscribeRequestParamsSchema, SubscribeRequestSchema, UnsubscribeRequestParamsSchema, UnsubscribeRequestSchema, ResourceUpdatedNotificationParamsSchema, ResourceUpdatedNotificationSchema, PromptArgumentSchema, PromptSchema, ListPromptsRequestSchema, ListPromptsResultSchema, GetPromptRequestParamsSchema, GetPromptRequestSchema, TextContentSchema, ImageContentSchema, AudioContentSchema, ToolUseContentSchema, EmbeddedResourceSchema, ResourceLinkSchema, ContentBlockSchema, PromptMessageSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ToolAnnotationsSchema, ToolExecutionSchema, ToolSchema, ListToolsRequestSchema, ListToolsResultSchema, CallToolResultSchema, CompatibilityCallToolResultSchema, CallToolRequestParamsSchema, CallToolRequestSchema, ToolListChangedNotificationSchema, ListChangedOptionsBaseSchema, LoggingLevelSchema, SetLevelRequestParamsSchema, SetLevelRequestSchema, LoggingMessageNotificationParamsSchema, LoggingMessageNotificationSchema, ModelHintSchema, ModelPreferencesSchema, ToolChoiceSchema, ToolResultContentSchema, SamplingContentSchema, SamplingMessageContentBlockSchema, SamplingMessageSchema, CreateMessageRequestParamsSchema, CreateMessageRequestSchema, CreateMessageResultSchema, CreateMessageResultWithToolsSchema, BooleanSchemaSchema, StringSchemaSchema, NumberSchemaSchema, UntitledSingleSelectEnumSchemaSchema, TitledSingleSelectEnumSchemaSchema, LegacyTitledEnumSchemaSchema, SingleSelectEnumSchemaSchema, UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema, MultiSelectEnumSchemaSchema, EnumSchemaSchema, PrimitiveSchemaDefinitionSchema, ElicitRequestFormParamsSchema, ElicitRequestURLParamsSchema, ElicitRequestParamsSchema, ElicitRequestSchema, ElicitationCompleteNotificationParamsSchema, ElicitationCompleteNotificationSchema, ElicitResultSchema, ResourceTemplateReferenceSchema, PromptReferenceSchema, CompleteRequestParamsSchema, CompleteRequestSchema, CompleteResultSchema, RootSchema, ListRootsRequestSchema, ListRootsResultSchema, RootsListChangedNotificationSchema, ClientRequestSchema, ClientNotificationSchema, ClientResultSchema, ServerRequestSchema, ServerNotificationSchema, ServerResultSchema, McpError, UrlElicitationRequiredError;
|
|
14450
14450
|
var init_types = __esm({
|
|
14451
|
-
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
14451
|
+
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js"() {
|
|
14452
14452
|
"use strict";
|
|
14453
14453
|
init_v4();
|
|
14454
14454
|
LATEST_PROTOCOL_VERSION = "2025-11-25";
|
|
@@ -14460,10 +14460,9 @@ var init_types = __esm({
|
|
|
14460
14460
|
CursorSchema = string2();
|
|
14461
14461
|
TaskCreationParamsSchema = looseObject({
|
|
14462
14462
|
/**
|
|
14463
|
-
*
|
|
14464
|
-
* If null, the task has unlimited lifetime until manually cleaned up.
|
|
14463
|
+
* Requested duration in milliseconds to retain task from creation.
|
|
14465
14464
|
*/
|
|
14466
|
-
ttl:
|
|
14465
|
+
ttl: number2().optional(),
|
|
14467
14466
|
/**
|
|
14468
14467
|
* Time in milliseconds to wait between task status requests.
|
|
14469
14468
|
*/
|
|
@@ -14762,7 +14761,11 @@ var init_types = __esm({
|
|
|
14762
14761
|
/**
|
|
14763
14762
|
* Present if the client supports task creation.
|
|
14764
14763
|
*/
|
|
14765
|
-
tasks: ClientTasksCapabilitySchema.optional()
|
|
14764
|
+
tasks: ClientTasksCapabilitySchema.optional(),
|
|
14765
|
+
/**
|
|
14766
|
+
* Extensions that the client supports. Keys are extension identifiers (vendor-prefix/extension-name).
|
|
14767
|
+
*/
|
|
14768
|
+
extensions: record(string2(), AssertObjectSchema).optional()
|
|
14766
14769
|
});
|
|
14767
14770
|
InitializeRequestParamsSchema = BaseRequestParamsSchema.extend({
|
|
14768
14771
|
/**
|
|
@@ -14823,7 +14826,11 @@ var init_types = __esm({
|
|
|
14823
14826
|
/**
|
|
14824
14827
|
* Present if the server supports task creation.
|
|
14825
14828
|
*/
|
|
14826
|
-
tasks: ServerTasksCapabilitySchema.optional()
|
|
14829
|
+
tasks: ServerTasksCapabilitySchema.optional(),
|
|
14830
|
+
/**
|
|
14831
|
+
* Extensions that the server supports. Keys are extension identifiers (vendor-prefix/extension-name).
|
|
14832
|
+
*/
|
|
14833
|
+
extensions: record(string2(), AssertObjectSchema).optional()
|
|
14827
14834
|
});
|
|
14828
14835
|
InitializeResultSchema = ResultSchema.extend({
|
|
14829
14836
|
/**
|
|
@@ -15015,6 +15022,12 @@ var init_types = __esm({
|
|
|
15015
15022
|
* The MIME type of this resource, if known.
|
|
15016
15023
|
*/
|
|
15017
15024
|
mimeType: optional(string2()),
|
|
15025
|
+
/**
|
|
15026
|
+
* The size of the raw resource content, in bytes (i.e., before base64 encoding or any tokenization), if known.
|
|
15027
|
+
*
|
|
15028
|
+
* This can be used by Hosts to display file sizes and estimate context window usage.
|
|
15029
|
+
*/
|
|
15030
|
+
size: optional(number2()),
|
|
15018
15031
|
/**
|
|
15019
15032
|
* Optional annotations for the client.
|
|
15020
15033
|
*/
|
|
@@ -22747,7 +22760,7 @@ var init_utils = __esm({
|
|
|
22747
22760
|
});
|
|
22748
22761
|
|
|
22749
22762
|
// src/internal/graphql.ts
|
|
22750
|
-
var LIST_BEANS_QUERY, CREATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION_WITH_IF_MATCH, DELETE_BEAN_MUTATION;
|
|
22763
|
+
var LIST_BEANS_QUERY, CREATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION_WITH_IF_MATCH, DELETE_BEAN_MUTATION, LIST_BEANS_TIMESTAMPS_QUERY;
|
|
22751
22764
|
var init_graphql = __esm({
|
|
22752
22765
|
"src/internal/graphql.ts"() {
|
|
22753
22766
|
"use strict";
|
|
@@ -22775,6 +22788,11 @@ var init_graphql = __esm({
|
|
|
22775
22788
|
mutation($id: ID!) {
|
|
22776
22789
|
deleteBean(id: $id)
|
|
22777
22790
|
}
|
|
22791
|
+
`;
|
|
22792
|
+
LIST_BEANS_TIMESTAMPS_QUERY = `
|
|
22793
|
+
query {
|
|
22794
|
+
beans { id updatedAt }
|
|
22795
|
+
}
|
|
22778
22796
|
`;
|
|
22779
22797
|
}
|
|
22780
22798
|
});
|
|
@@ -22797,12 +22815,26 @@ var init_backend = __esm({
|
|
|
22797
22815
|
init_graphql();
|
|
22798
22816
|
init_utils();
|
|
22799
22817
|
execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
22800
|
-
BeansCliBackend = class {
|
|
22818
|
+
BeansCliBackend = class _BeansCliBackend {
|
|
22801
22819
|
constructor(workspaceRoot, cliPath, logDir) {
|
|
22802
22820
|
this.workspaceRoot = workspaceRoot;
|
|
22803
22821
|
this.cliPath = cliPath;
|
|
22804
22822
|
this.logDir = logDir;
|
|
22805
22823
|
}
|
|
22824
|
+
// ---------------------------------------------------------------------------
|
|
22825
|
+
// Cache
|
|
22826
|
+
// ---------------------------------------------------------------------------
|
|
22827
|
+
/** Full unfiltered records keyed by bean ID, stored under the fixed cache key `'all'`. */
|
|
22828
|
+
_cache = /* @__PURE__ */ new Map();
|
|
22829
|
+
/** Last time the unfiltered cache entry `'all'` was fetched (ms). */
|
|
22830
|
+
_cacheTime = /* @__PURE__ */ new Map();
|
|
22831
|
+
/** Short-circuit TTL: skip even the timestamp check within this window (ms). */
|
|
22832
|
+
static BURST_TTL_MS = 5e3;
|
|
22833
|
+
/** Invalidate the unfiltered list cache so the next call does a full fetch. */
|
|
22834
|
+
invalidateCache() {
|
|
22835
|
+
this._cache.delete("all");
|
|
22836
|
+
this._cacheTime.delete("all");
|
|
22837
|
+
}
|
|
22806
22838
|
/**
|
|
22807
22839
|
* Returns a safe environment for executing the Beans CLI,
|
|
22808
22840
|
* whitelisting only necessary variables.
|
|
@@ -22826,7 +22858,7 @@ var init_backend = __esm({
|
|
|
22826
22858
|
return (0, import_node_path2.resolve)(this.workspaceRoot, ".beans");
|
|
22827
22859
|
}
|
|
22828
22860
|
resolveBeanFilePath(relativePath) {
|
|
22829
|
-
const cleaned = relativePath.trim().replace(/^\/+/, "");
|
|
22861
|
+
const cleaned = relativePath.trim().replace(/^\/+/, "").replace(/^\.beans(?:[\\/]|$)/, "");
|
|
22830
22862
|
if (!cleaned) {
|
|
22831
22863
|
throw new Error("Path is required");
|
|
22832
22864
|
}
|
|
@@ -22884,10 +22916,48 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22884
22916
|
if (options?.search) {
|
|
22885
22917
|
filter.search = options.search;
|
|
22886
22918
|
}
|
|
22919
|
+
const isCacheable = !filter.status && !filter.type && !filter.search;
|
|
22920
|
+
const cacheKey = "all";
|
|
22921
|
+
if (isCacheable) {
|
|
22922
|
+
const lastFetch = this._cacheTime.get(cacheKey) ?? 0;
|
|
22923
|
+
const cached2 = this._cache.get(cacheKey);
|
|
22924
|
+
const age = Date.now() - lastFetch;
|
|
22925
|
+
if (cached2 && age < _BeansCliBackend.BURST_TTL_MS) {
|
|
22926
|
+
return Array.from(cached2.values());
|
|
22927
|
+
}
|
|
22928
|
+
if (cached2) {
|
|
22929
|
+
try {
|
|
22930
|
+
const { data: tsData } = await this.executeGraphQL(
|
|
22931
|
+
LIST_BEANS_TIMESTAMPS_QUERY
|
|
22932
|
+
);
|
|
22933
|
+
const timestamps = tsData.beans;
|
|
22934
|
+
let dirty = timestamps.length !== cached2.size;
|
|
22935
|
+
if (!dirty) {
|
|
22936
|
+
for (const { id, updatedAt } of timestamps) {
|
|
22937
|
+
const existing = cached2.get(id);
|
|
22938
|
+
if (!existing || existing.updatedAt !== updatedAt) {
|
|
22939
|
+
dirty = true;
|
|
22940
|
+
break;
|
|
22941
|
+
}
|
|
22942
|
+
}
|
|
22943
|
+
}
|
|
22944
|
+
if (!dirty) {
|
|
22945
|
+
this._cacheTime.set(cacheKey, Date.now());
|
|
22946
|
+
return Array.from(cached2.values());
|
|
22947
|
+
}
|
|
22948
|
+
} catch {
|
|
22949
|
+
}
|
|
22950
|
+
}
|
|
22951
|
+
}
|
|
22887
22952
|
const { data, errors } = await this.executeGraphQL(LIST_BEANS_QUERY, { filter });
|
|
22888
22953
|
if (errors && errors.length > 0) {
|
|
22889
22954
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22890
22955
|
}
|
|
22956
|
+
if (isCacheable) {
|
|
22957
|
+
const byId = new Map(data.beans.map((b) => [b.id, b]));
|
|
22958
|
+
this._cache.set(cacheKey, byId);
|
|
22959
|
+
this._cacheTime.set(cacheKey, Date.now());
|
|
22960
|
+
}
|
|
22891
22961
|
return data.beans;
|
|
22892
22962
|
}
|
|
22893
22963
|
async create(input) {
|
|
@@ -22896,7 +22966,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22896
22966
|
type: input.type,
|
|
22897
22967
|
status: input.status,
|
|
22898
22968
|
priority: input.priority,
|
|
22899
|
-
body: input.description,
|
|
22969
|
+
body: input.body ?? input.description,
|
|
22900
22970
|
parent: input.parent
|
|
22901
22971
|
};
|
|
22902
22972
|
const { data, errors } = await this.executeGraphQL(CREATE_BEAN_MUTATION, {
|
|
@@ -22905,6 +22975,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22905
22975
|
if (errors && errors.length > 0) {
|
|
22906
22976
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22907
22977
|
}
|
|
22978
|
+
this.invalidateCache();
|
|
22908
22979
|
return data.createBean;
|
|
22909
22980
|
}
|
|
22910
22981
|
async update(beanId, updates) {
|
|
@@ -22974,6 +23045,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22974
23045
|
if (errors && errors.length > 0) {
|
|
22975
23046
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22976
23047
|
}
|
|
23048
|
+
this.invalidateCache();
|
|
22977
23049
|
return data.updateBean;
|
|
22978
23050
|
}
|
|
22979
23051
|
async delete(beanId) {
|
|
@@ -22983,8 +23055,37 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22983
23055
|
if (errors && errors.length > 0) {
|
|
22984
23056
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22985
23057
|
}
|
|
23058
|
+
this.invalidateCache();
|
|
22986
23059
|
return { deleted: true, beanId };
|
|
22987
23060
|
}
|
|
23061
|
+
async bulkCreate(beans, defaultParent) {
|
|
23062
|
+
const results = [];
|
|
23063
|
+
for (const item of beans) {
|
|
23064
|
+
try {
|
|
23065
|
+
const bean = await this.create({
|
|
23066
|
+
...item,
|
|
23067
|
+
parent: item.parent ?? defaultParent
|
|
23068
|
+
});
|
|
23069
|
+
results.push({ bean });
|
|
23070
|
+
} catch (error48) {
|
|
23071
|
+
results.push({ error: error48.message });
|
|
23072
|
+
}
|
|
23073
|
+
}
|
|
23074
|
+
return results;
|
|
23075
|
+
}
|
|
23076
|
+
async bulkUpdate(beans, defaultParent) {
|
|
23077
|
+
const results = [];
|
|
23078
|
+
for (const { beanId, ...updates } of beans) {
|
|
23079
|
+
try {
|
|
23080
|
+
const resolvedParent = updates.parent ?? (updates.clearParent ? void 0 : defaultParent);
|
|
23081
|
+
const bean = await this.update(beanId, { ...updates, parent: resolvedParent });
|
|
23082
|
+
results.push({ beanId, bean });
|
|
23083
|
+
} catch (error48) {
|
|
23084
|
+
results.push({ beanId, error: error48.message });
|
|
23085
|
+
}
|
|
23086
|
+
}
|
|
23087
|
+
return results;
|
|
23088
|
+
}
|
|
22988
23089
|
async openConfig() {
|
|
22989
23090
|
const configPath = (0, import_node_path2.join)(this.workspaceRoot, ".beans.yml");
|
|
22990
23091
|
const content = await (0, import_promises.readFile)(configPath, "utf8");
|
|
@@ -23043,6 +23144,120 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
23043
23144
|
linesReturned: ringBuffer.length
|
|
23044
23145
|
};
|
|
23045
23146
|
}
|
|
23147
|
+
/**
|
|
23148
|
+
* Split a YAML scalar value from any trailing inline comment.
|
|
23149
|
+
* Understands single-quoted and double-quoted YAML strings so it won't
|
|
23150
|
+
* mistake a `#` inside a quoted value for a comment delimiter.
|
|
23151
|
+
*/
|
|
23152
|
+
splitYamlInlineComment(value) {
|
|
23153
|
+
let inSingle = false;
|
|
23154
|
+
let inDouble = false;
|
|
23155
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
23156
|
+
const char = value[i];
|
|
23157
|
+
if (inSingle) {
|
|
23158
|
+
if (char === "'") {
|
|
23159
|
+
if (value[i + 1] === "'") {
|
|
23160
|
+
i += 1;
|
|
23161
|
+
} else {
|
|
23162
|
+
inSingle = false;
|
|
23163
|
+
}
|
|
23164
|
+
}
|
|
23165
|
+
continue;
|
|
23166
|
+
}
|
|
23167
|
+
if (inDouble) {
|
|
23168
|
+
if (char === "\\") {
|
|
23169
|
+
i += 1;
|
|
23170
|
+
continue;
|
|
23171
|
+
}
|
|
23172
|
+
if (char === '"') {
|
|
23173
|
+
inDouble = false;
|
|
23174
|
+
}
|
|
23175
|
+
continue;
|
|
23176
|
+
}
|
|
23177
|
+
if (char === "'") {
|
|
23178
|
+
inSingle = true;
|
|
23179
|
+
continue;
|
|
23180
|
+
}
|
|
23181
|
+
if (char === '"') {
|
|
23182
|
+
inDouble = true;
|
|
23183
|
+
continue;
|
|
23184
|
+
}
|
|
23185
|
+
if (char === "#" && i > 0 && /\s/.test(value[i - 1])) {
|
|
23186
|
+
const valuePart = value.slice(0, i).trimEnd();
|
|
23187
|
+
return {
|
|
23188
|
+
valuePart,
|
|
23189
|
+
commentPart: value.slice(valuePart.length)
|
|
23190
|
+
};
|
|
23191
|
+
}
|
|
23192
|
+
}
|
|
23193
|
+
return { valuePart: value, commentPart: "" };
|
|
23194
|
+
}
|
|
23195
|
+
/** Returns true when `value` looks like a YAML block scalar indicator (`>`, `|`, `>-`, `|-`, etc.) */
|
|
23196
|
+
isYamlBlockScalarIndicator(value) {
|
|
23197
|
+
return /^[>|][+-]?[0-9]*$/.test(value) || /^[>|][0-9]*[+-]?$/.test(value);
|
|
23198
|
+
}
|
|
23199
|
+
/** Escape a plain string for use inside a YAML double-quoted scalar. */
|
|
23200
|
+
escapeForYamlDoubleQuoted(value) {
|
|
23201
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
23202
|
+
}
|
|
23203
|
+
/**
|
|
23204
|
+
* Normalise a raw YAML title value to a double-quoted scalar.
|
|
23205
|
+
* Handles: empty, already double-quoted, single-quoted (unescaping `''`),
|
|
23206
|
+
* block-scalar indicators, and plain unquoted values.
|
|
23207
|
+
*/
|
|
23208
|
+
normalizeFrontmatterTitleValue(value) {
|
|
23209
|
+
const trimmed = value.trim();
|
|
23210
|
+
if (trimmed === "") {
|
|
23211
|
+
return '""';
|
|
23212
|
+
}
|
|
23213
|
+
if (this.isYamlBlockScalarIndicator(trimmed)) {
|
|
23214
|
+
return value;
|
|
23215
|
+
}
|
|
23216
|
+
if (/^"(?:[^"\\]|\\[\s\S])*"$/.test(trimmed)) {
|
|
23217
|
+
return trimmed;
|
|
23218
|
+
}
|
|
23219
|
+
if (/^'(?:[^']|'')*'$/.test(trimmed)) {
|
|
23220
|
+
const inner = trimmed.slice(1, -1).replace(/''/g, "'");
|
|
23221
|
+
return `"${this.escapeForYamlDoubleQuoted(inner)}"`;
|
|
23222
|
+
}
|
|
23223
|
+
return `"${this.escapeForYamlDoubleQuoted(trimmed)}"`;
|
|
23224
|
+
}
|
|
23225
|
+
/**
|
|
23226
|
+
* Ensure every `title:` line in YAML frontmatter is double-quoted.
|
|
23227
|
+
* Handles already-quoted (single or double), multi-word, and special-char values.
|
|
23228
|
+
* Preserves inline comments and handles both LF and CRLF line endings.
|
|
23229
|
+
*/
|
|
23230
|
+
quoteFrontmatterTitles(content) {
|
|
23231
|
+
const crlfOpen = content.startsWith("---\r\n");
|
|
23232
|
+
const lfOpen = content.startsWith("---\n");
|
|
23233
|
+
if (!crlfOpen && !lfOpen) {
|
|
23234
|
+
return content;
|
|
23235
|
+
}
|
|
23236
|
+
const eol = crlfOpen ? "\r\n" : "\n";
|
|
23237
|
+
const openEnd = `---${eol}`.length;
|
|
23238
|
+
const closeMarker = `${eol}---`;
|
|
23239
|
+
const closeIdx = content.indexOf(closeMarker, openEnd);
|
|
23240
|
+
if (closeIdx === -1) {
|
|
23241
|
+
return content;
|
|
23242
|
+
}
|
|
23243
|
+
const frontmatter = content.slice(openEnd, closeIdx);
|
|
23244
|
+
const rest = content.slice(closeIdx);
|
|
23245
|
+
const lines = frontmatter.split(eol);
|
|
23246
|
+
const fixedLines = lines.map((line) => {
|
|
23247
|
+
if (!line.startsWith("title:")) {
|
|
23248
|
+
return line;
|
|
23249
|
+
}
|
|
23250
|
+
const colonIdx = line.indexOf(":");
|
|
23251
|
+
const afterColon = line.slice(colonIdx + 1);
|
|
23252
|
+
const leadingSpace = afterColon.length - afterColon.trimStart().length;
|
|
23253
|
+
const raw = afterColon.trimStart();
|
|
23254
|
+
const { valuePart, commentPart } = this.splitYamlInlineComment(raw);
|
|
23255
|
+
const normalized = this.normalizeFrontmatterTitleValue(valuePart);
|
|
23256
|
+
const prefix = `title:${" ".repeat(Math.max(1, leadingSpace))}`;
|
|
23257
|
+
return `${prefix}${normalized}${commentPart}`;
|
|
23258
|
+
});
|
|
23259
|
+
return `---${eol}${fixedLines.join(eol)}${rest}`;
|
|
23260
|
+
}
|
|
23046
23261
|
async readBeanFile(relativePath) {
|
|
23047
23262
|
const absolutePath = this.resolveBeanFilePath(relativePath);
|
|
23048
23263
|
const content = await (0, import_promises.readFile)(absolutePath, "utf8");
|
|
@@ -23050,20 +23265,22 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
23050
23265
|
}
|
|
23051
23266
|
async editBeanFile(relativePath, content) {
|
|
23052
23267
|
const absolutePath = this.resolveBeanFilePath(relativePath);
|
|
23268
|
+
const fixed = this.quoteFrontmatterTitles(content);
|
|
23053
23269
|
await (0, import_promises.mkdir)((0, import_node_path2.dirname)(absolutePath), { recursive: true });
|
|
23054
|
-
await (0, import_promises.writeFile)(absolutePath,
|
|
23055
|
-
return { path: absolutePath, bytes: Buffer.byteLength(
|
|
23270
|
+
await (0, import_promises.writeFile)(absolutePath, fixed, "utf8");
|
|
23271
|
+
return { path: absolutePath, bytes: Buffer.byteLength(fixed, "utf8") };
|
|
23056
23272
|
}
|
|
23057
23273
|
async createBeanFile(relativePath, content, options) {
|
|
23058
23274
|
const absolutePath = this.resolveBeanFilePath(relativePath);
|
|
23275
|
+
const fixed = this.quoteFrontmatterTitles(content);
|
|
23059
23276
|
await (0, import_promises.mkdir)((0, import_node_path2.dirname)(absolutePath), { recursive: true });
|
|
23060
|
-
await (0, import_promises.writeFile)(absolutePath,
|
|
23277
|
+
await (0, import_promises.writeFile)(absolutePath, fixed, {
|
|
23061
23278
|
encoding: "utf8",
|
|
23062
23279
|
flag: options?.overwrite ? "w" : "wx"
|
|
23063
23280
|
});
|
|
23064
23281
|
return {
|
|
23065
23282
|
path: absolutePath,
|
|
23066
|
-
bytes: Buffer.byteLength(
|
|
23283
|
+
bytes: Buffer.byteLength(fixed, "utf8"),
|
|
23067
23284
|
created: true
|
|
23068
23285
|
};
|
|
23069
23286
|
}
|
|
@@ -23076,7 +23293,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
23076
23293
|
}
|
|
23077
23294
|
});
|
|
23078
23295
|
|
|
23079
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23296
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
|
|
23080
23297
|
function deserializeMessage(line) {
|
|
23081
23298
|
return JSONRPCMessageSchema.parse(JSON.parse(line));
|
|
23082
23299
|
}
|
|
@@ -23085,7 +23302,7 @@ function serializeMessage(message) {
|
|
|
23085
23302
|
}
|
|
23086
23303
|
var ReadBuffer;
|
|
23087
23304
|
var init_stdio = __esm({
|
|
23088
|
-
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23305
|
+
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js"() {
|
|
23089
23306
|
"use strict";
|
|
23090
23307
|
init_types();
|
|
23091
23308
|
ReadBuffer = class {
|
|
@@ -23111,14 +23328,14 @@ var init_stdio = __esm({
|
|
|
23111
23328
|
}
|
|
23112
23329
|
});
|
|
23113
23330
|
|
|
23114
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23331
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
23115
23332
|
var stdio_exports = {};
|
|
23116
23333
|
__export(stdio_exports, {
|
|
23117
23334
|
StdioServerTransport: () => StdioServerTransport
|
|
23118
23335
|
});
|
|
23119
23336
|
var import_node_process, StdioServerTransport;
|
|
23120
23337
|
var init_stdio2 = __esm({
|
|
23121
|
-
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23338
|
+
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js"() {
|
|
23122
23339
|
"use strict";
|
|
23123
23340
|
import_node_process = __toESM(require("process"), 1);
|
|
23124
23341
|
init_stdio();
|
|
@@ -27126,7 +27343,7 @@ init_core2();
|
|
|
27126
27343
|
// node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/mini/coerce.js
|
|
27127
27344
|
init_core2();
|
|
27128
27345
|
|
|
27129
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
27346
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
|
|
27130
27347
|
function isZ4Schema(s) {
|
|
27131
27348
|
const schema = s;
|
|
27132
27349
|
return !!schema._zod;
|
|
@@ -27270,10 +27487,10 @@ function getLiteralValue(schema) {
|
|
|
27270
27487
|
return void 0;
|
|
27271
27488
|
}
|
|
27272
27489
|
|
|
27273
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
27490
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
|
|
27274
27491
|
init_types();
|
|
27275
27492
|
|
|
27276
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
27493
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
|
|
27277
27494
|
function isTerminal(status) {
|
|
27278
27495
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
27279
27496
|
}
|
|
@@ -28562,7 +28779,7 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
28562
28779
|
return combined;
|
|
28563
28780
|
};
|
|
28564
28781
|
|
|
28565
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
28782
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
|
|
28566
28783
|
function mapMiniTarget(t) {
|
|
28567
28784
|
if (!t)
|
|
28568
28785
|
return "draft-7";
|
|
@@ -28604,7 +28821,7 @@ function parseWithCompat(schema, data) {
|
|
|
28604
28821
|
return result.data;
|
|
28605
28822
|
}
|
|
28606
28823
|
|
|
28607
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
28824
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
|
|
28608
28825
|
var DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
|
|
28609
28826
|
var Protocol = class {
|
|
28610
28827
|
constructor(_options) {
|
|
@@ -28816,6 +29033,10 @@ var Protocol = class {
|
|
|
28816
29033
|
this._progressHandlers.clear();
|
|
28817
29034
|
this._taskProgressTokens.clear();
|
|
28818
29035
|
this._pendingDebouncedNotifications.clear();
|
|
29036
|
+
for (const info of this._timeoutInfo.values()) {
|
|
29037
|
+
clearTimeout(info.timeoutId);
|
|
29038
|
+
}
|
|
29039
|
+
this._timeoutInfo.clear();
|
|
28819
29040
|
for (const controller of this._requestHandlerAbortControllers.values()) {
|
|
28820
29041
|
controller.abort();
|
|
28821
29042
|
}
|
|
@@ -28946,7 +29167,9 @@ var Protocol = class {
|
|
|
28946
29167
|
await capturedTransport?.send(errorResponse);
|
|
28947
29168
|
}
|
|
28948
29169
|
}).catch((error48) => this._onerror(new Error(`Failed to send response: ${error48}`))).finally(() => {
|
|
28949
|
-
this._requestHandlerAbortControllers.
|
|
29170
|
+
if (this._requestHandlerAbortControllers.get(request.id) === abortController) {
|
|
29171
|
+
this._requestHandlerAbortControllers.delete(request.id);
|
|
29172
|
+
}
|
|
28950
29173
|
});
|
|
28951
29174
|
}
|
|
28952
29175
|
_onprogress(notification) {
|
|
@@ -29552,10 +29775,10 @@ function mergeCapabilities(base, additional) {
|
|
|
29552
29775
|
return result;
|
|
29553
29776
|
}
|
|
29554
29777
|
|
|
29555
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
29778
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
|
|
29556
29779
|
init_types();
|
|
29557
29780
|
|
|
29558
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
29781
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
|
|
29559
29782
|
var import_ajv = __toESM(require_ajv(), 1);
|
|
29560
29783
|
var import_ajv_formats = __toESM(require_dist(), 1);
|
|
29561
29784
|
function createDefaultAjvInstance() {
|
|
@@ -29623,7 +29846,7 @@ var AjvJsonSchemaValidator = class {
|
|
|
29623
29846
|
}
|
|
29624
29847
|
};
|
|
29625
29848
|
|
|
29626
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
29849
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
|
|
29627
29850
|
init_types();
|
|
29628
29851
|
var ExperimentalServerTasks = class {
|
|
29629
29852
|
constructor(_server) {
|
|
@@ -29837,7 +30060,7 @@ var ExperimentalServerTasks = class {
|
|
|
29837
30060
|
}
|
|
29838
30061
|
};
|
|
29839
30062
|
|
|
29840
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30063
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
|
|
29841
30064
|
function assertToolsCallTaskCapability(requests, method, entityName) {
|
|
29842
30065
|
if (!requests) {
|
|
29843
30066
|
throw new Error(`${entityName} does not support task creation (required for ${method})`);
|
|
@@ -29872,7 +30095,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
|
|
|
29872
30095
|
}
|
|
29873
30096
|
}
|
|
29874
30097
|
|
|
29875
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30098
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
|
|
29876
30099
|
var Server = class extends Protocol {
|
|
29877
30100
|
/**
|
|
29878
30101
|
* Initializes this server with the given name and version information.
|
|
@@ -30252,10 +30475,10 @@ var Server = class extends Protocol {
|
|
|
30252
30475
|
}
|
|
30253
30476
|
};
|
|
30254
30477
|
|
|
30255
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30478
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
|
|
30256
30479
|
init_types();
|
|
30257
30480
|
|
|
30258
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30481
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
|
|
30259
30482
|
var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
|
|
30260
30483
|
function isCompletable(schema) {
|
|
30261
30484
|
return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
|
|
@@ -30269,7 +30492,7 @@ var McpZodTypeKind;
|
|
|
30269
30492
|
McpZodTypeKind2["Completable"] = "McpCompletable";
|
|
30270
30493
|
})(McpZodTypeKind || (McpZodTypeKind = {}));
|
|
30271
30494
|
|
|
30272
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30495
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
|
|
30273
30496
|
var TOOL_NAME_REGEX = /^[A-Za-z0-9._-]{1,128}$/;
|
|
30274
30497
|
function validateToolName(name) {
|
|
30275
30498
|
const warnings = [];
|
|
@@ -30327,7 +30550,7 @@ function validateAndWarnToolName(name) {
|
|
|
30327
30550
|
return result.isValid;
|
|
30328
30551
|
}
|
|
30329
30552
|
|
|
30330
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30553
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
|
|
30331
30554
|
var ExperimentalMcpServerTasks = class {
|
|
30332
30555
|
constructor(_mcpServer) {
|
|
30333
30556
|
this._mcpServer = _mcpServer;
|
|
@@ -30346,7 +30569,7 @@ var ExperimentalMcpServerTasks = class {
|
|
|
30346
30569
|
init_external();
|
|
30347
30570
|
init_external();
|
|
30348
30571
|
|
|
30349
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30572
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
|
|
30350
30573
|
var McpServer = class {
|
|
30351
30574
|
constructor(serverInfo, options) {
|
|
30352
30575
|
this._registeredResources = {};
|
|
@@ -30970,6 +31193,9 @@ var McpServer = class {
|
|
|
30970
31193
|
annotations = rest.shift();
|
|
30971
31194
|
}
|
|
30972
31195
|
} else if (typeof firstArg === "object" && firstArg !== null) {
|
|
31196
|
+
if (Object.values(firstArg).some((v) => typeof v === "object" && v !== null)) {
|
|
31197
|
+
throw new Error(`Tool ${name} expected a Zod schema or ToolAnnotations, but received an unrecognized object`);
|
|
31198
|
+
}
|
|
30973
31199
|
annotations = rest.shift();
|
|
30974
31200
|
}
|
|
30975
31201
|
}
|
|
@@ -31088,6 +31314,9 @@ function getZodSchemaObject(schema) {
|
|
|
31088
31314
|
if (isZodRawShapeCompat(schema)) {
|
|
31089
31315
|
return objectFromShape(schema);
|
|
31090
31316
|
}
|
|
31317
|
+
if (!isZodSchemaInstance(schema)) {
|
|
31318
|
+
throw new Error("inputSchema must be a Zod schema or raw shape, received an unrecognized object");
|
|
31319
|
+
}
|
|
31091
31320
|
return schema;
|
|
31092
31321
|
}
|
|
31093
31322
|
function promptArgumentsFromSchema(schema) {
|
|
@@ -31136,6 +31365,90 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
31136
31365
|
var import_node_child_process2 = require("child_process");
|
|
31137
31366
|
var import_node_util2 = require("util");
|
|
31138
31367
|
|
|
31368
|
+
// package.json
|
|
31369
|
+
var package_default = {
|
|
31370
|
+
name: "@selfagency/beans-mcp",
|
|
31371
|
+
version: "0.5.0",
|
|
31372
|
+
private: false,
|
|
31373
|
+
description: "MCP (Model Context Protocol) server for Beans issue tracker",
|
|
31374
|
+
author: {
|
|
31375
|
+
name: "Daniel Sieradski",
|
|
31376
|
+
email: "daniel@self.agency",
|
|
31377
|
+
url: "https://self.agency"
|
|
31378
|
+
},
|
|
31379
|
+
homepage: "https://github.com/selfagency/beans-mcp",
|
|
31380
|
+
bugs: {
|
|
31381
|
+
url: "https://github.com/selfagency/beans-mcp/issues"
|
|
31382
|
+
},
|
|
31383
|
+
repository: {
|
|
31384
|
+
type: "git",
|
|
31385
|
+
url: "git+https://github.com/selfagency/beans-mcp.git"
|
|
31386
|
+
},
|
|
31387
|
+
mcpName: "io.github.selfagency/beans-mcp",
|
|
31388
|
+
keywords: [
|
|
31389
|
+
"beans",
|
|
31390
|
+
"mcp",
|
|
31391
|
+
"model-context-protocol",
|
|
31392
|
+
"issue-tracker",
|
|
31393
|
+
"ai"
|
|
31394
|
+
],
|
|
31395
|
+
license: "MIT",
|
|
31396
|
+
type: "module",
|
|
31397
|
+
exports: {
|
|
31398
|
+
".": {
|
|
31399
|
+
types: "./dist/index.d.ts",
|
|
31400
|
+
import: "./dist/index.js",
|
|
31401
|
+
require: "./dist/index.cjs"
|
|
31402
|
+
}
|
|
31403
|
+
},
|
|
31404
|
+
main: "./dist/index.cjs",
|
|
31405
|
+
module: "./dist/index.js",
|
|
31406
|
+
types: "./dist/index.d.ts",
|
|
31407
|
+
bin: {
|
|
31408
|
+
"beans-mcp": "dist/beans-mcp-server.cjs"
|
|
31409
|
+
},
|
|
31410
|
+
scripts: {
|
|
31411
|
+
build: "tsup",
|
|
31412
|
+
format: "oxfmt",
|
|
31413
|
+
"lint:fix": "oxlint --fix",
|
|
31414
|
+
lint: "oxlint",
|
|
31415
|
+
postbuild: "node ./scripts/write-dist-package.js",
|
|
31416
|
+
prepare: "husky",
|
|
31417
|
+
release: "zx ./scripts/release.js",
|
|
31418
|
+
"test:coverage": "vitest run --coverage",
|
|
31419
|
+
"test:watch": "vitest",
|
|
31420
|
+
test: "vitest run",
|
|
31421
|
+
"type-check": "tsc --noEmit"
|
|
31422
|
+
},
|
|
31423
|
+
devDependencies: {
|
|
31424
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
31425
|
+
"@octokit/rest": "^22.0.1",
|
|
31426
|
+
"@types/node": "25.5.2",
|
|
31427
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
31428
|
+
"@vitest/ui": "4.1.2",
|
|
31429
|
+
husky: "^9.1.7",
|
|
31430
|
+
"lint-staged": "^16.4.0",
|
|
31431
|
+
ora: "^9.3.0",
|
|
31432
|
+
oxfmt: "^0.43.0",
|
|
31433
|
+
oxlint: "^1.58.0",
|
|
31434
|
+
"oxlint-tsgolint": "^0.20.0",
|
|
31435
|
+
tsup: "8.5.1",
|
|
31436
|
+
typescript: "6.0.2",
|
|
31437
|
+
vitest: "4.1.2",
|
|
31438
|
+
zod: "4.3.6",
|
|
31439
|
+
zx: "^8.8.5"
|
|
31440
|
+
},
|
|
31441
|
+
engines: {
|
|
31442
|
+
node: ">=18"
|
|
31443
|
+
},
|
|
31444
|
+
"lint-staged": {
|
|
31445
|
+
"src/**/*.ts": [
|
|
31446
|
+
"pnpm run lint:fix",
|
|
31447
|
+
"pnpm run format"
|
|
31448
|
+
]
|
|
31449
|
+
}
|
|
31450
|
+
};
|
|
31451
|
+
|
|
31139
31452
|
// src/internal/queryHelpers.ts
|
|
31140
31453
|
function sortBeansInternal(beans, mode) {
|
|
31141
31454
|
const sorted = [...beans];
|
|
@@ -31296,92 +31609,6 @@ var MAX_PATH_LENGTH = 1024;
|
|
|
31296
31609
|
|
|
31297
31610
|
// src/server/BeansMcpServer.ts
|
|
31298
31611
|
init_utils();
|
|
31299
|
-
|
|
31300
|
-
// package.json
|
|
31301
|
-
var package_default = {
|
|
31302
|
-
name: "@selfagency/beans-mcp",
|
|
31303
|
-
version: "0.4.2",
|
|
31304
|
-
private: false,
|
|
31305
|
-
description: "MCP (Model Context Protocol) server for Beans issue tracker",
|
|
31306
|
-
author: {
|
|
31307
|
-
name: "Daniel Sieradski",
|
|
31308
|
-
email: "daniel@self.agency",
|
|
31309
|
-
url: "https://self.agency"
|
|
31310
|
-
},
|
|
31311
|
-
homepage: "https://github.com/hmans/beans",
|
|
31312
|
-
bugs: {
|
|
31313
|
-
url: "https://github.com/selfagency/beans-mcp/issues"
|
|
31314
|
-
},
|
|
31315
|
-
repository: {
|
|
31316
|
-
type: "git",
|
|
31317
|
-
url: "git+https://github.com/selfagency/beans-mcp.git"
|
|
31318
|
-
},
|
|
31319
|
-
mcpName: "io.github.selfagency/beans-mcp",
|
|
31320
|
-
keywords: [
|
|
31321
|
-
"beans",
|
|
31322
|
-
"mcp",
|
|
31323
|
-
"model-context-protocol",
|
|
31324
|
-
"issue-tracker",
|
|
31325
|
-
"ai"
|
|
31326
|
-
],
|
|
31327
|
-
license: "MIT",
|
|
31328
|
-
type: "module",
|
|
31329
|
-
exports: {
|
|
31330
|
-
".": {
|
|
31331
|
-
types: "./dist/index.d.ts",
|
|
31332
|
-
import: "./dist/index.js",
|
|
31333
|
-
require: "./dist/index.cjs"
|
|
31334
|
-
}
|
|
31335
|
-
},
|
|
31336
|
-
main: "./dist/index.cjs",
|
|
31337
|
-
module: "./dist/index.js",
|
|
31338
|
-
types: "./dist/index.d.ts",
|
|
31339
|
-
bin: {
|
|
31340
|
-
"beans-mcp": "dist/beans-mcp-server.cjs"
|
|
31341
|
-
},
|
|
31342
|
-
scripts: {
|
|
31343
|
-
build: "tsup",
|
|
31344
|
-
format: "oxfmt",
|
|
31345
|
-
"lint:fix": "oxlint --fix",
|
|
31346
|
-
lint: "oxlint",
|
|
31347
|
-
postbuild: "node ./scripts/write-dist-package.js",
|
|
31348
|
-
prepare: "husky",
|
|
31349
|
-
release: "zx ./scripts/release.js",
|
|
31350
|
-
"test:coverage": "vitest run --coverage",
|
|
31351
|
-
"test:watch": "vitest",
|
|
31352
|
-
test: "vitest run",
|
|
31353
|
-
"type-check": "tsc --noEmit"
|
|
31354
|
-
},
|
|
31355
|
-
devDependencies: {
|
|
31356
|
-
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
31357
|
-
"@octokit/rest": "^22.0.1",
|
|
31358
|
-
"@types/node": "25.5.0",
|
|
31359
|
-
"@vitest/coverage-v8": "^4.1.0",
|
|
31360
|
-
"@vitest/ui": "4.1.0",
|
|
31361
|
-
husky: "^9.1.7",
|
|
31362
|
-
"lint-staged": "^16.3.3",
|
|
31363
|
-
ora: "^9.3.0",
|
|
31364
|
-
oxfmt: "^0.40.0",
|
|
31365
|
-
oxlint: "^1.55.0",
|
|
31366
|
-
"oxlint-tsgolint": "^0.16.0",
|
|
31367
|
-
tsup: "8.5.1",
|
|
31368
|
-
typescript: "^5.9.3",
|
|
31369
|
-
vitest: "4.1.0",
|
|
31370
|
-
zod: "4.3.6",
|
|
31371
|
-
zx: "^8.8.5"
|
|
31372
|
-
},
|
|
31373
|
-
engines: {
|
|
31374
|
-
node: ">=18"
|
|
31375
|
-
},
|
|
31376
|
-
"lint-staged": {
|
|
31377
|
-
"src/**/*.ts": [
|
|
31378
|
-
"pnpm run lint:fix",
|
|
31379
|
-
"pnpm run format"
|
|
31380
|
-
]
|
|
31381
|
-
}
|
|
31382
|
-
};
|
|
31383
|
-
|
|
31384
|
-
// src/server/BeansMcpServer.ts
|
|
31385
31612
|
var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process2.execFile);
|
|
31386
31613
|
var PACKAGE_VERSION = package_default.version ?? "0.0.0-dev";
|
|
31387
31614
|
function getSafeCliEnv(env) {
|
|
@@ -31453,7 +31680,12 @@ function viewHandler(backend) {
|
|
|
31453
31680
|
const byId = new Map(beans.map((b) => [b.id, b]));
|
|
31454
31681
|
const found = ids.map((id) => byId.get(id)).filter(Boolean);
|
|
31455
31682
|
const missingBeanIds = ids.filter((id) => !byId.has(id));
|
|
31456
|
-
return makeTextAndStructured({
|
|
31683
|
+
return makeTextAndStructured({
|
|
31684
|
+
beans: found,
|
|
31685
|
+
missingBeanIds,
|
|
31686
|
+
count: found.length,
|
|
31687
|
+
requestedCount: ids.length
|
|
31688
|
+
});
|
|
31457
31689
|
};
|
|
31458
31690
|
}
|
|
31459
31691
|
async function checkVersionCompatibility(cliPath, workspaceRoot, detector) {
|
|
@@ -31545,7 +31777,11 @@ function deleteHandler(backend) {
|
|
|
31545
31777
|
await backend.delete(id);
|
|
31546
31778
|
results.push({ beanId: id, deleted: true });
|
|
31547
31779
|
} catch (error48) {
|
|
31548
|
-
results.push({
|
|
31780
|
+
results.push({
|
|
31781
|
+
beanId: id,
|
|
31782
|
+
deleted: false,
|
|
31783
|
+
error: error48.message
|
|
31784
|
+
});
|
|
31549
31785
|
}
|
|
31550
31786
|
}
|
|
31551
31787
|
return makeTextAndStructured({
|
|
@@ -31556,6 +31792,28 @@ function deleteHandler(backend) {
|
|
|
31556
31792
|
});
|
|
31557
31793
|
};
|
|
31558
31794
|
}
|
|
31795
|
+
function bulkCreateHandler(backend) {
|
|
31796
|
+
return async (input) => {
|
|
31797
|
+
const results = await backend.bulkCreate(input.beans, input.parent);
|
|
31798
|
+
return makeTextAndStructured({
|
|
31799
|
+
results,
|
|
31800
|
+
requestedCount: input.beans.length,
|
|
31801
|
+
successCount: results.filter((r) => r.bean).length,
|
|
31802
|
+
failedCount: results.filter((r) => r.error).length
|
|
31803
|
+
});
|
|
31804
|
+
};
|
|
31805
|
+
}
|
|
31806
|
+
function bulkUpdateHandler(backend) {
|
|
31807
|
+
return async (input) => {
|
|
31808
|
+
const results = await backend.bulkUpdate(input.beans, input.parent);
|
|
31809
|
+
return makeTextAndStructured({
|
|
31810
|
+
results,
|
|
31811
|
+
requestedCount: input.beans.length,
|
|
31812
|
+
successCount: results.filter((r) => r.bean).length,
|
|
31813
|
+
failedCount: results.filter((r) => r.error).length
|
|
31814
|
+
});
|
|
31815
|
+
};
|
|
31816
|
+
}
|
|
31559
31817
|
function queryHandler(backend) {
|
|
31560
31818
|
return async (opts) => handleQueryOperation(backend, opts);
|
|
31561
31819
|
}
|
|
@@ -31639,7 +31897,8 @@ function registerTools(server, backend) {
|
|
|
31639
31897
|
type: external_exports3.string().min(1).max(MAX_METADATA_LENGTH),
|
|
31640
31898
|
status: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
31641
31899
|
priority: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
31642
|
-
|
|
31900
|
+
body: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Body markdown content"),
|
|
31901
|
+
description: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Deprecated alias for body"),
|
|
31643
31902
|
parent: external_exports3.string().max(MAX_ID_LENGTH).optional()
|
|
31644
31903
|
}),
|
|
31645
31904
|
annotations: {
|
|
@@ -31753,6 +32012,68 @@ function registerTools(server, backend) {
|
|
|
31753
32012
|
},
|
|
31754
32013
|
deleteHandler(backend)
|
|
31755
32014
|
);
|
|
32015
|
+
const beanCreateItemSchema = external_exports3.object({
|
|
32016
|
+
title: external_exports3.string().min(1).max(MAX_TITLE_LENGTH),
|
|
32017
|
+
type: external_exports3.string().min(1).max(MAX_METADATA_LENGTH),
|
|
32018
|
+
status: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32019
|
+
priority: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32020
|
+
body: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Body markdown content"),
|
|
32021
|
+
description: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Deprecated alias for body"),
|
|
32022
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Override the top-level parent for this item")
|
|
32023
|
+
});
|
|
32024
|
+
server.registerTool(
|
|
32025
|
+
"beans_bulk_create",
|
|
32026
|
+
{
|
|
32027
|
+
title: "Bulk Create Beans",
|
|
32028
|
+
description: "Create multiple beans in one call. Optionally assign all of them (or a subset) to a shared parent.",
|
|
32029
|
+
inputSchema: external_exports3.object({
|
|
32030
|
+
beans: external_exports3.array(beanCreateItemSchema).min(1),
|
|
32031
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Default parent ID applied to any bean that does not specify its own parent")
|
|
32032
|
+
}),
|
|
32033
|
+
annotations: {
|
|
32034
|
+
readOnlyHint: false,
|
|
32035
|
+
destructiveHint: false,
|
|
32036
|
+
idempotentHint: false,
|
|
32037
|
+
openWorldHint: false
|
|
32038
|
+
}
|
|
32039
|
+
},
|
|
32040
|
+
bulkCreateHandler(backend)
|
|
32041
|
+
);
|
|
32042
|
+
const beanUpdateItemSchema = external_exports3.object({
|
|
32043
|
+
beanId: external_exports3.string().min(1).max(MAX_ID_LENGTH),
|
|
32044
|
+
status: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32045
|
+
type: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32046
|
+
priority: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32047
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Override the top-level parent for this item"),
|
|
32048
|
+
clearParent: external_exports3.boolean().optional(),
|
|
32049
|
+
blocking: external_exports3.array(external_exports3.string().max(MAX_ID_LENGTH)).optional(),
|
|
32050
|
+
blockedBy: external_exports3.array(external_exports3.string().max(MAX_ID_LENGTH)).optional(),
|
|
32051
|
+
body: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional(),
|
|
32052
|
+
bodyAppend: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional(),
|
|
32053
|
+
bodyReplace: external_exports3.array(external_exports3.object({ old: external_exports3.string().max(MAX_DESCRIPTION_LENGTH), new: external_exports3.string().max(MAX_DESCRIPTION_LENGTH) })).optional(),
|
|
32054
|
+
ifMatch: external_exports3.string().max(MAX_METADATA_LENGTH).optional()
|
|
32055
|
+
}).refine(
|
|
32056
|
+
(input) => !(input.body !== void 0 && (input.bodyAppend !== void 0 || input.bodyReplace !== void 0)),
|
|
32057
|
+
{ message: "body cannot be combined with bodyAppend/bodyReplace" }
|
|
32058
|
+
);
|
|
32059
|
+
server.registerTool(
|
|
32060
|
+
"beans_bulk_update",
|
|
32061
|
+
{
|
|
32062
|
+
title: "Bulk Update Beans",
|
|
32063
|
+
description: "Update multiple beans in one call. Optionally assign all of them (or a subset) to a shared parent.",
|
|
32064
|
+
inputSchema: external_exports3.object({
|
|
32065
|
+
beans: external_exports3.array(beanUpdateItemSchema).min(1),
|
|
32066
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Default parent ID applied to any bean that does not specify its own parent")
|
|
32067
|
+
}),
|
|
32068
|
+
annotations: {
|
|
32069
|
+
readOnlyHint: false,
|
|
32070
|
+
destructiveHint: false,
|
|
32071
|
+
idempotentHint: false,
|
|
32072
|
+
openWorldHint: false
|
|
32073
|
+
}
|
|
32074
|
+
},
|
|
32075
|
+
bulkUpdateHandler(backend)
|
|
32076
|
+
);
|
|
31756
32077
|
server.registerTool(
|
|
31757
32078
|
"beans_query",
|
|
31758
32079
|
{
|
|
@@ -31838,6 +32159,12 @@ var MutableBackend = class {
|
|
|
31838
32159
|
delete(id) {
|
|
31839
32160
|
return this.inner.delete(id);
|
|
31840
32161
|
}
|
|
32162
|
+
bulkCreate(beans, defaultParent) {
|
|
32163
|
+
return this.inner.bulkCreate(beans, defaultParent);
|
|
32164
|
+
}
|
|
32165
|
+
bulkUpdate(beans, defaultParent) {
|
|
32166
|
+
return this.inner.bulkUpdate(beans, defaultParent);
|
|
32167
|
+
}
|
|
31841
32168
|
openConfig() {
|
|
31842
32169
|
return this.inner.openConfig();
|
|
31843
32170
|
}
|