@proletariat/cli 0.3.23 → 0.3.25

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 (235) hide show
  1. package/dist/commands/action/create.js +4 -4
  2. package/dist/commands/action/update.js +3 -3
  3. package/dist/commands/agent/{temp/cleanup.d.ts → cleanup.d.ts} +1 -1
  4. package/dist/commands/agent/{temp/cleanup.js → cleanup.js} +4 -4
  5. package/dist/commands/agent/index.js +8 -8
  6. package/dist/commands/branch/create.js +2 -2
  7. package/dist/commands/epic/activate.js +9 -17
  8. package/dist/commands/epic/archive.js +13 -24
  9. package/dist/commands/epic/create.d.ts +1 -0
  10. package/dist/commands/epic/create.js +46 -8
  11. package/dist/commands/epic/index.js +2 -2
  12. package/dist/commands/epic/move.js +28 -47
  13. package/dist/commands/epic/progress.js +10 -14
  14. package/dist/commands/epic/project.js +42 -59
  15. package/dist/commands/epic/reorder.js +25 -30
  16. package/dist/commands/epic/spec.d.ts +1 -0
  17. package/dist/commands/epic/spec.js +39 -40
  18. package/dist/commands/epic/ticket.d.ts +2 -0
  19. package/dist/commands/epic/ticket.js +63 -37
  20. package/dist/commands/feedback/index.d.ts +10 -0
  21. package/dist/commands/feedback/index.js +60 -0
  22. package/dist/commands/feedback/list.d.ts +12 -0
  23. package/dist/commands/feedback/list.js +126 -0
  24. package/dist/commands/feedback/submit.d.ts +16 -0
  25. package/dist/commands/feedback/submit.js +220 -0
  26. package/dist/commands/{template/phase/delete.d.ts → feedback/view.d.ts} +7 -5
  27. package/dist/commands/feedback/view.js +109 -0
  28. package/dist/commands/gh/index.js +4 -0
  29. package/dist/commands/{epic/link/remove.d.ts → link/create.d.ts} +6 -7
  30. package/dist/commands/link/create.js +141 -0
  31. package/dist/commands/{epic/link/relates.d.ts → link/index.d.ts} +4 -5
  32. package/dist/commands/link/index.js +87 -0
  33. package/dist/commands/{epic/link/duplicates.d.ts → link/list.d.ts} +7 -4
  34. package/dist/commands/link/list.js +182 -0
  35. package/dist/commands/{spec/link → link}/remove.d.ts +4 -5
  36. package/dist/commands/link/remove.js +120 -0
  37. package/dist/commands/mcp-server.d.ts +22 -0
  38. package/dist/commands/mcp-server.js +98 -0
  39. package/dist/commands/phase/create.js +1 -1
  40. package/dist/commands/project/create.d.ts +1 -0
  41. package/dist/commands/project/create.js +38 -4
  42. package/dist/commands/repo/create.d.ts +38 -0
  43. package/dist/commands/repo/create.js +283 -0
  44. package/dist/commands/repo/index.js +7 -0
  45. package/dist/commands/roadmap/add-project.js +9 -22
  46. package/dist/commands/roadmap/create.d.ts +0 -1
  47. package/dist/commands/roadmap/create.js +46 -40
  48. package/dist/commands/roadmap/delete.js +10 -24
  49. package/dist/commands/roadmap/generate.d.ts +1 -0
  50. package/dist/commands/roadmap/generate.js +21 -22
  51. package/dist/commands/roadmap/remove-project.js +14 -34
  52. package/dist/commands/roadmap/reorder.js +19 -26
  53. package/dist/commands/roadmap/update.js +27 -26
  54. package/dist/commands/roadmap/view.js +5 -12
  55. package/dist/commands/session/attach.d.ts +1 -8
  56. package/dist/commands/session/attach.js +93 -59
  57. package/dist/commands/session/list.d.ts +0 -8
  58. package/dist/commands/session/list.js +130 -81
  59. package/dist/commands/spec/create.d.ts +1 -0
  60. package/dist/commands/spec/create.js +44 -3
  61. package/dist/commands/spec/edit.js +63 -33
  62. package/dist/commands/spec/index.js +2 -2
  63. package/dist/commands/{agent/staff → staff}/add.js +10 -10
  64. package/dist/commands/{agent/staff → staff}/index.d.ts +1 -1
  65. package/dist/commands/{agent/staff → staff}/index.js +7 -7
  66. package/dist/commands/{agent/staff → staff}/list.js +3 -3
  67. package/dist/commands/{agent/staff → staff}/remove.d.ts +1 -1
  68. package/dist/commands/{agent/staff → staff}/remove.js +8 -8
  69. package/dist/commands/{template/phase/index.d.ts → support/book.d.ts} +2 -2
  70. package/dist/commands/support/book.js +54 -0
  71. package/dist/commands/{template/ticket/index.d.ts → support/discord.d.ts} +2 -2
  72. package/dist/commands/support/discord.js +54 -0
  73. package/dist/commands/support/docs.d.ts +10 -0
  74. package/dist/commands/support/docs.js +54 -0
  75. package/dist/commands/support/index.d.ts +19 -0
  76. package/dist/commands/support/index.js +81 -0
  77. package/dist/commands/support/issues.d.ts +11 -0
  78. package/dist/commands/support/issues.js +77 -0
  79. package/dist/commands/support/logs.d.ts +18 -0
  80. package/dist/commands/support/logs.js +247 -0
  81. package/dist/commands/{ticket/template → template}/apply.d.ts +8 -6
  82. package/dist/commands/template/apply.js +262 -0
  83. package/dist/commands/{ticket/template → template}/create.d.ts +5 -6
  84. package/dist/commands/template/create.js +238 -0
  85. package/dist/commands/template/index.js +48 -36
  86. package/dist/commands/{ticket/template → template}/save.d.ts +2 -2
  87. package/dist/commands/template/save.js +104 -0
  88. package/dist/commands/{phase/template → template}/update.d.ts +2 -2
  89. package/dist/commands/template/update.js +99 -0
  90. package/dist/commands/{agent/themes → theme}/add-names.d.ts +1 -1
  91. package/dist/commands/{agent/themes → theme}/add-names.js +6 -6
  92. package/dist/commands/{agent/themes → theme}/create.d.ts +1 -1
  93. package/dist/commands/{agent/themes → theme}/create.js +5 -5
  94. package/dist/commands/{agent/themes → theme}/index.d.ts +1 -1
  95. package/dist/commands/{agent/themes → theme}/index.js +10 -10
  96. package/dist/commands/{agent/themes → theme}/list.d.ts +1 -1
  97. package/dist/commands/{agent/themes → theme}/list.js +5 -5
  98. package/dist/commands/{agent/themes → theme}/set.d.ts +1 -1
  99. package/dist/commands/{agent/themes → theme}/set.js +7 -7
  100. package/dist/commands/ticket/create.d.ts +1 -0
  101. package/dist/commands/ticket/create.js +75 -15
  102. package/dist/commands/ticket/edit.js +44 -13
  103. package/dist/commands/ticket/index.js +6 -6
  104. package/dist/commands/ticket/move.d.ts +7 -0
  105. package/dist/commands/ticket/move.js +132 -0
  106. package/dist/commands/work/spawn.d.ts +1 -0
  107. package/dist/commands/work/spawn.js +72 -8
  108. package/dist/commands/work/start.js +6 -0
  109. package/dist/lib/execution/runners.js +21 -17
  110. package/dist/lib/execution/session-utils.d.ts +60 -0
  111. package/dist/lib/execution/session-utils.js +162 -0
  112. package/dist/lib/execution/spawner.d.ts +2 -0
  113. package/dist/lib/execution/spawner.js +42 -0
  114. package/dist/lib/flags/resolver.d.ts +2 -2
  115. package/dist/lib/flags/resolver.js +15 -0
  116. package/dist/lib/init/index.js +18 -0
  117. package/dist/lib/mcp/helpers.d.ts +43 -0
  118. package/dist/lib/mcp/helpers.js +57 -0
  119. package/dist/lib/mcp/index.d.ts +6 -0
  120. package/dist/lib/mcp/index.js +6 -0
  121. package/dist/lib/mcp/tools/action.d.ts +6 -0
  122. package/dist/lib/mcp/tools/action.js +88 -0
  123. package/dist/lib/mcp/tools/board.d.ts +6 -0
  124. package/dist/lib/mcp/tools/board.js +139 -0
  125. package/dist/lib/mcp/tools/category.d.ts +6 -0
  126. package/dist/lib/mcp/tools/category.js +84 -0
  127. package/dist/lib/mcp/tools/cli-passthrough.d.ts +15 -0
  128. package/dist/lib/mcp/tools/cli-passthrough.js +333 -0
  129. package/dist/lib/mcp/tools/epic.d.ts +6 -0
  130. package/dist/lib/mcp/tools/epic.js +178 -0
  131. package/dist/lib/mcp/tools/index.d.ts +18 -0
  132. package/dist/lib/mcp/tools/index.js +19 -0
  133. package/dist/lib/mcp/tools/phase.d.ts +6 -0
  134. package/dist/lib/mcp/tools/phase.js +131 -0
  135. package/dist/lib/mcp/tools/project.d.ts +6 -0
  136. package/dist/lib/mcp/tools/project.js +196 -0
  137. package/dist/lib/mcp/tools/roadmap.d.ts +6 -0
  138. package/dist/lib/mcp/tools/roadmap.js +123 -0
  139. package/dist/lib/mcp/tools/spec.d.ts +6 -0
  140. package/dist/lib/mcp/tools/spec.js +196 -0
  141. package/dist/lib/mcp/tools/status.d.ts +6 -0
  142. package/dist/lib/mcp/tools/status.js +109 -0
  143. package/dist/lib/mcp/tools/template.d.ts +6 -0
  144. package/dist/lib/mcp/tools/template.js +107 -0
  145. package/dist/lib/mcp/tools/ticket.d.ts +6 -0
  146. package/dist/lib/mcp/tools/ticket.js +393 -0
  147. package/dist/lib/mcp/tools/view.d.ts +6 -0
  148. package/dist/lib/mcp/tools/view.js +76 -0
  149. package/dist/lib/mcp/tools/work.d.ts +6 -0
  150. package/dist/lib/mcp/tools/work.js +132 -0
  151. package/dist/lib/mcp/tools/workflow.d.ts +6 -0
  152. package/dist/lib/mcp/tools/workflow.js +95 -0
  153. package/dist/lib/mcp/types.d.ts +17 -0
  154. package/dist/lib/mcp/types.js +4 -0
  155. package/dist/lib/multiline-input.d.ts +63 -0
  156. package/dist/lib/multiline-input.js +360 -0
  157. package/dist/lib/prompt-json.d.ts +57 -6
  158. package/dist/lib/prompt-json.js +45 -0
  159. package/dist/lib/repos/git.d.ts +7 -0
  160. package/dist/lib/repos/git.js +20 -0
  161. package/oclif.manifest.json +3690 -4995
  162. package/package.json +6 -4
  163. package/dist/commands/agent/temp/index.d.ts +0 -14
  164. package/dist/commands/agent/temp/index.js +0 -85
  165. package/dist/commands/agent/temp/list.d.ts +0 -7
  166. package/dist/commands/agent/temp/list.js +0 -108
  167. package/dist/commands/epic/link/block.d.ts +0 -14
  168. package/dist/commands/epic/link/block.js +0 -81
  169. package/dist/commands/epic/link/duplicates.js +0 -68
  170. package/dist/commands/epic/link/index.d.ts +0 -19
  171. package/dist/commands/epic/link/index.js +0 -272
  172. package/dist/commands/epic/link/relates.js +0 -68
  173. package/dist/commands/epic/link/remove.js +0 -93
  174. package/dist/commands/phase/template/apply.d.ts +0 -17
  175. package/dist/commands/phase/template/apply.js +0 -108
  176. package/dist/commands/phase/template/create.d.ts +0 -17
  177. package/dist/commands/phase/template/create.js +0 -104
  178. package/dist/commands/phase/template/delete.d.ts +0 -17
  179. package/dist/commands/phase/template/delete.js +0 -100
  180. package/dist/commands/phase/template/index.d.ts +0 -15
  181. package/dist/commands/phase/template/index.js +0 -130
  182. package/dist/commands/phase/template/list.d.ts +0 -16
  183. package/dist/commands/phase/template/list.js +0 -97
  184. package/dist/commands/phase/template/update.js +0 -89
  185. package/dist/commands/spec/link/depends.d.ts +0 -14
  186. package/dist/commands/spec/link/depends.js +0 -64
  187. package/dist/commands/spec/link/duplicates.d.ts +0 -14
  188. package/dist/commands/spec/link/duplicates.js +0 -63
  189. package/dist/commands/spec/link/index.d.ts +0 -19
  190. package/dist/commands/spec/link/index.js +0 -207
  191. package/dist/commands/spec/link/relates.d.ts +0 -14
  192. package/dist/commands/spec/link/relates.js +0 -63
  193. package/dist/commands/spec/link/remove.js +0 -96
  194. package/dist/commands/template/phase/apply.d.ts +0 -14
  195. package/dist/commands/template/phase/apply.js +0 -43
  196. package/dist/commands/template/phase/create.d.ts +0 -13
  197. package/dist/commands/template/phase/create.js +0 -38
  198. package/dist/commands/template/phase/delete.js +0 -36
  199. package/dist/commands/template/phase/index.js +0 -63
  200. package/dist/commands/template/phase/list.d.ts +0 -11
  201. package/dist/commands/template/phase/list.js +0 -36
  202. package/dist/commands/template/phase/update.d.ts +0 -14
  203. package/dist/commands/template/phase/update.js +0 -43
  204. package/dist/commands/template/ticket/apply.d.ts +0 -17
  205. package/dist/commands/template/ticket/apply.js +0 -60
  206. package/dist/commands/template/ticket/create.d.ts +0 -20
  207. package/dist/commands/template/ticket/create.js +0 -89
  208. package/dist/commands/template/ticket/delete.d.ts +0 -13
  209. package/dist/commands/template/ticket/delete.js +0 -38
  210. package/dist/commands/template/ticket/index.js +0 -63
  211. package/dist/commands/template/ticket/list.d.ts +0 -11
  212. package/dist/commands/template/ticket/list.js +0 -36
  213. package/dist/commands/template/ticket/save.d.ts +0 -15
  214. package/dist/commands/template/ticket/save.js +0 -46
  215. package/dist/commands/ticket/link/block.d.ts +0 -14
  216. package/dist/commands/ticket/link/block.js +0 -96
  217. package/dist/commands/ticket/link/duplicates.d.ts +0 -14
  218. package/dist/commands/ticket/link/duplicates.js +0 -95
  219. package/dist/commands/ticket/link/index.d.ts +0 -19
  220. package/dist/commands/ticket/link/index.js +0 -256
  221. package/dist/commands/ticket/link/relates.d.ts +0 -14
  222. package/dist/commands/ticket/link/relates.js +0 -95
  223. package/dist/commands/ticket/link/remove.d.ts +0 -16
  224. package/dist/commands/ticket/link/remove.js +0 -132
  225. package/dist/commands/ticket/template/apply.js +0 -252
  226. package/dist/commands/ticket/template/create.js +0 -386
  227. package/dist/commands/ticket/template/delete.d.ts +0 -17
  228. package/dist/commands/ticket/template/delete.js +0 -94
  229. package/dist/commands/ticket/template/index.d.ts +0 -15
  230. package/dist/commands/ticket/template/index.js +0 -120
  231. package/dist/commands/ticket/template/list.d.ts +0 -16
  232. package/dist/commands/ticket/template/list.js +0 -112
  233. package/dist/commands/ticket/template/save.js +0 -163
  234. /package/dist/commands/{agent/staff → staff}/add.d.ts +0 -0
  235. /package/dist/commands/{agent/staff → staff}/list.d.ts +0 -0
@@ -0,0 +1,131 @@
1
+ /**
2
+ * MCP Phase Tools
3
+ */
4
+ import { z } from 'zod';
5
+ import { errorResponse } from '../helpers.js';
6
+ export function registerPhaseTools(server, ctx) {
7
+ server.tool('phase_list', 'List project phases', { category: z.enum(['triage', 'backlog', 'unstarted', 'started', 'completed', 'canceled']).optional() }, async (params) => {
8
+ try {
9
+ const phases = await ctx.storage.listPhases({ category: params.category });
10
+ return {
11
+ content: [{
12
+ type: 'text',
13
+ text: JSON.stringify({
14
+ success: true,
15
+ phases: phases.map((p) => ({
16
+ id: p.id,
17
+ name: p.name,
18
+ category: p.category,
19
+ position: p.position,
20
+ isDefault: p.isDefault,
21
+ })),
22
+ }, null, 2),
23
+ }],
24
+ };
25
+ }
26
+ catch (error) {
27
+ return errorResponse(error);
28
+ }
29
+ });
30
+ server.tool('phase_create', 'Create a project phase', {
31
+ name: z.string().describe('Phase name'),
32
+ category: z.enum(['triage', 'backlog', 'unstarted', 'started', 'completed', 'canceled']),
33
+ position: z.number().optional(),
34
+ is_default: z.boolean().optional(),
35
+ }, async (params) => {
36
+ try {
37
+ const phase = await ctx.storage.createPhase({
38
+ name: params.name,
39
+ category: params.category,
40
+ position: params.position,
41
+ isDefault: params.is_default,
42
+ });
43
+ return {
44
+ content: [{
45
+ type: 'text',
46
+ text: JSON.stringify({ success: true, phase: { id: phase.id, name: phase.name } }, null, 2),
47
+ }],
48
+ };
49
+ }
50
+ catch (error) {
51
+ return errorResponse(error);
52
+ }
53
+ });
54
+ server.tool('phase_update', 'Update a phase', {
55
+ id: z.string().describe('Phase ID'),
56
+ name: z.string().optional(),
57
+ category: z.enum(['triage', 'backlog', 'unstarted', 'started', 'completed', 'canceled']).optional(),
58
+ }, async (params) => {
59
+ try {
60
+ const changes = {};
61
+ if (params.name)
62
+ changes.name = params.name;
63
+ if (params.category)
64
+ changes.category = params.category;
65
+ const phase = await ctx.storage.updatePhase(params.id, changes);
66
+ return {
67
+ content: [{
68
+ type: 'text',
69
+ text: JSON.stringify({ success: true, phase: { id: phase.id, name: phase.name } }, null, 2),
70
+ }],
71
+ };
72
+ }
73
+ catch (error) {
74
+ return errorResponse(error);
75
+ }
76
+ });
77
+ server.tool('phase_delete', 'Delete a phase', { id: z.string().describe('Phase ID') }, async (params) => {
78
+ try {
79
+ await ctx.storage.deletePhase(params.id);
80
+ return {
81
+ content: [{
82
+ type: 'text',
83
+ text: JSON.stringify({ success: true, message: 'Phase deleted' }, null, 2),
84
+ }],
85
+ };
86
+ }
87
+ catch (error) {
88
+ return errorResponse(error);
89
+ }
90
+ });
91
+ server.tool('phase_template_list', 'List phase templates', {}, async () => {
92
+ try {
93
+ const templates = await ctx.storage.listPhaseTemplates();
94
+ return {
95
+ content: [{
96
+ type: 'text',
97
+ text: JSON.stringify({
98
+ success: true,
99
+ templates: templates.map((t) => ({
100
+ id: t.id,
101
+ name: t.name,
102
+ description: t.description,
103
+ isBuiltin: t.isBuiltin,
104
+ })),
105
+ }, null, 2),
106
+ }],
107
+ };
108
+ }
109
+ catch (error) {
110
+ return errorResponse(error);
111
+ }
112
+ });
113
+ server.tool('phase_template_apply', 'Apply a phase template', { template_id: z.string().describe('Template ID') }, async (params) => {
114
+ try {
115
+ const phases = await ctx.storage.applyPhaseTemplate(params.template_id);
116
+ return {
117
+ content: [{
118
+ type: 'text',
119
+ text: JSON.stringify({
120
+ success: true,
121
+ message: `Applied template, created ${phases.length} phases`,
122
+ phases: phases.map((p) => ({ id: p.id, name: p.name })),
123
+ }, null, 2),
124
+ }],
125
+ };
126
+ }
127
+ catch (error) {
128
+ return errorResponse(error);
129
+ }
130
+ });
131
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP Project Tools
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { McpToolContext } from '../types.js';
6
+ export declare function registerProjectTools(server: McpServer, ctx: McpToolContext): void;
@@ -0,0 +1,196 @@
1
+ /**
2
+ * MCP Project Tools
3
+ */
4
+ import { z } from 'zod';
5
+ import { errorResponse } from '../helpers.js';
6
+ export function registerProjectTools(server, ctx) {
7
+ server.tool('project_list', 'List all projects', {
8
+ include_archived: z.boolean().optional().describe('Include archived'),
9
+ search: z.string().optional().describe('Search in name'),
10
+ }, async (params) => {
11
+ try {
12
+ const projects = await ctx.storage.listProjects({
13
+ isArchived: params.include_archived ? undefined : false,
14
+ search: params.search,
15
+ });
16
+ return {
17
+ content: [{
18
+ type: 'text',
19
+ text: JSON.stringify({
20
+ success: true,
21
+ count: projects.length,
22
+ projects: projects.map((p) => ({
23
+ id: p.id,
24
+ name: p.name,
25
+ description: p.description,
26
+ template: p.template,
27
+ status: p.status,
28
+ isArchived: p.isArchived,
29
+ workflowId: p.workflowId,
30
+ createdAt: p.createdAt.toISOString(),
31
+ updatedAt: p.updatedAt.toISOString(),
32
+ })),
33
+ }, null, 2),
34
+ }],
35
+ };
36
+ }
37
+ catch (error) {
38
+ return errorResponse(error);
39
+ }
40
+ });
41
+ server.tool('project_create', 'Create a new project', {
42
+ name: z.string().describe('Project name'),
43
+ description: z.string().optional().describe('Description'),
44
+ template: z.string().optional().describe('Template (kanban, scrum, linear, simple)'),
45
+ }, async (params) => {
46
+ try {
47
+ const board = await ctx.storage.createProject({
48
+ name: params.name,
49
+ description: params.description,
50
+ template: params.template,
51
+ });
52
+ return {
53
+ content: [{
54
+ type: 'text',
55
+ text: JSON.stringify({
56
+ success: true,
57
+ project: { id: board.id, name: board.name, columns: board.columns.map((c) => c.name) },
58
+ }, null, 2),
59
+ }],
60
+ };
61
+ }
62
+ catch (error) {
63
+ return errorResponse(error);
64
+ }
65
+ });
66
+ server.tool('project_show', 'Get project details', { id: z.string().describe('Project ID') }, async (params) => {
67
+ try {
68
+ const project = await ctx.storage.getProject(params.id);
69
+ if (!project)
70
+ throw new Error(`Project not found: ${params.id}`);
71
+ const tickets = await ctx.storage.listTickets(params.id);
72
+ return {
73
+ content: [{
74
+ type: 'text',
75
+ text: JSON.stringify({
76
+ success: true,
77
+ project: {
78
+ id: project.id,
79
+ name: project.name,
80
+ description: project.description,
81
+ template: project.template,
82
+ status: project.status,
83
+ isArchived: project.isArchived,
84
+ workflowId: project.workflowId,
85
+ ticketCount: tickets.length,
86
+ createdAt: project.createdAt.toISOString(),
87
+ updatedAt: project.updatedAt.toISOString(),
88
+ },
89
+ }, null, 2),
90
+ }],
91
+ };
92
+ }
93
+ catch (error) {
94
+ return errorResponse(error);
95
+ }
96
+ });
97
+ server.tool('project_update', 'Update a project', {
98
+ id: z.string().describe('Project ID'),
99
+ name: z.string().optional().describe('New name'),
100
+ description: z.string().optional().describe('New description'),
101
+ }, async (params) => {
102
+ try {
103
+ const changes = {};
104
+ if (params.name)
105
+ changes.name = params.name;
106
+ if (params.description !== undefined)
107
+ changes.description = params.description;
108
+ const project = await ctx.storage.updateProject(params.id, changes);
109
+ return {
110
+ content: [{
111
+ type: 'text',
112
+ text: JSON.stringify({ success: true, project: { id: project.id, name: project.name } }, null, 2),
113
+ }],
114
+ };
115
+ }
116
+ catch (error) {
117
+ return errorResponse(error);
118
+ }
119
+ });
120
+ server.tool('project_archive', 'Archive a project', { id: z.string().describe('Project ID') }, async (params) => {
121
+ try {
122
+ const project = await ctx.storage.archiveProject(params.id);
123
+ return {
124
+ content: [{
125
+ type: 'text',
126
+ text: JSON.stringify({ success: true, project: { id: project.id, isArchived: project.isArchived } }, null, 2),
127
+ }],
128
+ };
129
+ }
130
+ catch (error) {
131
+ return errorResponse(error);
132
+ }
133
+ });
134
+ server.tool('project_unarchive', 'Unarchive a project', { id: z.string().describe('Project ID') }, async (params) => {
135
+ try {
136
+ const project = await ctx.storage.unarchiveProject(params.id);
137
+ return {
138
+ content: [{
139
+ type: 'text',
140
+ text: JSON.stringify({ success: true, project: { id: project.id, isArchived: project.isArchived } }, null, 2),
141
+ }],
142
+ };
143
+ }
144
+ catch (error) {
145
+ return errorResponse(error);
146
+ }
147
+ });
148
+ server.tool('project_delete', 'Delete a project', { id: z.string().describe('Project ID') }, async (params) => {
149
+ try {
150
+ await ctx.storage.deleteProject(params.id);
151
+ return {
152
+ content: [{
153
+ type: 'text',
154
+ text: JSON.stringify({ success: true, message: `Deleted project ${params.id}` }, null, 2),
155
+ }],
156
+ };
157
+ }
158
+ catch (error) {
159
+ return errorResponse(error);
160
+ }
161
+ });
162
+ server.tool('project_link_to_spec', 'Link project to a spec', {
163
+ project_id: z.string().describe('Project ID'),
164
+ spec_id: z.string().describe('Spec ID'),
165
+ }, async (params) => {
166
+ try {
167
+ await ctx.storage.linkProjectToSpec(params.project_id, params.spec_id);
168
+ return {
169
+ content: [{
170
+ type: 'text',
171
+ text: JSON.stringify({ success: true, message: 'Project linked to spec' }, null, 2),
172
+ }],
173
+ };
174
+ }
175
+ catch (error) {
176
+ return errorResponse(error);
177
+ }
178
+ });
179
+ server.tool('project_get_specs', 'Get specs linked to a project', { project_id: z.string().describe('Project ID') }, async (params) => {
180
+ try {
181
+ const specs = await ctx.storage.getSpecsForProject(params.project_id);
182
+ return {
183
+ content: [{
184
+ type: 'text',
185
+ text: JSON.stringify({
186
+ success: true,
187
+ specs: specs.map((s) => ({ id: s.id, title: s.title, status: s.status })),
188
+ }, null, 2),
189
+ }],
190
+ };
191
+ }
192
+ catch (error) {
193
+ return errorResponse(error);
194
+ }
195
+ });
196
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP Roadmap Tools
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { McpToolContext } from '../types.js';
6
+ export declare function registerRoadmapTools(server: McpServer, ctx: McpToolContext): void;
@@ -0,0 +1,123 @@
1
+ /**
2
+ * MCP Roadmap Tools
3
+ */
4
+ import { z } from 'zod';
5
+ import { errorResponse } from '../helpers.js';
6
+ export function registerRoadmapTools(server, ctx) {
7
+ server.tool('roadmap_list', 'List roadmaps', {}, async () => {
8
+ try {
9
+ const roadmaps = await ctx.storage.listRoadmaps();
10
+ return {
11
+ content: [{
12
+ type: 'text',
13
+ text: JSON.stringify({
14
+ success: true,
15
+ roadmaps: roadmaps.map((r) => ({
16
+ id: r.id,
17
+ name: r.name,
18
+ description: r.description,
19
+ isDefault: r.isDefault,
20
+ })),
21
+ }, null, 2),
22
+ }],
23
+ };
24
+ }
25
+ catch (error) {
26
+ return errorResponse(error);
27
+ }
28
+ });
29
+ server.tool('roadmap_create', 'Create a roadmap', {
30
+ name: z.string().describe('Roadmap name'),
31
+ description: z.string().optional(),
32
+ is_default: z.boolean().optional(),
33
+ }, async (params) => {
34
+ try {
35
+ const roadmap = await ctx.storage.createRoadmap({
36
+ name: params.name,
37
+ description: params.description,
38
+ isDefault: params.is_default ?? false,
39
+ });
40
+ return {
41
+ content: [{
42
+ type: 'text',
43
+ text: JSON.stringify({ success: true, roadmap: { id: roadmap.id, name: roadmap.name } }, null, 2),
44
+ }],
45
+ };
46
+ }
47
+ catch (error) {
48
+ return errorResponse(error);
49
+ }
50
+ });
51
+ server.tool('roadmap_show', 'Get roadmap with projects', { id: z.string().describe('Roadmap ID') }, async (params) => {
52
+ try {
53
+ const roadmap = await ctx.storage.getRoadmap(params.id);
54
+ if (!roadmap)
55
+ throw new Error(`Roadmap not found: ${params.id}`);
56
+ const projects = await ctx.storage.listRoadmapProjects(params.id);
57
+ return {
58
+ content: [{
59
+ type: 'text',
60
+ text: JSON.stringify({
61
+ success: true,
62
+ roadmap: {
63
+ ...roadmap,
64
+ projects: projects.map((p) => ({ id: p.id, name: p.name })),
65
+ },
66
+ }, null, 2),
67
+ }],
68
+ };
69
+ }
70
+ catch (error) {
71
+ return errorResponse(error);
72
+ }
73
+ });
74
+ server.tool('roadmap_add_project', 'Add project to roadmap', {
75
+ roadmap_id: z.string().describe('Roadmap ID'),
76
+ project_id: z.string().describe('Project ID'),
77
+ position: z.number().optional(),
78
+ }, async (params) => {
79
+ try {
80
+ await ctx.storage.addProjectToRoadmap(params.roadmap_id, params.project_id, params.position);
81
+ return {
82
+ content: [{
83
+ type: 'text',
84
+ text: JSON.stringify({ success: true, message: 'Project added to roadmap' }, null, 2),
85
+ }],
86
+ };
87
+ }
88
+ catch (error) {
89
+ return errorResponse(error);
90
+ }
91
+ });
92
+ server.tool('roadmap_remove_project', 'Remove project from roadmap', {
93
+ roadmap_id: z.string().describe('Roadmap ID'),
94
+ project_id: z.string().describe('Project ID'),
95
+ }, async (params) => {
96
+ try {
97
+ await ctx.storage.removeProjectFromRoadmap(params.roadmap_id, params.project_id);
98
+ return {
99
+ content: [{
100
+ type: 'text',
101
+ text: JSON.stringify({ success: true, message: 'Project removed from roadmap' }, null, 2),
102
+ }],
103
+ };
104
+ }
105
+ catch (error) {
106
+ return errorResponse(error);
107
+ }
108
+ });
109
+ server.tool('roadmap_delete', 'Delete a roadmap', { id: z.string().describe('Roadmap ID') }, async (params) => {
110
+ try {
111
+ await ctx.storage.deleteRoadmap(params.id);
112
+ return {
113
+ content: [{
114
+ type: 'text',
115
+ text: JSON.stringify({ success: true, message: 'Roadmap deleted' }, null, 2),
116
+ }],
117
+ };
118
+ }
119
+ catch (error) {
120
+ return errorResponse(error);
121
+ }
122
+ });
123
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP Spec Tools
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { McpToolContext } from '../types.js';
6
+ export declare function registerSpecTools(server: McpServer, ctx: McpToolContext): void;
@@ -0,0 +1,196 @@
1
+ /**
2
+ * MCP Spec Tools
3
+ */
4
+ import { z } from 'zod';
5
+ import { errorResponse } from '../helpers.js';
6
+ export function registerSpecTools(server, ctx) {
7
+ server.tool('spec_list', 'List specifications', {
8
+ status: z.enum(['draft', 'active', 'implemented']).optional(),
9
+ type: z.enum(['product', 'platform', 'infra', 'integration']).optional(),
10
+ search: z.string().optional(),
11
+ }, async (params) => {
12
+ try {
13
+ const specs = await ctx.storage.listSpecs({
14
+ status: params.status,
15
+ type: params.type,
16
+ search: params.search,
17
+ });
18
+ return {
19
+ content: [{
20
+ type: 'text',
21
+ text: JSON.stringify({
22
+ success: true,
23
+ count: specs.length,
24
+ specs: specs.map((s) => ({
25
+ id: s.id,
26
+ title: s.title,
27
+ status: s.status,
28
+ type: s.type,
29
+ tags: s.tags,
30
+ createdAt: s.createdAt.toISOString(),
31
+ })),
32
+ }, null, 2),
33
+ }],
34
+ };
35
+ }
36
+ catch (error) {
37
+ return errorResponse(error);
38
+ }
39
+ });
40
+ server.tool('spec_create', 'Create a specification', {
41
+ title: z.string().describe('Spec title'),
42
+ status: z.enum(['draft', 'active', 'implemented']).optional(),
43
+ type: z.enum(['product', 'platform', 'infra', 'integration']).optional(),
44
+ problem: z.string().optional(),
45
+ solution: z.string().optional(),
46
+ acceptance_criteria: z.string().optional(),
47
+ context: z.string().optional(),
48
+ }, async (params) => {
49
+ try {
50
+ const spec = await ctx.storage.createSpec({
51
+ title: params.title,
52
+ status: params.status || 'draft',
53
+ type: params.type,
54
+ problem: params.problem,
55
+ solution: params.solution,
56
+ acceptanceCriteria: params.acceptance_criteria,
57
+ context: params.context,
58
+ });
59
+ return {
60
+ content: [{
61
+ type: 'text',
62
+ text: JSON.stringify({ success: true, spec: { id: spec.id, title: spec.title, status: spec.status } }, null, 2),
63
+ }],
64
+ };
65
+ }
66
+ catch (error) {
67
+ return errorResponse(error);
68
+ }
69
+ });
70
+ server.tool('spec_show', 'Get spec details', { id: z.string().describe('Spec ID') }, async (params) => {
71
+ try {
72
+ const spec = await ctx.storage.getSpec(params.id);
73
+ if (!spec)
74
+ throw new Error(`Spec not found: ${params.id}`);
75
+ return {
76
+ content: [{
77
+ type: 'text',
78
+ text: JSON.stringify({ success: true, spec }, null, 2),
79
+ }],
80
+ };
81
+ }
82
+ catch (error) {
83
+ return errorResponse(error);
84
+ }
85
+ });
86
+ server.tool('spec_update', 'Update a spec', {
87
+ id: z.string().describe('Spec ID'),
88
+ title: z.string().optional(),
89
+ status: z.enum(['draft', 'active', 'implemented']).optional(),
90
+ type: z.enum(['product', 'platform', 'infra', 'integration']).optional(),
91
+ problem: z.string().optional(),
92
+ solution: z.string().optional(),
93
+ acceptance_criteria: z.string().optional(),
94
+ }, async (params) => {
95
+ try {
96
+ const changes = {};
97
+ if (params.title)
98
+ changes.title = params.title;
99
+ if (params.status)
100
+ changes.status = params.status;
101
+ if (params.type)
102
+ changes.type = params.type;
103
+ if (params.problem !== undefined)
104
+ changes.problem = params.problem;
105
+ if (params.solution !== undefined)
106
+ changes.solution = params.solution;
107
+ if (params.acceptance_criteria !== undefined)
108
+ changes.acceptanceCriteria = params.acceptance_criteria;
109
+ const spec = await ctx.storage.updateSpec(params.id, changes);
110
+ return {
111
+ content: [{
112
+ type: 'text',
113
+ text: JSON.stringify({ success: true, spec: { id: spec.id, title: spec.title } }, null, 2),
114
+ }],
115
+ };
116
+ }
117
+ catch (error) {
118
+ return errorResponse(error);
119
+ }
120
+ });
121
+ server.tool('spec_delete', 'Delete a spec', { id: z.string().describe('Spec ID') }, async (params) => {
122
+ try {
123
+ await ctx.storage.deleteSpec(params.id);
124
+ return {
125
+ content: [{
126
+ type: 'text',
127
+ text: JSON.stringify({ success: true, message: `Deleted spec ${params.id}` }, null, 2),
128
+ }],
129
+ };
130
+ }
131
+ catch (error) {
132
+ return errorResponse(error);
133
+ }
134
+ });
135
+ server.tool('spec_add_dependency', 'Add spec dependency', {
136
+ spec_id: z.string().describe('Spec ID'),
137
+ depends_on_id: z.string().describe('ID of spec this depends on'),
138
+ }, async (params) => {
139
+ try {
140
+ await ctx.storage.addSpecDependency(params.spec_id, params.depends_on_id);
141
+ return {
142
+ content: [{
143
+ type: 'text',
144
+ text: JSON.stringify({ success: true, message: 'Dependency added' }, null, 2),
145
+ }],
146
+ };
147
+ }
148
+ catch (error) {
149
+ return errorResponse(error);
150
+ }
151
+ });
152
+ server.tool('spec_get_dependencies', 'Get spec dependencies', { spec_id: z.string().describe('Spec ID') }, async (params) => {
153
+ try {
154
+ const deps = await ctx.storage.getSpecDependencies(params.spec_id);
155
+ return {
156
+ content: [{
157
+ type: 'text',
158
+ text: JSON.stringify({
159
+ success: true,
160
+ dependencies: deps.map((s) => ({ id: s.id, title: s.title })),
161
+ }, null, 2),
162
+ }],
163
+ };
164
+ }
165
+ catch (error) {
166
+ return errorResponse(error);
167
+ }
168
+ });
169
+ server.tool('spec_get_tickets', 'Get tickets linked to a spec', {
170
+ spec_id: z.string().describe('Spec ID'),
171
+ project: z.string().optional().describe('Project ID'),
172
+ }, async (params) => {
173
+ try {
174
+ let projectId = params.project;
175
+ if (!projectId) {
176
+ const projects = await ctx.storage.listProjects();
177
+ if (projects.length === 0)
178
+ throw new Error('No projects');
179
+ projectId = projects[0].id;
180
+ }
181
+ const tickets = await ctx.storage.getTicketsForSpec(projectId, params.spec_id);
182
+ return {
183
+ content: [{
184
+ type: 'text',
185
+ text: JSON.stringify({
186
+ success: true,
187
+ tickets: tickets.map((t) => ({ id: t.id, title: t.title, statusName: t.statusName })),
188
+ }, null, 2),
189
+ }],
190
+ };
191
+ }
192
+ catch (error) {
193
+ return errorResponse(error);
194
+ }
195
+ });
196
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP Status Tools
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { McpToolContext } from '../types.js';
6
+ export declare function registerStatusTools(server: McpServer, ctx: McpToolContext): void;