pi-maestro-flow 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.
- package/README.md +124 -0
- package/agents/aggregator.md +27 -0
- package/agents/cli-explore-agent.md +188 -0
- package/agents/cross-role-reviewer.md +171 -0
- package/agents/delegate.md +19 -0
- package/agents/explorer.md +23 -0
- package/agents/impeccable-agent.md +99 -0
- package/agents/ralph-executor.md +81 -0
- package/agents/reference.md +24 -0
- package/agents/role-design-author.md +220 -0
- package/agents/team-supervisor.md +143 -0
- package/agents/team-worker.md +237 -0
- package/agents/ui-design-agent.md +270 -0
- package/agents/workflow-analyzer.md +116 -0
- package/agents/workflow-codebase-mapper.md +77 -0
- package/agents/workflow-collab-planner.md +147 -0
- package/agents/workflow-debugger.md +104 -0
- package/agents/workflow-executor.md +133 -0
- package/agents/workflow-external-researcher.md +86 -0
- package/agents/workflow-integration-checker.md +83 -0
- package/agents/workflow-nyquist-auditor.md +85 -0
- package/agents/workflow-phase-researcher.md +85 -0
- package/agents/workflow-plan-checker.md +100 -0
- package/agents/workflow-planner.md +200 -0
- package/agents/workflow-project-researcher.md +74 -0
- package/agents/workflow-research-synthesizer.md +70 -0
- package/agents/workflow-reviewer.md +82 -0
- package/agents/workflow-roadmapper.md +81 -0
- package/agents/workflow-verifier.md +120 -0
- package/package.json +58 -0
- package/skills/codify-to-knowhow/SKILL.md +167 -0
- package/skills/delegation-check/SKILL.md +297 -0
- package/skills/domain-add/SKILL.md +75 -0
- package/skills/insight-challenge/SKILL.md +226 -0
- package/skills/learn-decompose/SKILL.md +124 -0
- package/skills/learn-follow/SKILL.md +163 -0
- package/skills/learn-investigate/SKILL.md +160 -0
- package/skills/learn-second-opinion/SKILL.md +128 -0
- package/skills/maestro/SKILL.md +239 -0
- package/skills/maestro-amend/SKILL.md +169 -0
- package/skills/maestro-analyze/SKILL.md +173 -0
- package/skills/maestro-blueprint/SKILL.md +159 -0
- package/skills/maestro-brainstorm/SKILL.md +193 -0
- package/skills/maestro-collab/SKILL.md +181 -0
- package/skills/maestro-companion/SKILL.md +536 -0
- package/skills/maestro-composer/SKILL.md +192 -0
- package/skills/maestro-execute/SKILL.md +193 -0
- package/skills/maestro-fork/SKILL.md +104 -0
- package/skills/maestro-grill/SKILL.md +151 -0
- package/skills/maestro-guard/SKILL.md +124 -0
- package/skills/maestro-help/SKILL.md +328 -0
- package/skills/maestro-impeccable/SKILL.md +302 -0
- package/skills/maestro-init/SKILL.md +151 -0
- package/skills/maestro-merge/SKILL.md +90 -0
- package/skills/maestro-milestone-audit/SKILL.md +117 -0
- package/skills/maestro-milestone-complete/SKILL.md +133 -0
- package/skills/maestro-milestone-release/SKILL.md +131 -0
- package/skills/maestro-next/SKILL.md +269 -0
- package/skills/maestro-overlay/SKILL.md +203 -0
- package/skills/maestro-plan/SKILL.md +194 -0
- package/skills/maestro-player/SKILL.md +184 -0
- package/skills/maestro-quick/SKILL.md +117 -0
- package/skills/maestro-ralph/SKILL.md +905 -0
- package/skills/maestro-ralph-cli/SKILL.md +976 -0
- package/skills/maestro-ralph-cli-execute/SKILL.md +229 -0
- package/skills/maestro-ralph-execute/SKILL.md +409 -0
- package/skills/maestro-ralph-v2/SKILL.md +1198 -0
- package/skills/maestro-roadmap/SKILL.md +157 -0
- package/skills/maestro-swarm-workflow/SKILL.md +272 -0
- package/skills/maestro-tools-execute/SKILL.md +143 -0
- package/skills/maestro-tools-register/SKILL.md +192 -0
- package/skills/maestro-ui-codify/SKILL.md +127 -0
- package/skills/maestro-universal-workflow/SKILL.md +622 -0
- package/skills/maestro-update/SKILL.md +156 -0
- package/skills/manage-codebase-rebuild/SKILL.md +111 -0
- package/skills/manage-drift-realign/SKILL.md +159 -0
- package/skills/manage-harvest/SKILL.md +121 -0
- package/skills/manage-issue/SKILL.md +88 -0
- package/skills/manage-issue-discover/SKILL.md +104 -0
- package/skills/manage-kg-extractors/SKILL.md +147 -0
- package/skills/manage-knowhow/SKILL.md +102 -0
- package/skills/manage-knowhow-capture/SKILL.md +109 -0
- package/skills/manage-knowledge-audit/SKILL.md +147 -0
- package/skills/manage-status/SKILL.md +80 -0
- package/skills/manage-wiki/SKILL.md +104 -0
- package/skills/odyssey-debug/SKILL.md +344 -0
- package/skills/odyssey-improve/SKILL.md +423 -0
- package/skills/odyssey-planex/SKILL.md +542 -0
- package/skills/odyssey-review-test-fix/SKILL.md +392 -0
- package/skills/odyssey-ui/SKILL.md +388 -0
- package/skills/prompt-generator/SKILL.md +470 -0
- package/skills/quality-auto-test/SKILL.md +168 -0
- package/skills/quality-debug/SKILL.md +176 -0
- package/skills/quality-refactor/SKILL.md +108 -0
- package/skills/quality-retrospective/SKILL.md +134 -0
- package/skills/quality-review/SKILL.md +169 -0
- package/skills/quality-sync/SKILL.md +90 -0
- package/skills/quality-test/SKILL.md +183 -0
- package/skills/scholar-anti-ai-writing/SKILL.md +173 -0
- package/skills/scholar-anti-ai-writing/references/patterns-chinese.md +242 -0
- package/skills/scholar-anti-ai-writing/references/patterns-english.md +242 -0
- package/skills/scholar-citation-verify/SKILL.md +166 -0
- package/skills/scholar-citation-verify/references/api-usage.md +372 -0
- package/skills/scholar-citation-verify/references/common-errors.md +384 -0
- package/skills/scholar-citation-verify/references/verification-rules.md +399 -0
- package/skills/scholar-experiment/SKILL.md +321 -0
- package/skills/scholar-ideation/SKILL.md +288 -0
- package/skills/scholar-latex-organizer/SKILL.md +186 -0
- package/skills/scholar-publish/SKILL.md +220 -0
- package/skills/scholar-rebuttal-pro/README.md +313 -0
- package/skills/scholar-rebuttal-pro/SKILL.md +511 -0
- package/skills/scholar-review/SKILL.md +227 -0
- package/skills/scholar-thesis-docx/README.md +111 -0
- package/skills/scholar-thesis-docx/README_EN.md +108 -0
- package/skills/scholar-thesis-docx/SKILL.md +212 -0
- package/skills/scholar-thesis-docx/references/failure-patterns-and-quality-gates.md +178 -0
- package/skills/scholar-thesis-docx/references/figure-and-code-rules.md +33 -0
- package/skills/scholar-thesis-docx/references/paper-format-workflow.md +68 -0
- package/skills/scholar-thesis-docx/references/script-usage.md +157 -0
- package/skills/scholar-thesis-docx/scripts/audit_docx_ooxml.py +429 -0
- package/skills/scholar-thesis-docx/scripts/check_word_com.ps1 +50 -0
- package/skills/scholar-thesis-docx/scripts/export_word_pdf.ps1 +62 -0
- package/skills/scholar-thesis-docx/scripts/normalize_word_styles.ps1 +498 -0
- package/skills/scholar-thesis-docx/scripts/render_mermaid_figure.ps1 +148 -0
- package/skills/scholar-writing/SKILL.md +296 -0
- package/skills/security-audit/SKILL.md +244 -0
- package/skills/skill-generator/SKILL.md +472 -0
- package/skills/skill-iter-tune/SKILL.md +382 -0
- package/skills/skill-simplify/SKILL.md +63 -0
- package/skills/skill-tuning/SKILL.md +174 -0
- package/skills/spec-add/SKILL.md +105 -0
- package/skills/spec-load/SKILL.md +98 -0
- package/skills/spec-remove/SKILL.md +74 -0
- package/skills/spec-setup/SKILL.md +75 -0
- package/skills/team-adversarial-swarm/SKILL.md +233 -0
- package/skills/team-adversarial-swarm/scripts/__pycache__/pheromone.cpython-313.pyc +0 -0
- package/skills/team-adversarial-swarm/scripts/__pycache__/scoring.cpython-313.pyc +0 -0
- package/skills/team-adversarial-swarm/scripts/aco.py +473 -0
- package/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
- package/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
- package/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
- package/skills/team-arch-opt/SKILL.md +158 -0
- package/skills/team-brainstorm/SKILL.md +171 -0
- package/skills/team-coordinate/SKILL.md +266 -0
- package/skills/team-designer/SKILL.md +160 -0
- package/skills/team-executor/SKILL.md +189 -0
- package/skills/team-frontend/SKILL.md +136 -0
- package/skills/team-frontend-debug/SKILL.md +198 -0
- package/skills/team-interactive-craft/SKILL.md +141 -0
- package/skills/team-issue/SKILL.md +171 -0
- package/skills/team-lifecycle-v4/SKILL.md +209 -0
- package/skills/team-motion-design/SKILL.md +142 -0
- package/skills/team-perf-opt/SKILL.md +175 -0
- package/skills/team-planex/SKILL.md +137 -0
- package/skills/team-quality-assurance/SKILL.md +147 -0
- package/skills/team-review/SKILL.md +147 -0
- package/skills/team-roadmap-dev/SKILL.md +169 -0
- package/skills/team-swarm/SKILL.md +178 -0
- package/skills/team-swarm/scripts/aco.py +473 -0
- package/skills/team-swarm/scripts/pheromone.py +144 -0
- package/skills/team-swarm/scripts/scoring.py +92 -0
- package/skills/team-swarm/scripts/test_aco.py +475 -0
- package/skills/team-tech-debt/SKILL.md +128 -0
- package/skills/team-testing/SKILL.md +143 -0
- package/skills/team-ui-polish/SKILL.md +141 -0
- package/skills/team-uidesign/SKILL.md +144 -0
- package/skills/team-ultra-analyze/SKILL.md +173 -0
- package/skills/team-ux-improve/SKILL.md +151 -0
- package/skills/team-visual-a11y/SKILL.md +156 -0
- package/skills/workflow-skill-designer/SKILL.md +496 -0
- package/src/extension/index.ts +222 -0
- package/src/extension/schemas.ts +131 -0
- package/src/providers/cli-tools-loader.ts +74 -0
- package/src/providers/provider-registry.ts +130 -0
- package/src/tools/delegate.ts +85 -0
- package/src/tools/explore.ts +134 -0
- package/src/tools/moa.ts +213 -0
- package/src/tools/status.ts +99 -0
- package/src/tools/wait.ts +166 -0
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
param(
|
|
2
|
+
[Parameter(Mandatory = $true)]
|
|
3
|
+
[string]$InputPath,
|
|
4
|
+
|
|
5
|
+
[string]$OutputPath,
|
|
6
|
+
|
|
7
|
+
[string]$ConfigPath,
|
|
8
|
+
|
|
9
|
+
[switch]$AuditOnly,
|
|
10
|
+
|
|
11
|
+
[switch]$InPlace,
|
|
12
|
+
|
|
13
|
+
[switch]$Visible
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
Set-StrictMode -Version Latest
|
|
17
|
+
$ErrorActionPreference = "Stop"
|
|
18
|
+
|
|
19
|
+
function Get-DefaultConfig {
|
|
20
|
+
return @{
|
|
21
|
+
styles = @{
|
|
22
|
+
Body = @{
|
|
23
|
+
TargetStyleName = "Body Text"
|
|
24
|
+
BuiltinId = -1
|
|
25
|
+
FontName = "Times New Roman"
|
|
26
|
+
EastAsiaFontName = "SimSun"
|
|
27
|
+
Size = 12
|
|
28
|
+
Bold = $false
|
|
29
|
+
Italic = $false
|
|
30
|
+
Alignment = "Justify"
|
|
31
|
+
FirstLineIndentCm = 0.74
|
|
32
|
+
LeftIndentCm = 0
|
|
33
|
+
RightIndentCm = 0
|
|
34
|
+
SpaceBeforePt = 0
|
|
35
|
+
SpaceAfterPt = 0
|
|
36
|
+
LineSpacingMultiple = 1.5
|
|
37
|
+
KeepTogether = $false
|
|
38
|
+
KeepWithNext = $false
|
|
39
|
+
OutlineLevel = 10
|
|
40
|
+
}
|
|
41
|
+
Heading1 = @{
|
|
42
|
+
TargetStyleName = "Heading 1"
|
|
43
|
+
BuiltinId = -2
|
|
44
|
+
FontName = "Times New Roman"
|
|
45
|
+
EastAsiaFontName = "SimHei"
|
|
46
|
+
Size = 16
|
|
47
|
+
Bold = $true
|
|
48
|
+
Italic = $false
|
|
49
|
+
Alignment = "Center"
|
|
50
|
+
FirstLineIndentCm = 0
|
|
51
|
+
LeftIndentCm = 0
|
|
52
|
+
RightIndentCm = 0
|
|
53
|
+
SpaceBeforePt = 18
|
|
54
|
+
SpaceAfterPt = 12
|
|
55
|
+
LineSpacingMultiple = 1.5
|
|
56
|
+
KeepTogether = $true
|
|
57
|
+
KeepWithNext = $true
|
|
58
|
+
OutlineLevel = 1
|
|
59
|
+
}
|
|
60
|
+
Heading2 = @{
|
|
61
|
+
TargetStyleName = "Heading 2"
|
|
62
|
+
BuiltinId = -3
|
|
63
|
+
FontName = "Times New Roman"
|
|
64
|
+
EastAsiaFontName = "SimHei"
|
|
65
|
+
Size = 14
|
|
66
|
+
Bold = $true
|
|
67
|
+
Italic = $false
|
|
68
|
+
Alignment = "Left"
|
|
69
|
+
FirstLineIndentCm = 0
|
|
70
|
+
LeftIndentCm = 0
|
|
71
|
+
RightIndentCm = 0
|
|
72
|
+
SpaceBeforePt = 12
|
|
73
|
+
SpaceAfterPt = 6
|
|
74
|
+
LineSpacingMultiple = 1.5
|
|
75
|
+
KeepTogether = $true
|
|
76
|
+
KeepWithNext = $true
|
|
77
|
+
OutlineLevel = 2
|
|
78
|
+
}
|
|
79
|
+
Heading3 = @{
|
|
80
|
+
TargetStyleName = "Heading 3"
|
|
81
|
+
BuiltinId = -4
|
|
82
|
+
FontName = "Times New Roman"
|
|
83
|
+
EastAsiaFontName = "SimHei"
|
|
84
|
+
Size = 12
|
|
85
|
+
Bold = $true
|
|
86
|
+
Italic = $false
|
|
87
|
+
Alignment = "Left"
|
|
88
|
+
FirstLineIndentCm = 0
|
|
89
|
+
LeftIndentCm = 0
|
|
90
|
+
RightIndentCm = 0
|
|
91
|
+
SpaceBeforePt = 6
|
|
92
|
+
SpaceAfterPt = 6
|
|
93
|
+
LineSpacingMultiple = 1.5
|
|
94
|
+
KeepTogether = $true
|
|
95
|
+
KeepWithNext = $true
|
|
96
|
+
OutlineLevel = 3
|
|
97
|
+
}
|
|
98
|
+
FigureCaption = @{
|
|
99
|
+
TargetStyleName = "Figure Caption"
|
|
100
|
+
FontName = "Times New Roman"
|
|
101
|
+
EastAsiaFontName = "SimSun"
|
|
102
|
+
Size = 10.5
|
|
103
|
+
Bold = $false
|
|
104
|
+
Italic = $false
|
|
105
|
+
Alignment = "Center"
|
|
106
|
+
FirstLineIndentCm = 0
|
|
107
|
+
LeftIndentCm = 0
|
|
108
|
+
RightIndentCm = 0
|
|
109
|
+
SpaceBeforePt = 6
|
|
110
|
+
SpaceAfterPt = 6
|
|
111
|
+
LineSpacingMultiple = 1.0
|
|
112
|
+
KeepTogether = $true
|
|
113
|
+
KeepWithNext = $false
|
|
114
|
+
OutlineLevel = 10
|
|
115
|
+
}
|
|
116
|
+
TableCaption = @{
|
|
117
|
+
TargetStyleName = "Table Caption"
|
|
118
|
+
FontName = "Times New Roman"
|
|
119
|
+
EastAsiaFontName = "SimSun"
|
|
120
|
+
Size = 10.5
|
|
121
|
+
Bold = $false
|
|
122
|
+
Italic = $false
|
|
123
|
+
Alignment = "Center"
|
|
124
|
+
FirstLineIndentCm = 0
|
|
125
|
+
LeftIndentCm = 0
|
|
126
|
+
RightIndentCm = 0
|
|
127
|
+
SpaceBeforePt = 6
|
|
128
|
+
SpaceAfterPt = 6
|
|
129
|
+
LineSpacingMultiple = 1.0
|
|
130
|
+
KeepTogether = $true
|
|
131
|
+
KeepWithNext = $false
|
|
132
|
+
OutlineLevel = 10
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
patterns = @{
|
|
136
|
+
FigureCaption = '^(Figure|Fig\.?|\u56FE)\s*[\dA-Za-z]+'
|
|
137
|
+
TableCaption = '^(Table|\u8868)\s*[\dA-Za-z]+'
|
|
138
|
+
Heading3 = '^(\d+\.\d+\.\d+)\s+\S+'
|
|
139
|
+
Heading2 = '^(\d+\.\d+)\s+\S+'
|
|
140
|
+
Heading1 = '^(Chapter\s+\d+|第[\u4E00-\u5341]+章|\d+\s+\S+)'
|
|
141
|
+
}
|
|
142
|
+
styleHints = @{
|
|
143
|
+
FigureCaption = '(Figure Caption|Caption Figure|\u56FE)'
|
|
144
|
+
TableCaption = '(Table Caption|Caption Table|\u8868)'
|
|
145
|
+
Heading1 = '(Heading 1|\u6807\u9898 1)'
|
|
146
|
+
Heading2 = '(Heading 2|\u6807\u9898 2)'
|
|
147
|
+
Heading3 = '(Heading 3|\u6807\u9898 3)'
|
|
148
|
+
Body = '(Body Text|Normal|\u6B63\u6587)'
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function Merge-Hashtable {
|
|
154
|
+
param(
|
|
155
|
+
[hashtable]$Base,
|
|
156
|
+
[hashtable]$Override
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
foreach ($key in $Override.Keys) {
|
|
160
|
+
if ($Base.ContainsKey($key) -and $Base[$key] -is [hashtable] -and $Override[$key] -is [hashtable]) {
|
|
161
|
+
Merge-Hashtable -Base $Base[$key] -Override $Override[$key]
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
$Base[$key] = $Override[$key]
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function ConvertTo-Hashtable {
|
|
170
|
+
param([object]$Value)
|
|
171
|
+
|
|
172
|
+
if ($null -eq $Value) {
|
|
173
|
+
return $null
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if ($Value -is [System.Collections.IDictionary]) {
|
|
177
|
+
$hash = @{}
|
|
178
|
+
foreach ($key in $Value.Keys) {
|
|
179
|
+
$hash[$key] = ConvertTo-Hashtable -Value $Value[$key]
|
|
180
|
+
}
|
|
181
|
+
return $hash
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if ($Value -is [System.Collections.IEnumerable] -and -not ($Value -is [string])) {
|
|
185
|
+
$items = @()
|
|
186
|
+
foreach ($item in $Value) {
|
|
187
|
+
$items += ,(ConvertTo-Hashtable -Value $item)
|
|
188
|
+
}
|
|
189
|
+
return $items
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return $Value
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function Get-AlignmentValue {
|
|
196
|
+
param([object]$Value)
|
|
197
|
+
|
|
198
|
+
if ($Value -is [int]) {
|
|
199
|
+
return $Value
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
switch -Regex ([string]$Value) {
|
|
203
|
+
'^Center$' { return 1 }
|
|
204
|
+
'^Right$' { return 2 }
|
|
205
|
+
'^Justify$' { return 3 }
|
|
206
|
+
'^Distributed$' { return 4 }
|
|
207
|
+
default { return 0 }
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function Get-ComBool {
|
|
212
|
+
param([object]$Value)
|
|
213
|
+
|
|
214
|
+
if ([bool]$Value) {
|
|
215
|
+
return -1
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return 0
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function Resolve-Style {
|
|
222
|
+
param(
|
|
223
|
+
$Document,
|
|
224
|
+
[string]$LogicalName,
|
|
225
|
+
[hashtable]$StyleSpec
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
$targetName = $StyleSpec.TargetStyleName
|
|
229
|
+
$builtinId = $null
|
|
230
|
+
if ($StyleSpec.ContainsKey("BuiltinId")) {
|
|
231
|
+
$builtinId = [int]$StyleSpec.BuiltinId
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if ($targetName) {
|
|
235
|
+
try {
|
|
236
|
+
return $Document.Styles.Item($targetName)
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if ($null -ne $builtinId) {
|
|
243
|
+
try {
|
|
244
|
+
return $Document.Styles.Item($builtinId)
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (-not $targetName) {
|
|
251
|
+
throw "Style '$LogicalName' needs TargetStyleName when no built-in style is available."
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return $Document.Styles.Add($targetName, 1)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function Apply-StyleSpec {
|
|
258
|
+
param(
|
|
259
|
+
$Word,
|
|
260
|
+
$Style,
|
|
261
|
+
[hashtable]$StyleSpec
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
if ($StyleSpec.ContainsKey("FontName")) {
|
|
265
|
+
$Style.Font.Name = [string]$StyleSpec.FontName
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if ($StyleSpec.ContainsKey("EastAsiaFontName")) {
|
|
269
|
+
try {
|
|
270
|
+
$Style.Font.NameFarEast = [string]$StyleSpec.EastAsiaFontName
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if ($StyleSpec.ContainsKey("Size")) {
|
|
277
|
+
$Style.Font.Size = [double]$StyleSpec.Size
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if ($StyleSpec.ContainsKey("Bold")) {
|
|
281
|
+
$Style.Font.Bold = Get-ComBool -Value $StyleSpec.Bold
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if ($StyleSpec.ContainsKey("Italic")) {
|
|
285
|
+
$Style.Font.Italic = Get-ComBool -Value $StyleSpec.Italic
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if ($StyleSpec.ContainsKey("Alignment")) {
|
|
289
|
+
$Style.ParagraphFormat.Alignment = Get-AlignmentValue -Value $StyleSpec.Alignment
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if ($StyleSpec.ContainsKey("FirstLineIndentCm")) {
|
|
293
|
+
$Style.ParagraphFormat.FirstLineIndent = $Word.CentimetersToPoints([double]$StyleSpec.FirstLineIndentCm)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if ($StyleSpec.ContainsKey("LeftIndentCm")) {
|
|
297
|
+
$Style.ParagraphFormat.LeftIndent = $Word.CentimetersToPoints([double]$StyleSpec.LeftIndentCm)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if ($StyleSpec.ContainsKey("RightIndentCm")) {
|
|
301
|
+
$Style.ParagraphFormat.RightIndent = $Word.CentimetersToPoints([double]$StyleSpec.RightIndentCm)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if ($StyleSpec.ContainsKey("SpaceBeforePt")) {
|
|
305
|
+
$Style.ParagraphFormat.SpaceBefore = [double]$StyleSpec.SpaceBeforePt
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if ($StyleSpec.ContainsKey("SpaceAfterPt")) {
|
|
309
|
+
$Style.ParagraphFormat.SpaceAfter = [double]$StyleSpec.SpaceAfterPt
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if ($StyleSpec.ContainsKey("LineSpacingMultiple")) {
|
|
313
|
+
$Style.ParagraphFormat.LineSpacingRule = 5
|
|
314
|
+
$Style.ParagraphFormat.LineSpacing = $Word.LinesToPoints([double]$StyleSpec.LineSpacingMultiple)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if ($StyleSpec.ContainsKey("KeepTogether")) {
|
|
318
|
+
$Style.ParagraphFormat.KeepTogether = Get-ComBool -Value $StyleSpec.KeepTogether
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if ($StyleSpec.ContainsKey("KeepWithNext")) {
|
|
322
|
+
$Style.ParagraphFormat.KeepWithNext = Get-ComBool -Value $StyleSpec.KeepWithNext
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if ($StyleSpec.ContainsKey("OutlineLevel")) {
|
|
326
|
+
$Style.ParagraphFormat.OutlineLevel = [int]$StyleSpec.OutlineLevel
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function Get-ParagraphText {
|
|
331
|
+
param($Paragraph)
|
|
332
|
+
return ($Paragraph.Range.Text -replace "[`r`n]+$", "").Trim()
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function Get-StyleName {
|
|
336
|
+
param($Paragraph)
|
|
337
|
+
|
|
338
|
+
try {
|
|
339
|
+
return [string]$Paragraph.Range.Style.NameLocal
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
try {
|
|
343
|
+
return [string]$Paragraph.Range.Style.Name
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
return ""
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function Get-ParagraphKind {
|
|
352
|
+
param(
|
|
353
|
+
[string]$Text,
|
|
354
|
+
[string]$CurrentStyleName,
|
|
355
|
+
[hashtable]$Config
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
if ([string]::IsNullOrWhiteSpace($Text)) {
|
|
359
|
+
return $null
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
foreach ($kind in @("FigureCaption", "TableCaption", "Heading1", "Heading2", "Heading3")) {
|
|
363
|
+
if ($Config.styleHints.ContainsKey($kind) -and $CurrentStyleName -match $Config.styleHints[$kind]) {
|
|
364
|
+
return $kind
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
foreach ($kind in @("FigureCaption", "TableCaption", "Heading3", "Heading2", "Heading1")) {
|
|
369
|
+
if ($Config.patterns.ContainsKey($kind) -and $Text -match $Config.patterns[$kind]) {
|
|
370
|
+
return $kind
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if ($Config.styleHints.ContainsKey("Body") -and $CurrentStyleName -match $Config.styleHints.Body) {
|
|
375
|
+
return "Body"
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return "Body"
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
$resolvedInput = (Resolve-Path -LiteralPath $InputPath).Path
|
|
382
|
+
if (-not $InPlace -and -not $OutputPath) {
|
|
383
|
+
$directory = Split-Path -Parent $resolvedInput
|
|
384
|
+
$leaf = Split-Path -LeafBase $resolvedInput
|
|
385
|
+
$extension = [System.IO.Path]::GetExtension($resolvedInput)
|
|
386
|
+
$OutputPath = Join-Path $directory "$leaf.normalized$extension"
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
$config = Get-DefaultConfig
|
|
390
|
+
if ($ConfigPath) {
|
|
391
|
+
$overrideObject = Get-Content -LiteralPath $ConfigPath -Raw -Encoding UTF8 | ConvertFrom-Json
|
|
392
|
+
$overrideConfig = ConvertTo-Hashtable -Value $overrideObject
|
|
393
|
+
Merge-Hashtable -Base $config -Override $overrideConfig
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
$word = $null
|
|
397
|
+
$document = $null
|
|
398
|
+
$styles = @{}
|
|
399
|
+
$stats = @{
|
|
400
|
+
Body = 0
|
|
401
|
+
Heading1 = 0
|
|
402
|
+
Heading2 = 0
|
|
403
|
+
Heading3 = 0
|
|
404
|
+
FigureCaption = 0
|
|
405
|
+
TableCaption = 0
|
|
406
|
+
}
|
|
407
|
+
$previewChanges = New-Object System.Collections.Generic.List[object]
|
|
408
|
+
|
|
409
|
+
try {
|
|
410
|
+
$word = New-Object -ComObject Word.Application
|
|
411
|
+
$word.Visible = [bool]$Visible
|
|
412
|
+
$word.DisplayAlerts = 0
|
|
413
|
+
|
|
414
|
+
$document = $word.Documents.Open($resolvedInput, $false, $false)
|
|
415
|
+
|
|
416
|
+
foreach ($logicalName in $config.styles.Keys) {
|
|
417
|
+
$style = Resolve-Style -Document $document -LogicalName $logicalName -StyleSpec $config.styles[$logicalName]
|
|
418
|
+
Apply-StyleSpec -Word $word -Style $style -StyleSpec $config.styles[$logicalName]
|
|
419
|
+
$styles[$logicalName] = $style
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
foreach ($paragraph in $document.Paragraphs) {
|
|
423
|
+
$text = Get-ParagraphText -Paragraph $paragraph
|
|
424
|
+
if ([string]::IsNullOrWhiteSpace($text)) {
|
|
425
|
+
continue
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
$currentStyleName = Get-StyleName -Paragraph $paragraph
|
|
429
|
+
$kind = Get-ParagraphKind -Text $text -CurrentStyleName $currentStyleName -Config $config
|
|
430
|
+
if (-not $kind) {
|
|
431
|
+
continue
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
$targetStyle = $styles[$kind]
|
|
435
|
+
$targetStyleName = ""
|
|
436
|
+
try {
|
|
437
|
+
$targetStyleName = [string]$targetStyle.NameLocal
|
|
438
|
+
}
|
|
439
|
+
catch {
|
|
440
|
+
try {
|
|
441
|
+
$targetStyleName = [string]$targetStyle.Name
|
|
442
|
+
}
|
|
443
|
+
catch {
|
|
444
|
+
$targetStyleName = $kind
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
if ($currentStyleName -ne $targetStyleName) {
|
|
449
|
+
$previewChanges.Add([pscustomobject]@{
|
|
450
|
+
kind = $kind
|
|
451
|
+
fromStyle = $currentStyleName
|
|
452
|
+
toStyle = $targetStyleName
|
|
453
|
+
text = if ($text.Length -gt 80) { $text.Substring(0, 80) } else { $text }
|
|
454
|
+
}) | Out-Null
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (-not $AuditOnly) {
|
|
458
|
+
$paragraph.Range.Style = $targetStyle
|
|
459
|
+
$stats[$kind]++
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if ($AuditOnly) {
|
|
464
|
+
$finalPath = $resolvedInput
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
if ($InPlace) {
|
|
468
|
+
$document.Save()
|
|
469
|
+
$finalPath = $resolvedInput
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
$resolvedOutput = [System.IO.Path]::GetFullPath($OutputPath)
|
|
473
|
+
$document.SaveAs([ref]$resolvedOutput)
|
|
474
|
+
$finalPath = $resolvedOutput
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
[pscustomobject]@{
|
|
479
|
+
input = $resolvedInput
|
|
480
|
+
output = $finalPath
|
|
481
|
+
auditOnly = [bool]$AuditOnly
|
|
482
|
+
stats = [pscustomobject]$stats
|
|
483
|
+
previewChanges = $previewChanges
|
|
484
|
+
} | ConvertTo-Json -Depth 5
|
|
485
|
+
}
|
|
486
|
+
finally {
|
|
487
|
+
if ($document) {
|
|
488
|
+
$document.Close([ref]0)
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if ($word) {
|
|
492
|
+
$word.Quit()
|
|
493
|
+
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($word)
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
[gc]::Collect()
|
|
497
|
+
[gc]::WaitForPendingFinalizers()
|
|
498
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
param(
|
|
2
|
+
[Parameter(Mandatory = $true)]
|
|
3
|
+
[string]$InputPath,
|
|
4
|
+
|
|
5
|
+
[Parameter(Mandatory = $true)]
|
|
6
|
+
[string]$OutputPath,
|
|
7
|
+
|
|
8
|
+
[ValidateSet("svg", "png", "pdf")]
|
|
9
|
+
[string]$Format = "svg",
|
|
10
|
+
|
|
11
|
+
[ValidateSet("default", "neutral", "forest", "dark", "base")]
|
|
12
|
+
[string]$Theme = "base",
|
|
13
|
+
|
|
14
|
+
[int]$Width = 1600,
|
|
15
|
+
|
|
16
|
+
[int]$Height = 1200,
|
|
17
|
+
|
|
18
|
+
[double]$Scale = 2.0,
|
|
19
|
+
|
|
20
|
+
[string]$BackgroundColor = "white",
|
|
21
|
+
|
|
22
|
+
[string]$ConfigPath,
|
|
23
|
+
|
|
24
|
+
[switch]$Quiet
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
Set-StrictMode -Version Latest
|
|
28
|
+
$ErrorActionPreference = "Stop"
|
|
29
|
+
|
|
30
|
+
function New-DefaultConfigFile {
|
|
31
|
+
param([string]$Path)
|
|
32
|
+
|
|
33
|
+
$config = @'
|
|
34
|
+
{
|
|
35
|
+
"theme": "base",
|
|
36
|
+
"themeVariables": {
|
|
37
|
+
"fontFamily": "Times New Roman",
|
|
38
|
+
"fontSize": "18px",
|
|
39
|
+
"primaryColor": "#ffffff",
|
|
40
|
+
"primaryTextColor": "#111827",
|
|
41
|
+
"primaryBorderColor": "#111827",
|
|
42
|
+
"lineColor": "#374151",
|
|
43
|
+
"secondaryColor": "#f8fafc",
|
|
44
|
+
"tertiaryColor": "#ffffff"
|
|
45
|
+
},
|
|
46
|
+
"flowchart": {
|
|
47
|
+
"htmlLabels": false,
|
|
48
|
+
"curve": "linear"
|
|
49
|
+
},
|
|
50
|
+
"sequence": {
|
|
51
|
+
"useMaxWidth": false
|
|
52
|
+
},
|
|
53
|
+
"er": {
|
|
54
|
+
"layoutDirection": "TB"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
'@
|
|
58
|
+
$encoding = New-Object System.Text.UTF8Encoding($false)
|
|
59
|
+
[System.IO.File]::WriteAllText($Path, $config, $encoding)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function Resolve-MermaidRunner {
|
|
63
|
+
$mmdc = Get-Command mmdc -ErrorAction SilentlyContinue
|
|
64
|
+
if ($mmdc) {
|
|
65
|
+
return @{
|
|
66
|
+
Command = $mmdc.Source
|
|
67
|
+
PrefixArgs = @()
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
$npx = Get-Command npx.cmd -ErrorAction SilentlyContinue
|
|
72
|
+
if (-not $npx) {
|
|
73
|
+
$npx = Get-Command npx -ErrorAction SilentlyContinue
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if ($npx) {
|
|
77
|
+
return @{
|
|
78
|
+
Command = $npx.Source
|
|
79
|
+
PrefixArgs = @("-y", "@mermaid-js/mermaid-cli")
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
throw "Neither mmdc nor npx was found. Install Node.js and mermaid-cli."
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
$resolvedInput = (Resolve-Path -LiteralPath $InputPath).Path
|
|
87
|
+
$resolvedOutput = [System.IO.Path]::GetFullPath($OutputPath)
|
|
88
|
+
$outputDir = Split-Path -Parent $resolvedOutput
|
|
89
|
+
|
|
90
|
+
if (-not (Test-Path -LiteralPath $outputDir)) {
|
|
91
|
+
New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
$effectiveConfigPath = $ConfigPath
|
|
95
|
+
$temporaryConfig = $null
|
|
96
|
+
|
|
97
|
+
if (-not $effectiveConfigPath) {
|
|
98
|
+
$temporaryConfig = Join-Path ([System.IO.Path]::GetTempPath()) ("mermaid-config-" + [guid]::NewGuid().ToString("N") + ".json")
|
|
99
|
+
New-DefaultConfigFile -Path $temporaryConfig
|
|
100
|
+
$effectiveConfigPath = $temporaryConfig
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
$effectiveConfigPath = (Resolve-Path -LiteralPath $effectiveConfigPath).Path
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
$runner = Resolve-MermaidRunner
|
|
107
|
+
$arguments = @()
|
|
108
|
+
$arguments += $runner.PrefixArgs
|
|
109
|
+
$arguments += @(
|
|
110
|
+
"-i", $resolvedInput,
|
|
111
|
+
"-o", $resolvedOutput,
|
|
112
|
+
"-c", $effectiveConfigPath,
|
|
113
|
+
"-b", $BackgroundColor,
|
|
114
|
+
"-w", "$Width",
|
|
115
|
+
"-H", "$Height",
|
|
116
|
+
"-s", "$Scale"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
if ($Theme -ne "base") {
|
|
120
|
+
$arguments += @("-t", $Theme)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if ($Quiet) {
|
|
124
|
+
$arguments += "-q"
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
& $runner.Command @arguments
|
|
129
|
+
if ($LASTEXITCODE -ne 0) {
|
|
130
|
+
throw "Mermaid rendering failed with exit code $LASTEXITCODE."
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
[pscustomobject]@{
|
|
134
|
+
input = $resolvedInput
|
|
135
|
+
output = $resolvedOutput
|
|
136
|
+
format = $Format
|
|
137
|
+
theme = $Theme
|
|
138
|
+
width = $Width
|
|
139
|
+
height = $Height
|
|
140
|
+
scale = $Scale
|
|
141
|
+
command = $runner.Command
|
|
142
|
+
} | ConvertTo-Json -Depth 4
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
if ($temporaryConfig -and (Test-Path -LiteralPath $temporaryConfig)) {
|
|
146
|
+
Remove-Item -LiteralPath $temporaryConfig -Force
|
|
147
|
+
}
|
|
148
|
+
}
|