@we-scrum/cli 1.0.0 → 1.0.1

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/tsconfig.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "module": "commonjs",
4
- "moduleResolution": "node",
4
+ "moduleResolution": "bundler",
5
5
  "target": "es2021",
6
6
  "outDir": "./dist",
7
7
  "baseUrl": "src",
@@ -12,9 +12,7 @@
12
12
  "esModuleInterop": true,
13
13
  "skipLibCheck": true,
14
14
  "paths": {
15
- "@modelcontextprotocol/sdk/server": ["../node_modules/@modelcontextprotocol/sdk/dist/esm/server/index"],
16
- "@modelcontextprotocol/sdk/server/stdio.js": ["../node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio"],
17
- "@modelcontextprotocol/sdk/types.js": ["../node_modules/@modelcontextprotocol/sdk/dist/esm/types"]
15
+ "@helpers": ["helpers"]
18
16
  }
19
17
  }
20
18
  }
package/src/mcp-server.ts DELETED
@@ -1,127 +0,0 @@
1
- import { Server } from '@modelcontextprotocol/sdk/server';
2
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
- import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
4
- import { ProgressStatus } from '@we-scrum/enums';
5
- import { ProjectStoryModel, ProjectStorySectionModel } from '@we-scrum/models';
6
-
7
- import { AuthHelper } from './auth-helper';
8
- import { FirebaseHelper } from './firebase-helper';
9
- import { SettingsHelper } from './settings-helper';
10
-
11
- const TOOLS = [
12
- {
13
- name: 'get_next_task',
14
- description: `Get the next pending task (status: ToDo) for a story.
15
- Returns the task description, the task type template (development guidelines),
16
- and the full section analysis specifying what must be implemented
17
- (route changes, object/DTO changes, enumeration changes, relation/handler changes).
18
- Also returns storyId, sectionId and taskId needed to call start_task and complete_task.`,
19
- inputSchema: {
20
- type: 'object',
21
- properties: {
22
- identificationNumber: {
23
- type: 'string',
24
- description: 'The story identification number, e.g. "144154"',
25
- },
26
- },
27
- required: ['identificationNumber'],
28
- },
29
- },
30
- ];
31
-
32
- async function handleGetNextTask(identificationNumber: string): Promise<string> {
33
- const projectId = SettingsHelper.get().selectedProjectId;
34
- if (!projectId) {
35
- throw new Error('No active project selected. Please run "we-scrum use-project" first.');
36
- }
37
-
38
- // 1. Find story by identificationNumber
39
- const story = await FirebaseHelper.findDocument<ProjectStoryModel>(`/projects/${projectId}/stories`, [
40
- ['identificationNumber', '==', identificationNumber],
41
- ]);
42
-
43
- if (!story) {
44
- throw new Error(`Story "${identificationNumber}" not found in the active project.`);
45
- }
46
-
47
- // 2. Fetch all section documents at once
48
- const sections = await FirebaseHelper.getCollection<ProjectStorySectionModel>(
49
- `projects/${projectId}/stories/${story.storyId}/sections`,
50
- );
51
-
52
- // 3. Order sections using the position stored in story.sections[]
53
- const positionBySection = new Map(story.sections.map((s) => [s.sectionId, s.position ?? 0]));
54
- const sortedSections = sections.sort((a, b) => (positionBySection.get(a.sectionId) ?? 0) - (positionBySection.get(b.sectionId) ?? 0));
55
-
56
- // 4. Walk sections in order and find the first ToDo task
57
- for (const section of sortedSections) {
58
- const tasks = [...(section.tasks ?? [])].sort((a, b) => (a.position ?? 0) - (b.position ?? 0));
59
- const nextTask = tasks.find((t) => t.progress?.status === ProgressStatus.ToDo);
60
-
61
- if (!nextTask) continue;
62
-
63
- const result = {
64
- storyId: story.storyId,
65
- storyName: story.name,
66
- sectionId: section.sectionId,
67
- sectionName: section.name,
68
- task: {
69
- taskId: nextTask.taskId,
70
- description: nextTask.description,
71
- taskTypeName: nextTask.taskTypeName,
72
- position: nextTask.position,
73
- status: nextTask.progress?.status,
74
- },
75
- sectionAnalysis: {
76
- ...(section.routeChanges?.length && { routeChanges: section.routeChanges }),
77
- ...(section.objectChanges?.length && { objectChanges: section.objectChanges }),
78
- ...(section.enumerationChanges?.length && { enumerationChanges: section.enumerationChanges }),
79
- ...(section.relationChanges?.length && { relationChanges: section.relationChanges }),
80
- },
81
- };
82
-
83
- return JSON.stringify(result, null, 2);
84
- }
85
-
86
- return JSON.stringify({ message: `All tasks for story "${identificationNumber}" are complete.` });
87
- }
88
-
89
- export async function startMcpServer(): Promise<void> {
90
- const initialized = await AuthHelper.initializeFromStoredCredentials();
91
- if (!initialized) {
92
- process.stderr.write('Error: Not authenticated. Please run "we-scrum login" first.\n');
93
- process.exit(1);
94
- }
95
-
96
- const server = new Server({ name: 'we-scrum-mcp-server', version: '1.0.0' }, { capabilities: { tools: {} } });
97
-
98
- server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
99
-
100
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
101
- const { name, arguments: args } = request.params;
102
-
103
- try {
104
- let text: string;
105
-
106
- switch (name) {
107
- case 'get_next_task':
108
- text = await handleGetNextTask(args.identificationNumber as string);
109
- break;
110
- default:
111
- throw new Error(`Unknown tool: ${name}`);
112
- }
113
-
114
- return { content: [{ type: 'text', text }] };
115
- } catch (error) {
116
- return {
117
- content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }],
118
- isError: true,
119
- };
120
- }
121
- });
122
-
123
- const transport = new StdioServerTransport();
124
- await server.connect(transport);
125
-
126
- process.stderr.write('we-scrum MCP server running.\n');
127
- }
@@ -1,107 +0,0 @@
1
- import { Command, serialize } from '@my-devkit/core';
2
-
3
- export class WeScrumService {
4
- constructor(
5
- private backendUrl: string,
6
- private projectId: string,
7
- private userId: string,
8
- ) {}
9
-
10
- // public async createEnumeration(enumeration: Enumeration): Promise<string> {
11
- // Logger.info(`Creating enumeration ${enumeration.name}`);
12
-
13
- // const createCommand = TypeHelper.transform(CreateEnumerationCommand, {
14
- // projectId: this.projectId,
15
- // name: enumeration.name,
16
- // });
17
-
18
- // const enumerationId = await this.post<CreateEnumerationCommand, string>('enumeration-management/create-enumeration', createCommand);
19
- // for (const property of enumeration.properties) {
20
- // const propertyCommand = TypeHelper.transform(CreateEnumerationPropertyCommand, {
21
- // enumerationId,
22
- // enumerationPropertyId: guid(),
23
- // name: property.label,
24
- // value: property.value,
25
- // });
26
- // await this.post<CreateEnumerationPropertyCommand, string>(
27
- // 'enumeration-management/create-enumeration-property',
28
- // propertyCommand,
29
- // );
30
- // }
31
-
32
- // return enumerationId;
33
- // }
34
-
35
- // public async createObject(object: Object, getEnumerationId: (name: string) => string): Promise<string> {
36
- // Logger.info(`Creating object ${object.name}`);
37
-
38
- // const createCommand = TypeHelper.transform(CreateObjectCommand, {
39
- // projectId: this.projectId,
40
- // name: object.name,
41
- // });
42
- // const objectId = await this.post<CreateObjectCommand, string>('object-management/create-object', createCommand);
43
-
44
- // const propertyMap = new Map<string, string>();
45
- // for (const property of object.properties) {
46
- // const objectPropertyId = guid();
47
- // const propertyCommand = TypeHelper.transform(CreateObjectPropertyCommand, {
48
- // objectId,
49
- // objectPropertyId,
50
- // objectPropertyParentId: propertyMap.get(property.parent) || null,
51
- // name: property.name,
52
- // objectPropertyType: property.type,
53
- // isArray: property.isArray,
54
- // enumerationId: property.enumerationName ? getEnumerationId(property.enumerationName) : null,
55
- // });
56
- // await this.post<CreateObjectPropertyCommand, string>('object-management/create-object-property', propertyCommand);
57
-
58
- // propertyMap.set(property.path, objectPropertyId);
59
- // }
60
-
61
- // return objectId;
62
- // }
63
-
64
- // public async createHandler(handler: Handler, getObjectId: (name: string) => string): Promise<void> {
65
- // Logger.info(`Creating handler ${handler.name}`);
66
-
67
- // for (const relation of handler.relations) {
68
- // const createCommand = TypeHelper.transform(CreateRelationCommand, {
69
- // projectId: this.projectId,
70
- // boundedContext: handler.boundedContext,
71
- // handlerName: handler.name,
72
- // objectIds: relation.map((o) => getObjectId(o)),
73
- // subscriptionName: null,
74
- // });
75
- // await this.post<CreateRelationCommand, string>('relation-management/create-relation', createCommand);
76
- // }
77
- // }
78
-
79
- // public async createRoute(route: Route, getObjectId: (name: string) => string): Promise<string> {
80
- // Logger.info(`Creating route ${route.method} ${route.path}`);
81
-
82
- // const createCommand = TypeHelper.transform(CreateRouteCommand, {
83
- // projectId: this.projectId,
84
- // method: route.method,
85
- // path: route.path,
86
- // objectId: getObjectId(route.object),
87
- // permission: null,
88
- // });
89
-
90
- // return this.post<CreateRouteCommand, string>('route-management/create-route', createCommand);
91
- // }
92
-
93
- private async post<C extends Command, R>(route: string, command: C): Promise<R> {
94
- const response = await fetch(`${this.backendUrl}/command/${route}`, {
95
- method: 'POST',
96
- body: JSON.stringify(serialize(command)),
97
- headers: {
98
- 'Content-Type': 'application/json',
99
- Authorization: 'Basic ' + Buffer.from(`${this.userId}:20V0anV4M!we`).toString('base64'),
100
- },
101
- signal: AbortSignal.timeout(60 * 1000),
102
- });
103
-
104
- const body = (await response.json()) as { result: R };
105
- return body.result;
106
- }
107
- }