gsd-lite 0.1.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/src/server.js ADDED
@@ -0,0 +1,240 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
4
+ import { pathToFileURL } from 'node:url';
5
+ import { init, read, update, phaseComplete } from './tools/state.js';
6
+ import {
7
+ handleDebuggerResult,
8
+ handleExecutorResult,
9
+ handleResearcherResult,
10
+ handleReviewerResult,
11
+ resumeWorkflow,
12
+ } from './tools/orchestrator.js';
13
+
14
+ const server = new Server(
15
+ { name: 'gsd-lite', version: '0.1.0' },
16
+ { capabilities: { tools: {} } }
17
+ );
18
+
19
+ const TOOLS = [
20
+ {
21
+ name: 'gsd-health',
22
+ description: 'Health check: returns server status and whether .gsd state exists',
23
+ inputSchema: {
24
+ type: 'object',
25
+ properties: {},
26
+ },
27
+ },
28
+ {
29
+ name: 'gsd-state-init',
30
+ description: 'Initialize .gsd/ directory with state.json, plan.md, and phases/*.md',
31
+ inputSchema: {
32
+ type: 'object',
33
+ properties: {
34
+ project: { type: 'string', description: 'Project name' },
35
+ phases: {
36
+ type: 'array',
37
+ description: 'Phase definitions with tasks',
38
+ items: {
39
+ type: 'object',
40
+ properties: {
41
+ name: { type: 'string' },
42
+ tasks: { type: 'array' },
43
+ },
44
+ },
45
+ },
46
+ research: { type: 'boolean', description: 'Whether research directory is needed' },
47
+ },
48
+ required: ['project', 'phases'],
49
+ },
50
+ },
51
+ {
52
+ name: 'gsd-state-read',
53
+ description: 'Read state.json, optionally filtering to specific fields',
54
+ inputSchema: {
55
+ type: 'object',
56
+ properties: {
57
+ fields: {
58
+ type: 'array',
59
+ items: { type: 'string' },
60
+ description: 'Optional field names to return (returns all if omitted)',
61
+ },
62
+ },
63
+ },
64
+ },
65
+ {
66
+ name: 'gsd-state-update',
67
+ description: 'Update state.json canonical fields with lifecycle validation',
68
+ inputSchema: {
69
+ type: 'object',
70
+ properties: {
71
+ updates: {
72
+ type: 'object',
73
+ description: 'Key-value pairs of canonical fields to update',
74
+ },
75
+ },
76
+ required: ['updates'],
77
+ },
78
+ },
79
+ {
80
+ name: 'gsd-phase-complete',
81
+ description: 'Mark a phase as complete after verifying handoff gate conditions',
82
+ inputSchema: {
83
+ type: 'object',
84
+ properties: {
85
+ phase_id: { type: 'number', description: 'Phase number to complete' },
86
+ verification: {
87
+ type: 'object',
88
+ description: 'Optional precomputed verification result object with lint/typecheck/test exit codes',
89
+ },
90
+ run_verify: {
91
+ type: 'boolean',
92
+ description: 'When true, run lint/typecheck/test during handoff evaluation',
93
+ },
94
+ direction_ok: {
95
+ type: 'boolean',
96
+ description: 'Optional direction drift check result; false moves workflow into awaiting_user',
97
+ },
98
+ },
99
+ required: ['phase_id'],
100
+ },
101
+ },
102
+ {
103
+ name: 'gsd-orchestrator-resume',
104
+ description: 'Resume the minimal orchestration loop from workflow_mode/current_phase state',
105
+ inputSchema: {
106
+ type: 'object',
107
+ properties: {},
108
+ },
109
+ },
110
+ {
111
+ name: 'gsd-orchestrator-handle-executor-result',
112
+ description: 'Persist an executor result and determine the next orchestration action',
113
+ inputSchema: {
114
+ type: 'object',
115
+ properties: {
116
+ result: { type: 'object', description: 'Executor result payload' },
117
+ },
118
+ required: ['result'],
119
+ },
120
+ },
121
+ {
122
+ name: 'gsd-orchestrator-handle-debugger-result',
123
+ description: 'Persist a debugger result and determine the next orchestration action',
124
+ inputSchema: {
125
+ type: 'object',
126
+ properties: {
127
+ result: { type: 'object', description: 'Debugger result payload' },
128
+ },
129
+ required: ['result'],
130
+ },
131
+ },
132
+ {
133
+ name: 'gsd-orchestrator-handle-researcher-result',
134
+ description: 'Persist a researcher result, write .gsd/research artifacts, and continue orchestration',
135
+ inputSchema: {
136
+ type: 'object',
137
+ properties: {
138
+ result: { type: 'object', description: 'Researcher result payload' },
139
+ decision_index: { type: 'object', description: 'Decision index keyed by decision id' },
140
+ artifacts: { type: 'object', description: 'Markdown artifact contents keyed by file name' },
141
+ },
142
+ required: ['result', 'decision_index', 'artifacts'],
143
+ },
144
+ },
145
+ {
146
+ name: 'gsd-orchestrator-handle-reviewer-result',
147
+ description: 'Persist a reviewer result, update task lifecycles, and determine next orchestration action',
148
+ inputSchema: {
149
+ type: 'object',
150
+ properties: {
151
+ result: { type: 'object', description: 'Reviewer result payload' },
152
+ },
153
+ required: ['result'],
154
+ },
155
+ },
156
+ ];
157
+
158
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
159
+ tools: TOOLS,
160
+ }));
161
+
162
+ async function dispatchToolCall(name, args) {
163
+ let result;
164
+ switch (name) {
165
+ case 'gsd-health': {
166
+ const stateResult = await read(args || {});
167
+ result = {
168
+ status: 'ok',
169
+ server: 'gsd-lite',
170
+ version: '0.1.0',
171
+ state_exists: !stateResult.error,
172
+ ...(stateResult.error ? {} : {
173
+ project: stateResult.project,
174
+ workflow_mode: stateResult.workflow_mode,
175
+ current_phase: stateResult.current_phase,
176
+ total_phases: stateResult.total_phases,
177
+ }),
178
+ };
179
+ break;
180
+ }
181
+ case 'gsd-state-init':
182
+ result = await init(args);
183
+ break;
184
+ case 'gsd-state-read':
185
+ result = await read(args || {});
186
+ break;
187
+ case 'gsd-state-update':
188
+ result = await update(args);
189
+ break;
190
+ case 'gsd-phase-complete':
191
+ result = await phaseComplete(args);
192
+ break;
193
+ case 'gsd-orchestrator-resume':
194
+ result = await resumeWorkflow(args || {});
195
+ break;
196
+ case 'gsd-orchestrator-handle-executor-result':
197
+ result = await handleExecutorResult(args || {});
198
+ break;
199
+ case 'gsd-orchestrator-handle-debugger-result':
200
+ result = await handleDebuggerResult(args || {});
201
+ break;
202
+ case 'gsd-orchestrator-handle-researcher-result':
203
+ result = await handleResearcherResult(args || {});
204
+ break;
205
+ case 'gsd-orchestrator-handle-reviewer-result':
206
+ result = await handleReviewerResult(args || {});
207
+ break;
208
+ default:
209
+ result = { error: true, message: `Unknown tool: ${name}` };
210
+ }
211
+
212
+ return result;
213
+ }
214
+
215
+ export async function handleToolCall(name, args) {
216
+ try {
217
+ return await dispatchToolCall(name, args);
218
+ } catch (err) {
219
+ const message = err instanceof Error ? err.message : String(err);
220
+ return { error: true, message: `Tool execution failed: ${message}` };
221
+ }
222
+ }
223
+
224
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
225
+ const { name, arguments: args } = request.params;
226
+ const result = await handleToolCall(name, args);
227
+
228
+ return {
229
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
230
+ };
231
+ });
232
+
233
+ async function main() {
234
+ const transport = new StdioServerTransport();
235
+ await server.connect(transport);
236
+ }
237
+
238
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
239
+ main().catch(console.error);
240
+ }