agentopology 0.1.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 (174) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +450 -0
  3. package/dist/analyzer/__tests__/analyzer.test.d.ts +2 -0
  4. package/dist/analyzer/__tests__/analyzer.test.d.ts.map +1 -0
  5. package/dist/analyzer/__tests__/analyzer.test.js +258 -0
  6. package/dist/analyzer/__tests__/analyzer.test.js.map +1 -0
  7. package/dist/analyzer/index.d.ts +44 -0
  8. package/dist/analyzer/index.d.ts.map +1 -0
  9. package/dist/analyzer/index.js +308 -0
  10. package/dist/analyzer/index.js.map +1 -0
  11. package/dist/bindings/__tests__/bindings.test.d.ts +2 -0
  12. package/dist/bindings/__tests__/bindings.test.d.ts.map +1 -0
  13. package/dist/bindings/__tests__/bindings.test.js +2089 -0
  14. package/dist/bindings/__tests__/bindings.test.js.map +1 -0
  15. package/dist/bindings/claude-code.d.ts +12 -0
  16. package/dist/bindings/claude-code.d.ts.map +1 -0
  17. package/dist/bindings/claude-code.js +2063 -0
  18. package/dist/bindings/claude-code.js.map +1 -0
  19. package/dist/bindings/codex.d.ts +18 -0
  20. package/dist/bindings/codex.d.ts.map +1 -0
  21. package/dist/bindings/codex.js +1633 -0
  22. package/dist/bindings/codex.js.map +1 -0
  23. package/dist/bindings/copilot-cli.d.ts +20 -0
  24. package/dist/bindings/copilot-cli.d.ts.map +1 -0
  25. package/dist/bindings/copilot-cli.js +1515 -0
  26. package/dist/bindings/copilot-cli.js.map +1 -0
  27. package/dist/bindings/cursor.d.ts +17 -0
  28. package/dist/bindings/cursor.d.ts.map +1 -0
  29. package/dist/bindings/cursor.js +1715 -0
  30. package/dist/bindings/cursor.js.map +1 -0
  31. package/dist/bindings/gemini-cli.d.ts +18 -0
  32. package/dist/bindings/gemini-cli.d.ts.map +1 -0
  33. package/dist/bindings/gemini-cli.js +1327 -0
  34. package/dist/bindings/gemini-cli.js.map +1 -0
  35. package/dist/bindings/index.d.ts +20 -0
  36. package/dist/bindings/index.d.ts.map +1 -0
  37. package/dist/bindings/index.js +33 -0
  38. package/dist/bindings/index.js.map +1 -0
  39. package/dist/bindings/kiro.d.ts +17 -0
  40. package/dist/bindings/kiro.d.ts.map +1 -0
  41. package/dist/bindings/kiro.js +1624 -0
  42. package/dist/bindings/kiro.js.map +1 -0
  43. package/dist/bindings/openclaw.d.ts +18 -0
  44. package/dist/bindings/openclaw.d.ts.map +1 -0
  45. package/dist/bindings/openclaw.js +1578 -0
  46. package/dist/bindings/openclaw.js.map +1 -0
  47. package/dist/bindings/types.d.ts +33 -0
  48. package/dist/bindings/types.d.ts.map +1 -0
  49. package/dist/bindings/types.js +23 -0
  50. package/dist/bindings/types.js.map +1 -0
  51. package/dist/cli/index.d.ts +19 -0
  52. package/dist/cli/index.d.ts.map +1 -0
  53. package/dist/cli/index.js +679 -0
  54. package/dist/cli/index.js.map +1 -0
  55. package/dist/docs/__tests__/docs.test.d.ts +2 -0
  56. package/dist/docs/__tests__/docs.test.d.ts.map +1 -0
  57. package/dist/docs/__tests__/docs.test.js +438 -0
  58. package/dist/docs/__tests__/docs.test.js.map +1 -0
  59. package/dist/docs/content.d.ts +16 -0
  60. package/dist/docs/content.d.ts.map +1 -0
  61. package/dist/docs/content.js +3273 -0
  62. package/dist/docs/content.js.map +1 -0
  63. package/dist/docs/index.d.ts +17 -0
  64. package/dist/docs/index.d.ts.map +1 -0
  65. package/dist/docs/index.js +117 -0
  66. package/dist/docs/index.js.map +1 -0
  67. package/dist/exporters/__tests__/exporters.test.d.ts +2 -0
  68. package/dist/exporters/__tests__/exporters.test.d.ts.map +1 -0
  69. package/dist/exporters/__tests__/exporters.test.js +731 -0
  70. package/dist/exporters/__tests__/exporters.test.js.map +1 -0
  71. package/dist/exporters/index.d.ts +13 -0
  72. package/dist/exporters/index.d.ts.map +1 -0
  73. package/dist/exporters/index.js +18 -0
  74. package/dist/exporters/index.js.map +1 -0
  75. package/dist/exporters/json.d.ts +8 -0
  76. package/dist/exporters/json.d.ts.map +1 -0
  77. package/dist/exporters/json.js +25 -0
  78. package/dist/exporters/json.js.map +1 -0
  79. package/dist/exporters/markdown.d.ts +9 -0
  80. package/dist/exporters/markdown.d.ts.map +1 -0
  81. package/dist/exporters/markdown.js +686 -0
  82. package/dist/exporters/markdown.js.map +1 -0
  83. package/dist/exporters/mermaid.d.ts +11 -0
  84. package/dist/exporters/mermaid.d.ts.map +1 -0
  85. package/dist/exporters/mermaid.js +161 -0
  86. package/dist/exporters/mermaid.js.map +1 -0
  87. package/dist/exporters/types.d.ts +22 -0
  88. package/dist/exporters/types.d.ts.map +1 -0
  89. package/dist/exporters/types.js +10 -0
  90. package/dist/exporters/types.js.map +1 -0
  91. package/dist/import/__tests__/import.test.d.ts +2 -0
  92. package/dist/import/__tests__/import.test.d.ts.map +1 -0
  93. package/dist/import/__tests__/import.test.js +781 -0
  94. package/dist/import/__tests__/import.test.js.map +1 -0
  95. package/dist/import/claude-code.d.ts +38 -0
  96. package/dist/import/claude-code.d.ts.map +1 -0
  97. package/dist/import/claude-code.js +897 -0
  98. package/dist/import/claude-code.js.map +1 -0
  99. package/dist/import/index.d.ts +18 -0
  100. package/dist/import/index.d.ts.map +1 -0
  101. package/dist/import/index.js +28 -0
  102. package/dist/import/index.js.map +1 -0
  103. package/dist/import/serializer.d.ts +11 -0
  104. package/dist/import/serializer.d.ts.map +1 -0
  105. package/dist/import/serializer.js +960 -0
  106. package/dist/import/serializer.js.map +1 -0
  107. package/dist/index.d.ts +26 -0
  108. package/dist/index.d.ts.map +1 -0
  109. package/dist/index.js +21 -0
  110. package/dist/index.js.map +1 -0
  111. package/dist/parser/__tests__/parser.test.d.ts +2 -0
  112. package/dist/parser/__tests__/parser.test.d.ts.map +1 -0
  113. package/dist/parser/__tests__/parser.test.js +6514 -0
  114. package/dist/parser/__tests__/parser.test.js.map +1 -0
  115. package/dist/parser/ast.d.ts +708 -0
  116. package/dist/parser/ast.d.ts.map +1 -0
  117. package/dist/parser/ast.js +12 -0
  118. package/dist/parser/ast.js.map +1 -0
  119. package/dist/parser/index.d.ts +253 -0
  120. package/dist/parser/index.d.ts.map +1 -0
  121. package/dist/parser/index.js +1985 -0
  122. package/dist/parser/index.js.map +1 -0
  123. package/dist/parser/lexer.d.ts +100 -0
  124. package/dist/parser/lexer.d.ts.map +1 -0
  125. package/dist/parser/lexer.js +304 -0
  126. package/dist/parser/lexer.js.map +1 -0
  127. package/dist/parser/validator.d.ts +42 -0
  128. package/dist/parser/validator.d.ts.map +1 -0
  129. package/dist/parser/validator.js +2568 -0
  130. package/dist/parser/validator.js.map +1 -0
  131. package/dist/scaffold/__tests__/scaffold.test.d.ts +7 -0
  132. package/dist/scaffold/__tests__/scaffold.test.d.ts.map +1 -0
  133. package/dist/scaffold/__tests__/scaffold.test.js +295 -0
  134. package/dist/scaffold/__tests__/scaffold.test.js.map +1 -0
  135. package/dist/scaffold/incremental.d.ts +43 -0
  136. package/dist/scaffold/incremental.d.ts.map +1 -0
  137. package/dist/scaffold/incremental.js +185 -0
  138. package/dist/scaffold/incremental.js.map +1 -0
  139. package/dist/scaffold/index.d.ts +13 -0
  140. package/dist/scaffold/index.d.ts.map +1 -0
  141. package/dist/scaffold/index.js +13 -0
  142. package/dist/scaffold/index.js.map +1 -0
  143. package/dist/scaffold/manifest.d.ts +30 -0
  144. package/dist/scaffold/manifest.d.ts.map +1 -0
  145. package/dist/scaffold/manifest.js +71 -0
  146. package/dist/scaffold/manifest.js.map +1 -0
  147. package/dist/scaffold/merge.d.ts +52 -0
  148. package/dist/scaffold/merge.d.ts.map +1 -0
  149. package/dist/scaffold/merge.js +134 -0
  150. package/dist/scaffold/merge.js.map +1 -0
  151. package/dist/scaffold/types.d.ts +51 -0
  152. package/dist/scaffold/types.d.ts.map +1 -0
  153. package/dist/scaffold/types.js +10 -0
  154. package/dist/scaffold/types.js.map +1 -0
  155. package/dist/sync/index.d.ts +34 -0
  156. package/dist/sync/index.d.ts.map +1 -0
  157. package/dist/sync/index.js +392 -0
  158. package/dist/sync/index.js.map +1 -0
  159. package/dist/visualizer/index.d.ts +17 -0
  160. package/dist/visualizer/index.d.ts.map +1 -0
  161. package/dist/visualizer/index.js +1976 -0
  162. package/dist/visualizer/index.js.map +1 -0
  163. package/examples/code-review.at +167 -0
  164. package/examples/data-processing.at +296 -0
  165. package/examples/openclaw-assistant.at +142 -0
  166. package/examples/scheduled-monitor.at +193 -0
  167. package/examples/simple-pipeline.at +163 -0
  168. package/package.json +77 -0
  169. package/skill/SKILL.md +403 -0
  170. package/skill/scripts/emit.ts +853 -0
  171. package/skill/scripts/visualize.ts +89 -0
  172. package/spec/grammar.md +1466 -0
  173. package/spec/reserved-keywords.md +147 -0
  174. package/spec/validation.md +535 -0
@@ -0,0 +1,686 @@
1
+ /**
2
+ * Markdown exporter — converts a TopologyAST into a beautiful, shareable
3
+ * Markdown document suitable for stakeholders, documentation, and onboarding.
4
+ *
5
+ * @module
6
+ */
7
+ // ---------------------------------------------------------------------------
8
+ // Helpers
9
+ // ---------------------------------------------------------------------------
10
+ function toTitle(s) {
11
+ return s
12
+ .split("-")
13
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
14
+ .join(" ");
15
+ }
16
+ function edgeLabel(edge) {
17
+ const parts = [];
18
+ if (edge.isError) {
19
+ parts.push(edge.errorType ? `error(${edge.errorType})` : "error");
20
+ }
21
+ if (edge.condition)
22
+ parts.push(`when ${edge.condition}`);
23
+ if (edge.maxIterations)
24
+ parts.push(`max ${edge.maxIterations}`);
25
+ if (edge.race)
26
+ parts.push("race");
27
+ if (edge.tolerance != null)
28
+ parts.push(`tolerance: ${edge.tolerance}`);
29
+ if (edge.wait)
30
+ parts.push(`wait ${edge.wait}`);
31
+ if (edge.weight != null)
32
+ parts.push(`weight ${edge.weight}`);
33
+ if (edge.reflection)
34
+ parts.push("reflection");
35
+ return parts.length > 0 ? parts.join(", ") : "";
36
+ }
37
+ // ---------------------------------------------------------------------------
38
+ // Section renderers
39
+ // ---------------------------------------------------------------------------
40
+ function renderHeader(ast) {
41
+ const t = ast.topology;
42
+ const lines = [];
43
+ // Title block
44
+ lines.push(`<div align="center">`);
45
+ lines.push("");
46
+ lines.push(`# ${toTitle(t.name)}`);
47
+ lines.push("");
48
+ if (t.description) {
49
+ lines.push(`*${t.description}*`);
50
+ lines.push("");
51
+ }
52
+ // Badges row
53
+ const badges = [];
54
+ badges.push(`![version](https://img.shields.io/badge/version-${t.version}-blue)`);
55
+ for (const p of t.patterns) {
56
+ badges.push(`![${p}](https://img.shields.io/badge/pattern-${encodeURIComponent(p)}-purple)`);
57
+ }
58
+ if (t.domain) {
59
+ badges.push(`![${t.domain}](https://img.shields.io/badge/domain-${encodeURIComponent(t.domain)}-green)`);
60
+ }
61
+ lines.push(badges.join(" "));
62
+ lines.push("");
63
+ lines.push(`</div>`);
64
+ lines.push("");
65
+ // Extra metadata as a clean list if present
66
+ const extra = [];
67
+ if (t.foundations && t.foundations.length > 0) {
68
+ extra.push(`**Foundations:** ${t.foundations.map((f) => `\`${f}\``).join(", ")}`);
69
+ }
70
+ if (t.advanced && t.advanced.length > 0) {
71
+ extra.push(`**Advanced:** ${t.advanced.map((a) => `\`${a}\``).join(", ")}`);
72
+ }
73
+ if (t.timeout)
74
+ extra.push(`**Timeout:** ${t.timeout}`);
75
+ if (t.durable)
76
+ extra.push(`**Durable:** Yes`);
77
+ if (t.errorHandler)
78
+ extra.push(`**Error Handler:** \`${t.errorHandler}\``);
79
+ if (extra.length > 0) {
80
+ for (const e of extra)
81
+ lines.push(`> ${e}`);
82
+ lines.push("");
83
+ }
84
+ return lines.join("\n");
85
+ }
86
+ function renderOverview(ast) {
87
+ const agents = ast.nodes.filter((n) => n.type === "agent");
88
+ const actions = ast.nodes.filter((n) => n.type === "action");
89
+ const gates = ast.nodes.filter((n) => n.type === "gate");
90
+ const orchestrators = ast.nodes.filter((n) => n.type === "orchestrator");
91
+ const humans = ast.nodes.filter((n) => n.type === "human");
92
+ const groups = ast.nodes.filter((n) => n.type === "group");
93
+ const lines = [];
94
+ lines.push("## At a Glance");
95
+ lines.push("");
96
+ const items = [];
97
+ if (orchestrators.length)
98
+ items.push(`**${orchestrators.length}** Orchestrator${orchestrators.length > 1 ? "s" : ""}`);
99
+ if (agents.length)
100
+ items.push(`**${agents.length}** Agent${agents.length > 1 ? "s" : ""}`);
101
+ if (actions.length)
102
+ items.push(`**${actions.length}** Action${actions.length > 1 ? "s" : ""}`);
103
+ if (gates.length)
104
+ items.push(`**${gates.length}** Gate${gates.length > 1 ? "s" : ""}`);
105
+ if (humans.length)
106
+ items.push(`**${humans.length}** Human Node${humans.length > 1 ? "s" : ""}`);
107
+ if (groups.length)
108
+ items.push(`**${groups.length}** Group${groups.length > 1 ? "s" : ""}`);
109
+ items.push(`**${ast.edges.length}** Edge${ast.edges.length !== 1 ? "s" : ""}`);
110
+ lines.push(`> ${items.join(" &nbsp;&bull;&nbsp; ")}`);
111
+ lines.push("");
112
+ return lines.join("\n");
113
+ }
114
+ function renderRoles(ast) {
115
+ const entries = Object.entries(ast.roles);
116
+ if (entries.length === 0)
117
+ return "";
118
+ const lines = [];
119
+ lines.push("## Roles");
120
+ lines.push("");
121
+ for (const [name, desc] of entries) {
122
+ lines.push(`- **${toTitle(name)}** — ${desc}`);
123
+ }
124
+ lines.push("");
125
+ return lines.join("\n");
126
+ }
127
+ function renderOrchestrator(node) {
128
+ const lines = [];
129
+ lines.push(`### Orchestrator`);
130
+ lines.push("");
131
+ const details = [];
132
+ details.push(`Model: \`${node.model}\``);
133
+ if (node.generates)
134
+ details.push(`Generates: \`${node.generates}\``);
135
+ if (node.handles.length)
136
+ details.push(`Handles: ${node.handles.map((h) => `\`${h}\``).join(", ")}`);
137
+ lines.push(`> ${details.join(" &nbsp;&middot;&nbsp; ")}`);
138
+ lines.push("");
139
+ if (node.outputs) {
140
+ lines.push("**Outputs:**");
141
+ lines.push("");
142
+ for (const [key, values] of Object.entries(node.outputs)) {
143
+ lines.push(`- \`${key}\` — ${values.map((v) => `\`${v}\``).join(" / ")}`);
144
+ }
145
+ lines.push("");
146
+ }
147
+ return lines.join("\n");
148
+ }
149
+ function renderAgent(node, roles) {
150
+ const lines = [];
151
+ // Agent heading with model badge inline
152
+ const modelBadge = node.model ? ` \`${node.model}\`` : "";
153
+ lines.push(`#### ${toTitle(node.id)}${modelBadge}`);
154
+ lines.push("");
155
+ // Role description as italic subtitle
156
+ if (node.role && roles[node.role]) {
157
+ lines.push(`*${roles[node.role]}*`);
158
+ lines.push("");
159
+ }
160
+ // Compact key-value line
161
+ const kvParts = [];
162
+ if (node.phase != null)
163
+ kvParts.push(`Phase **${node.phase}**`);
164
+ if (node.permissions)
165
+ kvParts.push(`Permissions: \`${node.permissions}\``);
166
+ if (node.behavior)
167
+ kvParts.push(`Behavior: \`${node.behavior}\``);
168
+ if (node.isolation)
169
+ kvParts.push(`Isolation: \`${node.isolation}\``);
170
+ if (node.background)
171
+ kvParts.push(`Background`);
172
+ if (node.sandbox != null)
173
+ kvParts.push(`Sandbox: \`${String(node.sandbox)}\``);
174
+ if (node.maxTurns != null)
175
+ kvParts.push(`Max turns: ${node.maxTurns}`);
176
+ if (node.timeout)
177
+ kvParts.push(`Timeout: ${node.timeout}`);
178
+ if (node.temperature != null)
179
+ kvParts.push(`Temperature: ${node.temperature}`);
180
+ if (node.thinking)
181
+ kvParts.push(`Thinking: \`${node.thinking}\``);
182
+ if (node.rateLimit)
183
+ kvParts.push(`Rate limit: ${node.rateLimit}`);
184
+ if (node.onFail)
185
+ kvParts.push(`On fail: \`${node.onFail}\``);
186
+ if (node.compensates)
187
+ kvParts.push(`Compensates: \`${node.compensates}\``);
188
+ if (node.invocation)
189
+ kvParts.push(`Invocation: \`${node.invocation}\``);
190
+ if (kvParts.length) {
191
+ lines.push(kvParts.join(" &nbsp;&middot;&nbsp; "));
192
+ lines.push("");
193
+ }
194
+ // Tools & access in a compact block
195
+ const accessLines = [];
196
+ if (node.tools && node.tools.length) {
197
+ accessLines.push(`**Tools:** ${node.tools.map((t) => `\`${t}\``).join(", ")}`);
198
+ }
199
+ if (node.disallowedTools && node.disallowedTools.length) {
200
+ accessLines.push(`**Denied:** ${node.disallowedTools.map((t) => `~~\`${t}\`~~`).join(", ")}`);
201
+ }
202
+ if (node.reads && node.reads.length) {
203
+ accessLines.push(`**Reads:** ${node.reads.map((r) => `\`${r}\``).join(", ")}`);
204
+ }
205
+ if (node.writes && node.writes.length) {
206
+ accessLines.push(`**Writes:** ${node.writes.map((w) => `\`${w}\``).join(", ")}`);
207
+ }
208
+ if (node.skills && node.skills.length) {
209
+ accessLines.push(`**Skills:** ${node.skills.map((s) => `\`${s}\``).join(", ")}`);
210
+ }
211
+ if (node.mcpServers && node.mcpServers.length) {
212
+ accessLines.push(`**MCP Servers:** ${node.mcpServers.map((s) => `\`${s}\``).join(", ")}`);
213
+ }
214
+ if (accessLines.length) {
215
+ for (const l of accessLines)
216
+ lines.push(l + " ");
217
+ lines.push("");
218
+ }
219
+ // Fallback chain
220
+ if (node.fallbackChain && node.fallbackChain.length) {
221
+ lines.push(`**Fallback:** ${node.fallbackChain.map((m) => `\`${m}\``).join(" → ")}`);
222
+ lines.push("");
223
+ }
224
+ // Outputs
225
+ if (node.outputs) {
226
+ lines.push("**Outputs:**");
227
+ for (const [key, values] of Object.entries(node.outputs)) {
228
+ lines.push(`- \`${key}\` — ${values.map((v) => `\`${v}\``).join(" / ")}`);
229
+ }
230
+ lines.push("");
231
+ }
232
+ // Scale
233
+ if (node.scale) {
234
+ lines.push(`**Scale:** \`${node.scale.mode}\` by \`${node.scale.by}\` (${node.scale.min}–${node.scale.max}${node.scale.batchSize ? `, batch ${node.scale.batchSize}` : ""})`);
235
+ lines.push("");
236
+ }
237
+ // Circuit breaker
238
+ if (node.circuitBreaker) {
239
+ lines.push(`**Circuit Breaker:** threshold=${node.circuitBreaker.threshold}, window=${node.circuitBreaker.window}, cooldown=${node.circuitBreaker.cooldown}`);
240
+ lines.push("");
241
+ }
242
+ // Retry
243
+ if (node.retry) {
244
+ if (typeof node.retry === "number") {
245
+ lines.push(`**Retry:** ${node.retry}x`);
246
+ }
247
+ else {
248
+ const retryParts = [`max ${node.retry.max}`];
249
+ if (node.retry.backoff)
250
+ retryParts.push(node.retry.backoff);
251
+ if (node.retry.interval)
252
+ retryParts.push(node.retry.interval);
253
+ lines.push(`**Retry:** ${retryParts.join(", ")}`);
254
+ }
255
+ lines.push("");
256
+ }
257
+ // Prompt
258
+ if (node.prompt) {
259
+ lines.push("<details>");
260
+ lines.push("<summary>Prompt</summary>");
261
+ lines.push("");
262
+ lines.push("```");
263
+ lines.push(node.prompt.trim());
264
+ lines.push("```");
265
+ lines.push("");
266
+ lines.push("</details>");
267
+ lines.push("");
268
+ }
269
+ return lines.join("\n");
270
+ }
271
+ function renderAction(node) {
272
+ const lines = [];
273
+ const kindBadge = node.kind ? ` \`${node.kind}\`` : "";
274
+ lines.push(`#### ${toTitle(node.id)}${kindBadge}`);
275
+ lines.push("");
276
+ if (node.description) {
277
+ lines.push(node.description);
278
+ lines.push("");
279
+ }
280
+ const extra = [];
281
+ if (node.source)
282
+ extra.push(`Source: \`${node.source}\``);
283
+ if (node.timeout)
284
+ extra.push(`Timeout: ${node.timeout}`);
285
+ if (node.onFail)
286
+ extra.push(`On fail: \`${node.onFail}\``);
287
+ if (node.join)
288
+ extra.push(`Join: \`${node.join}\``);
289
+ if (extra.length) {
290
+ lines.push(extra.join(" &nbsp;&middot;&nbsp; "));
291
+ lines.push("");
292
+ }
293
+ if (node.commands && node.commands.length) {
294
+ lines.push("```bash");
295
+ lines.push(node.commands.join("\n"));
296
+ lines.push("```");
297
+ lines.push("");
298
+ }
299
+ return lines.join("\n");
300
+ }
301
+ function renderGate(node) {
302
+ const lines = [];
303
+ lines.push(`#### ${toTitle(node.id)}`);
304
+ lines.push("");
305
+ const parts = [];
306
+ if (node.after)
307
+ parts.push(`After: \`${node.after}\``);
308
+ if (node.before)
309
+ parts.push(`Before: \`${node.before}\``);
310
+ if (node.run)
311
+ parts.push(`Run: \`${node.run}\``);
312
+ if (node.onFail)
313
+ parts.push(`On fail: \`${node.onFail}\``);
314
+ if (node.retry)
315
+ parts.push(`Retry: ${node.retry}x`);
316
+ if (node.timeout)
317
+ parts.push(`Timeout: ${node.timeout}`);
318
+ if (parts.length) {
319
+ lines.push(parts.join(" &nbsp;&middot;&nbsp; "));
320
+ lines.push("");
321
+ }
322
+ if (node.checks && node.checks.length) {
323
+ lines.push(`Checks: ${node.checks.map((c) => `\`${c}\``).join(", ")}`);
324
+ lines.push("");
325
+ }
326
+ return lines.join("\n");
327
+ }
328
+ function renderHuman(node) {
329
+ const lines = [];
330
+ lines.push(`#### ${toTitle(node.id)}`);
331
+ lines.push("");
332
+ if (node.description) {
333
+ lines.push(node.description);
334
+ lines.push("");
335
+ }
336
+ const parts = [];
337
+ if (node.timeout)
338
+ parts.push(`Timeout: ${node.timeout}`);
339
+ if (node.onTimeout)
340
+ parts.push(`On timeout: \`${node.onTimeout}\``);
341
+ if (parts.length) {
342
+ lines.push(parts.join(" &nbsp;&middot;&nbsp; "));
343
+ lines.push("");
344
+ }
345
+ return lines.join("\n");
346
+ }
347
+ function renderGroup(node) {
348
+ const lines = [];
349
+ lines.push(`#### ${toTitle(node.id)}`);
350
+ lines.push("");
351
+ if (node.description) {
352
+ lines.push(node.description);
353
+ lines.push("");
354
+ }
355
+ if (node.members.length) {
356
+ lines.push(`**Members:** ${node.members.map((m) => `\`${m}\``).join(", ")}`);
357
+ lines.push("");
358
+ }
359
+ const parts = [];
360
+ if (node.speakerSelection)
361
+ parts.push(`Speaker: \`${node.speakerSelection}\``);
362
+ if (node.maxRounds)
363
+ parts.push(`Max rounds: ${node.maxRounds}`);
364
+ if (node.termination)
365
+ parts.push(`Termination: ${node.termination}`);
366
+ if (node.timeout)
367
+ parts.push(`Timeout: ${node.timeout}`);
368
+ if (parts.length) {
369
+ lines.push(parts.join(" &nbsp;&middot;&nbsp; "));
370
+ lines.push("");
371
+ }
372
+ return lines.join("\n");
373
+ }
374
+ function renderNodes(ast) {
375
+ const lines = [];
376
+ // Orchestrators
377
+ const orchestrators = ast.nodes.filter((n) => n.type === "orchestrator");
378
+ if (orchestrators.length) {
379
+ for (const n of orchestrators)
380
+ lines.push(renderOrchestrator(n));
381
+ }
382
+ // Agents by phase
383
+ const agents = ast.nodes.filter((n) => n.type === "agent");
384
+ if (agents.length) {
385
+ lines.push("## Agents");
386
+ lines.push("");
387
+ const sorted = [...agents].sort((a, b) => (a.phase ?? 0) - (b.phase ?? 0));
388
+ for (const n of sorted)
389
+ lines.push(renderAgent(n, ast.roles));
390
+ }
391
+ // Actions
392
+ const actions = ast.nodes.filter((n) => n.type === "action");
393
+ if (actions.length) {
394
+ lines.push("## Actions");
395
+ lines.push("");
396
+ for (const n of actions)
397
+ lines.push(renderAction(n));
398
+ }
399
+ // Gates
400
+ const gates = ast.nodes.filter((n) => n.type === "gate");
401
+ if (gates.length) {
402
+ lines.push("## Gates");
403
+ lines.push("");
404
+ for (const n of gates)
405
+ lines.push(renderGate(n));
406
+ }
407
+ // Humans
408
+ const humans = ast.nodes.filter((n) => n.type === "human");
409
+ if (humans.length) {
410
+ lines.push("## Human Nodes");
411
+ lines.push("");
412
+ for (const n of humans)
413
+ lines.push(renderHuman(n));
414
+ }
415
+ // Groups
416
+ const groups = ast.nodes.filter((n) => n.type === "group");
417
+ if (groups.length) {
418
+ lines.push("## Groups");
419
+ lines.push("");
420
+ for (const n of groups)
421
+ lines.push(renderGroup(n));
422
+ }
423
+ return lines.join("\n");
424
+ }
425
+ function renderFlow(ast) {
426
+ if (ast.edges.length === 0)
427
+ return "";
428
+ const lines = [];
429
+ lines.push("## Flow");
430
+ lines.push("");
431
+ lines.push("```");
432
+ for (const edge of ast.edges) {
433
+ const arrow = edge.isError ? " ─✗─> " : " ───> ";
434
+ const label = edgeLabel(edge);
435
+ const suffix = label ? ` [${label}]` : "";
436
+ lines.push(` ${edge.from}${arrow}${edge.to}${suffix}`);
437
+ }
438
+ lines.push("```");
439
+ lines.push("");
440
+ return lines.join("\n");
441
+ }
442
+ function renderMemory(ast) {
443
+ const entries = Object.entries(ast.memory);
444
+ if (entries.length === 0)
445
+ return "";
446
+ const lines = [];
447
+ lines.push("## Memory");
448
+ lines.push("");
449
+ for (const [name, config] of entries) {
450
+ lines.push(`**${toTitle(name)}**`);
451
+ if (typeof config === "object" && config !== null) {
452
+ const rec = config;
453
+ for (const [k, v] of Object.entries(rec)) {
454
+ if (Array.isArray(v)) {
455
+ lines.push(`- ${k}: ${v.map((i) => `\`${i}\``).join(", ")}`);
456
+ }
457
+ else {
458
+ lines.push(`- ${k}: \`${String(v)}\``);
459
+ }
460
+ }
461
+ }
462
+ lines.push("");
463
+ }
464
+ return lines.join("\n");
465
+ }
466
+ function renderTriggers(ast) {
467
+ if (ast.triggers.length === 0)
468
+ return "";
469
+ const lines = [];
470
+ lines.push("## Triggers");
471
+ lines.push("");
472
+ for (const t of ast.triggers) {
473
+ lines.push(`- **\`${t.name}\`** — \`${t.pattern}\`${t.argument ? ` (argument: \`${t.argument}\`)` : ""}`);
474
+ }
475
+ lines.push("");
476
+ return lines.join("\n");
477
+ }
478
+ function renderHooks(ast) {
479
+ if (ast.hooks.length === 0)
480
+ return "";
481
+ const lines = [];
482
+ lines.push("## Hooks");
483
+ lines.push("");
484
+ for (const h of ast.hooks) {
485
+ const matcher = h.matcher ? ` matching \`${h.matcher}\`` : "";
486
+ lines.push(`- **\`${h.name}\`** — on \`${h.on}\`${matcher} runs \`${h.run}\``);
487
+ }
488
+ lines.push("");
489
+ return lines.join("\n");
490
+ }
491
+ function renderSchedules(ast) {
492
+ if (ast.schedules.length === 0)
493
+ return "";
494
+ const lines = [];
495
+ lines.push("## Schedules");
496
+ lines.push("");
497
+ for (const s of ast.schedules) {
498
+ const schedule = s.cron ? `cron \`${s.cron}\`` : s.every ? `every \`${s.every}\`` : "";
499
+ const target = s.agent ? `agent \`${s.agent}\`` : s.action ? `action \`${s.action}\`` : "";
500
+ const enabled = s.enabled ? "" : " *(disabled)*";
501
+ lines.push(`- **\`${s.id}\`** — ${schedule} → ${target}${enabled}`);
502
+ }
503
+ lines.push("");
504
+ return lines.join("\n");
505
+ }
506
+ function renderSchemas(ast) {
507
+ if (ast.schemas.length === 0)
508
+ return "";
509
+ const lines = [];
510
+ lines.push("## Schemas");
511
+ lines.push("");
512
+ for (const schema of ast.schemas) {
513
+ lines.push(`**${toTitle(schema.id)}**`);
514
+ lines.push("");
515
+ for (const field of schema.fields) {
516
+ const typeStr = formatSchemaType(field.type);
517
+ const opt = field.optional ? " *(optional)*" : "";
518
+ lines.push(`- \`${field.name}\` — ${typeStr}${opt}`);
519
+ }
520
+ lines.push("");
521
+ }
522
+ return lines.join("\n");
523
+ }
524
+ function formatSchemaType(t) {
525
+ switch (t.kind) {
526
+ case "primitive": return `\`${t.value}\``;
527
+ case "array": return `\`${formatSchemaTypeRaw(t.itemType)}[]\``;
528
+ case "enum": return t.values.map((v) => `\`${v}\``).join(" / ");
529
+ case "ref": return `\`@${t.name}\``;
530
+ }
531
+ }
532
+ function formatSchemaTypeRaw(t) {
533
+ switch (t.kind) {
534
+ case "primitive": return t.value;
535
+ case "array": return `${formatSchemaTypeRaw(t.itemType)}[]`;
536
+ case "enum": return t.values.join(" / ");
537
+ case "ref": return `@${t.name}`;
538
+ }
539
+ }
540
+ function renderSkills(ast) {
541
+ if (ast.skills.length === 0)
542
+ return "";
543
+ const lines = [];
544
+ lines.push("## Skills");
545
+ lines.push("");
546
+ for (const s of ast.skills) {
547
+ lines.push(`- **${toTitle(s.id)}** — ${s.description}`);
548
+ if (s.scripts && s.scripts.length) {
549
+ lines.push(` - Scripts: ${s.scripts.map((x) => `\`${x}\``).join(", ")}`);
550
+ }
551
+ if (s.domains && s.domains.length) {
552
+ lines.push(` - Domains: ${s.domains.map((x) => `\`${x}\``).join(", ")}`);
553
+ }
554
+ }
555
+ lines.push("");
556
+ return lines.join("\n");
557
+ }
558
+ function renderTools(ast) {
559
+ if (ast.toolDefs.length === 0)
560
+ return "";
561
+ const lines = [];
562
+ lines.push("## Custom Tools");
563
+ lines.push("");
564
+ for (const t of ast.toolDefs) {
565
+ const lang = t.lang ? ` (\`${t.lang}\`)` : "";
566
+ lines.push(`- **\`${t.id}\`**${lang} — ${t.description} `);
567
+ lines.push(` Script: \`${t.script}\``);
568
+ }
569
+ lines.push("");
570
+ return lines.join("\n");
571
+ }
572
+ function renderMetering(ast) {
573
+ if (!ast.metering)
574
+ return "";
575
+ const m = ast.metering;
576
+ const lines = [];
577
+ lines.push("## Metering");
578
+ lines.push("");
579
+ lines.push(`- **Track:** ${m.track.map((t) => `\`${t}\``).join(", ")}`);
580
+ lines.push(`- **Per:** ${m.per.map((p) => `\`${p}\``).join(", ")}`);
581
+ lines.push(`- **Output:** \`${m.output}\` (\`${m.format}\`)`);
582
+ lines.push("");
583
+ return lines.join("\n");
584
+ }
585
+ function renderSettings(ast) {
586
+ const entries = Object.entries(ast.settings);
587
+ if (entries.length === 0)
588
+ return "";
589
+ const lines = [];
590
+ lines.push("## Settings");
591
+ lines.push("");
592
+ for (const [key, value] of entries) {
593
+ if (Array.isArray(value)) {
594
+ const arr = value;
595
+ if (arr.length === 0) {
596
+ lines.push(`- **${toTitle(key)}:** *(none)*`);
597
+ }
598
+ else {
599
+ lines.push(`- **${toTitle(key)}:** ${arr.map((v) => `\`${v}\``).join(", ")}`);
600
+ }
601
+ }
602
+ else {
603
+ lines.push(`- **${toTitle(key)}:** \`${String(value)}\``);
604
+ }
605
+ }
606
+ lines.push("");
607
+ return lines.join("\n");
608
+ }
609
+ function renderMcpServers(ast) {
610
+ const entries = Object.entries(ast.mcpServers);
611
+ if (entries.length === 0)
612
+ return "";
613
+ const lines = [];
614
+ lines.push("## MCP Servers");
615
+ lines.push("");
616
+ for (const [name, config] of entries) {
617
+ const configEntries = Object.entries(config);
618
+ const summary = configEntries.map(([k, v]) => {
619
+ if (Array.isArray(v))
620
+ return `${k}: ${v.map((i) => `\`${String(i)}\``).join(", ")}`;
621
+ return `${k}: \`${String(v)}\``;
622
+ }).join(" &nbsp;&middot;&nbsp; ");
623
+ lines.push(`- **${toTitle(name)}** — ${summary}`);
624
+ }
625
+ lines.push("");
626
+ return lines.join("\n");
627
+ }
628
+ function renderEnvironments(ast) {
629
+ const entries = Object.entries(ast.environments);
630
+ if (entries.length === 0)
631
+ return "";
632
+ const lines = [];
633
+ lines.push("## Environments");
634
+ lines.push("");
635
+ for (const [name, config] of entries) {
636
+ const summary = Object.entries(config).map(([k, v]) => `\`${k}\`=\`${String(v)}\``).join(", ");
637
+ lines.push(`- **${toTitle(name)}** — ${summary}`);
638
+ }
639
+ lines.push("");
640
+ return lines.join("\n");
641
+ }
642
+ function renderFooter() {
643
+ const lines = [];
644
+ lines.push("---");
645
+ lines.push("");
646
+ lines.push(`<sub>Generated by <a href="https://agentopology.com">AgenTopology</a></sub>`);
647
+ lines.push("");
648
+ return lines.join("\n");
649
+ }
650
+ // ---------------------------------------------------------------------------
651
+ // Main export function
652
+ // ---------------------------------------------------------------------------
653
+ function exportMarkdown(ast) {
654
+ const sections = [];
655
+ sections.push(renderHeader(ast));
656
+ sections.push(renderOverview(ast));
657
+ sections.push(renderRoles(ast));
658
+ sections.push(renderNodes(ast));
659
+ sections.push(renderFlow(ast));
660
+ sections.push(renderMemory(ast));
661
+ sections.push(renderTriggers(ast));
662
+ sections.push(renderHooks(ast));
663
+ sections.push(renderSchedules(ast));
664
+ sections.push(renderSchemas(ast));
665
+ sections.push(renderSkills(ast));
666
+ sections.push(renderTools(ast));
667
+ sections.push(renderMetering(ast));
668
+ sections.push(renderMcpServers(ast));
669
+ sections.push(renderEnvironments(ast));
670
+ sections.push(renderSettings(ast));
671
+ sections.push(renderFooter());
672
+ // Filter empty sections and join
673
+ const content = sections.filter((s) => s.trim().length > 0).join("\n");
674
+ const stem = ast.topology.name;
675
+ return [{ path: `${stem}.md`, content }];
676
+ }
677
+ // ---------------------------------------------------------------------------
678
+ // Exporter instance
679
+ // ---------------------------------------------------------------------------
680
+ export const markdownExporter = {
681
+ name: "markdown",
682
+ description: "Markdown documentation — shareable topology reference",
683
+ extension: ".md",
684
+ export: exportMarkdown,
685
+ };
686
+ //# sourceMappingURL=markdown.js.map