@jspg-ai/coding-bb 0.0.1 → 0.0.2-beta.23

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 (145) hide show
  1. package/cbb/bin/cbb.js +6 -0
  2. package/cbb/bin/cbbm.js +6 -0
  3. package/cbb/dev-standards/rules/cbb-ai-behavior.md +103 -103
  4. package/cbb/dev-standards/rules/cbb-priority.md +55 -55
  5. package/cbb/lib/install/claude-code.js +2 -0
  6. package/cbb/lib/install/init.js +496 -290
  7. package/cbb/lib/install/opencode.js +31 -0
  8. package/cbb/lib/install/qoder.js +2 -0
  9. package/cbb/lib/install/workspaces.js +53 -13
  10. package/cbb/lib/openspec/index.js +3 -3
  11. package/cbb/lib/superpowers/index.js +1 -1
  12. package/cbb/lib/utils/check-update.js +16 -14
  13. package/cbb/lib/utils/gitignore.js +2 -1
  14. package/cbb/lib/utils/output.js +92 -4
  15. package/cbb/lib/utils/version.js +2 -31
  16. package/cbb/lib/wiki/cli.js +25 -25
  17. package/cbb/lib/wiki/index.js +16 -16
  18. package/cbb/tools/cbb-design-to-wiki/SKILL.md +14 -14
  19. package/cbb/tools/cbb-wiki-ops/SKILL.md +22 -22
  20. package/cbb/worktrees/_shared/scripts/find-target-worktree.js +2 -2
  21. package/cbb/worktrees/_shared/scripts/find-workspace-root.js +7 -7
  22. package/cbb/worktrees/_shared/scripts/push-core.js +18 -0
  23. package/cbb/worktrees/commands/{close.md → worktree-close.md} +8 -8
  24. package/cbb/worktrees/commands/{init.md → worktree-init.md} +9 -9
  25. package/cbb/worktrees/commands/{push.md → worktree-push.md} +3 -3
  26. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/SKILL.md +20 -20
  27. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/check-env.js +4 -4
  28. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/check-unarchived.js +1 -1
  29. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/delete-branches.js +3 -3
  30. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/discover-apps.js +6 -6
  31. package/cbb/worktrees/skills/{openspec-extend-worktree → cbb-worktree-close}/scripts/find-target-worktree.js +2 -2
  32. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-close}/scripts/find-workspace-root.js +7 -7
  33. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/remove-worktrees.js +4 -4
  34. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/safety-check.js +4 -4
  35. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/SKILL.md +81 -107
  36. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/auto-open.js +1 -1
  37. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/check-env-deep.js +4 -4
  38. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/check-env.js +6 -6
  39. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/check-repos.js +4 -4
  40. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/create-branches.js +4 -4
  41. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/create-worktrees.js +8 -7
  42. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-init}/scripts/find-workspace-root.js +7 -7
  43. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/install-ai.js +33 -33
  44. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/parse-config.js +7 -7
  45. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/push-branches.js +9 -7
  46. package/cbb/worktrees/skills/{openspec-extend-worktree → cbb-worktree-init}/scripts/push-core.js +18 -0
  47. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/sync-repos.js +10 -12
  48. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/update-gitignore.js +19 -6
  49. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-push}/SKILL.md +16 -16
  50. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-push}/scripts/commit-worktrees.js +2 -2
  51. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-push}/scripts/find-target-worktree.js +2 -2
  52. package/cbb/worktrees/skills/{openspec-extend-worktree → cbb-worktree-push}/scripts/find-workspace-root.js +7 -7
  53. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-push}/scripts/push-core.js +18 -0
  54. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-push}/scripts/push-worktrees.js +7 -5
  55. package/config/workspace-config.sample.json +18 -0
  56. package/config/workspaces.json +11 -6
  57. package/openspec/.version +6 -6
  58. package/openspec/commands/apply.md +7 -7
  59. package/openspec/commands/archive.md +7 -7
  60. package/openspec/commands/bulk-archive.md +7 -7
  61. package/openspec/commands/continue.md +7 -7
  62. package/openspec/commands/explore.md +7 -7
  63. package/openspec/commands/ff.md +7 -7
  64. package/openspec/commands/new.md +7 -7
  65. package/openspec/commands/onboard.md +7 -7
  66. package/openspec/commands/propose.md +7 -7
  67. package/openspec/commands/sync.md +7 -7
  68. package/openspec/commands/update.md +7 -7
  69. package/openspec/commands/verify.md +7 -7
  70. package/openspec/skills/openspec-apply-change/SKILL.md +187 -187
  71. package/openspec/skills/openspec-archive-change/SKILL.md +181 -181
  72. package/openspec/skills/openspec-bulk-archive-change/SKILL.md +338 -338
  73. package/openspec/skills/openspec-continue-change/SKILL.md +117 -117
  74. package/openspec/skills/openspec-explore/SKILL.md +342 -342
  75. package/openspec/skills/openspec-ff-change/SKILL.md +116 -116
  76. package/openspec/skills/openspec-new-change/SKILL.md +76 -76
  77. package/openspec/skills/openspec-onboard/SKILL.md +560 -560
  78. package/openspec/skills/openspec-propose/SKILL.md +162 -162
  79. package/openspec/skills/openspec-sync-specs/SKILL.md +261 -261
  80. package/openspec/skills/openspec-update-change/SKILL.md +90 -90
  81. package/openspec/skills/openspec-verify-change/SKILL.md +174 -174
  82. package/package.json +4 -3
  83. package/superpowers/.version +6 -6
  84. package/superpowers/skills/brainstorming/SKILL.md +250 -250
  85. package/superpowers/skills/brainstorming/scripts/helper.js +167 -167
  86. package/superpowers/skills/brainstorming/scripts/start-server.sh +209 -209
  87. package/superpowers/skills/brainstorming/scripts/stop-server.sh +120 -120
  88. package/superpowers/skills/brainstorming/spec-document-reviewer-prompt.md +49 -49
  89. package/superpowers/skills/brainstorming/visual-companion.md +299 -299
  90. package/superpowers/skills/dispatching-parallel-agents/SKILL.md +167 -167
  91. package/superpowers/skills/executing-plans/SKILL.md +64 -64
  92. package/superpowers/skills/finishing-a-development-branch/SKILL.md +225 -225
  93. package/superpowers/skills/receiving-code-review/SKILL.md +205 -205
  94. package/superpowers/skills/requesting-code-review/SKILL.md +95 -95
  95. package/superpowers/skills/requesting-code-review/code-reviewer.md +181 -181
  96. package/superpowers/skills/subagent-driven-development/SKILL.md +568 -568
  97. package/superpowers/skills/subagent-driven-development/implementer-prompt.md +154 -154
  98. package/superpowers/skills/subagent-driven-development/re-review-prompt.md +115 -115
  99. package/superpowers/skills/subagent-driven-development/task-reviewer-prompt.md +207 -207
  100. package/superpowers/skills/systematic-debugging/CREATION-LOG.md +119 -119
  101. package/superpowers/skills/systematic-debugging/SKILL.md +283 -283
  102. package/superpowers/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
  103. package/superpowers/skills/systematic-debugging/condition-based-waiting.md +115 -115
  104. package/superpowers/skills/systematic-debugging/defense-in-depth.md +122 -122
  105. package/superpowers/skills/systematic-debugging/find-polluter.sh +72 -72
  106. package/superpowers/skills/systematic-debugging/root-cause-tracing.md +169 -169
  107. package/superpowers/skills/systematic-debugging/test-academic.md +14 -14
  108. package/superpowers/skills/systematic-debugging/test-pressure-1.md +58 -58
  109. package/superpowers/skills/systematic-debugging/test-pressure-2.md +68 -68
  110. package/superpowers/skills/systematic-debugging/test-pressure-3.md +69 -69
  111. package/superpowers/skills/test-driven-development/SKILL.md +320 -320
  112. package/superpowers/skills/test-driven-development/writing-good-tests.md +198 -198
  113. package/superpowers/skills/using-git-worktrees/SKILL.md +167 -167
  114. package/superpowers/skills/using-superpowers/SKILL.md +63 -63
  115. package/superpowers/skills/using-superpowers/references/antigravity-tools.md +23 -23
  116. package/superpowers/skills/using-superpowers/references/codex-tools.md +108 -108
  117. package/superpowers/skills/using-superpowers/references/gemini-tools.md +63 -63
  118. package/superpowers/skills/using-superpowers/references/hermes-tools.md +56 -56
  119. package/superpowers/skills/using-superpowers/references/pi-tools.md +16 -16
  120. package/superpowers/skills/verification-before-completion/SKILL.md +120 -120
  121. package/superpowers/skills/writing-plans/SKILL.md +171 -171
  122. package/superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +49 -49
  123. package/superpowers/skills/writing-skills/SKILL.md +679 -679
  124. package/superpowers/skills/writing-skills/anthropic-best-practices.md +1150 -1150
  125. package/superpowers/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -189
  126. package/superpowers/skills/writing-skills/persuasion-principles.md +187 -187
  127. package/superpowers/skills/writing-skills/render-graphs.js +169 -169
  128. package/superpowers/skills/writing-skills/testing-skills-with-subagents.md +384 -384
  129. package/cbb/worktrees/commands/extend.md +0 -65
  130. package/cbb/worktrees/skills/openspec-close-worktree/scripts/find-target-worktree.js +0 -96
  131. package/cbb/worktrees/skills/openspec-extend-worktree/SKILL.md +0 -390
  132. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/check-env.js +0 -95
  133. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/check-repos.js +0 -98
  134. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/create-branches-and-worktrees.js +0 -135
  135. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/install-ai.js +0 -150
  136. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/list-available-apps.js +0 -88
  137. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/sync-repos.js +0 -93
  138. package/cbb/worktrees/skills/openspec-init-worktree/scripts/find-workspace-root.js +0 -67
  139. package/cbb/worktrees/skills/openspec-init-worktree/scripts/generate-app-options.js +0 -93
  140. package/cbb/worktrees/skills/openspec-init-worktree/scripts/push-core.js +0 -136
  141. package/cbb/worktrees/skills/openspec-push-worktrees/scripts/silence-popup.js +0 -23
  142. package/config/config.sample.json +0 -16
  143. /package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/silence-popup.js +0 -0
  144. /package/cbb/worktrees/skills/{openspec-extend-worktree → cbb-worktree-init}/scripts/silence-popup.js +0 -0
  145. /package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-push}/scripts/silence-popup.js +0 -0
@@ -1,169 +1,169 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Render graphviz diagrams from a skill's SKILL.md to SVG files.
5
- *
6
- * Usage:
7
- * ./render-graphs.js <skill-directory> # Render each diagram separately
8
- * ./render-graphs.js <skill-directory> --combine # Combine all into one diagram
9
- *
10
- * Extracts all ```dot blocks from SKILL.md and renders to SVG.
11
- * Useful for helping your human partner visualize the process flows.
12
- *
13
- * Requires: graphviz (dot) installed on system
14
- */
15
-
16
- import * as fs from 'fs';
17
- import * as path from 'path';
18
- import { execFileSync } from 'child_process';
19
-
20
- function extractDotBlocks(markdown) {
21
- const blocks = [];
22
- const regex = /```dot\n([\s\S]*?)```/g;
23
- let match;
24
-
25
- while ((match = regex.exec(markdown)) !== null) {
26
- const content = match[1].trim();
27
-
28
- // Extract digraph name
29
- const nameMatch = content.match(/digraph\s+(\w+)/);
30
- const name = nameMatch ? nameMatch[1] : `graph_${blocks.length + 1}`;
31
-
32
- blocks.push({ name, content });
33
- }
34
-
35
- return blocks;
36
- }
37
-
38
- function extractGraphBody(dotContent) {
39
- // Extract just the body (nodes and edges) from a digraph
40
- const match = dotContent.match(/digraph\s+\w+\s*\{([\s\S]*)\}/);
41
- if (!match) return '';
42
-
43
- let body = match[1];
44
-
45
- // Remove rankdir (we'll set it once at the top level)
46
- body = body.replace(/^\s*rankdir\s*=\s*\w+\s*;?\s*$/gm, '');
47
-
48
- return body.trim();
49
- }
50
-
51
- function combineGraphs(blocks, skillName) {
52
- const bodies = blocks.map((block, i) => {
53
- const body = extractGraphBody(block.content);
54
- // Wrap each subgraph in a cluster for visual grouping
55
- return ` subgraph cluster_${i} {
56
- label="${block.name}";
57
- ${body.split('\n').map(line => ' ' + line).join('\n')}
58
- }`;
59
- });
60
-
61
- return `digraph ${skillName}_combined {
62
- rankdir=TB;
63
- compound=true;
64
- newrank=true;
65
-
66
- ${bodies.join('\n\n')}
67
- }`;
68
- }
69
-
70
- function renderToSvg(dotContent) {
71
- try {
72
- return execFileSync('dot', ['-Tsvg'], {
73
- input: dotContent,
74
- encoding: 'utf-8',
75
- maxBuffer: 10 * 1024 * 1024
76
- });
77
- } catch (err) {
78
- console.error('Error running dot:', err.message);
79
- if (err.stderr) console.error(err.stderr.toString());
80
- return null;
81
- }
82
- }
83
-
84
- function main() {
85
- const args = process.argv.slice(2);
86
- const combine = args.includes('--combine');
87
- const skillDirArg = args.find(a => !a.startsWith('--'));
88
-
89
- if (!skillDirArg) {
90
- console.error('Usage: render-graphs.js <skill-directory> [--combine]');
91
- console.error('');
92
- console.error('Options:');
93
- console.error(' --combine Combine all diagrams into one SVG');
94
- console.error('');
95
- console.error('Example:');
96
- console.error(' ./render-graphs.js ../subagent-driven-development');
97
- console.error(' ./render-graphs.js ../subagent-driven-development --combine');
98
- process.exit(1);
99
- }
100
-
101
- const skillDir = path.resolve(skillDirArg);
102
- const skillFile = path.join(skillDir, 'SKILL.md');
103
- const skillName = path.basename(skillDir).replace(/-/g, '_');
104
-
105
- if (!fs.existsSync(skillFile)) {
106
- console.error(`Error: ${skillFile} not found`);
107
- process.exit(1);
108
- }
109
-
110
- // Check if dot is available. Run the binary directly rather than probing
111
- // with `which`, which is not a command on Windows.
112
- try {
113
- execFileSync('dot', ['-V'], { stdio: 'ignore' });
114
- } catch {
115
- console.error('Error: graphviz (dot) not found. Install with:');
116
- console.error(' brew install graphviz # macOS');
117
- console.error(' apt install graphviz # Linux');
118
- process.exit(1);
119
- }
120
-
121
- const markdown = fs.readFileSync(skillFile, 'utf-8');
122
- const blocks = extractDotBlocks(markdown);
123
-
124
- if (blocks.length === 0) {
125
- console.log('No ```dot blocks found in', skillFile);
126
- process.exit(0);
127
- }
128
-
129
- console.log(`Found ${blocks.length} diagram(s) in ${path.basename(skillDir)}/SKILL.md`);
130
-
131
- const outputDir = path.join(skillDir, 'diagrams');
132
- if (!fs.existsSync(outputDir)) {
133
- fs.mkdirSync(outputDir);
134
- }
135
-
136
- if (combine) {
137
- // Combine all graphs into one
138
- const combined = combineGraphs(blocks, skillName);
139
- const svg = renderToSvg(combined);
140
- if (svg) {
141
- const outputPath = path.join(outputDir, `${skillName}_combined.svg`);
142
- fs.writeFileSync(outputPath, svg);
143
- console.log(` Rendered: ${skillName}_combined.svg`);
144
-
145
- // Also write the dot source for debugging
146
- const dotPath = path.join(outputDir, `${skillName}_combined.dot`);
147
- fs.writeFileSync(dotPath, combined);
148
- console.log(` Source: ${skillName}_combined.dot`);
149
- } else {
150
- console.error(' Failed to render combined diagram');
151
- }
152
- } else {
153
- // Render each separately
154
- for (const block of blocks) {
155
- const svg = renderToSvg(block.content);
156
- if (svg) {
157
- const outputPath = path.join(outputDir, `${block.name}.svg`);
158
- fs.writeFileSync(outputPath, svg);
159
- console.log(` Rendered: ${block.name}.svg`);
160
- } else {
161
- console.error(` Failed: ${block.name}`);
162
- }
163
- }
164
- }
165
-
166
- console.log(`\nOutput: ${outputDir}/`);
167
- }
168
-
169
- main();
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Render graphviz diagrams from a skill's SKILL.md to SVG files.
5
+ *
6
+ * Usage:
7
+ * ./render-graphs.js <skill-directory> # Render each diagram separately
8
+ * ./render-graphs.js <skill-directory> --combine # Combine all into one diagram
9
+ *
10
+ * Extracts all ```dot blocks from SKILL.md and renders to SVG.
11
+ * Useful for helping your human partner visualize the process flows.
12
+ *
13
+ * Requires: graphviz (dot) installed on system
14
+ */
15
+
16
+ import * as fs from 'fs';
17
+ import * as path from 'path';
18
+ import { execFileSync } from 'child_process';
19
+
20
+ function extractDotBlocks(markdown) {
21
+ const blocks = [];
22
+ const regex = /```dot\n([\s\S]*?)```/g;
23
+ let match;
24
+
25
+ while ((match = regex.exec(markdown)) !== null) {
26
+ const content = match[1].trim();
27
+
28
+ // Extract digraph name
29
+ const nameMatch = content.match(/digraph\s+(\w+)/);
30
+ const name = nameMatch ? nameMatch[1] : `graph_${blocks.length + 1}`;
31
+
32
+ blocks.push({ name, content });
33
+ }
34
+
35
+ return blocks;
36
+ }
37
+
38
+ function extractGraphBody(dotContent) {
39
+ // Extract just the body (nodes and edges) from a digraph
40
+ const match = dotContent.match(/digraph\s+\w+\s*\{([\s\S]*)\}/);
41
+ if (!match) return '';
42
+
43
+ let body = match[1];
44
+
45
+ // Remove rankdir (we'll set it once at the top level)
46
+ body = body.replace(/^\s*rankdir\s*=\s*\w+\s*;?\s*$/gm, '');
47
+
48
+ return body.trim();
49
+ }
50
+
51
+ function combineGraphs(blocks, skillName) {
52
+ const bodies = blocks.map((block, i) => {
53
+ const body = extractGraphBody(block.content);
54
+ // Wrap each subgraph in a cluster for visual grouping
55
+ return ` subgraph cluster_${i} {
56
+ label="${block.name}";
57
+ ${body.split('\n').map(line => ' ' + line).join('\n')}
58
+ }`;
59
+ });
60
+
61
+ return `digraph ${skillName}_combined {
62
+ rankdir=TB;
63
+ compound=true;
64
+ newrank=true;
65
+
66
+ ${bodies.join('\n\n')}
67
+ }`;
68
+ }
69
+
70
+ function renderToSvg(dotContent) {
71
+ try {
72
+ return execFileSync('dot', ['-Tsvg'], {
73
+ input: dotContent,
74
+ encoding: 'utf-8',
75
+ maxBuffer: 10 * 1024 * 1024
76
+ });
77
+ } catch (err) {
78
+ console.error('Error running dot:', err.message);
79
+ if (err.stderr) console.error(err.stderr.toString());
80
+ return null;
81
+ }
82
+ }
83
+
84
+ function main() {
85
+ const args = process.argv.slice(2);
86
+ const combine = args.includes('--combine');
87
+ const skillDirArg = args.find(a => !a.startsWith('--'));
88
+
89
+ if (!skillDirArg) {
90
+ console.error('Usage: render-graphs.js <skill-directory> [--combine]');
91
+ console.error('');
92
+ console.error('Options:');
93
+ console.error(' --combine Combine all diagrams into one SVG');
94
+ console.error('');
95
+ console.error('Example:');
96
+ console.error(' ./render-graphs.js ../subagent-driven-development');
97
+ console.error(' ./render-graphs.js ../subagent-driven-development --combine');
98
+ process.exit(1);
99
+ }
100
+
101
+ const skillDir = path.resolve(skillDirArg);
102
+ const skillFile = path.join(skillDir, 'SKILL.md');
103
+ const skillName = path.basename(skillDir).replace(/-/g, '_');
104
+
105
+ if (!fs.existsSync(skillFile)) {
106
+ console.error(`Error: ${skillFile} not found`);
107
+ process.exit(1);
108
+ }
109
+
110
+ // Check if dot is available. Run the binary directly rather than probing
111
+ // with `which`, which is not a command on Windows.
112
+ try {
113
+ execFileSync('dot', ['-V'], { stdio: 'ignore' });
114
+ } catch {
115
+ console.error('Error: graphviz (dot) not found. Install with:');
116
+ console.error(' brew install graphviz # macOS');
117
+ console.error(' apt install graphviz # Linux');
118
+ process.exit(1);
119
+ }
120
+
121
+ const markdown = fs.readFileSync(skillFile, 'utf-8');
122
+ const blocks = extractDotBlocks(markdown);
123
+
124
+ if (blocks.length === 0) {
125
+ console.log('No ```dot blocks found in', skillFile);
126
+ process.exit(0);
127
+ }
128
+
129
+ console.log(`Found ${blocks.length} diagram(s) in ${path.basename(skillDir)}/SKILL.md`);
130
+
131
+ const outputDir = path.join(skillDir, 'diagrams');
132
+ if (!fs.existsSync(outputDir)) {
133
+ fs.mkdirSync(outputDir);
134
+ }
135
+
136
+ if (combine) {
137
+ // Combine all graphs into one
138
+ const combined = combineGraphs(blocks, skillName);
139
+ const svg = renderToSvg(combined);
140
+ if (svg) {
141
+ const outputPath = path.join(outputDir, `${skillName}_combined.svg`);
142
+ fs.writeFileSync(outputPath, svg);
143
+ console.log(` Rendered: ${skillName}_combined.svg`);
144
+
145
+ // Also write the dot source for debugging
146
+ const dotPath = path.join(outputDir, `${skillName}_combined.dot`);
147
+ fs.writeFileSync(dotPath, combined);
148
+ console.log(` Source: ${skillName}_combined.dot`);
149
+ } else {
150
+ console.error(' Failed to render combined diagram');
151
+ }
152
+ } else {
153
+ // Render each separately
154
+ for (const block of blocks) {
155
+ const svg = renderToSvg(block.content);
156
+ if (svg) {
157
+ const outputPath = path.join(outputDir, `${block.name}.svg`);
158
+ fs.writeFileSync(outputPath, svg);
159
+ console.log(` Rendered: ${block.name}.svg`);
160
+ } else {
161
+ console.error(` Failed: ${block.name}`);
162
+ }
163
+ }
164
+ }
165
+
166
+ console.log(`\nOutput: ${outputDir}/`);
167
+ }
168
+
169
+ main();