@galaxy-tool-util/cli 0.1.0 → 0.4.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 (121) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bin/galaxy-tool-cache.js +15 -0
  3. package/dist/bin/galaxy-tool-cache.js.map +1 -1
  4. package/dist/bin/gxwf.d.ts +3 -0
  5. package/dist/bin/gxwf.d.ts.map +1 -0
  6. package/dist/bin/gxwf.js +150 -0
  7. package/dist/bin/gxwf.js.map +1 -0
  8. package/dist/commands/add.js +2 -2
  9. package/dist/commands/add.js.map +1 -1
  10. package/dist/commands/clean-tree.d.ts +9 -0
  11. package/dist/commands/clean-tree.d.ts.map +1 -0
  12. package/dist/commands/clean-tree.js +69 -0
  13. package/dist/commands/clean-tree.js.map +1 -0
  14. package/dist/commands/clean.d.ts +10 -0
  15. package/dist/commands/clean.d.ts.map +1 -0
  16. package/dist/commands/clean.js +48 -0
  17. package/dist/commands/clean.js.map +1 -0
  18. package/dist/commands/clear.js +4 -4
  19. package/dist/commands/clear.js.map +1 -1
  20. package/dist/commands/convert-tree.d.ts +32 -0
  21. package/dist/commands/convert-tree.d.ts.map +1 -0
  22. package/dist/commands/convert-tree.js +229 -0
  23. package/dist/commands/convert-tree.js.map +1 -0
  24. package/dist/commands/convert.d.ts +13 -0
  25. package/dist/commands/convert.d.ts.map +1 -0
  26. package/dist/commands/convert.js +151 -0
  27. package/dist/commands/convert.js.map +1 -0
  28. package/dist/commands/info.d.ts.map +1 -1
  29. package/dist/commands/info.js +5 -4
  30. package/dist/commands/info.js.map +1 -1
  31. package/dist/commands/lint-tree.d.ts +11 -0
  32. package/dist/commands/lint-tree.d.ts.map +1 -0
  33. package/dist/commands/lint-tree.js +104 -0
  34. package/dist/commands/lint-tree.js.map +1 -0
  35. package/dist/commands/lint.d.ts +34 -0
  36. package/dist/commands/lint.d.ts.map +1 -0
  37. package/dist/commands/lint.js +195 -0
  38. package/dist/commands/lint.js.map +1 -0
  39. package/dist/commands/list.js +3 -3
  40. package/dist/commands/list.js.map +1 -1
  41. package/dist/commands/populate-workflow.d.ts +6 -0
  42. package/dist/commands/populate-workflow.d.ts.map +1 -0
  43. package/dist/commands/populate-workflow.js +55 -0
  44. package/dist/commands/populate-workflow.js.map +1 -0
  45. package/dist/commands/render-results.d.ts +11 -0
  46. package/dist/commands/render-results.d.ts.map +1 -0
  47. package/dist/commands/render-results.js +27 -0
  48. package/dist/commands/render-results.js.map +1 -0
  49. package/dist/commands/report-output.d.ts +34 -0
  50. package/dist/commands/report-output.d.ts.map +1 -0
  51. package/dist/commands/report-output.js +70 -0
  52. package/dist/commands/report-output.js.map +1 -0
  53. package/dist/commands/resolve-tool.js +1 -1
  54. package/dist/commands/resolve-tool.js.map +1 -1
  55. package/dist/commands/roundtrip-tree.d.ts +15 -0
  56. package/dist/commands/roundtrip-tree.d.ts.map +1 -0
  57. package/dist/commands/roundtrip-tree.js +178 -0
  58. package/dist/commands/roundtrip-tree.js.map +1 -0
  59. package/dist/commands/roundtrip.d.ts +31 -0
  60. package/dist/commands/roundtrip.d.ts.map +1 -0
  61. package/dist/commands/roundtrip.js +144 -0
  62. package/dist/commands/roundtrip.js.map +1 -0
  63. package/dist/commands/schema.js +2 -2
  64. package/dist/commands/schema.js.map +1 -1
  65. package/dist/commands/stateful-tool-inputs.d.ts +33 -0
  66. package/dist/commands/stateful-tool-inputs.d.ts.map +1 -0
  67. package/dist/commands/stateful-tool-inputs.js +73 -0
  68. package/dist/commands/stateful-tool-inputs.js.map +1 -0
  69. package/dist/commands/strict-options.d.ts +22 -0
  70. package/dist/commands/strict-options.d.ts.map +1 -0
  71. package/dist/commands/strict-options.js +18 -0
  72. package/dist/commands/strict-options.js.map +1 -0
  73. package/dist/commands/structural-schema.d.ts +6 -0
  74. package/dist/commands/structural-schema.d.ts.map +1 -0
  75. package/dist/commands/structural-schema.js +31 -0
  76. package/dist/commands/structural-schema.js.map +1 -0
  77. package/dist/commands/tree.d.ts +45 -0
  78. package/dist/commands/tree.d.ts.map +1 -0
  79. package/dist/commands/tree.js +155 -0
  80. package/dist/commands/tree.js.map +1 -0
  81. package/dist/commands/validate-tests-tree.d.ts +36 -0
  82. package/dist/commands/validate-tests-tree.d.ts.map +1 -0
  83. package/dist/commands/validate-tests-tree.js +191 -0
  84. package/dist/commands/validate-tests-tree.js.map +1 -0
  85. package/dist/commands/validate-tests.d.ts +21 -0
  86. package/dist/commands/validate-tests.d.ts.map +1 -0
  87. package/dist/commands/validate-tests.js +83 -0
  88. package/dist/commands/validate-tests.js.map +1 -0
  89. package/dist/commands/validate-tree.d.ts +12 -0
  90. package/dist/commands/validate-tree.d.ts.map +1 -0
  91. package/dist/commands/validate-tree.js +124 -0
  92. package/dist/commands/validate-tree.js.map +1 -0
  93. package/dist/commands/validate-workflow-json-schema.d.ts +8 -2
  94. package/dist/commands/validate-workflow-json-schema.d.ts.map +1 -1
  95. package/dist/commands/validate-workflow-json-schema.js +129 -50
  96. package/dist/commands/validate-workflow-json-schema.js.map +1 -1
  97. package/dist/commands/validate-workflow.d.ts +18 -10
  98. package/dist/commands/validate-workflow.d.ts.map +1 -1
  99. package/dist/commands/validate-workflow.js +215 -88
  100. package/dist/commands/validate-workflow.js.map +1 -1
  101. package/dist/commands/workflow-io.d.ts +7 -0
  102. package/dist/commands/workflow-io.d.ts.map +1 -0
  103. package/dist/commands/workflow-io.js +38 -0
  104. package/dist/commands/workflow-io.js.map +1 -0
  105. package/dist/index.d.ts +41 -0
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +36 -0
  108. package/dist/index.js.map +1 -1
  109. package/dist/workflow/_templates-bundled.d.ts +2 -0
  110. package/dist/workflow/_templates-bundled.d.ts.map +1 -0
  111. package/dist/workflow/_templates-bundled.js +324 -0
  112. package/dist/workflow/_templates-bundled.js.map +1 -0
  113. package/dist/workflow/report-templates.d.ts +13 -0
  114. package/dist/workflow/report-templates.d.ts.map +1 -0
  115. package/dist/workflow/report-templates.js +91 -0
  116. package/dist/workflow/report-templates.js.map +1 -0
  117. package/package.json +18 -16
  118. package/dist/bin/galaxy-workflow-validate.d.ts +0 -3
  119. package/dist/bin/galaxy-workflow-validate.d.ts.map +0 -1
  120. package/dist/bin/galaxy-workflow-validate.js +0 -17
  121. package/dist/bin/galaxy-workflow-validate.js.map +0 -1
@@ -0,0 +1,324 @@
1
+ // AUTO-GENERATED by scripts/bundle-templates.mjs — do not edit.
2
+ export const BUNDLED_TEMPLATES = {
3
+ "_macros.md.j2": `{#-
4
+ Shared macros for workflow_state report templates.
5
+
6
+ IMPORTANT: every construct used here must also be valid in Nunjucks so
7
+ the TypeScript mirror can render identical markdown. That means: only
8
+ \`for\`, \`if\`, \`set\`, \`macro\`, \`import\`, \`include\`, and the shared-subset
9
+ filters (\`length\`, \`default\`, \`upper\`, \`lower\`, \`replace\`, \`join\`,
10
+ \`sort\`, \`selectattr\`). No custom filters, no globals.
11
+ -#}
12
+
13
+ {#-
14
+ status_badge(label)
15
+ Renders the summary-line badge shared across every report header.
16
+ -#}
17
+ {% macro status_badge(label) -%}
18
+ **Status:** {{ label }}
19
+ {%- endmacro %}
20
+
21
+ {#-
22
+ kv_summary(summary)
23
+ Render a dict-of-counts as \`\`key: value, key: value\`\` (insertion order
24
+ is preserved by Pydantic \`\`model_dump\`\`, so upstream models control
25
+ ordering). Used under the status badge in every report header.
26
+ -#}
27
+ {% macro kv_summary(summary) -%}
28
+ {% for key, value in summary.items() -%}
29
+ {{ key }}: {{ value }}{% if not loop.last %}, {% endif %}
30
+ {%- endfor %}
31
+ {%- endmacro %}
32
+
33
+ {#-
34
+ workflow_state_cells(r)
35
+ Renders the 5 trailing cells of a workflow table row — handling the
36
+ error / skipped / ok three-branch logic that every current
37
+ \`\`format_*_markdown\`\` reimplements. \`\`r\`\` is the json-dumped
38
+ workflow result dict.
39
+
40
+ Expected columns (Total | OK | Fail | Skip | Details). Callers provide
41
+ the leading \`\`| name\`\` cell themselves so they can choose how to label
42
+ it (basename, relative_path, etc.).
43
+ -#}
44
+ {% macro workflow_state_cells(r) -%}
45
+ {% if r.skipped_reason -%}
46
+ - | - | - | - | SKIPPED: {{ r.skipped_reason }}
47
+ {%- elif r.error -%}
48
+ - | - | - | - | ERROR: {{ r.error }}
49
+ {%- else -%}
50
+ {% set s = r.summary %}
51
+ {{ (r.results | length) }} | {{ s.ok }} | {{ s.fail }} | {{ s.skip }} |
52
+ {%- endif %}
53
+ {%- endmacro %}
54
+
55
+ {#-
56
+ failure_bullet(f)
57
+ Renders a single \`\`all_failures\`\` entry as a markdown bullet. The input
58
+ dict has keys \`\`workflow\`\`, \`\`step\`\`, \`\`tool_id\`\`, \`\`message\`\`.
59
+ -#}
60
+ {% macro failure_bullet(f) -%}
61
+ - **{{ f.workflow }}** Step {{ f.step }} ({{ f.tool_id }}): {{ f.message }}
62
+ {%- endmacro %}
63
+ `,
64
+ "clean_tree.md.j2": `{#-
65
+ Tree-level report for \`\`gxwf-state-clean\`\`.
66
+
67
+ Three sections: affected-workflows table, clean-workflows banner, and
68
+ per-workflow detail bullets. Uses \`\`selectattr("removed_keys")\`\` and
69
+ \`\`selectattr("total_removed")\`\` for filtering, \`\`loop.first\`\` to gate
70
+ the Per-Workflow Details header, and the \`\`steps_affected\`\` +
71
+ \`\`display_label\`\` computed fields landed in step 1.
72
+
73
+ Context:
74
+ report — TreeCleanReport as json-dumped dict (\`\`results\`\` → \`\`workflows\`\`)
75
+ meta — ignored here; kept for uniform signature
76
+ -#}
77
+ # Stale State Cleaning Report
78
+
79
+ Root: \`{{ report.root }}\`
80
+ Workflows: {{ report.workflows | length }} | {{ report.summary.total_keys }} stale key(s) across {{ report.summary.affected }} workflow(s)
81
+
82
+ {% if report.summary.affected > 0 or report.summary.errors > 0 %}
83
+ ## Affected Workflows
84
+
85
+ | Workflow | Steps Affected | Keys Removed | Details |
86
+ | --- | --- | --- | --- |
87
+ {% for r in report.workflows %}
88
+ {% if r.error %}
89
+ | {{ r.path }} | - | - | ERROR: {{ r.error }} |
90
+ {% elif r.total_removed > 0 %}
91
+ | {{ r.path }} | {{ r.steps_affected }} | {{ r.total_removed }} | {% for sr in r.results | selectattr("removed_keys") %}Step {{ sr.step }} ({{ sr.tool_id }}): {{ sr.removed_keys | join(", ") }}{% if not loop.last %}; {% endif %}{% endfor %} |
92
+ {% endif %}
93
+ {% endfor %}
94
+
95
+ {% endif %}
96
+ {% if report.summary.clean > 0 %}
97
+ ## Clean Workflows ({{ report.summary.clean }})
98
+
99
+ All other workflows have no stale keys.
100
+
101
+ {% endif %}
102
+ {% for r in report.workflows | selectattr("total_removed") %}
103
+ {% if loop.first %}
104
+ ## Per-Workflow Details
105
+
106
+ {% endif %}
107
+ ### {{ r.path }}
108
+ {% for sr in r.results | selectattr("removed_keys") %}
109
+ - Step {{ sr.step }} ({{ sr.display_label }}): Removed \`{{ sr.removed_keys | join("\`, \`") }}\`
110
+ {% endfor %}
111
+
112
+ {% endfor %}
113
+ `,
114
+ "connection_section.md.j2": `{#-
115
+ Connection validation section.
116
+
117
+ Ported verbatim from \`\`validate.format_connection_markdown\`\`. Standalone
118
+ renderer today; also an include target for \`\`validate_tree.md.j2\`\` when a
119
+ workflow carries a \`\`connection_report\`\`.
120
+
121
+ Context:
122
+ report — ConnectionValidationReport as json-dumped dict
123
+ -#}
124
+ {% set s = report.summary %}
125
+ {% set valid_label = "VALID" if report.valid else "INVALID" %}
126
+ ## Connection Validation
127
+
128
+ **Status:** {{ valid_label }}
129
+ **Connections:** {{ s.ok | default(0) }} OK, {{ s.invalid | default(0) }} INVALID, {{ s.skip | default(0) }} SKIP
130
+ {% if report.has_details %}
131
+
132
+ | Source | Target | Status | Mapping | Errors |
133
+ | --- | --- | --- | --- | --- |
134
+ {% for sr in report.step_results %}
135
+ {% for cr in sr.connections %}
136
+ {% set mapping_cell = cr.mapping if cr.mapping else "-" %}
137
+ {% set errors_cell = cr.errors | join("; ") if cr.errors else "-" %}
138
+ | {{ cr.source_step }}/{{ cr.source_output }} | {{ cr.target_step }}/{{ cr.target_input }} | {{ cr.status }} | {{ mapping_cell }} | {{ errors_cell }} |
139
+ {% endfor %}
140
+ {% for err in sr.errors %}
141
+ {% set step_label = (sr.step ~ " (" ~ sr.tool_id ~ ")") if sr.tool_id else sr.step %}
142
+ | - | {{ step_label }} | error | - | {{ err }} |
143
+ {% endfor %}
144
+ {% endfor %}
145
+ {% endif %}
146
+ `,
147
+ "export_tree.md.j2": `{#-
148
+ Tree-level report for \`\`gxwf-to-format2-stateful\`\`.
149
+
150
+ Pure port of \`\`export_format2._format_tree_markdown\`\`. Content improvements
151
+ (category grouping, per-tool fallback aggregation, skipped appendix) are
152
+ deferred to follow-up commits — per the plan, per-tool fallback aggregation
153
+ needs step-level \`\`tool_id\`\` plumbing that is out of scope here.
154
+
155
+ Context:
156
+ report — ExportTreeReport as json-dumped dict (\`\`results\`\` → \`\`workflows\`\`)
157
+ meta — ignored here; kept for uniform signature
158
+ -#}
159
+ # Export Report: {{ report.root }}
160
+
161
+ {% for r in report.workflows %}
162
+ {% if r.error %}
163
+ - **{{ r.path }}**: ERROR ({{ r.error }})
164
+ {% elif r.skipped_reason %}
165
+ - **{{ r.path }}**: SKIPPED ({{ r.skipped_reason }})
166
+ {% elif r.ok %}
167
+ - **{{ r.path }}**: OK ({{ r.steps_converted }} steps)
168
+ {% else %}
169
+ - **{{ r.path }}**: PARTIAL ({{ r.steps_fallback }} fallbacks)
170
+ {% endif %}
171
+ {% endfor %}
172
+
173
+ **Summary**: {{ report.summary.ok }} OK, {{ report.summary.fail }} errors, {{ report.summary.skipped }} skipped
174
+ `,
175
+ "lint_tree.md.j2": `{#-
176
+ Tree-level report for \`\`gxwf-lint-stateful\`\`.
177
+
178
+ Pure port of \`\`lint_stateful._format_lint_tree_markdown\`\` — single wide
179
+ table with one row per workflow. Uses the \`\`step_counts\`\` computed field
180
+ on \`\`LintWorkflowResult\`\` instead of re-looping \`\`results\`\`.
181
+
182
+ Content improvements deferred — surfacing lint messages and exit-code
183
+ meaning needs model + pipeline changes called out in the plan's
184
+ Step 1 "out of scope" list.
185
+
186
+ Context:
187
+ report — LintTreeReport as json-dumped dict (\`\`results\`\` → \`\`workflows\`\`)
188
+ meta — ignored here; kept for uniform signature
189
+ -#}
190
+ # Lint Report
191
+
192
+ Root: \`{{ report.root }}\`
193
+ Workflows: {{ report.workflows | length }} | Lint: {{ report.summary.lint_errors }} errors, {{ report.summary.lint_warnings }} warnings | State: {{ report.summary.state_ok }} OK, {{ report.summary.state_fail }} FAIL, {{ report.summary.state_skip }} SKIP
194
+
195
+ | Workflow | Lint Errors | Lint Warnings | State OK | State Fail | State Skip |
196
+ | --- | --- | --- | --- | --- | --- |
197
+ {% for r in report.workflows %}
198
+ {% if r.error %}
199
+ | {{ r.path }} | - | - | - | - | ERROR: {{ r.error }} |
200
+ {% elif r.skipped_reason %}
201
+ | {{ r.path }} | - | - | - | - | SKIPPED |
202
+ {% else %}
203
+ | {{ r.path }} | {{ r.lint_errors }} | {{ r.lint_warnings }} | {{ r.step_counts.ok }} | {{ r.step_counts.fail }} | {{ r.step_counts.skip }} |
204
+ {% endif %}
205
+ {% endfor %}
206
+ `,
207
+ "roundtrip_tree.md.j2": `{#-
208
+ Tree-level report for \`\`gxwf-roundtrip-validate-tree\`\`.
209
+
210
+ Pure port of \`\`roundtrip.format_roundtrip_markdown\`\`. Flat bullet list
211
+ per workflow with sub-bullets for conversion failures and error diffs.
212
+
213
+ Context:
214
+ report — RoundTripTreeReport as json-dumped dict (\`\`results\`\` → \`\`workflows\`\`)
215
+ meta — ignored here; kept for uniform signature
216
+ -#}
217
+ {% set s = report.summary %}
218
+ # Roundtrip Validation: {{ report.root }}
219
+
220
+ **{{ report.total }} workflows:** {{ s.clean }} clean, {{ s.benign_only }} benign, {{ s.fail }} fail, {{ s.error }} error, {{ s.skipped }} skipped
221
+
222
+ {% for r in report.workflows %}
223
+ {% set benign = r.benign_diffs | length %}
224
+ {% set error_count = r.error_diffs | length %}
225
+ {% set detail = "" %}
226
+ {% if benign %}{% set detail = detail ~ " (" ~ benign ~ " benign)" %}{% endif %}
227
+ {% if error_count %}{% set detail = detail ~ " (" ~ error_count ~ " errors)" %}{% endif %}
228
+ - **{{ r.workflow_path }}**: {{ r.status | upper }}{{ detail }}
229
+ {% for line in r.conversion_failure_lines %}
230
+ - {{ line }}
231
+ {% endfor %}
232
+ {% for d in r.error_diffs %}
233
+ - {{ d.step_path }}: {{ d.description }}
234
+ {% endfor %}
235
+ {% endfor %}
236
+ `,
237
+ "to_native_tree.md.j2": `{#-
238
+ Tree-level report for \`\`gxwf-to-native-stateful\`\`.
239
+
240
+ Pure port of \`\`to_native_stateful._format_tree_markdown\`\`. Structure is
241
+ identical to \`\`export_tree.md.j2\`\` — same four branches, only the H1 and
242
+ the OK-branch count field (\`\`steps_encoded\`\` vs \`\`steps_converted\`\`)
243
+ differ. Content improvements deferred, same rationale as export.
244
+
245
+ Context:
246
+ report — ToNativeTreeReport as json-dumped dict (\`\`results\`\` → \`\`workflows\`\`)
247
+ meta — ignored here; kept for uniform signature
248
+ -#}
249
+ # Conversion Report: {{ report.root }}
250
+
251
+ {% for r in report.workflows %}
252
+ {% if r.error %}
253
+ - **{{ r.path }}**: ERROR ({{ r.error }})
254
+ {% elif r.skipped_reason %}
255
+ - **{{ r.path }}**: SKIPPED ({{ r.skipped_reason }})
256
+ {% elif r.ok %}
257
+ - **{{ r.path }}**: OK ({{ r.steps_encoded }} steps)
258
+ {% else %}
259
+ - **{{ r.path }}**: PARTIAL ({{ r.steps_fallback }} fallbacks)
260
+ {% endif %}
261
+ {% endfor %}
262
+
263
+ **Summary**: {{ report.summary.ok }} OK, {{ report.summary.fail }} errors, {{ report.summary.skipped }} skipped
264
+ `,
265
+ "validate_tree.md.j2": `{#-
266
+ Tree-level report for \`\`gxwf-state-validate\`\`.
267
+
268
+ Pure port of \`\`validate.format_tree_markdown\`\`. Per-category tables with
269
+ a Details column showing failure counts, a Failure Details appendix using
270
+ \`\`report.all_failures\`\`, and per-workflow connection sections via
271
+ \`\`{% include "connection_section.md.j2" %}\`\`.
272
+
273
+ The \`\`workflow_state_cells\`\` macro is NOT used here because the validate
274
+ table has a 6th "Details" column whose content varies (failure count for
275
+ normal rows, SKIPPED/ERROR for exceptional rows) — inlining the 3-branch
276
+ logic keeps the template straightforward.
277
+
278
+ Context:
279
+ report — TreeValidationReport as json-dumped dict (\`\`results\`\` → \`\`workflows\`\`)
280
+ meta — ignored here; kept for uniform signature
281
+ -#}
282
+ {% import "_macros.md.j2" as m %}
283
+ {% set s = report.summary %}
284
+ # Workflow Validation Report
285
+
286
+ Root: \`{{ report.root }}\`
287
+ Workflows: {{ report.workflows | length }} | Steps: {{ s.ok }} OK, {{ s.fail }} FAIL, {{ s.skip }} SKIP, {{ s.error }} ERROR{% if s.skipped %} | {{ s.skipped }} workflow(s) skipped{% endif %}
288
+
289
+
290
+ {% for cat in report.categories %}
291
+ ## {{ cat.name }} ({{ cat.results | length }} workflows)
292
+
293
+ | Workflow | Steps | OK | Fail | Skip | Details |
294
+ | --- | --- | --- | --- | --- | --- |
295
+ {% for r in cat.results %}
296
+ {% if r.skipped_reason %}
297
+ | {{ r.name }} | - | - | - | - | SKIPPED: {{ r.skipped_reason }} |
298
+ {% elif r.error %}
299
+ | {{ r.name }} | - | - | - | - | ERROR: {{ r.error }} |
300
+ {% else %}
301
+ {% set fail_count = r.failures | length %}
302
+ | {{ r.name }} | {{ r.results | length }} | {{ r.summary.ok }} | {{ r.summary.fail }} | {{ r.summary.skip }} | {% if fail_count %}{{ fail_count }} failure(s){% endif %} |
303
+ {% endif %}
304
+ {% endfor %}
305
+
306
+ {% endfor %}
307
+ {% if report.all_failures %}
308
+ ## Failure Details
309
+
310
+ {% for f in report.all_failures %}
311
+ {{ m.failure_bullet(f) }}
312
+ {% endfor %}
313
+
314
+ {% endif %}
315
+ {% for r in report.workflows | selectattr("connection_report") %}
316
+ ## Connections: {{ r.path }}
317
+
318
+ {% set report = r.connection_report %}
319
+ {% include "connection_section.md.j2" %}
320
+
321
+ {% endfor %}
322
+ `,
323
+ };
324
+ //# sourceMappingURL=_templates-bundled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_templates-bundled.js","sourceRoot":"","sources":["../../src/workflow/_templates-bundled.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,MAAM,CAAC,MAAM,iBAAiB,GAA2B;IACvD,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4DlB;IACC,kBAAkB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDrB;IACC,0BAA0B,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgC7B;IACC,mBAAmB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BtB;IACC,iBAAiB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BpB;IACC,sBAAsB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BzB;IACC,sBAAsB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BzB;IACC,qBAAqB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyDxB;CACA,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface ReportMeta {
2
+ generated_at?: string;
3
+ tool_util_version?: string;
4
+ }
5
+ /**
6
+ * Render a Markdown report template by name.
7
+ *
8
+ * @param templateName - e.g. `"validate_tree.md.j2"`
9
+ * @param report - the tree report object (plain JSON-serialisable value)
10
+ * @param meta - optional metadata (generated_at, tool_util_version)
11
+ */
12
+ export declare function renderReport(templateName: string, report: unknown, meta?: ReportMeta): Promise<string>;
13
+ //# sourceMappingURL=report-templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-templates.d.ts","sourceRoot":"","sources":["../../src/workflow/report-templates.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,UAAU;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AA+DD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,OAAO,EACf,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CAAC,MAAM,CAAC,CAQjB"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Nunjucks renderer for workflow_state tree-level Markdown reports.
3
+ *
4
+ * Mirrors Python's `_report_templates.py`. Templates are the synced `.md.j2`
5
+ * files under `templates/reports/`. The Nunjucks environment aliases
6
+ * `_macros.md.j2` to the bundled macro file so body templates remain unchanged.
7
+ *
8
+ * Nunjucks/Jinja2 compatibility note:
9
+ * The synced `_macros.md.j2` uses `summary.items()` in `kv_summary`. This is
10
+ * valid Jinja2 but NOT Nunjucks — use plain `for k, v in obj` in Nunjucks.
11
+ * `kv_summary` is currently unused by all body templates, so this is latent.
12
+ * If a future sync adds a template that calls `kv_summary`, the `.items()` call
13
+ * will fail at render time. Fix in `_macros.md.j2` (TS-side) by using plain
14
+ * iteration; for the Python-side file the issue upstream with Python first.
15
+ */
16
+ import nunjucks from "nunjucks";
17
+ import { readFileSync } from "node:fs";
18
+ import { join, dirname } from "node:path";
19
+ import { fileURLToPath } from "node:url";
20
+ // ── Template loader ──────────────────────────────────────────────────
21
+ /**
22
+ * Custom Nunjucks loader that resolves templates from an in-memory map
23
+ * (bundled mode) with a filesystem fallback (dev/test mode).
24
+ */
25
+ class ReportTemplateLoader extends nunjucks.Loader {
26
+ async = false;
27
+ bundled;
28
+ fsDir;
29
+ constructor(bundled, fsDir) {
30
+ super();
31
+ this.bundled = bundled;
32
+ this.fsDir = fsDir;
33
+ }
34
+ getSource(name) {
35
+ if (this.bundled[name] !== undefined) {
36
+ return { src: this.bundled[name], path: name, noCache: false };
37
+ }
38
+ // Filesystem fallback (dev/test without a prior build)
39
+ const fsPath = join(this.fsDir, name);
40
+ const src = readFileSync(fsPath, "utf-8");
41
+ return { src, path: fsPath, noCache: true };
42
+ }
43
+ }
44
+ // ── Lazy singleton environment ───────────────────────────────────────
45
+ let _mdEnv;
46
+ /** Path to `templates/reports/` resolved relative to this source file. */
47
+ function getTemplatesDir() {
48
+ return join(dirname(fileURLToPath(import.meta.url)), "templates/reports");
49
+ }
50
+ async function loadBundled() {
51
+ try {
52
+ // Dynamic import so the module is optional (not present before `pnpm build`)
53
+ const mod = await import("./_templates-bundled.js");
54
+ return mod.BUNDLED_TEMPLATES;
55
+ }
56
+ catch {
57
+ return {};
58
+ }
59
+ }
60
+ async function getMdEnv() {
61
+ if (_mdEnv)
62
+ return _mdEnv;
63
+ const bundled = await loadBundled();
64
+ const loader = new ReportTemplateLoader(bundled, getTemplatesDir());
65
+ _mdEnv = new nunjucks.Environment(loader, {
66
+ autoescape: false,
67
+ trimBlocks: true,
68
+ lstripBlocks: true,
69
+ });
70
+ return _mdEnv;
71
+ }
72
+ // ── Public API ───────────────────────────────────────────────────────
73
+ /**
74
+ * Render a Markdown report template by name.
75
+ *
76
+ * @param templateName - e.g. `"validate_tree.md.j2"`
77
+ * @param report - the tree report object (plain JSON-serialisable value)
78
+ * @param meta - optional metadata (generated_at, tool_util_version)
79
+ */
80
+ export async function renderReport(templateName, report, meta) {
81
+ const env = await getMdEnv();
82
+ return new Promise((resolve, reject) => {
83
+ env.render(templateName, { report, meta }, (err, result) => {
84
+ if (err)
85
+ reject(err);
86
+ else
87
+ resolve(result ?? "");
88
+ });
89
+ });
90
+ }
91
+ //# sourceMappingURL=report-templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-templates.js","sourceRoot":"","sources":["../../src/workflow/report-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAOzC,wEAAwE;AAExE;;;GAGG;AACH,MAAM,oBAAqB,SAAQ,QAAQ,CAAC,MAAM;IAChD,KAAK,GAAG,KAAc,CAAC;IACf,OAAO,CAAyB;IAChC,KAAK,CAAS;IAEtB,YAAY,OAA+B,EAAE,KAAa;QACxD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACrC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACjE,CAAC;QACD,uDAAuD;QACvD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC9C,CAAC;CACF;AAED,wEAAwE;AAExE,IAAI,MAAwC,CAAC;AAE7C,0EAA0E;AAC1E,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;AAC5E,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,IAAI,CAAC;QACH,6EAA6E;QAC7E,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;QACpD,OAAO,GAAG,CAAC,iBAA2C,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ;IACrB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,oBAAoB,CAAC,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;IACpE,MAAM,GAAG,IAAI,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE;QACxC,UAAU,EAAE,KAAK;QACjB,UAAU,EAAE,IAAI;QAChB,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,wEAAwE;AAExE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,YAAoB,EACpB,MAAe,EACf,IAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC7B,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;YACzD,IAAI,GAAG;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;gBAChB,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@galaxy-tool-util/cli",
3
- "version": "0.1.0",
3
+ "version": "0.4.0",
4
4
  "description": "galaxy-tool-cache CLI — cache and inspect Galaxy tool metadata",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "galaxy-tool-cache": "dist/bin/galaxy-tool-cache.js",
8
- "galaxy-workflow-validate": "dist/bin/galaxy-workflow-validate.js"
8
+ "gxwf": "dist/bin/gxwf.js"
9
9
  },
10
10
  "exports": {
11
11
  ".": {
@@ -27,25 +27,27 @@
27
27
  "access": "public",
28
28
  "provenance": true
29
29
  },
30
- "scripts": {
31
- "build": "tsc",
32
- "typecheck": "tsc --noEmit",
33
- "test": "tsc --noEmit && vitest run",
34
- "test:watch": "vitest",
35
- "lint": "eslint src/ test/",
36
- "format": "prettier --check 'src/**/*.ts' 'test/**/*.ts'",
37
- "format-fix": "prettier --write 'src/**/*.ts' 'test/**/*.ts'"
38
- },
39
30
  "license": "MIT",
40
31
  "dependencies": {
41
- "@galaxy-tool-util/core": "workspace:*",
42
- "@galaxy-tool-util/schema": "workspace:*",
43
32
  "ajv": "^8.18.0",
44
33
  "commander": "^14.0.0",
45
34
  "effect": "^3.21.0",
46
- "yaml": "^2.8.3"
35
+ "nunjucks": "^3.2.4",
36
+ "yaml": "^2.8.3",
37
+ "@galaxy-tool-util/core": "0.3.0",
38
+ "@galaxy-tool-util/schema": "0.4.0"
47
39
  },
48
40
  "devDependencies": {
49
- "@types/node": "^25.5.0"
41
+ "@types/node": "^25.5.0",
42
+ "@types/nunjucks": "^3.2.6"
43
+ },
44
+ "scripts": {
45
+ "build": "node scripts/bundle-templates.mjs && tsc",
46
+ "typecheck": "tsc --noEmit",
47
+ "test": "tsc --noEmit && vitest run",
48
+ "test:watch": "vitest",
49
+ "lint": "eslint src/ test/",
50
+ "format": "prettier --check 'src/**/*.ts' 'test/**/*.ts'",
51
+ "format-fix": "prettier --write 'src/**/*.ts' 'test/**/*.ts'"
50
52
  }
51
- }
53
+ }
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=galaxy-workflow-validate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"galaxy-workflow-validate.d.ts","sourceRoot":"","sources":["../../src/bin/galaxy-workflow-validate.ts"],"names":[],"mappings":""}
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command } from "commander";
3
- import { runValidateWorkflow } from "../commands/validate-workflow.js";
4
- const program = new Command();
5
- program
6
- .name("galaxy-workflow-validate")
7
- .description("Validate Galaxy workflow files (structure + optional tool state)")
8
- .version("1.0.0")
9
- .argument("<file>", "Workflow file (.ga, .gxwf.yml)")
10
- .option("--format <fmt>", "Force format: native or format2 (auto-detected by default)")
11
- .option("--no-tool-state", "Skip tool state validation")
12
- .option("--cache-dir <dir>", "Tool cache directory")
13
- .option("--mode <mode>", "Validation backend: effect (default) or json-schema", "effect")
14
- .option("--tool-schema-dir <dir>", "Directory of pre-exported per-tool JSON Schemas (for offline json-schema mode)")
15
- .action(runValidateWorkflow);
16
- program.parse();
17
- //# sourceMappingURL=galaxy-workflow-validate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"galaxy-workflow-validate.js","sourceRoot":"","sources":["../../src/bin/galaxy-workflow-validate.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAEvE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,0BAA0B,CAAC;KAChC,WAAW,CAAC,kEAAkE,CAAC;KAC/E,OAAO,CAAC,OAAO,CAAC;KAChB,QAAQ,CAAC,QAAQ,EAAE,gCAAgC,CAAC;KACpD,MAAM,CAAC,gBAAgB,EAAE,4DAA4D,CAAC;KACtF,MAAM,CAAC,iBAAiB,EAAE,4BAA4B,CAAC;KACvD,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC;KACnD,MAAM,CAAC,eAAe,EAAE,qDAAqD,EAAE,QAAQ,CAAC;KACxF,MAAM,CAAC,yBAAyB,EAAE,gFAAgF,CAAC;KACnH,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAE/B,OAAO,CAAC,KAAK,EAAE,CAAC"}