@selfagency/beans-mcp 0.1.4 → 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/index.d.ts CHANGED
@@ -57,6 +57,8 @@ interface BackendInterface {
57
57
  type: string;
58
58
  status?: string;
59
59
  priority?: string;
60
+ /** Body markdown content. `description` is a deprecated alias. */
61
+ body?: string;
60
62
  description?: string;
61
63
  parent?: string;
62
64
  }): Promise<BeanRecord>;
@@ -69,12 +71,53 @@ interface BackendInterface {
69
71
  blocking?: string[];
70
72
  blockedBy?: string[];
71
73
  body?: string;
74
+ bodyAppend?: string;
75
+ bodyReplace?: Array<{
76
+ old: string;
77
+ new: string;
78
+ }>;
79
+ ifMatch?: string;
72
80
  }): Promise<BeanRecord>;
73
81
  delete(beanId: string): Promise<Record<string, unknown>>;
82
+ bulkCreate(beans: Array<{
83
+ title: string;
84
+ type: string;
85
+ status?: string;
86
+ priority?: string;
87
+ body?: string;
88
+ description?: string;
89
+ parent?: string;
90
+ }>, defaultParent?: string): Promise<Array<{
91
+ bean?: BeanRecord;
92
+ error?: string;
93
+ }>>;
94
+ bulkUpdate(beans: Array<{
95
+ beanId: string;
96
+ status?: string;
97
+ type?: string;
98
+ priority?: string;
99
+ parent?: string;
100
+ clearParent?: boolean;
101
+ blocking?: string[];
102
+ blockedBy?: string[];
103
+ body?: string;
104
+ bodyAppend?: string;
105
+ bodyReplace?: Array<{
106
+ old: string;
107
+ new: string;
108
+ }>;
109
+ ifMatch?: string;
110
+ }>, defaultParent?: string): Promise<Array<{
111
+ beanId: string;
112
+ bean?: BeanRecord;
113
+ error?: string;
114
+ }>>;
74
115
  openConfig(): Promise<{
75
116
  configPath: string;
76
117
  content: string;
77
118
  }>;
119
+ primeInstructions?(): Promise<string>;
120
+ writeInstructions?(instructions: string): Promise<string | null>;
78
121
  graphqlSchema(): Promise<string>;
79
122
  readOutputLog(options?: {
80
123
  lines?: number;
@@ -112,6 +155,14 @@ declare class BeansCliBackend implements BackendInterface {
112
155
  private readonly cliPath;
113
156
  private readonly logDir?;
114
157
  constructor(workspaceRoot: string, cliPath: string, logDir?: string | undefined);
158
+ /** Full unfiltered records keyed by bean ID, stored under the fixed cache key `'all'`. */
159
+ private readonly _cache;
160
+ /** Last time the unfiltered cache entry `'all'` was fetched (ms). */
161
+ private readonly _cacheTime;
162
+ /** Short-circuit TTL: skip even the timestamp check within this window (ms). */
163
+ private static readonly BURST_TTL_MS;
164
+ /** Invalidate the unfiltered list cache so the next call does a full fetch. */
165
+ private invalidateCache;
115
166
  /**
116
167
  * Returns a safe environment for executing the Beans CLI,
117
168
  * whitelisting only necessary variables.
@@ -134,6 +185,7 @@ declare class BeansCliBackend implements BackendInterface {
134
185
  type: string;
135
186
  status?: string;
136
187
  priority?: string;
188
+ body?: string;
137
189
  description?: string;
138
190
  parent?: string;
139
191
  }): Promise<BeanRecord>;
@@ -146,12 +198,53 @@ declare class BeansCliBackend implements BackendInterface {
146
198
  blocking?: string[];
147
199
  blockedBy?: string[];
148
200
  body?: string;
201
+ bodyAppend?: string;
202
+ bodyReplace?: Array<{
203
+ old: string;
204
+ new: string;
205
+ }>;
206
+ ifMatch?: string;
149
207
  }): Promise<BeanRecord>;
150
208
  delete(beanId: string): Promise<Record<string, unknown>>;
209
+ bulkCreate(beans: Array<{
210
+ title: string;
211
+ type: string;
212
+ status?: string;
213
+ priority?: string;
214
+ body?: string;
215
+ description?: string;
216
+ parent?: string;
217
+ }>, defaultParent?: string): Promise<Array<{
218
+ bean?: BeanRecord;
219
+ error?: string;
220
+ }>>;
221
+ bulkUpdate(beans: Array<{
222
+ beanId: string;
223
+ status?: string;
224
+ type?: string;
225
+ priority?: string;
226
+ parent?: string;
227
+ clearParent?: boolean;
228
+ blocking?: string[];
229
+ blockedBy?: string[];
230
+ body?: string;
231
+ bodyAppend?: string;
232
+ bodyReplace?: Array<{
233
+ old: string;
234
+ new: string;
235
+ }>;
236
+ ifMatch?: string;
237
+ }>, defaultParent?: string): Promise<Array<{
238
+ beanId: string;
239
+ bean?: BeanRecord;
240
+ error?: string;
241
+ }>>;
151
242
  openConfig(): Promise<{
152
243
  configPath: string;
153
244
  content: string;
154
245
  }>;
246
+ primeInstructions(): Promise<string>;
247
+ writeInstructions(instructions: string): Promise<string>;
155
248
  graphqlSchema(): Promise<string>;
156
249
  readOutputLog(options?: {
157
250
  lines?: number;
@@ -160,6 +253,28 @@ declare class BeansCliBackend implements BackendInterface {
160
253
  content: string;
161
254
  linesReturned: number;
162
255
  }>;
256
+ /**
257
+ * Split a YAML scalar value from any trailing inline comment.
258
+ * Understands single-quoted and double-quoted YAML strings so it won't
259
+ * mistake a `#` inside a quoted value for a comment delimiter.
260
+ */
261
+ private splitYamlInlineComment;
262
+ /** Returns true when `value` looks like a YAML block scalar indicator (`>`, `|`, `>-`, `|-`, etc.) */
263
+ private isYamlBlockScalarIndicator;
264
+ /** Escape a plain string for use inside a YAML double-quoted scalar. */
265
+ private escapeForYamlDoubleQuoted;
266
+ /**
267
+ * Normalise a raw YAML title value to a double-quoted scalar.
268
+ * Handles: empty, already double-quoted, single-quoted (unescaping `''`),
269
+ * block-scalar indicators, and plain unquoted values.
270
+ */
271
+ private normalizeFrontmatterTitleValue;
272
+ /**
273
+ * Ensure every `title:` line in YAML frontmatter is double-quoted.
274
+ * Handles already-quoted (single or double), multi-word, and special-char values.
275
+ * Preserves inline comments and handles both LF and CRLF line endings.
276
+ */
277
+ private quoteFrontmatterTitles;
163
278
  readBeanFile(relativePath: string): Promise<{
164
279
  path: string;
165
280
  content: string;
@@ -202,7 +317,9 @@ declare function parseCliArgs(argv: string[]): {
202
317
  };
203
318
  declare function startBeansMcpServer(argv: string[],
204
319
  /** For testing only: override the roots resolver so tests can cover the setInner branch. */
205
- _resolveRoots?: (server: McpServer) => Promise<string | null>): Promise<void>;
320
+ _resolveRoots?: (server: McpServer) => Promise<string | null>,
321
+ /** For testing only: override Beans CLI version detection. */
322
+ _detectBeansVersion?: (cliPath: string, workspaceRoot: string) => Promise<string | null>): Promise<void>;
206
323
 
207
324
  /**
208
325
  * Check whether `target` is contained within `root` after resolving both paths.