@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,794 @@
1
+ /**
2
+ * Нормализация текстов WorkItem на читаемый русский.
3
+ * Технические идентификаторы (пути, npm, MCP, API) сохраняются.
4
+ */
5
+
6
+ const PHRASE_REPLACEMENTS = [
7
+ ['review and promote to ready', 'просмотреть и перевести в ready'],
8
+ ['WorkItem atom проходит StepAtomDraft validation', 'Atom WorkItem проходит StepAtomDraft validation'],
9
+ ['intent/index.bvc обновлён', 'intent/index.bvc актуален'],
10
+ ['evidence записан перед done', 'Свидетельства записаны перед переводом в done'],
11
+ ['Cross-highlight', 'перекрёстная подсветка'],
12
+ ['cross-highlight', 'перекрёстная подсветка'],
13
+ ['end-to-end', 'сквозной'],
14
+ ['design task', 'задача проектирования'],
15
+ ['operator shell', 'оболочка оператора'],
16
+ ['operator run', 'запуск оператора'],
17
+ ['operator workflow', 'workflow оператора'],
18
+ ['operator dashboard', 'dashboard оператора'],
19
+ ['task cards', 'карточки задач'],
20
+ ['graph nodes', 'узлы графа'],
21
+ ['semantic nodes', 'семантические узлы'],
22
+ ['semantic map', 'semantic map'],
23
+ ['hover/focus', 'наведении и фокусе'],
24
+ ['tests pass', 'тесты проходят'],
25
+ ['manual smoke', 'ручной smoke-тест'],
26
+ ['backlog feeder', 'источник пополнения бэклога'],
27
+ ['source of truth', 'источник истины'],
28
+ ['controlled intake', 'контролируемый приём'],
29
+ ['produce suggestions', 'формировать предложения'],
30
+ ['promotion flow', 'поток продвижения'],
31
+ ['review gates', 'шлюзы проверки'],
32
+ ['port reference', 'ссылка на port'],
33
+ ['read-only MVP tools', 'read-only MVP-инструменты'],
34
+ ['guarded write tools', 'инструменты записи с guard'],
35
+ ['write tools', 'инструменты записи'],
36
+ ['Optional live LLM eval', 'Опциональная live LLM eval'],
37
+ ['Optional live worker path', 'Опциональный live worker path'],
38
+ ['Optional eval', 'Опциональная eval'],
39
+ ['Optional read path', 'Опциональный read path'],
40
+ ['Optional LLM', 'Опциональная LLM'],
41
+ ['Tier B fixture', 'Фикстура Tier B'],
42
+ ['Tier B catalog', 'Каталог Tier B'],
43
+ ['Tier B', 'Tier B'],
44
+ ['fixture script или eval doc', 'скрипт фикстуры или eval-док'],
45
+ ['Deterministic gates', 'Детерминированные gates'],
46
+ ['Deterministic rubric documented', 'Детерминированная rubric задокументирована'],
47
+ ['Deterministic rules', 'Детерминированные правила'],
48
+ ['Deterministic/local mode', 'Детерминированный/local mode'],
49
+ ['Controlled intake', 'Контролируемый приём'],
50
+ ['Draft store', 'Хранилище черновиков'],
51
+ ['draft store', 'хранилище черновиков'],
52
+ ['Draft intake', 'Приём черновиков'],
53
+ ['draft intake', 'приём черновиков'],
54
+ ['backlog intake', 'приём в бэклог'],
55
+ ['backlog candidate', 'кандидат бэклога'],
56
+ ['backlog pollution', 'засорение бэклога'],
57
+ ['silent backlog', '«тихий» бэклог'],
58
+ ['without silent', 'без «тихого»'],
59
+ ['contract-only', 'только контракт'],
60
+ ['failure/blocker path', 'сценарий failure/blocker'],
61
+ ['failure path', 'сценарий ошибки'],
62
+ ['success path', 'успешный сценарий'],
63
+ ['dry-run path', 'dry-run path'],
64
+ ['transition request', 'запрос transition'],
65
+ ['transition proposal', 'предложение transition'],
66
+ ['transition/evidence', 'transition/evidence'],
67
+ ['Worker Output', 'Worker Output'],
68
+ ['Worker Input', 'Worker Input'],
69
+ ['live loop', 'live-loop'],
70
+ ['live-loop', 'live-loop'],
71
+ ['live LLM', 'live LLM'],
72
+ ['golden path', 'golden path'],
73
+ ['golden-path', 'golden-path'],
74
+ ['promote-ready', 'promote-ready'],
75
+ ['promote ready', 'promote-ready'],
76
+ ['ready queue', 'очередь ready'],
77
+ ['ready-задачу', 'ready-задачу'],
78
+ ['ready-задача', 'ready-задача'],
79
+ ['in_progress', 'in_progress'],
80
+ ['Bounded target', 'Ограниченный target'],
81
+ ['bounded subgraph', 'ограниченный subgraph'],
82
+ ['bounded block', 'ограниченный block'],
83
+ ['bounded size', 'ограничение размера'],
84
+ ['unbounded dump', 'без ограничения размера'],
85
+ ['detail drawer', 'detail drawer'],
86
+ ['verification panel', 'панель verification'],
87
+ ['verification UI', 'UI verification'],
88
+ ['verification loop', 'verification loop'],
89
+ ['audit trail', 'audit trail'],
90
+ ['audit journal', 'audit journal'],
91
+ ['audit-gap', 'audit-gap'],
92
+ ['release gate', 'release gate'],
93
+ ['release matrix', 'release matrix'],
94
+ ['regression gate', 'regression gate'],
95
+ ['Browser regression', 'Browser regression'],
96
+ ['smoke-тест', 'smoke-тест'],
97
+ ['smoke test', 'smoke-тест'],
98
+ ['smoke с', 'smoke с'],
99
+ ['Port minimal subset', 'Port minimal subset'],
100
+ ['Port structural diff', 'Port structural diff'],
101
+ ['Port полного', 'Port полного'],
102
+ ['Port compiler', 'Port compiler'],
103
+ ['Port subset', 'Port subset'],
104
+ ['Port reference', 'Port reference'],
105
+ ['Port ', 'Перенести '],
106
+ ['Wire в', 'Подключить в'],
107
+ ['Wire ', 'Подключить '],
108
+ ['Merge релевантных', 'Включить релевантные'],
109
+ ['Merge ', 'Объединить '],
110
+ ['Design optional', 'Design optional'],
111
+ ['Design doc', 'Design doc'],
112
+ ['Design +', 'Design +'],
113
+ ['Implement ', 'Реализовать '],
114
+ ['Validate ', 'Проверить '],
115
+ ['Checklist doc', 'Checklist doc'],
116
+ ['Checklist:', 'Checklist:'],
117
+ ['Harness:', 'Harness:'],
118
+ ['Parity с', 'Parity с'],
119
+ ['Parity ', 'Parity '],
120
+ ['MVP tools', 'MVP-инструменты'],
121
+ ['MVP server', 'MVP server'],
122
+ ['MVP path', 'MVP path'],
123
+ ['MVP panel', 'MVP panel'],
124
+ ['MVP UI', 'MVP UI'],
125
+ ['MVP ', 'MVP '],
126
+ ['UI MVP', 'UI MVP'],
127
+ ['UI server', 'UI server'],
128
+ ['UI toggle', 'переключатель UI'],
129
+ ['UI фильтрует', 'UI фильтрует'],
130
+ ['UI показывает', 'UI показывает'],
131
+ ['UI test', 'UI-тест'],
132
+ ['UI cross-highlight', 'UI перекрёстная подсветка'],
133
+ ['UI operator', 'UI оператора'],
134
+ ['UI verification', 'UI verification'],
135
+ ['Graph RAG', 'Graph RAG'],
136
+ ['MemoryRecord', 'MemoryRecord'],
137
+ ['MemoryRecords', 'MemoryRecords'],
138
+ ['WorkItems', 'WorkItems'],
139
+ ['WorkItem', 'WorkItem'],
140
+ ['Work Graph', 'Work Graph'],
141
+ ['WorkGraph', 'WorkGraph'],
142
+ ['intent tree', 'intent tree'],
143
+ ['intent/index.bvc', 'intent/index.bvc'],
144
+ ['provenance', 'provenance'],
145
+ ['provenance labels', 'метки provenance'],
146
+ ['review status', 'статус review'],
147
+ ['review/evidence', 'review/evidence'],
148
+ ['suggestions/drafts', 'suggestions/черновики'],
149
+ ['without изменения', 'без изменения'],
150
+ ['without доступа', 'без доступа'],
151
+ ['without live LLM', 'без live LLM'],
152
+ ['without parsing', 'без парсинга'],
153
+ ['without mandatory', 'без mandatory'],
154
+ ['without UI', 'без UI'],
155
+ ['without реального', 'без реального'],
156
+ ['without second', 'без второго'],
157
+ ['without silent', 'без «тихого»'],
158
+ ['without inventing', 'без выдумывания'],
159
+ ['stop-without-invented-workId', 'stop без выдуманного workId'],
160
+ ['invented work', 'выдуманную задачу'],
161
+ ['invented-workId', 'выдуманный workId'],
162
+ ['invented task', 'выдуманную задачу'],
163
+ ['invisible в', 'невидимы в'],
164
+ ['discoverable из', 'видны из'],
165
+ ['documented', 'задокументировано'],
166
+ ['documented в', 'задокументировано в'],
167
+ ['skip if missing', 'skip если отсутствует'],
168
+ ['skip when', 'skip когда'],
169
+ ['skip без', 'skip без'],
170
+ ['stub architecture', 'заглушку architecture'],
171
+ ['stub ', 'заглушка '],
172
+ ['feeder', 'feeder'],
173
+ ['drill-down', 'drill-down'],
174
+ ['cross-link', 'cross-link'],
175
+ ['snapshot projection', 'snapshot projection'],
176
+ ['feature flag', 'feature flag'],
177
+ ['no-op', 'no-op'],
178
+ ['pass/fail', 'pass/fail'],
179
+ ['exit 0', 'exit 0'],
180
+ ['exit 1', 'exit 1'],
181
+ ['query param', 'query param'],
182
+ ['read path', 'read path'],
183
+ ['read-first', 'read-first'],
184
+ ['read-only', 'read-only'],
185
+ ['read-only ingest', 'read-only ingest'],
186
+ ['disk-first', 'disk-first'],
187
+ ['JSON fallback', 'JSON fallback'],
188
+ ['JSONL', 'JSONL'],
189
+ ['NDJSON', 'NDJSON'],
190
+ ['preflight', 'preflight'],
191
+ ['preflight stub', 'preflight stub'],
192
+ ['loop guard', 'loop guard'],
193
+ ['loop-hint', 'loop-hint'],
194
+ ['tool call', 'вызов tool'],
195
+ ['tool surface', 'tool surface'],
196
+ ['tool-rules', 'tool-rules'],
197
+ ['tool_calls', 'tool_calls'],
198
+ ['native tools', 'нативные tools'],
199
+ ['native tool_calls', 'нативные tool_calls'],
200
+ ['behavior rules', 'behavior rules'],
201
+ ['behavior bundle', 'behavior bundle'],
202
+ ['editing policy', 'editing policy'],
203
+ ['prompt slice', 'prompt slice'],
204
+ ['prompt rules', 'prompt rules'],
205
+ ['prompt-step', 'prompt-step'],
206
+ ['prompt eval', 'prompt eval'],
207
+ ['agent-matrix', 'agent-matrix'],
208
+ ['agent-behavior', 'agent-behavior'],
209
+ ['agent runtime', 'agent runtime'],
210
+ ['agent run', 'agent run'],
211
+ ['agent chat', 'agent chat'],
212
+ ['orchestrator', 'orchestrator'],
213
+ ['scheduler/recovery', 'scheduler/recovery'],
214
+ ['scheduler tick', 'scheduler tick'],
215
+ ['daemon tick', 'daemon tick'],
216
+ ['watch mode', 'режим watch'],
217
+ ['Watch mode', 'Режим watch'],
218
+ ['lease/expiry', 'lease/expiry'],
219
+ ['lease не', 'lease не'],
220
+ ['claimNext', 'claimNext'],
221
+ ['claim work', 'claim work'],
222
+ ['claim одну', 'claim одну'],
223
+ ['claim повторный', 'claim повторный'],
224
+ ['claim-no-eligible', 'claim-no-eligible'],
225
+ ['complete_work_item', 'complete_work_item'],
226
+ ['semantic_search', 'semantic_search'],
227
+ ['semantic search', 'semantic search'],
228
+ ['hybrid mode', 'hybrid mode'],
229
+ ['hybrid semantic', 'hybrid semantic'],
230
+ ['lexical sync', 'lexical sync'],
231
+ ['BM25 hits', 'BM25 hits'],
232
+ ['vector ANN', 'vector ANN'],
233
+ ['embedding index', 'embedding index'],
234
+ ['code-gap', 'code-gap'],
235
+ ['code gap', 'code gap'],
236
+ ['codegen', 'codegen'],
237
+ ['round-trip', 'round-trip'],
238
+ ['round trip', 'round-trip'],
239
+ ['low-code', 'low-code'],
240
+ ['onebase', 'onebase'],
241
+ ['OneBase', 'OneBase'],
242
+ ['gross-profit', 'gross-profit'],
243
+ ['kanban', 'kanban'],
244
+ ['Kanban', 'Kanban'],
245
+ ['Kanban view', 'Kanban view'],
246
+ ['Kanban columns', 'Kanban columns'],
247
+ ['Playwright', 'Playwright'],
248
+ ['Playwright spec', 'Playwright spec'],
249
+ ['Vitest', 'Vitest'],
250
+ ['E2E', 'E2E'],
251
+ ['CI/release', 'CI/release'],
252
+ ['ci:mandatory', 'ci:mandatory'],
253
+ ['ci или', 'ci или'],
254
+ ['lint tier', 'lint tier'],
255
+ ['lint находит', 'lint находит'],
256
+ ['lint:backlog', 'lint:backlog'],
257
+ ['npm run', 'npm run'],
258
+ ['package.json', 'package.json'],
259
+ ['playwright.config.js', 'playwright.config.js'],
260
+ ['work/backlog.bvc', 'work/backlog.bvc'],
261
+ ['work/daemon-audit.jsonl', 'work/daemon-audit.jsonl'],
262
+ ['work/worker-runs.jsonl', 'work/worker-runs.jsonl'],
263
+ ['../project', '../project'],
264
+ ['IOHASC_', 'IOHASC_'],
265
+ ['WORKGRAPH_', 'WORKGRAPH_'],
266
+ ['ADR ', 'ADR '],
267
+ ['ADR.', 'ADR.'],
268
+ ['ADR,', 'ADR,'],
269
+ ['ADR перечисляет', 'ADR перечисляет'],
270
+ ['ADR описывает', 'ADR описывает'],
271
+ ['ADR границы', 'ADR границы'],
272
+ ['ADR по', 'ADR по'],
273
+ ['ADR —', 'ADR —'],
274
+ ['ADR.', 'ADR.'],
275
+ [' vs ', ' vs '],
276
+ [' ↔ ', ' ↔ '],
277
+ [' → ', ' → '],
278
+ [' — ', ' — '],
279
+ [' intake ', ' приём '],
280
+ [' intake.', ' приём.'],
281
+ [' intake,', ' приём,'],
282
+ [' intake без', ' приём без'],
283
+ [' intake в', ' приём в'],
284
+ [' intake→', ' приём→'],
285
+ [' backlog ', ' бэклог '],
286
+ [' backlog.', ' бэклог.'],
287
+ [' backlog,', ' бэклог,'],
288
+ [' backlog без', ' бэклог без'],
289
+ [' backlog→', ' бэклог→'],
290
+ [' backlog:', ' бэклог:'],
291
+ [' backlog и', ' бэклог и'],
292
+ [' backlog UI', ' бэклог UI'],
293
+ [' backlog:ui', ' бэклог:ui'],
294
+ [' checks ', ' проверки '],
295
+ [' checks→', ' проверки→'],
296
+ [' checks,', ' проверки,'],
297
+ [' checks.', ' проверки.'],
298
+ [' checks и', ' проверки и'],
299
+ [' checks без', ' проверки без'],
300
+ [' checks на', ' проверки на'],
301
+ [' checks →', ' проверки →'],
302
+ [' с checks', ' с проверками'],
303
+ [' без checks', ' без проверок'],
304
+ [' пройденными checks', ' пройденными проверками'],
305
+ [' candidate list', 'список кандидатов'],
306
+ [' candidate;', ' кандидат;'],
307
+ [' candidate,', ' кандидат,'],
308
+ [' → candidate', ' → кандидат'],
309
+ [' → reject', ' → отказ'],
310
+ [' reject', ' отказ'],
311
+ [' protocol ', ' протокол '],
312
+ [' protocol.', ' протокол.'],
313
+ [' protocol или', ' протокол или'],
314
+ [' protocol —', ' протокол —'],
315
+ [' protocol с', ' протокол с'],
316
+ [' в protocol', ' в протоколе'],
317
+ [' в коде', ' в коде'],
318
+ [' draft ', ' черновик '],
319
+ [' draft.', ' черновик.'],
320
+ [' draft,', ' черновик,'],
321
+ [' draft→', ' черновик→'],
322
+ [' draft с', ' черновик с'],
323
+ [' drafts ', ' черновики '],
324
+ [' drafts с', ' черновики с'],
325
+ [' черновиков intake', ' черновиков приёма'],
326
+ [' operator ', ' оператор '],
327
+ [' operator.', ' оператор.'],
328
+ [' operator,', ' оператор,'],
329
+ [' operator promotion', ' продвижение оператором'],
330
+ [' operator видит', ' оператор видит'],
331
+ [' operator run', ' запуск оператора'],
332
+ [' operator shell', ' оболочка оператора'],
333
+ [' operator dashboard', ' dashboard оператора'],
334
+ [' operator workflow', ' workflow оператора'],
335
+ [' operator правит', ' оператор правит'],
336
+ [' operator retrieval', ' retrieval оператора'],
337
+ [' Оператор видит', ' Оператор видит'],
338
+ [' Оператор правит', ' Оператор правит'],
339
+ [' optional tier', ' optional tier'],
340
+ [' mandatory gate', ' mandatory gate'],
341
+ [' mandatory tier', ' mandatory tier'],
342
+ [' mandatory fixtures', ' mandatory fixtures'],
343
+ [' optional tier', ' optional tier'],
344
+ [' defer', ' defer'],
345
+ [' defer.', ' defer.'],
346
+ [' reopen', ' reopen'],
347
+ [' rollout', ' rollout'],
348
+ [' inventory', ' inventory'],
349
+ [' inventory.', ' inventory.'],
350
+ [' inventory,', ' inventory,'],
351
+ [' scope', ' scope'],
352
+ [' scope.', ' scope.'],
353
+ [' scope,', ' scope,'],
354
+ [' scope устава', ' scope устава'],
355
+ [' scope debates', ' споры о scope'],
356
+ [' design only', ' только design'],
357
+ [' только design', ' только design'],
358
+ [' только контракт', ' только контракт'],
359
+ [' только lexical', ' только lexical'],
360
+ [' только static', ' только static'],
361
+ [' только MCP', ' только MCP'],
362
+ [' только ioHasC', ' только ioHasC'],
363
+ [' только в', ' только в'],
364
+ [' только design', ' только design'],
365
+ [' full editor', ' полный editor'],
366
+ [' full ../project', ' полный ../project'],
367
+ [' full orchestrator', ' полный orchestrator'],
368
+ [' full semantic', ' полный semantic'],
369
+ [' full tool-rules', ' полный tool-rules'],
370
+ [' minimal port', ' минимальный port'],
371
+ [' minimal subset', ' minimal subset'],
372
+ [' minimal ', ' минимальный '],
373
+ [' subset ', ' subset '],
374
+ [' sample ', ' sample '],
375
+ [' sample CLI', ' sample CLI'],
376
+ [' sample slice', ' sample slice'],
377
+ [' sample passport', ' sample passport'],
378
+ [' pilot ', ' пилот '],
379
+ [' pilot doc', ' pilot doc'],
380
+ [' pilot без', ' пилот без'],
381
+ [' pilot ingest', ' pilot ingest'],
382
+ [' pilot read', ' pilot read'],
383
+ [' extended graph', ' extended graph'],
384
+ [' domain vertical', ' domain vertical'],
385
+ [' domain evidence', ' domain evidence'],
386
+ [' domain query', ' domain query'],
387
+ [' Domain/synonym', ' Domain/synonym'],
388
+ [' static gate', ' static gate'],
389
+ [' static gross-profit', ' static gross-profit'],
390
+ [' static verify', ' static verify'],
391
+ [' gross-profit gate', ' gross-profit gate'],
392
+ [' timeline', ' timeline'],
393
+ [' Timeline', ' Timeline'],
394
+ [' timeline view', ' timeline view'],
395
+ [' projection', ' projection'],
396
+ [' projection test', ' projection test'],
397
+ [' projection в', ' projection в'],
398
+ [' adapter', ' adapter'],
399
+ [' Adapter:', ' Adapter:'],
400
+ [' Adapter ', ' Adapter '],
401
+ [' checklist', ' checklist'],
402
+ [' Checklist', ' Checklist'],
403
+ [' assess ', ' оценить '],
404
+ [' evaluate', ' evaluate'],
405
+ [' configured', ' configured'],
406
+ [' configurable', ' configurable'],
407
+ [' configurable minPhase', ' configurable minPhase'],
408
+ [' promotable items', ' promotable items'],
409
+ [' promote queue', ' promote queue'],
410
+ [' promote-ready queue', ' promote-ready queue'],
411
+ [' promote блокируется', ' promote блокируется'],
412
+ [' Promote-ready', ' Promote-ready'],
413
+ [' Promote ', ' Promote '],
414
+ [' promote ', ' promote '],
415
+ [' sync ', ' синхронизировать '],
416
+ [' refresh ', ' обновить '],
417
+ [' chain ', ' связать '],
418
+ [' upgrade ', ' обновить '],
419
+ [' wire ', ' подключить '],
420
+ [' run ', ' прогнать '],
421
+ [' extend ', ' расширить '],
422
+ [' document ', ' документировать '],
423
+ [' analyze ', ' проанализировать '],
424
+ [' define ', ' определить '],
425
+ [' separate ', ' разделить '],
426
+ [' rebuild ', ' пересобрать '],
427
+ [' defer-', ' defer-'],
428
+ [' design-', ' design-'],
429
+ [' implement-', ' implement-'],
430
+ [' optional-', ' optional-'],
431
+ [' golden-path', ' golden-path'],
432
+ [' add-workgraph-mcp-client-configs', ' добавить конфиги MCP-клиента Work Graph'],
433
+ ['implement-architecture-block-detail-mvp', 'реализовать MVP detail architecture block'],
434
+ ['implement-operator-memory-panel-mvp', 'реализовать MVP панели памяти оператора'],
435
+ ['implement-schematic-visualization-view-mvp', 'реализовать MVP schematic visualization view'],
436
+ ['implement-workgraph-mcp-server-mvp', 'реализовать MVP MCP-сервера Work Graph'],
437
+ ['onebase-implement-gross-profit-warehouse-dimension', 'OneBase: gross-profit по складу'],
438
+ ['implement-pvrg-graph-rag-context-slice', 'реализовать PVRG Graph RAG context slice'],
439
+ ['port-agent-behavior-rules-bundle', 'перенести bundle agent-behavior rules'],
440
+ ['implement-full-semantic-search-workflow', 'реализовать полный semantic search workflow'],
441
+ ['design-workgraph-mcp-prompts-and-skills', 'спроектировать MCP prompts и skills Work Graph'],
442
+ ['design-operator-dashboard', 'спроектировать operator dashboard'],
443
+ ['analyze-claude-note-memory-extractor-reference', 'проанализировать reference Claude note memory extractor'],
444
+ ['rebuild-verification-loop', 'пересобрать verification loop'],
445
+ ['separate-architecture-and-work-deps-ui', 'разделить UI architecture и work deps'],
446
+ ['draft-workitem-v1-schema', 'черновик схемы WorkItem v1'],
447
+ ['implement-memory-record-journal-persist', 'реализовать persist journal MemoryRecord'],
448
+ ['implement-agent-chat-ui-with-nlux', 'реализовать agent chat UI с NLUX'],
449
+ ['optional-live-llm-eval', 'опциональная live LLM eval'],
450
+ ['defer-gbc-gvm-zig-scope', 'defer scope GBC/GVM/Zig'],
451
+ ['golden-path-test', 'тест golden path'],
452
+ ];
453
+
454
+ const WORD_REPLACEMENTS = [
455
+ ['backlog', 'бэклог'],
456
+ ['intake', 'приём'],
457
+ ['checks', 'проверки'],
458
+ ['candidate', 'кандидат'],
459
+ ['protocol', 'протокол'],
460
+ ['operator', 'оператор'],
461
+ ['fixture', 'фикстура'],
462
+ ['inventory', 'инвентарь'],
463
+ ['feeder', 'источник пополнения'],
464
+ ['promotion', 'продвижение'],
465
+ ['suggestions', 'предложения'],
466
+ ['provenance', 'происхождение'],
467
+ ['controlled', 'контролируемый'],
468
+ ['deterministic', 'детерминированный'],
469
+ ['optional', 'опциональный'],
470
+ ['bounded', 'ограниченный'],
471
+ ['unbounded', 'неограниченный'],
472
+ ['stub', 'заглушка'],
473
+ ['discoverable', 'доступный'],
474
+ ['documented', 'задокументированный'],
475
+ ['invisible', 'невидимый'],
476
+ ['invented', 'выдуманный'],
477
+ ['reject', 'отказ'],
478
+ ['design', 'проектирование'],
479
+ ['implement', 'реализация'],
480
+ ['port', 'перенос'],
481
+ ['wire', 'подключение'],
482
+ ['merge', 'слияние'],
483
+ ['validate', 'проверка'],
484
+ ['assess', 'оценка'],
485
+ ['extend', 'расширение'],
486
+ ['pilot', 'пилот'],
487
+ ['timeline', 'хронология'],
488
+ ['projection', 'проекция'],
489
+ ['adapter', 'адаптер'],
490
+ ['checklist', 'чеклист'],
491
+ ['promote', 'promote'],
492
+ ['review', 'review'],
493
+ ['evidence', 'свидетельства'],
494
+ ['transition', 'transition'],
495
+ ['scheduler', 'scheduler'],
496
+ ['recovery', 'recovery'],
497
+ ['daemon', 'daemon'],
498
+ ['worker', 'worker'],
499
+ ['provider', 'провайдер'],
500
+ ['orchestrator', 'orchestrator'],
501
+ ['semantic', 'semantic'],
502
+ ['linkage', 'linkage'],
503
+ ['trace', 'trace'],
504
+ ['verification', 'verification'],
505
+ ['regression', 'regression'],
506
+ ['browser', 'browser'],
507
+ ['snapshot', 'snapshot'],
508
+ ['journal', 'journal'],
509
+ ['persist', 'persist'],
510
+ ['deferred', 'отложено'],
511
+ ['defer', 'defer'],
512
+ ['reopen', 'reopen'],
513
+ ['rollout', 'rollout'],
514
+ ['drift', 'drift'],
515
+ ['reconcile', 'reconcile'],
516
+ ['scope', 'scope'],
517
+ ['parity', 'parity'],
518
+ ['matrix', 'matrix'],
519
+ ['workflow', 'workflow'],
520
+ ['bundle', 'bundle'],
521
+ ['rules', 'rules'],
522
+ ['policy', 'policy'],
523
+ ['guard', 'guard'],
524
+ ['gate', 'gate'],
525
+ ['tier', 'tier'],
526
+ ['path', 'path'],
527
+ ['mode', 'mode'],
528
+ ['view', 'view'],
529
+ ['panel', 'panel'],
530
+ ['shell', 'shell'],
531
+ ['dashboard', 'dashboard'],
532
+ ['board', 'board'],
533
+ ['column', 'column'],
534
+ ['columns', 'columns'],
535
+ ['editor', 'editor'],
536
+ ['search', 'search'],
537
+ ['retrieval', 'retrieval'],
538
+ ['embedding', 'embedding'],
539
+ ['embeddings', 'embeddings'],
540
+ ['synonym', 'synonym'],
541
+ ['domain', 'domain'],
542
+ ['vertical', 'vertical'],
543
+ ['catalog', 'catalog'],
544
+ ['passport', 'passport'],
545
+ ['alignment', 'alignment'],
546
+ ['orphan', 'orphan'],
547
+ ['charter', 'charter'],
548
+ ['preflight', 'preflight'],
549
+ ['compiler', 'compiler'],
550
+ ['codegen', 'codegen'],
551
+ ['analyzer', 'analyzer'],
552
+ ['roundtrip', 'roundtrip'],
553
+ ['round-trip', 'round-trip'],
554
+ ['memory', 'memory'],
555
+ ['fusion', 'fusion'],
556
+ ['slice', 'slice'],
557
+ ['prompt', 'prompt'],
558
+ ['eval', 'eval'],
559
+ ['harness', 'harness'],
560
+ ['rubric', 'rubric'],
561
+ ['scenario', 'scenario'],
562
+ ['scenarios', 'scenarios'],
563
+ ['matrix', 'matrix'],
564
+ ['playwright', 'Playwright'],
565
+ ['kanban', 'kanban'],
566
+ ['hybrid', 'hybrid'],
567
+ ['lexical', 'lexical'],
568
+ ['vector', 'vector'],
569
+ ['ingest', 'ingest'],
570
+ ['overlay', 'overlay'],
571
+ ['passport', 'passport'],
572
+ ['wasm', 'wasm'],
573
+ ['missing', 'missing'],
574
+ ['sample', 'sample'],
575
+ ['report', 'report'],
576
+ ['block', 'block'],
577
+ ['detail', 'detail'],
578
+ ['drawer', 'drawer'],
579
+ ['click', 'click'],
580
+ ['toggle', 'toggle'],
581
+ ['query', 'query'],
582
+ ['param', 'param'],
583
+ ['hits', 'hits'],
584
+ ['green', 'green'],
585
+ ['pass', 'pass'],
586
+ ['fail', 'fail'],
587
+ ['skip', 'skip'],
588
+ ['live', 'live'],
589
+ ['local', 'local'],
590
+ ['native', 'native'],
591
+ ['tools', 'tools'],
592
+ ['tool', 'tool'],
593
+ ['calls', 'calls'],
594
+ ['call', 'call'],
595
+ ['loop', 'loop'],
596
+ ['hint', 'hint'],
597
+ ['repeat', 'repeat'],
598
+ ['lease', 'lease'],
599
+ ['expiry', 'expiry'],
600
+ ['claim', 'claim'],
601
+ ['ready', 'ready'],
602
+ ['done', 'done'],
603
+ ['blocked', 'blocked'],
604
+ ['blocked', 'blocked'],
605
+ ['blocked', 'blocked'],
606
+ ];
607
+
608
+ const NEXT_ACTION_MAP = {
609
+ 'review and promote to ready': 'просмотреть и перевести в ready',
610
+ 'optional-live-llm-eval': 'опциональная live LLM eval',
611
+ 'defer-gbc-gvm-zig-scope': 'defer: scope GBC/GVM/Zig',
612
+ 'golden-path-test': 'тест golden path',
613
+ 'add-workgraph-mcp-client-configs': 'добавить конфиги MCP-клиента Work Graph',
614
+ 'implement-architecture-block-detail-mvp': 'реализовать MVP detail architecture block',
615
+ 'implement-operator-memory-panel-mvp': 'реализовать MVP панели памяти оператора',
616
+ 'implement-schematic-visualization-view-mvp': 'реализовать MVP schematic visualization view',
617
+ 'implement-workgraph-mcp-server-mvp': 'реализовать MVP MCP-сервера Work Graph',
618
+ 'onebase-implement-gross-profit-warehouse-dimension': 'OneBase: gross-profit по складу',
619
+ 'implement-pvrg-graph-rag-context-slice': 'реализовать PVRG Graph RAG context slice',
620
+ 'port-agent-behavior-rules-bundle': 'перенести bundle agent-behavior rules',
621
+ 'implement-full-semantic-search-workflow': 'реализовать полный semantic search workflow',
622
+ 'design-workgraph-mcp-prompts-and-skills': 'спроектировать MCP prompts и skills Work Graph',
623
+ 'design-operator-dashboard': 'спроектировать dashboard оператора',
624
+ 'analyze-claude-note-memory-extractor-reference': 'проанализировать reference Claude note memory extractor',
625
+ 'rebuild-verification-loop': 'пересобрать verification loop',
626
+ 'separate-architecture-and-work-deps-ui': 'разделить UI architecture и work deps',
627
+ 'draft-workitem-v1-schema': 'черновик схемы WorkItem v1',
628
+ 'implement-memory-record-journal-persist': 'реализовать persist journal MemoryRecord',
629
+ 'implement-agent-chat-ui-with-nlux': 'реализовать agent chat UI с NLUX',
630
+ };
631
+
632
+ const TITLE_PREFIX = {
633
+ implement: 'реализовать',
634
+ design: 'спроектировать',
635
+ wire: 'подключить',
636
+ port: 'перенести',
637
+ optional: 'опционально:',
638
+ run: 'прогнать',
639
+ refresh: 'обновить',
640
+ sync: 'синхронизировать',
641
+ upgrade: 'обновить',
642
+ evaluate: 'оценить',
643
+ extend: 'расширить',
644
+ pilot: 'пилот:',
645
+ document: 'документировать',
646
+ define: 'определить',
647
+ analyze: 'проанализировать',
648
+ chain: 'связать',
649
+ rebuild: 'пересобрать',
650
+ separate: 'разделить',
651
+ draft: 'черновик:',
652
+ defer: 'defer:',
653
+ rebuild: 'пересобрать',
654
+ };
655
+
656
+ function protectTechnical(text, fn) {
657
+ const tokens = [];
658
+ const protectedText = String(text ?? '').replace(
659
+ /(`[^`]+`|\b(?:npm run|IOHASC_[A-Z0-9_]+|WORKGRAPH_[A-Z0-9_]+|[a-z]+:[a-z-]+(?:\/[a-z-]+)*|\/?(?:src|docs|protocols|packages|tests|e2e|rules|domains|intent|work)\/[^\s,]+|\b[a-z][a-z0-9-]*\.(?:mjs|js|ts|step|json|jsonl|md|spec\.js))\b)/giu,
660
+ (match) => {
661
+ const key = `__TOK${tokens.length}__`;
662
+ tokens.push(match);
663
+ return key;
664
+ },
665
+ );
666
+ let result = fn(protectedText);
667
+ for (let index = 0; index < tokens.length; index += 1) {
668
+ result = result.replace(`__TOK${index}__`, tokens[index]);
669
+ }
670
+ return result;
671
+ }
672
+
673
+ export function rusifyLine(text) {
674
+ if (!text || typeof text !== 'string') {
675
+ return text;
676
+ }
677
+
678
+ const result = protectTechnical(text, (input) => {
679
+ let value = input;
680
+ for (const [from, to] of PHRASE_REPLACEMENTS) {
681
+ if (from.includes(' ') || from.length >= 8) {
682
+ value = value.split(from).join(to);
683
+ }
684
+ }
685
+ return value.replace(/\s{2,}/gu, ' ').trim();
686
+ });
687
+
688
+ return applyPostFixes(result);
689
+ }
690
+
691
+ const POST_FIXES = [
692
+ ['перекрёстная подсветка спроектирован', 'перекрёстная подсветка спроектирована'],
693
+ ['в оболочка оператора', 'в оболочке оператора'],
694
+ ['в оболочка ', 'в оболочке '],
695
+ ['становится источником пополнения бэклога, а не вторым источник истины', 'становится источником пополнения бэклога, а не вторым источником истины'],
696
+ ['для карточек задач и узлы графа', 'для карточек задач и узлов графа'],
697
+ ['но пересобрать бэклог нужен контролируемый приём', 'но для бэклога нужен контролируемый приём черновиков'],
698
+ ['для карточки задач', 'для карточек задач'],
699
+ ['спроектировать приём черновиков в бэклог', 'спроектировать приём черновиков в бэклог'],
700
+ ['спроектировать приём черновиков в backlog', 'спроектировать приём черновиков в бэклог'],
701
+ ['draft provenance сохраняется', 'provenance черновика сохраняется'],
702
+ ['intake требует', 'приём требует'],
703
+ ['generated tasks используют', 'сгенерированные задачи используют'],
704
+ ['Спроектировать promotion из', 'Спроектировать продвижение из'],
705
+ ['спроектировать promotion из', 'спроектировать продвижение из'],
706
+ ['ручной smoke-тест на backlog:ui', 'ручной smoke-тест: npm run backlog:ui'],
707
+ ['реализовать UI перекрёстная подсветка', 'реализовать UI: перекрёстная подсветка'],
708
+ ['↔ backlog', '↔ бэклог'],
709
+ [' в backlog', ' в бэклог'],
710
+ [' intake ', ' приём '],
711
+ [' intake.', ' приём.'],
712
+ [' intake,', ' приём,'],
713
+ [' intake→', ' приём→'],
714
+ [' intake в', ' приём в'],
715
+ [' intake без', ' приём без'],
716
+ [' intake и', ' приём и'],
717
+ [' intake требует', ' приём требует'],
718
+ ['backlog:ui', 'backlog:ui'],
719
+ ['бэклог UI', 'бэклог UI'],
720
+ ['без «тихого» засорения бэклога', 'без «тихого» засорения бэклога'],
721
+ ['scope не reopen', 'scope не reopen'],
722
+ ['споры о границах scope', 'споры о границах scope'],
723
+ ];
724
+
725
+ function applyPostFixes(text) {
726
+ let value = String(text);
727
+ for (const [from, to] of POST_FIXES) {
728
+ value = value.split(from).join(to);
729
+ }
730
+ return value;
731
+ }
732
+
733
+ export function rusifyNextAction(nextAction, workId) {
734
+ const raw = String(nextAction ?? '').trim();
735
+ if (raw === '' || raw === '—') {
736
+ return raw;
737
+ }
738
+ if (NEXT_ACTION_MAP[raw]) {
739
+ return NEXT_ACTION_MAP[raw];
740
+ }
741
+ if (/^review and promote/i.test(raw)) {
742
+ return 'просмотреть и перевести в ready';
743
+ }
744
+ if (/^[a-z0-9-]+$/u.test(raw) && raw.includes('-')) {
745
+ return rusifyLine(raw.replace(/-/gu, ' '));
746
+ }
747
+ return rusifyLine(raw);
748
+ }
749
+
750
+ const TITLE_OVERRIDES = {
751
+ 'design-draft-store-backlog-intake': 'спроектировать приём черновиков в бэклог',
752
+ 'implement-semantic-map-ui-cross-highlight': 'реализовать перекрёстную подсветку semantic map ↔ бэклог',
753
+ 'implement-workgraph-mcp-server-mvp': 'реализовать MVP MCP-сервера Work Graph',
754
+ };
755
+
756
+ export function rusifyTitle(title, workId) {
757
+ if (TITLE_OVERRIDES[workId]) {
758
+ return TITLE_OVERRIDES[workId];
759
+ }
760
+ const raw = String(title ?? workId ?? '').trim();
761
+ const rusified = rusifyLine(raw);
762
+ if (/^[a-z]/u.test(rusified) && workId) {
763
+ const [prefix] = workId.split('-');
764
+ const ruPrefix = TITLE_PREFIX[prefix];
765
+ if (ruPrefix) {
766
+ const tail = workId.slice(prefix.length + 1).replace(/-/gu, ' ');
767
+ return `${ruPrefix} ${rusifyLine(tail)}`.replace(/\s{2,}/gu, ' ').trim();
768
+ }
769
+ }
770
+ return rusified;
771
+ }
772
+
773
+ export function rusifyStringList(values) {
774
+ if (!Array.isArray(values)) {
775
+ return values;
776
+ }
777
+ return values
778
+ .flatMap((line) => String(line).split(/\n+/u).map((part) => rusifyLine(part.trim())).filter(Boolean))
779
+ .filter(Boolean);
780
+ }
781
+
782
+ export function rusifyWorkItemFields(item) {
783
+ return {
784
+ basis: rusifyStringList(Array.isArray(item.basis) ? item.basis : [item.basis].filter(Boolean)),
785
+ vector: rusifyStringList(Array.isArray(item.vector) ? item.vector : [item.vector].filter(Boolean)),
786
+ goal: rusifyStringList(Array.isArray(item.goal) ? item.goal : [item.goal].filter(Boolean)),
787
+ checks: item.checks ? rusifyStringList(item.checks) : undefined,
788
+ evidence: item.evidence,
789
+ title: rusifyTitle(item.title, item.id),
790
+ nextAction: rusifyNextAction(item.nextAction, item.id),
791
+ };
792
+ }
793
+
794
+ export const DEFAULT_NEXT_ACTION_RU = 'просмотреть и перевести в ready';