@work-graph/cli 0.2.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.
Files changed (194) hide show
  1. package/README.md +31 -0
  2. package/bin/work-graph.mjs +238 -0
  3. package/package.json +38 -0
  4. package/vendor/packages/design-tokens/generated/gripe-dark-default.css +67 -0
  5. package/vendor/packages/design-tokens/generated/marketplace-default.css +67 -0
  6. package/vendor/packages/design-tokens/generated/workgraph-dark.css +67 -0
  7. package/vendor/packages/workgraph-mcp/README.md +28 -0
  8. package/vendor/packages/workgraph-mcp/bin/workgraph-mcp.mjs +21 -0
  9. package/vendor/packages/workgraph-mcp/package.json +37 -0
  10. package/vendor/packages/workgraph-mcp/src/handlers.mjs +761 -0
  11. package/vendor/packages/workgraph-mcp/src/index.mjs +638 -0
  12. package/vendor/packages/workgraph-mcp/src/prompts.mjs +162 -0
  13. package/vendor/public/assets/workgraph-logo.svg +11 -0
  14. package/vendor/public/fonts/GraphikLCG/GraphikLCG-Medium.woff2 +0 -0
  15. package/vendor/public/fonts/GraphikLCG/GraphikLCG-Regular.woff2 +0 -0
  16. package/vendor/public/fonts/GraphikLCG/GraphikLCG-Semibold.woff2 +0 -0
  17. package/vendor/public/fonts/GraphikLCG/stylesheet.css +25 -0
  18. package/vendor/public/graph-canvas-lit-flow.css +154 -0
  19. package/vendor/public/graph-canvas-lit-flow.css.map +7 -0
  20. package/vendor/public/graph-canvas-lit-flow.js +8530 -0
  21. package/vendor/public/graph-canvas-lit-flow.js.map +7 -0
  22. package/vendor/src/agentBehaviorRulesAudit.mjs +168 -0
  23. package/vendor/src/agentBehaviorRulesBundle.mjs +144 -0
  24. package/vendor/src/agentRunApi.mjs +136 -0
  25. package/vendor/src/agentToolLoopGuard.mjs +88 -0
  26. package/vendor/src/agentWorkerClaudeProvider.mjs +288 -0
  27. package/vendor/src/agentWorkerCursorSdkProvider.mjs +156 -0
  28. package/vendor/src/agentWorkerLiveLoop.mjs +455 -0
  29. package/vendor/src/agentWorkerLocalCliProvider.mjs +217 -0
  30. package/vendor/src/agentWorkerLocalRunner.mjs +246 -0
  31. package/vendor/src/agentWorkerOpenAiProvider.mjs +459 -0
  32. package/vendor/src/analyticsPanelProjection.mjs +212 -0
  33. package/vendor/src/analyticsRecordStore.mjs +165 -0
  34. package/vendor/src/analyticsRecordWorkItems.mjs +104 -0
  35. package/vendor/src/architectureL1Canon.mjs +419 -0
  36. package/vendor/src/architectureLayout.mjs +229 -0
  37. package/vendor/src/architectureSnapshot.mjs +490 -0
  38. package/vendor/src/architectureViewsProjection.mjs +116 -0
  39. package/vendor/src/atomInspector.mjs +253 -0
  40. package/vendor/src/atomInspectorApi.mjs +130 -0
  41. package/vendor/src/auditGapMatrixRefresh.mjs +121 -0
  42. package/vendor/src/backlogSchemaLint.mjs +176 -0
  43. package/vendor/src/blockedOnebaseGoPreflightEval.mjs +100 -0
  44. package/vendor/src/bracketIrTraceSignal.mjs +93 -0
  45. package/vendor/src/bvcAtomParser.mjs +210 -0
  46. package/vendor/src/bvcDialectRegistry.mjs +86 -0
  47. package/vendor/src/bvcFileFormat.mjs +218 -0
  48. package/vendor/src/bvcFormatCli.mjs +55 -0
  49. package/vendor/src/bvcLintCli.mjs +48 -0
  50. package/vendor/src/bvcNewWritePolicy.mjs +70 -0
  51. package/vendor/src/charterPreflightPromoteGate.mjs +194 -0
  52. package/vendor/src/claimNoEligibleEval.mjs +205 -0
  53. package/vendor/src/closingAnalysisSuggest.mjs +59 -0
  54. package/vendor/src/codeGapAnalyzer.mjs +308 -0
  55. package/vendor/src/codeGapBacklogFeeder.mjs +82 -0
  56. package/vendor/src/codeGapDraftIntakeApi.mjs +307 -0
  57. package/vendor/src/codeGapOperatorProjection.mjs +60 -0
  58. package/vendor/src/codeSyntaxHighlight.mjs +123 -0
  59. package/vendor/src/codegenEvidence.mjs +187 -0
  60. package/vendor/src/compilerRoundTripCli.mjs +164 -0
  61. package/vendor/src/dagreGraphLayout.mjs +78 -0
  62. package/vendor/src/draftIntakePromotionRules.mjs +205 -0
  63. package/vendor/src/epicWorkScope.mjs +85 -0
  64. package/vendor/src/evalLiveLlmEnv.mjs +63 -0
  65. package/vendor/src/evidenceReadModel.mjs +167 -0
  66. package/vendor/src/gfsOverlayProjectPassport.mjs +235 -0
  67. package/vendor/src/globalStepPathToBvcReferences.mjs +196 -0
  68. package/vendor/src/goldenPath.mjs +69 -0
  69. package/vendor/src/graphCanvasLayout.mjs +464 -0
  70. package/vendor/src/graphCanvasLitFlow/client/graphCanvasMinimap.ts +261 -0
  71. package/vendor/src/graphCanvasLitFlow/client/graphCanvasSvgEdges.ts +259 -0
  72. package/vendor/src/graphCanvasLitFlow/client/graphCanvasTheme.css +152 -0
  73. package/vendor/src/graphCanvasLitFlow/client/graphCardNode.ts +328 -0
  74. package/vendor/src/graphCanvasLitFlow/client/mountGraphCanvasLitFlow.ts +322 -0
  75. package/vendor/src/graphCanvasLitFlow/graphCanvasEdgeLabels.mjs +58 -0
  76. package/vendor/src/graphCanvasLitFlow/graphCanvasEdgeRouter.mjs +142 -0
  77. package/vendor/src/graphCanvasLitFlow/graphCanvasLayoutProfile.mjs +32 -0
  78. package/vendor/src/graphCanvasLitFlow/graphCanvasNodeMetrics.mjs +45 -0
  79. package/vendor/src/graphCanvasLitFlow/graphCanvasProjection.mjs +115 -0
  80. package/vendor/src/graphCanvasLitFlow/graphCanvasProjectionToFlow.mjs +133 -0
  81. package/vendor/src/graphCanvasLitFlow/graphCanvasTraversal.mjs +77 -0
  82. package/vendor/src/graphCanvasLitFlow/layoutIntentRoadmapWorkStack.mjs +73 -0
  83. package/vendor/src/graphCanvasLitFlow/resolveGraphCanvasOverlaps.mjs +77 -0
  84. package/vendor/src/graphRagContextSlice.mjs +461 -0
  85. package/vendor/src/gvmVerifyWorkerGate.mjs +95 -0
  86. package/vendor/src/homeSnapshotApi.mjs +131 -0
  87. package/vendor/src/homeSnapshotProjection.mjs +275 -0
  88. package/vendor/src/inboxEventStream.mjs +140 -0
  89. package/vendor/src/intentComposerApi.mjs +245 -0
  90. package/vendor/src/intentGraphGbcSliceBoundary.mjs +258 -0
  91. package/vendor/src/intentGraphProjection.mjs +208 -0
  92. package/vendor/src/intentHierarchy.mjs +241 -0
  93. package/vendor/src/intentNodeLint.mjs +107 -0
  94. package/vendor/src/intentNodeRuntime.mjs +185 -0
  95. package/vendor/src/intentRoadmapCanvas.mjs +393 -0
  96. package/vendor/src/intentRoadmapEpicProjection.mjs +122 -0
  97. package/vendor/src/intentRoadmapMermaid.mjs +165 -0
  98. package/vendor/src/intentRoadmapProjection.mjs +85 -0
  99. package/vendor/src/intentTreeLint.mjs +114 -0
  100. package/vendor/src/intentTreeMigration.mjs +150 -0
  101. package/vendor/src/intentTreeWorkItems.mjs +227 -0
  102. package/vendor/src/kanbanBoardProjection.mjs +58 -0
  103. package/vendor/src/languageAdapterRegistry.mjs +180 -0
  104. package/vendor/src/languageAdapters/goAdapter.mjs +62 -0
  105. package/vendor/src/languageAdapters/jsTsAdapter.mjs +60 -0
  106. package/vendor/src/languageAdapters/jsonYamlAdapter.mjs +103 -0
  107. package/vendor/src/languageAdapters/onebaseOsAdapter.mjs +55 -0
  108. package/vendor/src/languageAdapters/plaintextAdapter.mjs +36 -0
  109. package/vendor/src/languageAdapters/shared.mjs +68 -0
  110. package/vendor/src/languageAdapters/stepAdapter.mjs +81 -0
  111. package/vendor/src/lintPlanWorkAlignment.mjs +136 -0
  112. package/vendor/src/loopHintRepeatToolEval.mjs +153 -0
  113. package/vendor/src/lowcodeScaffoldCli.mjs +386 -0
  114. package/vendor/src/markdownDocumentRender.mjs +208 -0
  115. package/vendor/src/memoryPanelProjection.mjs +116 -0
  116. package/vendor/src/memoryRecordWriter.mjs +243 -0
  117. package/vendor/src/memoryWorkerSlice.mjs +238 -0
  118. package/vendor/src/migrateStepToBvc.mjs +133 -0
  119. package/vendor/src/missionControlServerHandlers.mjs +195 -0
  120. package/vendor/src/missionControlUiClient.mjs +278 -0
  121. package/vendor/src/onebaseCliCapabilityProbe.mjs +107 -0
  122. package/vendor/src/onebaseCliRunner.mjs +145 -0
  123. package/vendor/src/onebaseGrossProfitStaticVerify.mjs +98 -0
  124. package/vendor/src/onebaseParityEvidenceSync.mjs +88 -0
  125. package/vendor/src/onebasePvrgGraphNodes.mjs +257 -0
  126. package/vendor/src/onebaseRestEvidenceAdapter.mjs +216 -0
  127. package/vendor/src/onebaseVectorDslCodegenReadiness.mjs +137 -0
  128. package/vendor/src/onebaseWorkItemTemplate.mjs +154 -0
  129. package/vendor/src/onebaseWorkerTools.mjs +586 -0
  130. package/vendor/src/operatorShellProjection.mjs +102 -0
  131. package/vendor/src/pipelineProseRender.mjs +180 -0
  132. package/vendor/src/pipelineStageLint.mjs +118 -0
  133. package/vendor/src/promptRulesEditorApi.mjs +174 -0
  134. package/vendor/src/promptRulesProjection.mjs +134 -0
  135. package/vendor/src/pvrg/bladeAdapter.mjs +40 -0
  136. package/vendor/src/pvrgTaskScope.mjs +152 -0
  137. package/vendor/src/releaseGateMatrix.mjs +188 -0
  138. package/vendor/src/schematicView.mjs +305 -0
  139. package/vendor/src/seedAnalyticsRecord.mjs +217 -0
  140. package/vendor/src/semanticSearchBm25.mjs +103 -0
  141. package/vendor/src/semanticSearchExcerpts.mjs +68 -0
  142. package/vendor/src/semanticSearchTfidfVector.mjs +86 -0
  143. package/vendor/src/semanticSearchWorkflow.mjs +366 -0
  144. package/vendor/src/stepAtomFormatter.mjs +413 -0
  145. package/vendor/src/stepGraphSlice.mjs +318 -0
  146. package/vendor/src/ui/atoms/badge.mjs +40 -0
  147. package/vendor/src/ui/atoms/badgeClient.mjs +32 -0
  148. package/vendor/src/ui/atoms/button.mjs +114 -0
  149. package/vendor/src/ui/atoms/buttonClient.mjs +49 -0
  150. package/vendor/src/ui/atoms/icon.mjs +23 -0
  151. package/vendor/src/ui/atoms/input.mjs +38 -0
  152. package/vendor/src/ui/atoms/modal.mjs +44 -0
  153. package/vendor/src/ui/atoms/select.mjs +98 -0
  154. package/vendor/src/ui/backlogShellButtons.mjs +238 -0
  155. package/vendor/src/ui/htmlEscape.mjs +11 -0
  156. package/vendor/src/ui/molecules/rating.mjs +48 -0
  157. package/vendor/src/ui/molecules/tabs.mjs +70 -0
  158. package/vendor/src/ui/organisms/modal.mjs +1 -0
  159. package/vendor/src/ui/pages/uiKitPage.mjs +147 -0
  160. package/vendor/src/ui/workItemStatusTone.mjs +36 -0
  161. package/vendor/src/unifiedLinkageProjection.mjs +264 -0
  162. package/vendor/src/verificationLoop.mjs +206 -0
  163. package/vendor/src/workGraphBacklogPersist.mjs +234 -0
  164. package/vendor/src/workGraphBacklogUiServer.mjs +9192 -0
  165. package/vendor/src/workGraphBoundedTargetFileRead.mjs +178 -0
  166. package/vendor/src/workGraphCycleSlice.mjs +184 -0
  167. package/vendor/src/workGraphDaemonTick.mjs +307 -0
  168. package/vendor/src/workGraphDaemonWatch.mjs +157 -0
  169. package/vendor/src/workGraphEngineRoot.mjs +136 -0
  170. package/vendor/src/workGraphInstallLayout.mjs +65 -0
  171. package/vendor/src/workGraphLlmUsefulnessEval.mjs +611 -0
  172. package/vendor/src/workGraphPhasePromoteReadyQueue.mjs +159 -0
  173. package/vendor/src/workGraphProjectHost.mjs +149 -0
  174. package/vendor/src/workGraphProjectInit.mjs +392 -0
  175. package/vendor/src/workGraphPromoteReadyApi.mjs +115 -0
  176. package/vendor/src/workGraphRecoveryPolicy.mjs +124 -0
  177. package/vendor/src/workGraphRunnerQueueProjection.mjs +187 -0
  178. package/vendor/src/workGraphRuntime.mjs +1008 -0
  179. package/vendor/src/workGraphToolSurfaceAudit.mjs +372 -0
  180. package/vendor/src/workGraphToolTransportRuntime.mjs +195 -0
  181. package/vendor/src/workGraphWorkerProvider.mjs +600 -0
  182. package/vendor/src/workItemBvcQuality.mjs +262 -0
  183. package/vendor/src/workItemCreateAnalysis.mjs +157 -0
  184. package/vendor/src/workItemDecisionPipeline.mjs +278 -0
  185. package/vendor/src/workItemEpicCascade.mjs +176 -0
  186. package/vendor/src/workItemExecutionGate.mjs +78 -0
  187. package/vendor/src/workItemHierarchy.mjs +226 -0
  188. package/vendor/src/workItemProseLint.mjs +133 -0
  189. package/vendor/src/workItemTextRusify.mjs +794 -0
  190. package/vendor/src/workItemTraceEnvelope.mjs +158 -0
  191. package/vendor/src/workItemUiReferences.mjs +272 -0
  192. package/vendor/src/workflowEpicGrouping.mjs +67 -0
  193. package/vendor/src/workflowTreeProjection.mjs +53 -0
  194. package/vendor/src/workspaceRegistry.mjs +150 -0
@@ -0,0 +1,638 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
4
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
+ import { z } from 'zod';
6
+
7
+ import {
8
+ addWorkItemEvidence,
9
+ attachWorkItemUiReference,
10
+ claimWorkItem,
11
+ completeWorkItem,
12
+ createWorkItem,
13
+ getBacklogSnapshot,
14
+ getCurrentCycle,
15
+ getEpicWorkScope,
16
+ getArchitectureSnapshot,
17
+ getEvidenceRecord,
18
+ getGraphRagContext,
19
+ getIntentHierarchy,
20
+ getMemoryRecord,
21
+ getOperatorShellSnapshot,
22
+ getPromoteReadyQueue,
23
+ getPvrgTaskScope,
24
+ getStepGraphProjection,
25
+ getStepGraphSlice,
26
+ getUnifiedLinkage,
27
+ getWorkItem,
28
+ getWorkItemPipeline,
29
+ listEvidenceRecords,
30
+ listMemoryRecords,
31
+ listWorkItems,
32
+ listWorkItemUiReferences,
33
+ readWorkGraphResource,
34
+ readWorkItemAtomResource,
35
+ recordWorkItemAnalysisFromMcp,
36
+ recordWorkItemDecisionFromMcp,
37
+ resolveWorkGraphRoot,
38
+ semanticSearch,
39
+ updateWorkItemStatus,
40
+ } from './handlers.mjs';
41
+ import { toMcpPromptResult, workgraphPrompts } from './prompts.mjs';
42
+
43
+ const server = new McpServer({ name: 'workgraph-mcp', version: '0.1.0' });
44
+
45
+ const jsonText = (value) => ({
46
+ content: [{ type: 'text', text: JSON.stringify(value, null, 2) }],
47
+ });
48
+
49
+ const rootOptions = () => ({ root: resolveWorkGraphRoot() });
50
+
51
+ server.tool(
52
+ 'list_work_items',
53
+ 'List WorkGraph WorkItems from the intent tree',
54
+ {
55
+ status: z.string().optional().describe('Optional exact work.status filter'),
56
+ query: z.string().optional().describe('Optional text query over id/title/role/files'),
57
+ limit: z.number().optional().describe('Maximum rows, 1..200'),
58
+ },
59
+ async (args) => jsonText(await listWorkItems(args, rootOptions())),
60
+ );
61
+
62
+ server.tool(
63
+ 'get_work_item',
64
+ 'Read one WorkGraph WorkItem by id',
65
+ { workId: z.string().describe('WorkItem id') },
66
+ async (args) => jsonText(await getWorkItem(args, rootOptions())),
67
+ );
68
+
69
+ server.tool(
70
+ 'get_backlog_snapshot',
71
+ 'Read the full WorkGraph snapshot derived from intent tree files',
72
+ {},
73
+ async () => jsonText(await getBacklogSnapshot({}, rootOptions())),
74
+ );
75
+
76
+ server.tool(
77
+ 'get_current_cycle',
78
+ 'Read current WorkGraph cycle/queue summary',
79
+ {},
80
+ async () => jsonText(await getCurrentCycle({}, rootOptions())),
81
+ );
82
+
83
+ server.tool(
84
+ 'get_promote_ready_queue',
85
+ 'List backlog WorkItems eligible for promote-ready (minPhase defaults to 8; use 0 for all phases)',
86
+ {
87
+ minPhase: z.number().optional().describe('Minimum phase number (default 8; 0 includes phases 0–7)'),
88
+ limit: z.number().optional().describe('Maximum queue rows, 1..200'),
89
+ },
90
+ async (args) => jsonText(await getPromoteReadyQueue(args, rootOptions())),
91
+ );
92
+
93
+ server.tool(
94
+ 'get_intent_hierarchy',
95
+ 'Read intent.hierarchy.snapshot.v1 derived from WorkItems (domain/feature taxonomy)',
96
+ {},
97
+ async () => jsonText(await getIntentHierarchy({}, rootOptions())),
98
+ );
99
+
100
+ server.tool(
101
+ 'get_architecture_snapshot',
102
+ 'Read architecture.snapshot.v1 L1 blocks and edges for Work Graph rebuild',
103
+ {
104
+ focusBlockId: z.string().optional().describe('Optional architecture block id to focus'),
105
+ },
106
+ async (args) => jsonText(await getArchitectureSnapshot(args, rootOptions())),
107
+ );
108
+
109
+ server.tool(
110
+ 'get_unified_linkage',
111
+ 'Read unified-linkage.projection.v1 (trace links, planning edges, reverse markers)',
112
+ {},
113
+ async () => jsonText(await getUnifiedLinkage({}, rootOptions())),
114
+ );
115
+
116
+ server.tool(
117
+ 'get_epic_work_scope',
118
+ 'Read compact read-only epic scope rollup (direct children with work.status) for chat/UI',
119
+ {
120
+ epicId: z.string().describe('Epic WorkItem id'),
121
+ },
122
+ async (args) => jsonText(await getEpicWorkScope(args, rootOptions())),
123
+ );
124
+
125
+ server.tool(
126
+ 'get_pvrg_task_scope',
127
+ 'Read bounded pvrg.task-scope.slice.v1 subgraph for one WorkItem',
128
+ {
129
+ workId: z.string().describe('Seed WorkItem id'),
130
+ maxNodes: z.number().optional().describe('Maximum nodes in subgraph (default 24)'),
131
+ maxDepth: z.number().optional().describe('Maximum depends_on expansion depth (default 2)'),
132
+ },
133
+ async (args) => jsonText(await getPvrgTaskScope(args, rootOptions())),
134
+ );
135
+
136
+ server.tool(
137
+ 'get_graph_rag_context',
138
+ 'Read pvrg.graph_rag.context.v1 for one WorkItem (WorkItems, files, evidence, memory — same bundle as WG worker prompt)',
139
+ {
140
+ workId: z.string().describe('Seed WorkItem id'),
141
+ maxNodes: z.number().optional().describe('Maximum nodes in graph RAG slice (default 32)'),
142
+ maxDepth: z.number().optional().describe('Maximum depends_on expansion depth (default 2)'),
143
+ },
144
+ async (args) => jsonText(await getGraphRagContext(args, rootOptions())),
145
+ );
146
+
147
+ server.tool(
148
+ 'list_memory_records',
149
+ 'List memory-record.v1 entries (derived from done WorkItems + journal)',
150
+ {
151
+ workId: z.string().optional().describe('Filter by sourceWorkItem or relatedTasks'),
152
+ type: z.string().optional().describe('Filter by memory type (decision, invariant, ...)'),
153
+ status: z.string().optional().describe('Filter by status (active, draft, needs-review)'),
154
+ query: z.string().optional().describe('Optional text query over id/summary/files'),
155
+ limit: z.number().optional().describe('Maximum rows, 1..200'),
156
+ },
157
+ async (args) => jsonText(await listMemoryRecords(args, rootOptions())),
158
+ );
159
+
160
+ server.tool(
161
+ 'get_memory_record',
162
+ 'Read one memory-record.v1 by id',
163
+ { recordId: z.string().describe('MemoryRecord id') },
164
+ async (args) => jsonText(await getMemoryRecord(args, rootOptions())),
165
+ );
166
+
167
+ server.tool(
168
+ 'list_evidence_records',
169
+ 'List evidence-record.v1 entries (from WorkItem evidence strings)',
170
+ {
171
+ workId: z.string().optional().describe('Filter by taskId'),
172
+ type: z.string().optional().describe('Filter by evidence type'),
173
+ status: z.string().optional().describe('Filter by status (succeeded, failed)'),
174
+ query: z.string().optional().describe('Optional text query'),
175
+ limit: z.number().optional().describe('Maximum rows, 1..200'),
176
+ },
177
+ async (args) => jsonText(await listEvidenceRecords(args, rootOptions())),
178
+ );
179
+
180
+ server.tool(
181
+ 'get_evidence_record',
182
+ 'Read one evidence-record.v1 by id',
183
+ { recordId: z.string().describe('EvidenceRecord id') },
184
+ async (args) => jsonText(await getEvidenceRecord(args, rootOptions())),
185
+ );
186
+
187
+ server.tool(
188
+ 'get_operator_shell_snapshot',
189
+ 'Read operator-shell.snapshot.v2 (intent sidebar, cross-highlight, cycle slice)',
190
+ {},
191
+ async () => jsonText(await getOperatorShellSnapshot({}, rootOptions())),
192
+ );
193
+
194
+ server.tool(
195
+ 'get_step_graph_projection',
196
+ 'Read step-graph.projection.v1 from repo .bvc/.bvc files (refs between blocks, no UI)',
197
+ {
198
+ maxNodes: z.number().optional().describe('Optional cap on returned nodes'),
199
+ roots: z.string().optional().describe('Comma-separated scan roots (default charter,protocols,plans,intent,...)'),
200
+ },
201
+ async (args) => jsonText(await getStepGraphProjection(args, rootOptions())),
202
+ );
203
+
204
+ server.tool(
205
+ 'get_step_graph_slice',
206
+ 'Read bounded step-graph.slice.v1 around one step block (semantic map headless)',
207
+ {
208
+ seedStepName: z.string().optional().describe('Step block name (#Name)'),
209
+ seedPath: z.string().optional().describe('Logical .bvc or legacy .bvc path containing the block'),
210
+ seedNodeId: z.string().optional().describe('Full node id path\\u001fStepName'),
211
+ maxNodes: z.number().optional().describe('Maximum nodes (default 32)'),
212
+ maxDepth: z.number().optional().describe('Expansion depth (default 2)'),
213
+ },
214
+ async (args) => jsonText(await getStepGraphSlice(args, rootOptions())),
215
+ );
216
+
217
+ server.tool(
218
+ 'update_work_item_status',
219
+ 'Update WorkItem status through WorkGraph policy gates',
220
+ {
221
+ workId: z.string().describe('WorkItem id'),
222
+ status: z.string().describe('Target status: backlog, ready, claimed, doing, verify, done, blocked'),
223
+ reason: z.string().optional().describe('Required for blocked; useful audit reason otherwise'),
224
+ evidence: z.string().optional().describe('Evidence line, required by policy for done'),
225
+ },
226
+ async (args) => jsonText(await updateWorkItemStatus(args, rootOptions())),
227
+ );
228
+
229
+ server.tool(
230
+ 'add_work_item_evidence',
231
+ 'Append one evidence line to a WorkItem',
232
+ {
233
+ workId: z.string().describe('WorkItem id'),
234
+ evidence: z.string().describe('Evidence line to append'),
235
+ },
236
+ async (args) => jsonText(await addWorkItemEvidence(args, rootOptions())),
237
+ );
238
+
239
+ server.tool(
240
+ 'claim_work_item',
241
+ 'Claim the next ready WorkItem or a specific ready WorkItem',
242
+ {
243
+ workId: z.string().optional().describe('Optional ready WorkItem id; omitted means claimNext'),
244
+ evidence: z.string().optional().describe('Optional evidence line for the claim'),
245
+ },
246
+ async (args) => jsonText(await claimWorkItem(args, rootOptions())),
247
+ );
248
+
249
+ server.tool(
250
+ 'complete_work_item',
251
+ 'Mark a WorkItem done with required evidence',
252
+ {
253
+ workId: z.string().describe('WorkItem id'),
254
+ evidence: z.string().describe('Required evidence line'),
255
+ },
256
+ async (args) => jsonText(await completeWorkItem(args, rootOptions())),
257
+ );
258
+
259
+ server.tool(
260
+ 'create_work_item',
261
+ 'Create a new WorkItem atom in intent tree as *.work.bvc (legacy *.work.bvc read-only)',
262
+ {
263
+ workId: z.string().describe('Unique work.id slug'),
264
+ title: z.string().describe('Human title'),
265
+ basis: z.string().optional().describe('Basis text or newline-separated bullets'),
266
+ vector: z.string().optional().describe('Vector text or newline-separated bullets'),
267
+ goal: z.string().optional().describe('Goal text or newline-separated bullets'),
268
+ department: z.string().optional().describe('e.g. domain-onebase, agent-platform'),
269
+ ownerRole: z.string().optional().describe('work.owner_role'),
270
+ priority: z.string().optional().describe('low | medium | high | critical'),
271
+ risk: z.string().optional().describe('low | medium | high'),
272
+ status: z.string().optional().describe('Default backlog'),
273
+ nextAction: z.string().optional().describe('work.next_action hint'),
274
+ dependsOn: z.string().optional().describe('Comma-separated work ids'),
275
+ targetFiles: z.string().optional().describe('Comma-separated relative file paths'),
276
+ checks: z.string().optional().describe('Newline-separated readiness checks'),
277
+ analysis: z.string().optional().describe('Newline-separated «Анализ» lines; auto-generated if omitted'),
278
+ decision: z.string().optional().describe('Newline-separated «Решение» lines; auto-generated if omitted'),
279
+ decisionVerdict: z.enum(['useful', 'harmful', 'defer']).optional().describe('Default useful'),
280
+ intakeSourceKind: z.string().optional().describe('e.g. analytics-record'),
281
+ intakeSourceRef: z.string().optional().describe('e.g. analytics:graph-canvas-layout-mess'),
282
+ analyticsKey: z.string().optional().describe('e.g. AN-1'),
283
+ },
284
+ async (args) => {
285
+ const parsed = {
286
+ ...args,
287
+ dependsOn: args.dependsOn?.split(',').map((entry) => entry.trim()).filter(Boolean),
288
+ targetFiles: args.targetFiles?.split(',').map((entry) => entry.trim()).filter(Boolean),
289
+ };
290
+ return jsonText(await createWorkItem(parsed, rootOptions()));
291
+ },
292
+ );
293
+
294
+ server.tool(
295
+ 'get_work_item_pipeline',
296
+ 'Read analyze/decide pipeline state for one WorkItem (analysis and decision live on the atom)',
297
+ { workId: z.string().describe('WorkItem id') },
298
+ async (args) => jsonText(await getWorkItemPipeline(args, rootOptions())),
299
+ );
300
+
301
+ server.tool(
302
+ 'record_work_item_analysis',
303
+ 'Write pre-execution feasibility analysis into WorkItem «Анализ» (стоит ли делать; not post-factum review). Text must come from Cursor LLM — server does not call models.',
304
+ {
305
+ workId: z.string().describe('WorkItem id'),
306
+ analysis: z.string().describe('Full analysis text produced in Cursor'),
307
+ },
308
+ async (args) => jsonText(await recordWorkItemAnalysisFromMcp(args, rootOptions())),
309
+ );
310
+
311
+ server.tool(
312
+ 'record_work_item_decision',
313
+ 'Record operator verdict useful|harmful|defer into «Решение» after analysis',
314
+ {
315
+ workId: z.string().describe('WorkItem id'),
316
+ verdict: z.enum(['useful', 'harmful', 'defer']).describe('Pipeline decision'),
317
+ notes: z.string().describe('Decision rationale (required)'),
318
+ },
319
+ async (args) => jsonText(await recordWorkItemDecisionFromMcp(args, rootOptions())),
320
+ );
321
+
322
+ server.tool(
323
+ 'list_work_item_ui_references',
324
+ 'List UI reference screenshots attached to a WorkItem (ui-facing tasks)',
325
+ { workId: z.string().describe('WorkItem id') },
326
+ async (args) => jsonText(await listWorkItemUiReferences(args, rootOptions())),
327
+ );
328
+
329
+ server.tool(
330
+ 'attach_work_item_ui_reference',
331
+ 'Attach a UI reference screenshot (base64) to a WorkItem; updates atom labels and Референсы_UI section',
332
+ {
333
+ workId: z.string().describe('WorkItem id'),
334
+ filename: z.string().describe('Original filename with extension (.png, .jpg, .webp, .gif)'),
335
+ contentBase64: z.string().describe('Base64-encoded image bytes'),
336
+ caption: z.string().optional().describe('Optional caption shown in task card'),
337
+ force: z.boolean().optional().describe('Allow attach on non-UI tasks when true'),
338
+ },
339
+ async (args) => jsonText(await attachWorkItemUiReference(args, rootOptions())),
340
+ );
341
+
342
+ server.resource(
343
+ 'workgraph-backlog',
344
+ 'workgraph://backlog',
345
+ { description: 'Full WorkGraph snapshot', mimeType: 'application/json' },
346
+ async (uri) => ({
347
+ contents: [{
348
+ uri: uri.href,
349
+ mimeType: 'application/json',
350
+ text: JSON.stringify(await readWorkGraphResource(uri.href, rootOptions()), null, 2),
351
+ }],
352
+ }),
353
+ );
354
+
355
+ server.resource(
356
+ 'workgraph-current-cycle',
357
+ 'workgraph://cycle/current',
358
+ { description: 'Current WorkGraph cycle summary', mimeType: 'application/json' },
359
+ async (uri) => ({
360
+ contents: [{
361
+ uri: uri.href,
362
+ mimeType: 'application/json',
363
+ text: JSON.stringify(await readWorkGraphResource(uri.href, rootOptions()), null, 2),
364
+ }],
365
+ }),
366
+ );
367
+
368
+ server.resource(
369
+ 'workgraph-intent-hierarchy',
370
+ 'workgraph://intent/hierarchy',
371
+ { description: 'Intent hierarchy snapshot (domains and classified nodes)', mimeType: 'application/json' },
372
+ async (uri) => ({
373
+ contents: [{
374
+ uri: uri.href,
375
+ mimeType: 'application/json',
376
+ text: JSON.stringify(await readWorkGraphResource(uri.href, rootOptions()), null, 2),
377
+ }],
378
+ }),
379
+ );
380
+
381
+ server.resource(
382
+ 'workgraph-architecture-snapshot',
383
+ 'workgraph://architecture/snapshot',
384
+ { description: 'Architecture L1 snapshot with blocks and edges', mimeType: 'application/json' },
385
+ async (uri) => ({
386
+ contents: [{
387
+ uri: uri.href,
388
+ mimeType: 'application/json',
389
+ text: JSON.stringify(await readWorkGraphResource(uri.href, rootOptions()), null, 2),
390
+ }],
391
+ }),
392
+ );
393
+
394
+ server.resource(
395
+ 'workgraph-linkage-projection',
396
+ 'workgraph://linkage/projection',
397
+ { description: 'Unified linkage projection (step/code/task edges)', mimeType: 'application/json' },
398
+ async (uri) => ({
399
+ contents: [{
400
+ uri: uri.href,
401
+ mimeType: 'application/json',
402
+ text: JSON.stringify(await readWorkGraphResource(uri.href, rootOptions()), null, 2),
403
+ }],
404
+ }),
405
+ );
406
+
407
+ server.resource(
408
+ 'workgraph-step-graph-projection',
409
+ 'workgraph://step-graph/projection',
410
+ { description: 'Step graph projection from .bvc block refs', mimeType: 'application/json' },
411
+ async (uri) => ({
412
+ contents: [{
413
+ uri: uri.href,
414
+ mimeType: 'application/json',
415
+ text: JSON.stringify(await readWorkGraphResource(uri.href, rootOptions()), null, 2),
416
+ }],
417
+ }),
418
+ );
419
+
420
+ server.resource(
421
+ 'workgraph-memory-records',
422
+ 'workgraph://memory/records',
423
+ { description: 'Project memory records (memory-record-list.v1)', mimeType: 'application/json' },
424
+ async (uri) => ({
425
+ contents: [{
426
+ uri: uri.href,
427
+ mimeType: 'application/json',
428
+ text: JSON.stringify(await readWorkGraphResource(uri.href, rootOptions()), null, 2),
429
+ }],
430
+ }),
431
+ );
432
+
433
+ server.resource(
434
+ 'workgraph-evidence-records',
435
+ 'workgraph://evidence/records',
436
+ { description: 'Evidence records (evidence-record-list.v1)', mimeType: 'application/json' },
437
+ async (uri) => ({
438
+ contents: [{
439
+ uri: uri.href,
440
+ mimeType: 'application/json',
441
+ text: JSON.stringify(await readWorkGraphResource(uri.href, rootOptions()), null, 2),
442
+ }],
443
+ }),
444
+ );
445
+
446
+ server.resource(
447
+ 'workgraph-graph-rag-context',
448
+ new ResourceTemplate('workgraph://pvrg/graph-rag/{workId}', {
449
+ list: async () => {
450
+ const items = await listWorkItems({ limit: 200 }, rootOptions());
451
+ return {
452
+ resources: items.map((item) => ({
453
+ name: item.id,
454
+ uri: `workgraph://pvrg/graph-rag/${encodeURIComponent(item.id)}`,
455
+ description: `Graph RAG context: ${item.title}`,
456
+ mimeType: 'application/json',
457
+ })),
458
+ };
459
+ },
460
+ complete: {
461
+ workId: async (value) => {
462
+ const query = String(value ?? '').toLowerCase();
463
+ const items = await listWorkItems({ limit: 200 }, rootOptions());
464
+ return items
465
+ .map((item) => item.id)
466
+ .filter((id) => id.toLowerCase().includes(query))
467
+ .slice(0, 50);
468
+ },
469
+ },
470
+ }),
471
+ { description: 'Graph RAG context for one WorkItem', mimeType: 'application/json' },
472
+ async (uri, variables) => ({
473
+ contents: [{
474
+ uri: uri.href,
475
+ mimeType: 'application/json',
476
+ text: JSON.stringify(await getGraphRagContext({ workId: variables.workId }, rootOptions()), null, 2),
477
+ }],
478
+ }),
479
+ );
480
+
481
+ server.resource(
482
+ 'workgraph-memory-record',
483
+ new ResourceTemplate('workgraph://memory/record/{recordId}', {
484
+ complete: {
485
+ recordId: async (value) => {
486
+ const query = String(value ?? '').toLowerCase();
487
+ const list = await listMemoryRecords({ limit: 200 }, rootOptions());
488
+ return list.records
489
+ .map((record) => record.id)
490
+ .filter((id) => id.toLowerCase().includes(query))
491
+ .slice(0, 50);
492
+ },
493
+ },
494
+ }),
495
+ { description: 'Single memory-record.v1 by id', mimeType: 'application/json' },
496
+ async (uri, variables) => ({
497
+ contents: [{
498
+ uri: uri.href,
499
+ mimeType: 'application/json',
500
+ text: JSON.stringify(await getMemoryRecord({ recordId: variables.recordId }, rootOptions()), null, 2),
501
+ }],
502
+ }),
503
+ );
504
+
505
+ server.resource(
506
+ 'workgraph-evidence-record',
507
+ new ResourceTemplate('workgraph://evidence/record/{recordId}', {
508
+ complete: {
509
+ recordId: async (value) => {
510
+ const query = String(value ?? '').toLowerCase();
511
+ const list = await listEvidenceRecords({ limit: 200 }, rootOptions());
512
+ return list.records
513
+ .map((record) => record.id)
514
+ .filter((id) => id.toLowerCase().includes(query))
515
+ .slice(0, 50);
516
+ },
517
+ },
518
+ }),
519
+ { description: 'Single evidence-record.v1 by id', mimeType: 'application/json' },
520
+ async (uri, variables) => ({
521
+ contents: [{
522
+ uri: uri.href,
523
+ mimeType: 'application/json',
524
+ text: JSON.stringify(await getEvidenceRecord({ recordId: variables.recordId }, rootOptions()), null, 2),
525
+ }],
526
+ }),
527
+ );
528
+
529
+ server.resource(
530
+ 'workgraph-item',
531
+ new ResourceTemplate('workgraph://item/{workId}', {
532
+ list: async () => {
533
+ const items = await listWorkItems({ limit: 200 }, rootOptions());
534
+ return {
535
+ resources: items.map((item) => ({
536
+ name: item.id,
537
+ uri: `workgraph://item/${encodeURIComponent(item.id)}`,
538
+ description: item.title,
539
+ mimeType: 'application/json',
540
+ })),
541
+ };
542
+ },
543
+ complete: {
544
+ workId: async (value) => {
545
+ const query = String(value ?? '').toLowerCase();
546
+ const items = await listWorkItems({ limit: 200 }, rootOptions());
547
+ return items
548
+ .map((item) => item.id)
549
+ .filter((id) => id.toLowerCase().includes(query))
550
+ .slice(0, 50);
551
+ },
552
+ },
553
+ }),
554
+ { description: 'Parsed WorkItem by id', mimeType: 'application/json' },
555
+ async (uri, variables) => ({
556
+ contents: [{
557
+ uri: uri.href,
558
+ mimeType: 'application/json',
559
+ text: JSON.stringify(await getWorkItem({ workId: variables.workId }, rootOptions()), null, 2),
560
+ }],
561
+ }),
562
+ );
563
+
564
+ server.resource(
565
+ 'workgraph-epic-scope',
566
+ new ResourceTemplate('workgraph://epic/{epicId}/scope', {
567
+ list: async () => {
568
+ const items = await listWorkItems({ limit: 200 }, rootOptions());
569
+ return {
570
+ resources: items
571
+ .filter((item) => String(item.id).startsWith('epic-'))
572
+ .map((item) => ({
573
+ name: item.id,
574
+ uri: `workgraph://epic/${encodeURIComponent(item.id)}/scope`,
575
+ description: `Epic scope: ${item.title}`,
576
+ mimeType: 'application/json',
577
+ })),
578
+ };
579
+ },
580
+ complete: {
581
+ epicId: async (value) => {
582
+ const query = String(value ?? '').toLowerCase();
583
+ const items = await listWorkItems({ limit: 200 }, rootOptions());
584
+ return items
585
+ .map((item) => item.id)
586
+ .filter((id) => id.toLowerCase().includes(query))
587
+ .slice(0, 50);
588
+ },
589
+ },
590
+ }),
591
+ { description: 'Read-only epic child scope rollup', mimeType: 'application/json' },
592
+ async (uri, variables) => ({
593
+ contents: [{
594
+ uri: uri.href,
595
+ mimeType: 'application/json',
596
+ text: JSON.stringify(await getEpicWorkScope({ epicId: variables.epicId }, rootOptions()), null, 2),
597
+ }],
598
+ }),
599
+ );
600
+
601
+ server.tool(
602
+ 'read_work_item_atom',
603
+ 'Read raw .work.bvc atom text for a WorkItem',
604
+ { workId: z.string().describe('WorkItem id') },
605
+ async ({ workId }) => ({
606
+ content: [{ type: 'text', text: await readWorkItemAtomResource(workId, rootOptions()) }],
607
+ }),
608
+ );
609
+
610
+ server.tool(
611
+ 'semantic_search',
612
+ 'Lexical or hybrid semantic search over WorkItems and linked target files',
613
+ {
614
+ query: z.string().describe('Search query (min 2-char tokens)'),
615
+ limit: z.number().optional().describe('Maximum hits, 1..200 (default 12)'),
616
+ mode: z.string().optional().describe('lexical-v1 | hybrid-lexical-bm25-v1 | hybrid-lexical-bm25-tfidf-v1'),
617
+ },
618
+ async (args) => jsonText(await semanticSearch(args, rootOptions())),
619
+ );
620
+
621
+ for (const [name, prompt] of Object.entries(workgraphPrompts)) {
622
+ const argsSchema = Object.fromEntries(
623
+ Object.entries(prompt.argsSchema).map(([key, description]) => [
624
+ key,
625
+ z.string().optional().describe(description),
626
+ ]),
627
+ );
628
+ server.prompt(name, prompt.description, argsSchema, (args) => toMcpPromptResult(name, args));
629
+ }
630
+
631
+ async function main() {
632
+ await server.connect(new StdioServerTransport());
633
+ }
634
+
635
+ main().catch((error) => {
636
+ console.error(error);
637
+ process.exit(1);
638
+ });