@selfagency/beans-mcp 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/{dist/beans-mcp-server.cjs → beans-mcp-server.cjs} +2 -1
  2. package/{dist/index.cjs → index.cjs} +2 -1
  3. package/{dist/index.js → index.js} +2 -1
  4. package/package.json +28 -64
  5. package/.beans.yml +0 -6
  6. package/.claude/settings.local.json +0 -18
  7. package/.editorconfig +0 -13
  8. package/.github/dependabot.yml +0 -11
  9. package/.github/workflows/release.yml +0 -235
  10. package/.github/workflows/test.yml +0 -84
  11. package/.husky/pre-commit +0 -1
  12. package/.nvmrc +0 -1
  13. package/.oxfmtrc.json +0 -11
  14. package/.oxlintrc.json +0 -37
  15. package/.vscode/settings.json +0 -3
  16. package/CHANGELOG.md +0 -160
  17. package/CONTRIBUTING.md +0 -139
  18. package/LICENSE.txt +0 -21
  19. package/codeql/codeql-custom-queries-actions/README.md +0 -14
  20. package/codeql/codeql-custom-queries-actions/codeql-pack.lock.yml +0 -32
  21. package/codeql/codeql-custom-queries-actions/codeql-pack.yml +0 -7
  22. package/codeql/codeql-custom-queries-actions/qlpack.yml +0 -6
  23. package/codeql/codeql-custom-queries-actions/queries/github-script-without-tojson.ql +0 -18
  24. package/codeql/codeql-custom-queries-actions/queries/strict-external-action-pinning.ql +0 -18
  25. package/codeql/codeql-custom-queries-javascript/README.md +0 -14
  26. package/codeql/codeql-custom-queries-javascript/codeql-pack.lock.yml +0 -30
  27. package/codeql/codeql-custom-queries-javascript/codeql-pack.yml +0 -7
  28. package/codeql/codeql-custom-queries-javascript/qlpack.yml +0 -6
  29. package/codeql/codeql-custom-queries-javascript/queries/child-process-shell-apis.ql +0 -26
  30. package/codeql/codeql-custom-queries-javascript/queries/innerhtml-assignment.ql +0 -24
  31. package/dist/README.md +0 -307
  32. package/dist/beans-mcp-server.cjs.map +0 -1
  33. package/dist/index.cjs.map +0 -1
  34. package/dist/index.js.map +0 -1
  35. package/dist/package.json +0 -43
  36. package/pnpm-workspace.yaml +0 -2
  37. package/scripts/release.js +0 -433
  38. package/scripts/write-dist-package.js +0 -53
  39. package/src/cli.ts +0 -14
  40. package/src/index.ts +0 -21
  41. package/src/internal/graphql.ts +0 -33
  42. package/src/internal/queryHelpers.ts +0 -157
  43. package/src/server/BeansMcpServer.ts +0 -623
  44. package/src/server/backend.ts +0 -364
  45. package/src/test/BeansMcpServer.test.ts +0 -514
  46. package/src/test/handlers.unit.test.ts +0 -201
  47. package/src/test/parseCliArgs.test.ts +0 -69
  48. package/src/test/protocol.e2e.test.ts +0 -884
  49. package/src/test/queryHelpers.test.ts +0 -524
  50. package/src/test/startBeansMcpServer.test.ts +0 -146
  51. package/src/test/tools-integration.test.ts +0 -912
  52. package/src/test/utils.test.ts +0 -81
  53. package/src/types.ts +0 -46
  54. package/src/utils.ts +0 -20
  55. package/tsconfig.json +0 -24
  56. package/tsup.config.ts +0 -42
  57. package/vitest.config.ts +0 -18
  58. /package/{dist/index.d.ts → index.d.ts} +0 -0
@@ -1,157 +0,0 @@
1
- import { BeanRecord, SortMode } from '../types';
2
-
3
- export type QueryBackend = {
4
- graphqlSchema?: () => Promise<string>;
5
- writeInstructions?: (instructions: string) => Promise<string | null>;
6
- openConfig?: () => Promise<Record<string, unknown>>;
7
- list(options?: { status?: string[]; type?: string[]; search?: string }): Promise<BeanRecord[]>;
8
- };
9
-
10
- function sortBeansInternal(beans: BeanRecord[], mode: SortMode): BeanRecord[] {
11
- const sorted = [...beans];
12
- const statusWeight: Record<string, number> = {
13
- 'in-progress': 0,
14
- todo: 1,
15
- draft: 2,
16
- completed: 3,
17
- scrapped: 4,
18
- };
19
- const priorityWeight: Record<string, number> = {
20
- critical: 0,
21
- high: 1,
22
- normal: 2,
23
- low: 3,
24
- deferred: 4,
25
- };
26
- const typeWeight: Record<string, number> = {
27
- milestone: 0,
28
- epic: 1,
29
- feature: 2,
30
- bug: 3,
31
- task: 4,
32
- };
33
-
34
- if (mode === 'updated') {
35
- return sorted.sort((a, b) => (b.updatedAt || '').localeCompare(a.updatedAt || ''));
36
- }
37
-
38
- if (mode === 'created') {
39
- return sorted.sort((a, b) => (b.createdAt || '').localeCompare(a.createdAt || ''));
40
- }
41
-
42
- if (mode === 'id') {
43
- return sorted.sort((a, b) => a.id.localeCompare(b.id));
44
- }
45
-
46
- return sorted.sort((a, b) => {
47
- const statusCmp = (statusWeight[a.status] ?? 99) - (statusWeight[b.status] ?? 99);
48
- if (statusCmp !== 0) {
49
- return statusCmp;
50
- }
51
-
52
- const aPriority = a.priority || 'normal';
53
- const bPriority = b.priority || 'normal';
54
- const priorityCmp = (priorityWeight[aPriority] ?? 99) - (priorityWeight[bPriority] ?? 99);
55
- if (priorityCmp !== 0) {
56
- return priorityCmp;
57
- }
58
-
59
- const typeCmp = (typeWeight[a.type] ?? 99) - (typeWeight[b.type] ?? 99);
60
- if (typeCmp !== 0) {
61
- return typeCmp;
62
- }
63
-
64
- return a.title.localeCompare(b.title);
65
- });
66
- }
67
-
68
- export async function handleQueryOperation(
69
- backend: QueryBackend,
70
- params: {
71
- operation: string;
72
- mode?: SortMode;
73
- statuses?: string[] | null;
74
- types?: string[] | null;
75
- search?: string;
76
- tags?: string[] | null;
77
- writeToWorkspaceInstructions?: boolean;
78
- includeClosed?: boolean;
79
- },
80
- ): Promise<{ content: Array<{ type: 'text'; text: string }>; structuredContent: Record<string, unknown> }> {
81
- const { operation, mode, statuses, types, search, tags, writeToWorkspaceInstructions, includeClosed } = params;
82
-
83
- if (operation === 'llm_context') {
84
- const graphqlSchema = typeof backend.graphqlSchema === 'function' ? await backend.graphqlSchema() : '';
85
- const instructionsPath =
86
- writeToWorkspaceInstructions && typeof backend.writeInstructions === 'function'
87
- ? await backend.writeInstructions('')
88
- : null;
89
- return {
90
- content: [
91
- {
92
- type: 'text',
93
- text: JSON.stringify({ graphqlSchema, generatedInstructions: '', instructionsPath }, null, 2),
94
- },
95
- ],
96
- structuredContent: { graphqlSchema, generatedInstructions: '', instructionsPath },
97
- };
98
- }
99
-
100
- if (operation === 'open_config') {
101
- const config = typeof backend.openConfig === 'function' ? await backend.openConfig() : {};
102
- return { content: [{ type: 'text', text: JSON.stringify(config, null, 2) }], structuredContent: config };
103
- }
104
-
105
- const normalizedStatuses = Array.isArray(statuses) ? statuses : undefined;
106
- const normalizedTypes = Array.isArray(types) ? types : undefined;
107
-
108
- if (operation === 'refresh') {
109
- const beans = await backend.list();
110
- return {
111
- content: [{ type: 'text', text: JSON.stringify({ count: beans.length, beans }, null, 2) }],
112
- structuredContent: { count: beans.length, beans },
113
- };
114
- }
115
-
116
- if (operation === 'filter') {
117
- let beans = await backend.list({ status: normalizedStatuses, type: normalizedTypes, search });
118
- if (Array.isArray(tags) && tags.length > 0) {
119
- const tagSet = new Set(tags);
120
- beans = beans.filter((bean: BeanRecord) => (bean.tags || []).some((tag: string) => tagSet.has(tag)));
121
- }
122
- return {
123
- content: [{ type: 'text', text: JSON.stringify({ count: beans.length, beans }, null, 2) }],
124
- structuredContent: { count: beans.length, beans },
125
- };
126
- }
127
-
128
- if (operation === 'search') {
129
- let beans = await backend.list({ search });
130
- if (typeof search === 'string' && search.length > 0) {
131
- const q = search.toLowerCase();
132
- beans = beans.filter((b: BeanRecord) => {
133
- const title = (b.title || '').toLowerCase();
134
- const id = (b.id || '').toLowerCase();
135
- const tagsStr = (b.tags || []).join(' ').toLowerCase();
136
- return title.includes(q) || id.includes(q) || tagsStr.includes(q);
137
- });
138
- }
139
- if (includeClosed === false) {
140
- beans = beans.filter((b: BeanRecord) => b.status !== 'completed' && b.status !== 'scrapped');
141
- }
142
- return {
143
- content: [{ type: 'text', text: JSON.stringify({ query: search, count: beans.length, beans }, null, 2) }],
144
- structuredContent: { query: search, count: beans.length, beans },
145
- };
146
- }
147
-
148
- // sort
149
- const beans = await backend.list({ status: normalizedStatuses, type: normalizedTypes, search });
150
- const sorted = sortBeansInternal(beans, mode ?? 'status-priority-type-title');
151
- return {
152
- content: [{ type: 'text', text: JSON.stringify({ mode, count: beans.length, beans: sorted }, null, 2) }],
153
- structuredContent: { mode, count: beans.length, beans: sorted },
154
- };
155
- }
156
-
157
- export { sortBeansInternal as sortBeans };