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,960 @@
1
+ /**
2
+ * AST serializer — converts a TopologyAST back to .at source text.
3
+ *
4
+ * This is the inverse of the parser. The output must be valid .at syntax
5
+ * that round-trips through `parse()` without errors.
6
+ *
7
+ * @module
8
+ */
9
+ // ---------------------------------------------------------------------------
10
+ // Helpers
11
+ // ---------------------------------------------------------------------------
12
+ /** Quote a string if it contains spaces, special chars, or is empty. */
13
+ function q(s) {
14
+ if (!s)
15
+ return '""';
16
+ if (/[\s#:{}[\],|]/.test(s) || s.includes('"'))
17
+ return `"${s.replace(/"/g, '\\"')}"`;
18
+ return s;
19
+ }
20
+ /** Format a list inline: [a, b, c] */
21
+ function inlineList(items) {
22
+ return `[${items.map(q).join(", ")}]`;
23
+ }
24
+ /** Indent each line of text by n spaces. */
25
+ function indent(text, n) {
26
+ const pad = " ".repeat(n);
27
+ return text
28
+ .split("\n")
29
+ .map((line) => (line.trim() ? pad + line : ""))
30
+ .join("\n");
31
+ }
32
+ function formatSchemaType(t) {
33
+ switch (t.kind) {
34
+ case "primitive": return t.value;
35
+ case "array": return `${formatSchemaType(t.itemType)}[]`;
36
+ case "enum": return t.values.join(" | ");
37
+ case "ref": return t.name;
38
+ }
39
+ }
40
+ // ---------------------------------------------------------------------------
41
+ // Section serializers
42
+ // ---------------------------------------------------------------------------
43
+ function serializeMeta(ast) {
44
+ const meta = ast.topology;
45
+ const lines = [];
46
+ lines.push(" meta {");
47
+ if (meta.version)
48
+ lines.push(` version: "${meta.version}"`);
49
+ if (meta.description)
50
+ lines.push(` description: "${meta.description}"`);
51
+ if (meta.domain)
52
+ lines.push(` domain: ${q(meta.domain)}`);
53
+ if (meta.foundations?.length)
54
+ lines.push(` foundations: ${inlineList(meta.foundations)}`);
55
+ if (meta.advanced?.length)
56
+ lines.push(` advanced: ${inlineList(meta.advanced)}`);
57
+ if (meta.timeout)
58
+ lines.push(` timeout: ${q(meta.timeout)}`);
59
+ if (meta.errorHandler)
60
+ lines.push(` error-handler: ${meta.errorHandler}`);
61
+ if (meta.durable)
62
+ lines.push(" durable: true");
63
+ lines.push(" }");
64
+ return lines.join("\n");
65
+ }
66
+ function serializeOrchestrator(node) {
67
+ const lines = [];
68
+ lines.push(" orchestrator {");
69
+ lines.push(` model: ${node.model}`);
70
+ if (node.generates)
71
+ lines.push(` generates: "${node.generates}"`);
72
+ if (node.handles.length)
73
+ lines.push(` handles: ${inlineList(node.handles)}`);
74
+ if (node.outputs) {
75
+ lines.push(" outputs: {");
76
+ for (const [field, values] of Object.entries(node.outputs)) {
77
+ lines.push(` ${field}: ${values.join(" | ")}`);
78
+ }
79
+ lines.push(" }");
80
+ }
81
+ lines.push(" }");
82
+ return lines.join("\n");
83
+ }
84
+ function serializeRoles(roles) {
85
+ const entries = Object.entries(roles);
86
+ if (entries.length === 0)
87
+ return null;
88
+ const lines = [" roles {"];
89
+ for (const [name, desc] of entries) {
90
+ lines.push(` ${name}: "${desc}"`);
91
+ }
92
+ lines.push(" }");
93
+ return lines.join("\n");
94
+ }
95
+ function serializeOutputs(outputs, pad) {
96
+ const lines = [];
97
+ lines.push(`${pad}outputs: {`);
98
+ for (const [field, values] of Object.entries(outputs)) {
99
+ lines.push(`${pad} ${field}: ${values.join(" | ")}`);
100
+ }
101
+ lines.push(`${pad}}`);
102
+ return lines;
103
+ }
104
+ function serializeRetry(retry, pad) {
105
+ if (typeof retry === "number") {
106
+ return [`${pad}retry: ${retry}`];
107
+ }
108
+ const lines = [`${pad}retry {`];
109
+ lines.push(`${pad} max: ${retry.max}`);
110
+ if (retry.backoff)
111
+ lines.push(`${pad} backoff: ${retry.backoff}`);
112
+ if (retry.interval)
113
+ lines.push(`${pad} interval: ${retry.interval}`);
114
+ if (retry.maxInterval)
115
+ lines.push(`${pad} max-interval: ${retry.maxInterval}`);
116
+ if (retry.jitter)
117
+ lines.push(`${pad} jitter: true`);
118
+ if (retry.nonRetryable?.length)
119
+ lines.push(`${pad} non-retryable: ${inlineList(retry.nonRetryable)}`);
120
+ lines.push(`${pad}}`);
121
+ return lines;
122
+ }
123
+ function serializeAgent(node) {
124
+ const lines = [];
125
+ lines.push(` agent ${node.id} {`);
126
+ if (node.role)
127
+ lines.push(` role: ${node.role}`);
128
+ if (node.model)
129
+ lines.push(` model: ${node.model}`);
130
+ if (node.permissions)
131
+ lines.push(` permissions: ${node.permissions}`);
132
+ if (node.phase !== undefined)
133
+ lines.push(` phase: ${node.phase}`);
134
+ if (node.description)
135
+ lines.push(` description: "${node.description}"`);
136
+ if (node.tools?.length)
137
+ lines.push(` tools: ${inlineList(node.tools)}`);
138
+ if (node.disallowedTools?.length)
139
+ lines.push(` disallowed-tools: ${inlineList(node.disallowedTools)}`);
140
+ if (node.skills?.length)
141
+ lines.push(` skills: ${inlineList(node.skills)}`);
142
+ if (node.reads?.length)
143
+ lines.push(` reads: ${inlineList(node.reads)}`);
144
+ if (node.writes?.length)
145
+ lines.push(` writes: ${inlineList(node.writes)}`);
146
+ if (node.outputs)
147
+ lines.push(...serializeOutputs(node.outputs, " "));
148
+ if (node.mcpServers?.length)
149
+ lines.push(` mcp-servers: ${inlineList(node.mcpServers)}`);
150
+ if (node.isolation)
151
+ lines.push(` isolation: ${node.isolation}`);
152
+ if (node.background)
153
+ lines.push(" background: true");
154
+ if (node.sandbox !== undefined) {
155
+ lines.push(` sandbox: ${typeof node.sandbox === "boolean" ? node.sandbox : q(node.sandbox)}`);
156
+ }
157
+ if (node.fallbackChain?.length)
158
+ lines.push(` fallback-chain: ${inlineList(node.fallbackChain)}`);
159
+ if (node.maxTurns)
160
+ lines.push(` max-turns: ${node.maxTurns}`);
161
+ if (node.timeout)
162
+ lines.push(` timeout: ${q(node.timeout)}`);
163
+ if (node.onFail)
164
+ lines.push(` on-fail: ${node.onFail}`);
165
+ if (node.behavior)
166
+ lines.push(` behavior: ${node.behavior}`);
167
+ if (node.invocation)
168
+ lines.push(` invocation: ${node.invocation}`);
169
+ if (node.skip)
170
+ lines.push(` skip: ${q(node.skip)}`);
171
+ if (node.join)
172
+ lines.push(` join: ${node.join}`);
173
+ if (node.compensates)
174
+ lines.push(` compensates: ${node.compensates}`);
175
+ if (node.temperature !== undefined)
176
+ lines.push(` temperature: ${node.temperature}`);
177
+ if (node.maxTokens !== undefined)
178
+ lines.push(` max-tokens: ${node.maxTokens}`);
179
+ if (node.topP !== undefined)
180
+ lines.push(` top-p: ${node.topP}`);
181
+ if (node.topK !== undefined)
182
+ lines.push(` top-k: ${node.topK}`);
183
+ if (node.stop?.length)
184
+ lines.push(` stop: ${inlineList(node.stop)}`);
185
+ if (node.seed !== undefined)
186
+ lines.push(` seed: ${node.seed}`);
187
+ if (node.thinking)
188
+ lines.push(` thinking: ${node.thinking}`);
189
+ if (node.thinkingBudget)
190
+ lines.push(` thinking-budget: ${node.thinkingBudget}`);
191
+ if (node.outputFormat)
192
+ lines.push(` output-format: ${node.outputFormat}`);
193
+ if (node.logLevel)
194
+ lines.push(` log-level: ${node.logLevel}`);
195
+ if (node.rateLimit)
196
+ lines.push(` rate-limit: ${q(node.rateLimit)}`);
197
+ if (node.retry !== undefined)
198
+ lines.push(...serializeRetry(node.retry, " "));
199
+ if (node.circuitBreaker) {
200
+ const cb = node.circuitBreaker;
201
+ lines.push(" circuit-breaker {");
202
+ lines.push(` threshold: ${cb.threshold}`);
203
+ lines.push(` window: ${cb.window}`);
204
+ lines.push(` cooldown: ${cb.cooldown}`);
205
+ lines.push(" }");
206
+ }
207
+ if (node.scale) {
208
+ const s = node.scale;
209
+ lines.push(" scale {");
210
+ lines.push(` mode: ${s.mode}`);
211
+ lines.push(` by: ${q(s.by)}`);
212
+ lines.push(` min: ${s.min}`);
213
+ lines.push(` max: ${s.max}`);
214
+ if (s.batchSize !== null)
215
+ lines.push(` batch-size: ${s.batchSize}`);
216
+ lines.push(" }");
217
+ }
218
+ if (node.inputSchema?.length) {
219
+ lines.push(" input-schema {");
220
+ for (const f of node.inputSchema) {
221
+ lines.push(` ${f.name}${f.optional ? "?" : ""}: ${formatSchemaType(f.type)}`);
222
+ }
223
+ lines.push(" }");
224
+ }
225
+ if (node.outputSchema?.length) {
226
+ lines.push(" output-schema {");
227
+ for (const f of node.outputSchema) {
228
+ lines.push(` ${f.name}${f.optional ? "?" : ""}: ${formatSchemaType(f.type)}`);
229
+ }
230
+ lines.push(" }");
231
+ }
232
+ if (node.produces?.length)
233
+ lines.push(` produces: ${inlineList(node.produces)}`);
234
+ if (node.consumes?.length)
235
+ lines.push(` consumes: ${inlineList(node.consumes)}`);
236
+ if (node.variants?.length) {
237
+ for (const v of node.variants) {
238
+ lines.push(` variant ${v.id} {`);
239
+ lines.push(` weight: ${v.weight}`);
240
+ if (v.model)
241
+ lines.push(` model: ${v.model}`);
242
+ if (v.temperature !== undefined)
243
+ lines.push(` temperature: ${v.temperature}`);
244
+ if (v.prompt) {
245
+ lines.push(" prompt {");
246
+ lines.push(indent(v.prompt, 8));
247
+ lines.push(" }");
248
+ }
249
+ lines.push(" }");
250
+ }
251
+ }
252
+ if (node.hooks?.length) {
253
+ for (const hook of node.hooks) {
254
+ lines.push(...serializeHook(hook, " "));
255
+ }
256
+ }
257
+ if (node.extensions) {
258
+ for (const [binding, fields] of Object.entries(node.extensions)) {
259
+ lines.push(` extensions {`);
260
+ lines.push(` ${binding} {`);
261
+ for (const [k, v] of Object.entries(fields)) {
262
+ lines.push(` ${k}: ${JSON.stringify(v)}`);
263
+ }
264
+ lines.push(" }");
265
+ lines.push(" }");
266
+ }
267
+ }
268
+ if (node.prompt) {
269
+ lines.push(" prompt {");
270
+ lines.push(indent(node.prompt, 6));
271
+ lines.push(" }");
272
+ }
273
+ lines.push(" }");
274
+ return lines.join("\n");
275
+ }
276
+ function serializeAction(node) {
277
+ const lines = [];
278
+ lines.push(` action ${node.id} {`);
279
+ if (node.kind)
280
+ lines.push(` kind: ${node.kind}`);
281
+ if (node.description)
282
+ lines.push(` description: "${node.description}"`);
283
+ if (node.source)
284
+ lines.push(` source: "${node.source}"`);
285
+ if (node.commands?.length) {
286
+ lines.push(" commands: [");
287
+ for (const cmd of node.commands) {
288
+ lines.push(` "${cmd}"`);
289
+ }
290
+ lines.push(" ]");
291
+ }
292
+ if (node.timeout)
293
+ lines.push(` timeout: ${q(node.timeout)}`);
294
+ if (node.onFail)
295
+ lines.push(` on-fail: ${node.onFail}`);
296
+ if (node.join)
297
+ lines.push(` join: ${node.join}`);
298
+ lines.push(" }");
299
+ return lines.join("\n");
300
+ }
301
+ function serializeGate(node) {
302
+ const lines = [];
303
+ lines.push(` gate ${node.id} {`);
304
+ if (node.after)
305
+ lines.push(` after: ${node.after}`);
306
+ if (node.before)
307
+ lines.push(` before: ${node.before}`);
308
+ if (node.run)
309
+ lines.push(` run: "${node.run}"`);
310
+ if (node.checks?.length)
311
+ lines.push(` checks: ${inlineList(node.checks)}`);
312
+ if (node.onFail)
313
+ lines.push(` on-fail: ${node.onFail}`);
314
+ if (node.retry)
315
+ lines.push(` retry: ${node.retry}`);
316
+ if (node.behavior)
317
+ lines.push(` behavior: ${node.behavior}`);
318
+ if (node.timeout)
319
+ lines.push(` timeout: ${q(node.timeout)}`);
320
+ lines.push(" }");
321
+ return lines.join("\n");
322
+ }
323
+ function serializeHuman(node) {
324
+ const lines = [];
325
+ lines.push(` human ${node.id} {`);
326
+ if (node.description)
327
+ lines.push(` description: "${node.description}"`);
328
+ if (node.timeout)
329
+ lines.push(` timeout: ${q(node.timeout)}`);
330
+ if (node.onTimeout)
331
+ lines.push(` on-timeout: ${node.onTimeout}`);
332
+ lines.push(" }");
333
+ return lines.join("\n");
334
+ }
335
+ function serializeGroup(node) {
336
+ const lines = [];
337
+ lines.push(` group ${node.id} {`);
338
+ if (node.members?.length)
339
+ lines.push(` members: ${inlineList(node.members)}`);
340
+ if (node.speakerSelection)
341
+ lines.push(` speaker-selection: ${q(node.speakerSelection)}`);
342
+ if (node.maxRounds)
343
+ lines.push(` max-rounds: ${node.maxRounds}`);
344
+ if (node.termination)
345
+ lines.push(` termination: "${node.termination}"`);
346
+ if (node.description)
347
+ lines.push(` description: "${node.description}"`);
348
+ if (node.timeout)
349
+ lines.push(` timeout: ${q(node.timeout)}`);
350
+ lines.push(" }");
351
+ return lines.join("\n");
352
+ }
353
+ function serializeEdge(edge) {
354
+ let line = ` ${edge.from} -> ${edge.to}`;
355
+ const attrs = [];
356
+ if (edge.isError) {
357
+ const errPart = edge.errorType ? `x[${edge.errorType}]` : "x";
358
+ line = ` ${edge.from} -${errPart}-> ${edge.to}`;
359
+ }
360
+ if (edge.condition)
361
+ attrs.push(`when ${edge.condition}`);
362
+ if (edge.maxIterations)
363
+ attrs.push(`max ${edge.maxIterations}`);
364
+ if (edge.per)
365
+ attrs.push(`per ${edge.per}`);
366
+ if (edge.race)
367
+ attrs.push("race");
368
+ if (edge.tolerance !== undefined)
369
+ attrs.push(`tolerance: ${edge.tolerance}`);
370
+ if (edge.wait)
371
+ attrs.push(`wait ${edge.wait}`);
372
+ if (edge.weight !== undefined)
373
+ attrs.push(`weight ${edge.weight}`);
374
+ if (edge.reflection)
375
+ attrs.push("reflection");
376
+ if (attrs.length > 0) {
377
+ line += ` [${attrs.join(", ")}]`;
378
+ }
379
+ return line;
380
+ }
381
+ function serializeFlow(edges) {
382
+ if (edges.length === 0)
383
+ return null;
384
+ const lines = [" flow {"];
385
+ for (const edge of edges) {
386
+ lines.push(serializeEdge(edge));
387
+ }
388
+ lines.push(" }");
389
+ return lines.join("\n");
390
+ }
391
+ function serializeGates(gates) {
392
+ if (gates.length === 0)
393
+ return null;
394
+ const lines = [" gates {"];
395
+ for (const gate of gates) {
396
+ lines.push(serializeGate(gate));
397
+ }
398
+ lines.push(" }");
399
+ return lines.join("\n");
400
+ }
401
+ function serializeHook(hook, pad) {
402
+ const lines = [];
403
+ lines.push(`${pad}hook ${hook.name} {`);
404
+ lines.push(`${pad} on: ${hook.on}`);
405
+ if (hook.matcher)
406
+ lines.push(`${pad} matcher: ${q(hook.matcher)}`);
407
+ lines.push(`${pad} run: "${hook.run}"`);
408
+ if (hook.type)
409
+ lines.push(`${pad} type: ${hook.type}`);
410
+ if (hook.timeout)
411
+ lines.push(`${pad} timeout: ${hook.timeout}`);
412
+ lines.push(`${pad}}`);
413
+ return lines;
414
+ }
415
+ function serializeHooks(hooks) {
416
+ if (hooks.length === 0)
417
+ return null;
418
+ const lines = [" hooks {"];
419
+ for (const hook of hooks) {
420
+ lines.push(...serializeHook(hook, " "));
421
+ }
422
+ lines.push(" }");
423
+ return lines.join("\n");
424
+ }
425
+ function serializeSettings(settings) {
426
+ const allow = settings.allow;
427
+ const deny = settings.deny;
428
+ const ask = settings.ask;
429
+ if (!allow?.length && !deny?.length && !ask?.length)
430
+ return null;
431
+ const lines = [" settings {"];
432
+ if (allow?.length)
433
+ lines.push(` allow: ${inlineList(allow)}`);
434
+ if (deny?.length)
435
+ lines.push(` deny: ${inlineList(deny)}`);
436
+ if (ask?.length)
437
+ lines.push(` ask: ${inlineList(ask)}`);
438
+ lines.push(" }");
439
+ return lines.join("\n");
440
+ }
441
+ function serializeMcpServers(servers) {
442
+ const entries = Object.entries(servers);
443
+ if (entries.length === 0)
444
+ return null;
445
+ const lines = [" mcp-servers {"];
446
+ for (const [name, config] of entries) {
447
+ lines.push(` ${name} {`);
448
+ for (const [k, v] of Object.entries(config)) {
449
+ if (Array.isArray(v)) {
450
+ lines.push(` ${k}: ${inlineList(v.map(String))}`);
451
+ }
452
+ else if (typeof v === "object" && v !== null) {
453
+ lines.push(` ${k} {`);
454
+ for (const [ek, ev] of Object.entries(v)) {
455
+ lines.push(` ${ek}: ${q(String(ev))}`);
456
+ }
457
+ lines.push(" }");
458
+ }
459
+ else {
460
+ lines.push(` ${k}: ${q(String(v))}`);
461
+ }
462
+ }
463
+ lines.push(" }");
464
+ }
465
+ lines.push(" }");
466
+ return lines.join("\n");
467
+ }
468
+ function serializeTriggers(triggers) {
469
+ if (triggers.length === 0)
470
+ return null;
471
+ const lines = [" triggers {"];
472
+ for (const t of triggers) {
473
+ lines.push(` command ${t.name} {`);
474
+ lines.push(` pattern: "${t.pattern}"`);
475
+ if (t.argument)
476
+ lines.push(` argument: ${t.argument}`);
477
+ lines.push(" }");
478
+ }
479
+ lines.push(" }");
480
+ return lines.join("\n");
481
+ }
482
+ function serializeMemory(memory) {
483
+ const entries = Object.entries(memory);
484
+ if (entries.length === 0)
485
+ return null;
486
+ const lines = [" memory {"];
487
+ for (const [key, value] of entries) {
488
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
489
+ lines.push(` ${key} {`);
490
+ for (const [k, v] of Object.entries(value)) {
491
+ if (Array.isArray(v)) {
492
+ lines.push(` ${k}: ${inlineList(v.map(String))}`);
493
+ }
494
+ else {
495
+ lines.push(` ${k}: ${q(String(v))}`);
496
+ }
497
+ }
498
+ lines.push(" }");
499
+ }
500
+ else if (Array.isArray(value)) {
501
+ lines.push(` ${key}: ${inlineList(value.map(String))}`);
502
+ }
503
+ else {
504
+ lines.push(` ${key}: ${q(String(value))}`);
505
+ }
506
+ }
507
+ lines.push(" }");
508
+ return lines.join("\n");
509
+ }
510
+ function serializeDepth(depth) {
511
+ if (!depth.factors?.length && !depth.levels?.length)
512
+ return null;
513
+ const lines = [" depth {"];
514
+ if (depth.factors?.length)
515
+ lines.push(` factors: ${inlineList(depth.factors)}`);
516
+ for (const lvl of depth.levels ?? []) {
517
+ lines.push(` ${lvl.level}: ${q(lvl.label)}${lvl.omit?.length ? ` omit ${inlineList(lvl.omit)}` : ""}`);
518
+ }
519
+ lines.push(" }");
520
+ return lines.join("\n");
521
+ }
522
+ function serializeMetering(metering) {
523
+ const lines = [" metering {"];
524
+ lines.push(` track: ${inlineList(metering.track)}`);
525
+ lines.push(` per: ${inlineList(metering.per)}`);
526
+ lines.push(` output: ${q(metering.output)}`);
527
+ lines.push(` format: ${metering.format}`);
528
+ lines.push(` pricing: ${metering.pricing}`);
529
+ lines.push(" }");
530
+ return lines.join("\n");
531
+ }
532
+ function serializeSkills(skills) {
533
+ if (skills.length === 0)
534
+ return null;
535
+ const lines = [" skills {"];
536
+ for (const skill of skills) {
537
+ lines.push(` skill ${skill.id} {`);
538
+ if (skill.description)
539
+ lines.push(` description: "${skill.description}"`);
540
+ if (skill.scripts?.length)
541
+ lines.push(` scripts: ${inlineList(skill.scripts)}`);
542
+ if (skill.domains?.length)
543
+ lines.push(` domains: ${inlineList(skill.domains)}`);
544
+ if (skill.references?.length)
545
+ lines.push(` references: ${inlineList(skill.references)}`);
546
+ if (skill.prompt)
547
+ lines.push(` prompt: "${skill.prompt}"`);
548
+ if (skill.disableModelInvocation)
549
+ lines.push(" disable-model-invocation: true");
550
+ if (skill.userInvocable)
551
+ lines.push(" user-invocable: true");
552
+ if (skill.context)
553
+ lines.push(` context: ${skill.context}`);
554
+ if (skill.agent)
555
+ lines.push(` agent: ${skill.agent}`);
556
+ if (skill.allowedTools?.length)
557
+ lines.push(` allowed-tools: ${inlineList(skill.allowedTools)}`);
558
+ lines.push(" }");
559
+ }
560
+ lines.push(" }");
561
+ return lines.join("\n");
562
+ }
563
+ function serializeTools(tools) {
564
+ if (tools.length === 0)
565
+ return null;
566
+ const lines = [" tools {"];
567
+ for (const tool of tools) {
568
+ lines.push(` tool ${tool.id} {`);
569
+ lines.push(` script: "${tool.script}"`);
570
+ lines.push(` description: "${tool.description}"`);
571
+ if (tool.lang)
572
+ lines.push(` lang: ${tool.lang}`);
573
+ if (tool.args?.length)
574
+ lines.push(` args: ${inlineList(tool.args)}`);
575
+ lines.push(" }");
576
+ }
577
+ lines.push(" }");
578
+ return lines.join("\n");
579
+ }
580
+ function serializeProviders(providers) {
581
+ if (providers.length === 0)
582
+ return null;
583
+ const lines = [" providers {"];
584
+ for (const p of providers) {
585
+ lines.push(` ${p.name} {`);
586
+ if (p.apiKey)
587
+ lines.push(` api-key: ${q(p.apiKey)}`);
588
+ if (p.baseUrl)
589
+ lines.push(` base-url: ${q(p.baseUrl)}`);
590
+ if (p.models.length)
591
+ lines.push(` models: ${inlineList(p.models)}`);
592
+ if (p.default)
593
+ lines.push(" default: true");
594
+ if (p.auth) {
595
+ lines.push(" auth {");
596
+ lines.push(` type: ${p.auth.type}`);
597
+ if (p.auth.issuer)
598
+ lines.push(` issuer: ${q(p.auth.issuer)}`);
599
+ if (p.auth.audience)
600
+ lines.push(` audience: ${q(p.auth.audience)}`);
601
+ if (p.auth.tokenUrl)
602
+ lines.push(` token-url: ${q(p.auth.tokenUrl)}`);
603
+ if (p.auth.clientId)
604
+ lines.push(` client-id: ${q(p.auth.clientId)}`);
605
+ if (p.auth.scopes?.length)
606
+ lines.push(` scopes: ${inlineList(p.auth.scopes)}`);
607
+ lines.push(" }");
608
+ }
609
+ lines.push(" }");
610
+ }
611
+ lines.push(" }");
612
+ return lines.join("\n");
613
+ }
614
+ function serializeSchedules(jobs) {
615
+ if (jobs.length === 0)
616
+ return null;
617
+ const lines = [" schedule {"];
618
+ for (const job of jobs) {
619
+ lines.push(` job ${job.id} {`);
620
+ if (job.cron)
621
+ lines.push(` cron: "${job.cron}"`);
622
+ if (job.every)
623
+ lines.push(` every: "${job.every}"`);
624
+ if (job.agent)
625
+ lines.push(` agent: ${job.agent}`);
626
+ if (job.action)
627
+ lines.push(` action: ${job.action}`);
628
+ if (job.enabled === false)
629
+ lines.push(" enabled: false");
630
+ lines.push(" }");
631
+ }
632
+ lines.push(" }");
633
+ return lines.join("\n");
634
+ }
635
+ function serializeInterfaces(ifaces) {
636
+ if (ifaces.length === 0)
637
+ return null;
638
+ const lines = [" interfaces {"];
639
+ for (const iface of ifaces) {
640
+ lines.push(` ${iface.id} {`);
641
+ if (iface.type)
642
+ lines.push(` type: ${iface.type}`);
643
+ for (const [k, v] of Object.entries(iface.config)) {
644
+ lines.push(` ${k}: ${q(String(v))}`);
645
+ }
646
+ lines.push(" }");
647
+ }
648
+ lines.push(" }");
649
+ return lines.join("\n");
650
+ }
651
+ function serializeSchemas(schemas) {
652
+ if (schemas.length === 0)
653
+ return null;
654
+ const lines = [" schemas {"];
655
+ for (const schema of schemas) {
656
+ lines.push(` schema ${schema.id} {`);
657
+ for (const f of schema.fields) {
658
+ lines.push(` ${f.name}${f.optional ? "?" : ""}: ${formatSchemaType(f.type)}`);
659
+ }
660
+ lines.push(" }");
661
+ }
662
+ lines.push(" }");
663
+ return lines.join("\n");
664
+ }
665
+ function serializeEnv(env) {
666
+ const entries = Object.entries(env);
667
+ if (entries.length === 0)
668
+ return null;
669
+ const lines = [" env {"];
670
+ for (const [key, value] of entries) {
671
+ const val = typeof value === "string" ? value : value.value;
672
+ lines.push(` ${key}: ${q(val)}`);
673
+ }
674
+ lines.push(" }");
675
+ return lines.join("\n");
676
+ }
677
+ function serializeBatch(batch) {
678
+ const entries = Object.entries(batch);
679
+ if (entries.length === 0)
680
+ return null;
681
+ const lines = [" batch {"];
682
+ for (const [k, v] of entries) {
683
+ lines.push(` ${k}: ${JSON.stringify(v)}`);
684
+ }
685
+ lines.push(" }");
686
+ return lines.join("\n");
687
+ }
688
+ function serializeEnvironments(environments) {
689
+ const entries = Object.entries(environments);
690
+ if (entries.length === 0)
691
+ return null;
692
+ const lines = [" environments {"];
693
+ for (const [name, config] of entries) {
694
+ lines.push(` ${name} {`);
695
+ for (const [k, v] of Object.entries(config)) {
696
+ lines.push(` ${k}: ${JSON.stringify(v)}`);
697
+ }
698
+ lines.push(" }");
699
+ }
700
+ lines.push(" }");
701
+ return lines.join("\n");
702
+ }
703
+ function serializeCheckpoint(cp) {
704
+ const lines = [" checkpoint {"];
705
+ lines.push(` backend: ${cp.backend}`);
706
+ if (cp.connection)
707
+ lines.push(` connection: ${q(cp.connection)}`);
708
+ lines.push(` strategy: ${cp.strategy}`);
709
+ if (cp.ttl)
710
+ lines.push(` ttl: ${cp.ttl}`);
711
+ if (cp.replay) {
712
+ lines.push(" replay {");
713
+ lines.push(` enabled: ${cp.replay.enabled}`);
714
+ if (cp.replay.maxHistory)
715
+ lines.push(` max-history: ${cp.replay.maxHistory}`);
716
+ if (cp.replay.branch)
717
+ lines.push(` branch: true`);
718
+ lines.push(" }");
719
+ }
720
+ lines.push(" }");
721
+ return lines.join("\n");
722
+ }
723
+ function serializeArtifacts(artifacts) {
724
+ if (artifacts.length === 0)
725
+ return null;
726
+ const lines = [" artifacts {"];
727
+ for (const a of artifacts) {
728
+ lines.push(` artifact ${a.id} {`);
729
+ lines.push(` type: ${a.type}`);
730
+ if (a.path)
731
+ lines.push(` path: "${a.path}"`);
732
+ if (a.retention)
733
+ lines.push(` retention: ${a.retention}`);
734
+ if (a.dependsOn?.length)
735
+ lines.push(` depends-on: ${inlineList(a.dependsOn)}`);
736
+ lines.push(" }");
737
+ }
738
+ lines.push(" }");
739
+ return lines.join("\n");
740
+ }
741
+ function serializeParams(params) {
742
+ if (params.length === 0)
743
+ return null;
744
+ const lines = [" params {"];
745
+ for (const p of params) {
746
+ const parts = [`type: ${p.type}`];
747
+ if (p.required)
748
+ parts.push("required: true");
749
+ if (p.default !== undefined)
750
+ parts.push(`default: ${JSON.stringify(p.default)}`);
751
+ lines.push(` param ${p.name} { ${parts.join("; ")} }`);
752
+ }
753
+ lines.push(" }");
754
+ return lines.join("\n");
755
+ }
756
+ // ---------------------------------------------------------------------------
757
+ // Main serializer
758
+ // ---------------------------------------------------------------------------
759
+ export function serializeAST(ast) {
760
+ const sections = [];
761
+ // Header
762
+ const patterns = ast.topology.patterns.length > 0
763
+ ? ast.topology.patterns.join(", ")
764
+ : "";
765
+ const keyword = ast.isFragment ? "fragment" : "topology";
766
+ sections.push(`${keyword} ${ast.topology.name} : [${patterns}] {`);
767
+ // Meta
768
+ sections.push(serializeMeta(ast));
769
+ // Orchestrator
770
+ const orchestrator = ast.nodes.find((n) => n.type === "orchestrator");
771
+ if (orchestrator) {
772
+ sections.push("");
773
+ sections.push(serializeOrchestrator(orchestrator));
774
+ }
775
+ // Roles
776
+ const roles = serializeRoles(ast.roles);
777
+ if (roles) {
778
+ sections.push("");
779
+ sections.push(roles);
780
+ }
781
+ // Nodes: agents, actions, groups, humans
782
+ const agents = ast.nodes.filter((n) => n.type === "agent");
783
+ const actions = ast.nodes.filter((n) => n.type === "action");
784
+ const groups = ast.nodes.filter((n) => n.type === "group");
785
+ const humans = ast.nodes.filter((n) => n.type === "human");
786
+ const gates = ast.nodes.filter((n) => n.type === "gate");
787
+ for (const action of actions) {
788
+ sections.push("");
789
+ sections.push(serializeAction(action));
790
+ }
791
+ for (const agent of agents) {
792
+ sections.push("");
793
+ sections.push(serializeAgent(agent));
794
+ }
795
+ for (const group of groups) {
796
+ sections.push("");
797
+ sections.push(serializeGroup(group));
798
+ }
799
+ for (const human of humans) {
800
+ sections.push("");
801
+ sections.push(serializeHuman(human));
802
+ }
803
+ // Flow
804
+ const flow = serializeFlow(ast.edges);
805
+ if (flow) {
806
+ sections.push("");
807
+ sections.push(flow);
808
+ }
809
+ // Gates
810
+ const gatesSerialized = serializeGates(gates);
811
+ if (gatesSerialized) {
812
+ sections.push("");
813
+ sections.push(gatesSerialized);
814
+ }
815
+ // Depth
816
+ const depth = serializeDepth(ast.depth);
817
+ if (depth) {
818
+ sections.push("");
819
+ sections.push(depth);
820
+ }
821
+ // Memory
822
+ const memory = serializeMemory(ast.memory);
823
+ if (memory) {
824
+ sections.push("");
825
+ sections.push(memory);
826
+ }
827
+ // Batch
828
+ const batch = serializeBatch(ast.batch);
829
+ if (batch) {
830
+ sections.push("");
831
+ sections.push(batch);
832
+ }
833
+ // Environments
834
+ const environments = serializeEnvironments(ast.environments);
835
+ if (environments) {
836
+ sections.push("");
837
+ sections.push(environments);
838
+ }
839
+ // Triggers
840
+ const triggers = serializeTriggers(ast.triggers);
841
+ if (triggers) {
842
+ sections.push("");
843
+ sections.push(triggers);
844
+ }
845
+ // Hooks
846
+ const hooks = serializeHooks(ast.hooks);
847
+ if (hooks) {
848
+ sections.push("");
849
+ sections.push(hooks);
850
+ }
851
+ // Settings
852
+ const settings = serializeSettings(ast.settings);
853
+ if (settings) {
854
+ sections.push("");
855
+ sections.push(settings);
856
+ }
857
+ // MCP Servers
858
+ const mcp = serializeMcpServers(ast.mcpServers);
859
+ if (mcp) {
860
+ sections.push("");
861
+ sections.push(mcp);
862
+ }
863
+ // Metering
864
+ if (ast.metering) {
865
+ sections.push("");
866
+ sections.push(serializeMetering(ast.metering));
867
+ }
868
+ // Skills
869
+ const skills = serializeSkills(ast.skills);
870
+ if (skills) {
871
+ sections.push("");
872
+ sections.push(skills);
873
+ }
874
+ // Tools
875
+ const tools = serializeTools(ast.toolDefs);
876
+ if (tools) {
877
+ sections.push("");
878
+ sections.push(tools);
879
+ }
880
+ // Schemas
881
+ const schemas = serializeSchemas(ast.schemas);
882
+ if (schemas) {
883
+ sections.push("");
884
+ sections.push(schemas);
885
+ }
886
+ // Providers
887
+ const providers = serializeProviders(ast.providers);
888
+ if (providers) {
889
+ sections.push("");
890
+ sections.push(providers);
891
+ }
892
+ // Schedules
893
+ const schedules = serializeSchedules(ast.schedules);
894
+ if (schedules) {
895
+ sections.push("");
896
+ sections.push(schedules);
897
+ }
898
+ // Interfaces
899
+ const interfaces = serializeInterfaces(ast.interfaces);
900
+ if (interfaces) {
901
+ sections.push("");
902
+ sections.push(interfaces);
903
+ }
904
+ // Params
905
+ const params = serializeParams(ast.params);
906
+ if (params) {
907
+ sections.push("");
908
+ sections.push(params);
909
+ }
910
+ // Env
911
+ const env = serializeEnv(ast.env);
912
+ if (env) {
913
+ sections.push("");
914
+ sections.push(env);
915
+ }
916
+ // Checkpoint
917
+ if (ast.checkpoint) {
918
+ sections.push("");
919
+ sections.push(serializeCheckpoint(ast.checkpoint));
920
+ }
921
+ // Artifacts
922
+ const artifacts = serializeArtifacts(ast.artifacts);
923
+ if (artifacts) {
924
+ sections.push("");
925
+ sections.push(artifacts);
926
+ }
927
+ // Interface endpoints
928
+ if (ast.interfaceEndpoints) {
929
+ sections.push("");
930
+ sections.push(" interface {");
931
+ sections.push(` entry: ${ast.interfaceEndpoints.entry}`);
932
+ sections.push(` exit: ${ast.interfaceEndpoints.exit}`);
933
+ sections.push(" }");
934
+ }
935
+ // Imports
936
+ if (ast.imports.length > 0) {
937
+ sections.push("");
938
+ for (const imp of ast.imports) {
939
+ let line = ` import ${imp.alias} from "${imp.source}"`;
940
+ if (imp.sha256)
941
+ line += ` sha256 "${imp.sha256}"`;
942
+ const paramEntries = Object.entries(imp.params);
943
+ if (paramEntries.length > 0) {
944
+ line += ` with { ${paramEntries.map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ")} }`;
945
+ }
946
+ sections.push(line);
947
+ }
948
+ }
949
+ // Includes
950
+ if (ast.includes.length > 0) {
951
+ sections.push("");
952
+ for (const inc of ast.includes) {
953
+ sections.push(` include "${inc.source}"`);
954
+ }
955
+ }
956
+ // Close
957
+ sections.push("}");
958
+ return sections.join("\n") + "\n";
959
+ }
960
+ //# sourceMappingURL=serializer.js.map