@fnet/cli 0.133.0 → 0.133.1

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 (182) hide show
  1. package/dist/fbin/index.js +14 -1
  2. package/dist/fnet/index.0jcm9pn5.js +1 -0
  3. package/dist/fnet/index.2084z2ed.js +2 -0
  4. package/dist/fnet/index.33f1ggpr.js +1 -0
  5. package/dist/fnet/index.3exge2js.js +1 -0
  6. package/dist/fnet/index.3kfx538h.js +1 -0
  7. package/dist/fnet/index.490y87nc.js +1 -0
  8. package/dist/fnet/index.4g9yezkq.js +1 -0
  9. package/dist/fnet/index.4jkat7r4.js +1 -0
  10. package/dist/fnet/index.7crx8ky1.js +1 -0
  11. package/dist/fnet/index.7vw06nrn.js +1 -0
  12. package/dist/fnet/index.9567fa9x.js +1 -0
  13. package/dist/fnet/index.gh75wt1m.js +1 -0
  14. package/dist/fnet/index.hzsfswvp.js +1 -0
  15. package/dist/fnet/index.jgpc3grc.js +1 -0
  16. package/dist/fnet/index.js +19 -1
  17. package/dist/fnet/index.p0zb7e1b.js +1 -0
  18. package/dist/fnet/index.r19p3bpa.js +2 -0
  19. package/dist/fnet/index.r82rtnmz.js +1 -0
  20. package/dist/fnet/index.s662t98v.js +1 -0
  21. package/dist/fnet/index.w74dpnpn.js +1 -0
  22. package/dist/fnet/index.xeaw5xa9.js +1 -0
  23. package/dist/fnet/index.zm4kesg6.js +1 -0
  24. package/dist/fnode/index.05n3mvs9.js +2 -0
  25. package/dist/fnode/index.2hc9tbyx.js +1 -0
  26. package/dist/fnode/index.2pnjg6dc.js +1 -0
  27. package/dist/fnode/index.9qgtmxq3.js +2 -0
  28. package/dist/fnode/index.b1q7y05p.js +1 -0
  29. package/dist/fnode/index.bhapgrs7.js +1 -0
  30. package/dist/fnode/index.cvxrf34y.js +2 -0
  31. package/dist/fnode/index.dp9wyahp.js +1 -0
  32. package/dist/fnode/index.eqxmcpdc.js +1 -0
  33. package/dist/fnode/index.f2tb0x3t.js +1 -0
  34. package/dist/fnode/index.fbzv6wwf.js +1 -0
  35. package/dist/fnode/index.gazd9raq.js +1 -0
  36. package/dist/fnode/index.hv4s25f0.js +3 -0
  37. package/dist/fnode/index.j5z7dtsx.js +1 -0
  38. package/dist/fnode/index.js +9 -1
  39. package/dist/fnode/index.kb4e4bxf.js +1 -0
  40. package/dist/fnode/index.qn0schqp.js +1 -0
  41. package/dist/fnode/index.rht29phd.js +1 -0
  42. package/dist/fnode/index.rzsfmek6.js +3 -0
  43. package/dist/fnode/index.s0nk6cv8.js +4 -0
  44. package/dist/fnode/index.s66v6wt4.js +1 -0
  45. package/dist/fnode/index.sv7v0y60.js +1 -0
  46. package/dist/fnode/index.tgkhgnrp.js +1 -0
  47. package/dist/fnode/index.vq706f75.js +1 -0
  48. package/dist/fnode/index.y8pvdcny.js +1 -0
  49. package/dist/fnode/index.z4vz93ww.js +1 -0
  50. package/dist/frun/index.js +1 -1
  51. package/dist/fservice/index.js +18 -1
  52. package/dist/fservice/index.q01yvaz0.js +2 -0
  53. package/package.json +21 -18
  54. package/readme.md +62 -15
  55. package/template/fnet/core/object.js +10 -10
  56. package/template/fnet/node/package.json.njk +6 -3
  57. package/template/fnet/node/src/cli/index.js.njk +5 -315
  58. package/template/fnet/node/src/cli/index.js.v1.njk +318 -0
  59. package/template/fnet/node/src/cli/v2/core/args-parser.njk +10 -0
  60. package/template/fnet/node/src/cli/v2/core/imports.njk +31 -0
  61. package/template/fnet/node/src/cli/v2/core/run-wrapper.njk +25 -0
  62. package/template/fnet/node/src/cli/v2/index.js.njk +184 -0
  63. package/template/fnet/node/src/cli/v2/modes/default/extend.njk +11 -0
  64. package/template/fnet/node/src/cli/v2/modes/default/standard.njk +20 -0
  65. package/template/fnet/node/src/cli/v2/modes/http/builtin.njk +66 -0
  66. package/template/fnet/node/src/cli/v2/modes/http/imports.njk +9 -0
  67. package/template/fnet/node/src/cli/v2/modes/http/index.njk +12 -0
  68. package/template/fnet/node/src/cli/v2/modes/mcp/imports.njk +33 -0
  69. package/template/fnet/node/src/cli/v2/modes/mcp/index.njk +30 -0
  70. package/template/fnet/node/src/cli/v2/modes/mcp/server-setup.njk +15 -0
  71. package/template/fnet/node/src/cli/v2/modes/mcp/tool-handlers.njk +46 -0
  72. package/template/fnet/node/src/cli/v2/modes/mcp/transport-http.njk +222 -0
  73. package/template/fnet/node/src/cli/v2/modes/mcp/transport-stdio.njk +9 -0
  74. package/template/fnet/node/src/cli/v2/modes/pipeline/imports.njk +9 -0
  75. package/template/fnet/node/src/cli/v2/modes/pipeline/index.njk +113 -0
  76. package/template/fnet/node/src/cli/v2/modes/webhook/imports.njk +9 -0
  77. package/template/fnet/node/src/cli/v2/modes/webhook/index.njk +127 -0
  78. package/template/fnet/node/src/cli/v2/modes/websocket/imports.njk +15 -0
  79. package/template/fnet/node/src/cli/v2/modes/websocket/index.njk +104 -0
  80. package/template/fnet/node/src/default/blocks/assign.js.njk +10 -48
  81. package/template/fnet/node/src/default/blocks/call.js.njk +110 -156
  82. package/template/fnet/node/src/default/blocks/for.js.njk +58 -74
  83. package/template/fnet/node/src/default/blocks/form.js.njk +21 -59
  84. package/template/fnet/node/src/default/blocks/http.js.njk +135 -0
  85. package/template/fnet/node/src/default/blocks/modules.js.njk +10 -52
  86. package/template/fnet/node/src/default/blocks/new.js.njk +40 -85
  87. package/template/fnet/node/src/default/blocks/next.js.njk +10 -32
  88. package/template/fnet/node/src/default/blocks/output.js.njk +10 -48
  89. package/template/fnet/node/src/default/blocks/parallel.js.njk +64 -0
  90. package/template/fnet/node/src/default/blocks/pipeline.js.njk +109 -0
  91. package/template/fnet/node/src/default/blocks/raise.js.njk +9 -25
  92. package/template/fnet/node/src/default/blocks/retry.js.njk +70 -0
  93. package/template/fnet/node/src/default/blocks/return.js.njk +13 -25
  94. package/template/fnet/node/src/default/blocks/schedule.js.njk +66 -0
  95. package/template/fnet/node/src/default/blocks/signal.js.njk +10 -32
  96. package/template/fnet/node/src/default/blocks/steps.js.njk +32 -48
  97. package/template/fnet/node/src/default/blocks/switch.js.njk +37 -67
  98. package/template/fnet/node/src/default/blocks/tryexcept.js.njk +58 -52
  99. package/template/fnet/node/src/default/blocks/wait.js.njk +10 -30
  100. package/template/fnet/node/src/default/input.args.js.njk +5 -2
  101. package/template/fnet/node/src/default/macros/block-body-header.js.njk +1 -1
  102. package/template/fnet/node/src/default/macros/block-header.js.njk +0 -3
  103. package/template/fnet/node/src/default/macros/block-next.js.njk +1 -1
  104. package/template/fnet/node/src/default/macros/block-run-footer.js.njk +1 -1
  105. package/template/fnet/node/src/default/macros/block-run-header.js.njk +14 -2
  106. package/template/fnet/node/src/default/macros/page.js.njk +1 -1
  107. package/template/fnet/node/src/default/types/block.js.njk +133 -0
  108. package/template/fnet/node/src/default/workflow.js.njk +8 -6
  109. package/template/fnode/node/package.json.njk +5 -4
  110. package/template/fnode/node/src/cli/index.js.njk +3 -397
  111. package/template/fnode/node/src/cli/index.js.v1.njk +464 -0
  112. package/template/fnode/node/src/cli/v2/core/args-parser.njk +10 -0
  113. package/template/fnode/node/src/cli/v2/core/imports.njk +29 -0
  114. package/template/fnode/node/src/cli/v2/core/run-wrapper.njk +25 -0
  115. package/template/fnode/node/src/cli/v2/index.js.njk +184 -0
  116. package/template/fnode/node/src/cli/v2/modes/default/extend.njk +11 -0
  117. package/template/fnode/node/src/cli/v2/modes/default/standard.njk +19 -0
  118. package/template/fnode/node/src/cli/v2/modes/http/builtin.njk +61 -0
  119. package/template/fnode/node/src/cli/v2/modes/http/imports.njk +9 -0
  120. package/template/fnode/node/src/cli/v2/modes/http/index.njk +12 -0
  121. package/template/fnode/node/src/cli/v2/modes/mcp/imports.njk +33 -0
  122. package/template/fnode/node/src/cli/v2/modes/mcp/index.njk +30 -0
  123. package/template/fnode/node/src/cli/v2/modes/mcp/server-setup.njk +15 -0
  124. package/template/fnode/node/src/cli/v2/modes/mcp/tool-handlers.njk +41 -0
  125. package/template/fnode/node/src/cli/v2/modes/mcp/transport-http.njk +212 -0
  126. package/template/fnode/node/src/cli/v2/modes/mcp/transport-stdio.njk +9 -0
  127. package/template/fnode/node/src/cli/v2/modes/pipeline/imports.njk +9 -0
  128. package/template/fnode/node/src/cli/v2/modes/pipeline/index.njk +103 -0
  129. package/template/fnode/node/src/cli/v2/modes/webhook/imports.njk +9 -0
  130. package/template/fnode/node/src/cli/v2/modes/webhook/index.njk +122 -0
  131. package/template/fnode/node/src/cli/v2/modes/websocket/imports.njk +15 -0
  132. package/template/fnode/node/src/cli/v2/modes/websocket/index.njk +99 -0
  133. package/template/fnode/node/src/default/input.args.js.njk +6 -2
  134. package/dist/fnet/index.-SGbq2cI.js +0 -1
  135. package/dist/fnet/index.B5XE4ChJ.js +0 -1
  136. package/dist/fnet/index.Bft2w7m3.js +0 -1
  137. package/dist/fnet/index.BuYxdKtK.js +0 -1
  138. package/dist/fnet/index.C0YpfQ5j.js +0 -1
  139. package/dist/fnet/index.C2S9JYhS.js +0 -1
  140. package/dist/fnet/index.C7saWH6d.js +0 -1
  141. package/dist/fnet/index.CDct_kkF.js +0 -1
  142. package/dist/fnet/index.CMC8mlye.js +0 -1
  143. package/dist/fnet/index.CmMM-Ek9.js +0 -1
  144. package/dist/fnet/index.CuMyez3E.js +0 -1
  145. package/dist/fnet/index.CzAV0S36.js +0 -1
  146. package/dist/fnet/index.D2N9YZmA.js +0 -1
  147. package/dist/fnet/index.D3p7pncT.js +0 -1
  148. package/dist/fnet/index.DG8TqL-1.js +0 -1
  149. package/dist/fnet/index.DI3yyTtl.js +0 -1
  150. package/dist/fnet/index.DOYkqsYT.js +0 -1
  151. package/dist/fnet/index.DWpw12No.js +0 -1
  152. package/dist/fnet/index.DrwlOzAe.js +0 -1
  153. package/dist/fnet/index.Q-CYRcna.js +0 -1
  154. package/dist/fnet/index.W6RYgypK.js +0 -1
  155. package/dist/fnet/index.xd8c7XMr.js +0 -1
  156. package/dist/fnode/index.-SGbq2cI.js +0 -1
  157. package/dist/fnode/index.B5XE4ChJ.js +0 -1
  158. package/dist/fnode/index.B8gal9up.js +0 -1
  159. package/dist/fnode/index.BU1440aO.js +0 -1
  160. package/dist/fnode/index.BcGYSPne.js +0 -1
  161. package/dist/fnode/index.Bft2w7m3.js +0 -1
  162. package/dist/fnode/index.BuYxdKtK.js +0 -1
  163. package/dist/fnode/index.C2S9JYhS.js +0 -1
  164. package/dist/fnode/index.C7saWH6d.js +0 -1
  165. package/dist/fnode/index.CDct_kkF.js +0 -1
  166. package/dist/fnode/index.CMC8mlye.js +0 -1
  167. package/dist/fnode/index.CmMM-Ek9.js +0 -1
  168. package/dist/fnode/index.CuMyez3E.js +0 -1
  169. package/dist/fnode/index.CzAV0S36.js +0 -1
  170. package/dist/fnode/index.D2N9YZmA.js +0 -1
  171. package/dist/fnode/index.D3p7pncT.js +0 -1
  172. package/dist/fnode/index.DG8TqL-1.js +0 -1
  173. package/dist/fnode/index.DI3yyTtl.js +0 -1
  174. package/dist/fnode/index.DWpw12No.js +0 -1
  175. package/dist/fnode/index.DrwlOzAe.js +0 -1
  176. package/dist/fnode/index.N_a5FdgA.js +0 -1
  177. package/dist/fnode/index.Q-CYRcna.js +0 -1
  178. package/dist/fnode/index.UNoFg95r.js +0 -1
  179. package/dist/fnode/index.W6RYgypK.js +0 -1
  180. package/dist/fnode/index.xd8c7XMr.js +0 -1
  181. package/template/fnet/core/print.js +0 -1
  182. package/template/fnet/node/src/default/macros/workflow-header.js.njk +0 -7
@@ -0,0 +1,318 @@
1
+ {% if atom.doc.features.cli.enabled===true %}
2
+
3
+ {# Define macros for reusable code blocks #}
4
+ {% macro importMcpDependencies() %}
5
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
6
+ import { ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js";
7
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
9
+ import express from "express";
10
+ {% endmacro %}
11
+
12
+ {% macro mcpModeCodeExtended(runFn) %}
13
+ if (cliMode === 'mcp') {
14
+ // MCP mode code
15
+ const server = new Server({
16
+ name: "{{atom.doc.features.cli.mcp.name or atom.doc.name}}",
17
+ version: "{{atom.doc.version or '0.0.1'}}"
18
+ }, {
19
+ capabilities: {
20
+ tools: {}
21
+ }
22
+ });
23
+
24
+ // Define available tools
25
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
26
+ return {
27
+ tools: [{
28
+ name: "{{atom.doc.features.cli.mcp.tool.name or atom.doc.name}}",
29
+ description: "{{atom.doc.features.cli.mcp.tool.description or atom.doc.description}}",
30
+ inputSchema: inputSchema,
31
+ }]
32
+ };
33
+ });
34
+
35
+ // Handle tool execution
36
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
37
+ if (request.params.name === "{{atom.doc.features.cli.mcp.tool.name or atom.doc.name}}") {
38
+ try {
39
+ const result = await {{ runFn }}(request.params.arguments, { Engine });
40
+ return {
41
+ content: [{
42
+ type: "text",
43
+ text: JSON.stringify(result)
44
+ }]
45
+ };
46
+ } catch (error) {
47
+ return {
48
+ content: [{
49
+ type: "text",
50
+ text: `Error: ${error.message}`
51
+ }],
52
+ isError: true
53
+ };
54
+ }
55
+ }
56
+ throw new Error("Tool not found");
57
+ });
58
+
59
+ // Get transport type from arguments
60
+ const transportType = args['mcp-transport'] || args.mcp_transport || 'stdio';
61
+ let transport;
62
+
63
+ if (transportType === 'stdio') {
64
+ // Use stdio transport
65
+ transport = new StdioServerTransport();
66
+ } else if (transportType === 'sse') {
67
+ // Use SSE transport
68
+ const app = express();
69
+ app.use(express.json());
70
+
71
+ const port = args['cli-port'] || args.cli_port || 3000;
72
+ const server = app.listen(port, () => {
73
+ console.log(`MCP server started with SSE transport on port ${port}`);
74
+ });
75
+
76
+ transport = new StreamableHTTPServerTransport({
77
+ sessionIdGenerator: () => Math.random().toString(36).substring(2, 15),
78
+ });
79
+
80
+ app.post('/sse', async (req, res) => {
81
+ await transport.handleRequest(req, res, req.body);
82
+ });
83
+
84
+ app.get('/sse', async (req, res) => {
85
+ await transport.handleRequest(req, res);
86
+ });
87
+
88
+ app.delete('/sse', async (req, res) => {
89
+ await transport.handleRequest(req, res);
90
+ });
91
+ } else {
92
+ console.error(`Unknown MCP transport type: ${transportType}`);
93
+ console.error(`Supported types: stdio, sse`);
94
+ process.exit(1);
95
+ }
96
+
97
+ await server.connect(transport);
98
+ return;
99
+ }
100
+ {% endmacro %}
101
+
102
+ {% macro mcpModeCodeEngine(engineVar) %}
103
+ if (cliMode === 'mcp') {
104
+ // MCP mode code
105
+ const server = new Server({
106
+ name: "{{atom.doc.features.cli.mcp.name or atom.doc.name}}",
107
+ version: "{{atom.doc.version or '0.0.1'}}"
108
+ }, {
109
+ capabilities: {
110
+ tools: {}
111
+ }
112
+ });
113
+
114
+ // Define available tools
115
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
116
+ return {
117
+ tools: [{
118
+ name: "{{atom.doc.features.cli.mcp.tool.name or atom.doc.name}}",
119
+ description: "{{atom.doc.features.cli.mcp.tool.description or atom.doc.description}}",
120
+ inputSchema: inputSchema,
121
+ }]
122
+ };
123
+ });
124
+
125
+ // Handle tool execution
126
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
127
+ if (request.params.name === "{{atom.doc.features.cli.mcp.tool.name or atom.doc.name}}") {
128
+ try {
129
+ const result = await {{ engineVar }}.run(request.params.arguments);
130
+ return {
131
+ content: [{
132
+ type: "text",
133
+ text: JSON.stringify(result)
134
+ }]
135
+ };
136
+ } catch (error) {
137
+ return {
138
+ content: [{
139
+ type: "text",
140
+ text: `Error: ${error.message}`
141
+ }],
142
+ isError: true
143
+ };
144
+ }
145
+ }
146
+ throw new Error("Tool not found");
147
+ });
148
+
149
+ // Note: Direct access to workflow nodes is not implemented in this version
150
+ // In a future version, we could expose workflow nodes as separate MCP tools
151
+
152
+ // Get transport type from arguments
153
+ const transportType = args['mcp-transport'] || args.mcp_transport || 'stdio';
154
+ let transport;
155
+
156
+ if (transportType === 'stdio') {
157
+ // Use stdio transport
158
+ transport = new StdioServerTransport();
159
+ } else if (transportType === 'sse') {
160
+ // Use SSE transport
161
+ const app = express();
162
+ app.use(express.json());
163
+
164
+ const port = args['cli-port'] || args.cli_port || 3000;
165
+ const server = app.listen(port, () => {
166
+ console.log(`MCP server started with SSE transport on port ${port}`);
167
+ });
168
+
169
+ transport = new StreamableHTTPServerTransport({
170
+ sessionIdGenerator: () => Math.random().toString(36).substring(2, 15),
171
+ });
172
+
173
+ app.post('/sse', async (req, res) => {
174
+ await transport.handleRequest(req, res, req.body);
175
+ });
176
+
177
+ app.get('/sse', async (req, res) => {
178
+ await transport.handleRequest(req, res);
179
+ });
180
+
181
+ app.delete('/sse', async (req, res) => {
182
+ await transport.handleRequest(req, res);
183
+ });
184
+ } else {
185
+ console.error(`Unknown MCP transport type: ${transportType}`);
186
+ console.error(`Supported types: stdio, sse`);
187
+ process.exit(1);
188
+ }
189
+
190
+ await server.connect(transport);
191
+ return;
192
+ }
193
+ {% endmacro %}
194
+
195
+ {% macro httpModeCodeExpress(runFn, engineParam) %}
196
+ if (cliMode === 'http') {
197
+ // HTTP mode code using Express
198
+ const app = express();
199
+ app.use(express.json());
200
+
201
+ app.post('/{{atom.doc.features.cli.http.path or atom.doc.name}}', async (req, res) => {
202
+ try {
203
+ const result = await {{ runFn }}(req.body{{ engineParam }});
204
+ res.json(result);
205
+ } catch (error) {
206
+ res.status(500).json({ error: error.message });
207
+ }
208
+ });
209
+
210
+ const port = args['cli-port'] || args.cli_port || 3000;
211
+ app.listen(port, () => {
212
+ console.log(`HTTP server started on port ${port}`);
213
+ });
214
+ return;
215
+ }
216
+ {% endmacro %}
217
+
218
+ {% macro defaultModeExtended() %}
219
+ if (cliMode === 'default') {
220
+ // Default mode code
221
+ return await runExtended(await argv(), { Engine });
222
+ }
223
+ {% endmacro %}
224
+
225
+ {% macro defaultModeEngine(engineVar) %}
226
+ if (cliMode === 'default') {
227
+ // Default mode code
228
+ const result = await {{ engineVar }}.run(await argv());
229
+
230
+ if (typeof result !== 'undefined') {
231
+ const stdout_format = args['stdout-format'] || args.stdout_format || null;
232
+
233
+ if (stdout_format === 'json') console.log(JSON.stringify(result, null, 2));
234
+ else console.log(result);
235
+ }
236
+ return;
237
+ }
238
+ {% endmacro %}
239
+
240
+ {% macro runWithCatch() %}
241
+ run()
242
+ .catch((error) => {
243
+ console.error(error.message);
244
+ process.exit(1);
245
+ });
246
+ {% endmacro %}
247
+
248
+ {% macro runWithThenCatch() %}
249
+ run()
250
+ .then(() => {
251
+ {# process.exit(0); #}
252
+ })
253
+ .catch((error) => {
254
+ console.error(error.message);
255
+ process.exit(1);
256
+ });
257
+ {% endmacro %}
258
+
259
+ {# Main template starts here #}
260
+ import argv,{argsParser} from '../default/input.args.js';
261
+ import { schema as inputSchema } from '../default/validate_input.js';
262
+ import { default as Engine } from '../default/{{atom.doc.features.cli_default_entry_file or atom.doc.features.main_default_entry_file}}';
263
+
264
+ {% if atom.doc.features.cli.mcp.enabled === true %}
265
+ {{ importMcpDependencies() }}
266
+ {% elif atom.doc.features.cli.http.enabled===true %}
267
+ // Using express for HTTP mode
268
+ import express from 'express';
269
+ {% endif %}
270
+
271
+ {% if atom.doc.features.cli.extend===true %}
272
+ {# TYPE 1 #}
273
+ import { default as runExtended } from '../../../cli/index.js';
274
+
275
+ const run = async () => {
276
+ const args = argsParser(process.argv.slice(2));
277
+ const cliMode = args['cli-mode'] || args.cli_mode || 'default';
278
+
279
+ {{ defaultModeExtended() }}
280
+
281
+ {% if atom.doc.features.cli.mcp.enabled === true %}
282
+ {{ mcpModeCodeExtended('runExtended') }}
283
+ {% endif %}
284
+
285
+ {% if atom.doc.features.cli.http.enabled===true %}
286
+ {{ httpModeCodeExpress('runExtended', ', { Engine }') }}
287
+ {% endif %}
288
+
289
+ console.error(`Unknown CLI mode: ${cliMode}`);
290
+ process.exit(1);
291
+ };
292
+
293
+ {{ runWithThenCatch() }}
294
+ {% else %}
295
+ {# TYPE 2 #}
296
+ import { argsParser } from '@fnet/args';
297
+ const run = async () => {
298
+ const args =argsParser(process.argv.slice(2));
299
+ const cliMode = args['cli-mode'] || args.cli_mode || 'default';
300
+ const engine = new Engine();
301
+
302
+ {{ defaultModeEngine('engine') }}
303
+
304
+ {% if atom.doc.features.cli.mcp.enabled === true %}
305
+ {{ mcpModeCodeEngine('engine') }}
306
+ {% endif %}
307
+
308
+ {% if atom.doc.features.cli.http.enabled===true %}
309
+ {{ httpModeCodeExpress('engine.run', '') }}
310
+ {% endif %}
311
+
312
+ console.error(`Unknown CLI mode: ${cliMode}`);
313
+ process.exit(1);
314
+ };
315
+
316
+ {{ runWithCatch() }}
317
+ {% endif %}
318
+ {% endif %}
@@ -0,0 +1,10 @@
1
+ {# ============================================================================
2
+ ARGUMENT PARSER
3
+ ============================================================================
4
+ Parses command-line arguments and extracts CLI mode
5
+ ============================================================================ #}
6
+
7
+ const parseArgs = () => {
8
+ return argsParser(process.argv.slice(2));
9
+ };
10
+
@@ -0,0 +1,31 @@
1
+ {# ============================================================================
2
+ CORE IMPORTS
3
+ ============================================================================
4
+ Base imports required for all CLI modes
5
+ Supports both ESM and CJS formats, standard and extend modes
6
+
7
+ fnet-specific: Imports Engine instead of Node
8
+ - Standard mode: Creates engine instance and calls engine.run()
9
+ - Extend mode: Imports runExtended and passes { Engine } as context
10
+ ============================================================================ #}
11
+
12
+ {% if atom.doc.features.project.format==='esm' %}
13
+ {# ESM Format #}
14
+ import argv,{argsParser} from '../default/input.args.js';
15
+ import { schema as inputSchema } from '../default/validate_input.js';
16
+ import { default as Engine } from '../default/{{atom.doc.features.cli_default_entry_file or atom.doc.features.main_default_entry_file}}';
17
+ {% if atom.doc.features.cli.extend===true %}
18
+ import { default as runExtended } from '../../../cli/index.js';
19
+ {% endif %}
20
+
21
+ {% elif atom.doc.features.project.format==='cjs' %}
22
+ {# CJS Format #}
23
+ const { default:argv,argsParser } = require('../default/input.args.js');
24
+ const { schema: inputSchema } = require('../default/validate_input.js');
25
+ const { default: Engine } = require('../default/{{atom.doc.features.cli_default_entry_file or atom.doc.features.main_default_entry_file}}');
26
+ {% if atom.doc.features.cli.extend===true %}
27
+ const { default: runExtended } = require('../../../cli/index.js');
28
+ {% endif %}
29
+
30
+ {% endif %}
31
+
@@ -0,0 +1,25 @@
1
+ {# ============================================================================
2
+ RUN WRAPPER
3
+ ============================================================================
4
+ Error handling wrapper for the main run function
5
+ Supports both standard and extend modes
6
+ ============================================================================ #}
7
+
8
+ {% if atom.doc.features.cli.extend===true %}
9
+ {# Extend mode - with then() chain #}
10
+ run()
11
+ .then(() => {
12
+ {# process.exit(0); #}
13
+ })
14
+ .catch((error) => {
15
+ console.error(error.message);
16
+ process.exit(1);
17
+ });
18
+ {% else %}
19
+ {# Standard mode - simple catch #}
20
+ run().catch((error) => {
21
+ console.error(error.message);
22
+ process.exit(1);
23
+ });
24
+ {% endif %}
25
+
@@ -0,0 +1,184 @@
1
+ {# ============================================================================
2
+ CLI TEMPLATE V2 - MODULAR ARCHITECTURE
3
+ ============================================================================
4
+
5
+ This template uses a modular, registry-based approach for maximum
6
+ extensibility. New modes, transports, and output formats can be added
7
+ without modifying the core template structure.
8
+
9
+ Architecture:
10
+ - core/ : Base imports, argument parsing, error handling
11
+ - modes/ : CLI execution modes (default, mcp, http, pipeline, etc.)
12
+ - output/ : Output formatters (json, yaml, table, etc.)
13
+
14
+ Each mode is self-contained and can be enabled/disabled via feature flags.
15
+
16
+ Supports:
17
+ - ESM and CJS formats
18
+ - Standard and Extend modes
19
+ - Multiple CLI modes (default, mcp, http)
20
+
21
+ ============================================================================ #}
22
+
23
+ {% if atom.doc.features.cli.enabled===true %}
24
+
25
+ {# --------------------------------------------------------------------------
26
+ CORE IMPORTS
27
+ -------------------------------------------------------------------------- #}
28
+ {% include "./core/imports.njk" %}
29
+
30
+ {# --------------------------------------------------------------------------
31
+ SHARED IMPORTS
32
+ --------------------------------------------------------------------------
33
+ Shared dependencies used by multiple modes
34
+ Prevents duplicate imports when multiple modes are enabled
35
+ -------------------------------------------------------------------------- #}
36
+ {% if atom.doc.features.cli.http.enabled===true or atom.doc.features.cli.webhook.enabled===true %}
37
+ // Shared: http module (used by HTTP and Webhook modes)
38
+ {% if atom.doc.features.project.format==='esm' %}
39
+ import http from 'http';
40
+ {% elif atom.doc.features.project.format==='cjs' %}
41
+ const http = require('http');
42
+ {% endif %}
43
+ {% endif %}
44
+
45
+ {% if atom.doc.features.cli.mcp.enabled === true or atom.doc.features.cli.webhook.enabled===true %}
46
+ // Shared: crypto module (used by MCP and Webhook modes)
47
+ {% if atom.doc.features.project.format==='esm' %}
48
+ import crypto from 'crypto';
49
+ {% elif atom.doc.features.project.format==='cjs' %}
50
+ const crypto = require('crypto');
51
+ {% endif %}
52
+ {% endif %}
53
+
54
+ {# --------------------------------------------------------------------------
55
+ MODE-SPECIFIC IMPORTS
56
+ --------------------------------------------------------------------------
57
+ Import dependencies for ALL enabled CLI modes
58
+ Multiple modes can be enabled simultaneously
59
+ -------------------------------------------------------------------------- #}
60
+ {% if atom.doc.features.cli.mcp.enabled === true %}
61
+ {% include "./modes/mcp/imports.njk" %}
62
+ {% endif %}
63
+
64
+ {% if atom.doc.features.cli.http.enabled===true %}
65
+ {% include "./modes/http/imports.njk" %}
66
+ {% endif %}
67
+
68
+ {% if atom.doc.features.cli.pipeline.enabled===true %}
69
+ {% include "./modes/pipeline/imports.njk" %}
70
+ {% endif %}
71
+
72
+ {% if atom.doc.features.cli.websocket.enabled===true %}
73
+ {% include "./modes/websocket/imports.njk" %}
74
+ {% endif %}
75
+
76
+ {% if atom.doc.features.cli.webhook.enabled===true %}
77
+ {% include "./modes/webhook/imports.njk" %}
78
+ {% endif %}
79
+
80
+ {# --------------------------------------------------------------------------
81
+ ARGUMENT PARSER
82
+ -------------------------------------------------------------------------- #}
83
+ {% include "./core/args-parser.njk" %}
84
+
85
+ {# --------------------------------------------------------------------------
86
+ MAIN RUN FUNCTION
87
+ --------------------------------------------------------------------------
88
+ Mode registry: Each mode is self-contained and handles its own logic
89
+ -------------------------------------------------------------------------- #}
90
+ const run = async () => {
91
+ const args = parseArgs();
92
+ const cliMode = args['cli-mode'] || args.cli_mode || 'default';
93
+
94
+ {# --------------------------------------------------------------------------
95
+ DEFAULT MODE
96
+ --------------------------------------------------------------------------
97
+ Standard or extended mode based on CLI configuration
98
+ -------------------------------------------------------------------------- #}
99
+ {% if atom.doc.features.cli.extend===true %}
100
+ {% include "./modes/default/extend.njk" %}
101
+ {% else %}
102
+ {% include "./modes/default/standard.njk" %}
103
+ {% endif %}
104
+
105
+ {# --------------------------------------------------------------------------
106
+ MCP MODE
107
+ --------------------------------------------------------------------------
108
+ Model Context Protocol server with multiple transport options
109
+ -------------------------------------------------------------------------- #}
110
+ {% if atom.doc.features.cli.mcp.enabled === true %}
111
+ {% include "./modes/mcp/index.njk" %}
112
+ {% endif %}
113
+
114
+ {# --------------------------------------------------------------------------
115
+ HTTP MODE
116
+ --------------------------------------------------------------------------
117
+ REST API server using built-in http module
118
+ -------------------------------------------------------------------------- #}
119
+ {% if atom.doc.features.cli.http.enabled===true %}
120
+ {% include "./modes/http/index.njk" %}
121
+ {% endif %}
122
+
123
+ {# --------------------------------------------------------------------------
124
+ PIPELINE MODE
125
+ --------------------------------------------------------------------------
126
+ Unix pipeline integration via stdin/stdout
127
+ -------------------------------------------------------------------------- #}
128
+ {% if atom.doc.features.cli.pipeline.enabled===true %}
129
+ {% include "./modes/pipeline/index.njk" %}
130
+ {% endif %}
131
+
132
+ {# --------------------------------------------------------------------------
133
+ WEBSOCKET MODE
134
+ --------------------------------------------------------------------------
135
+ Real-time bidirectional communication
136
+ -------------------------------------------------------------------------- #}
137
+ {% if atom.doc.features.cli.websocket.enabled===true %}
138
+ {% include "./modes/websocket/index.njk" %}
139
+ {% endif %}
140
+
141
+ {# --------------------------------------------------------------------------
142
+ WEBHOOK MODE
143
+ --------------------------------------------------------------------------
144
+ Event-driven HTTP with HMAC signature verification
145
+ -------------------------------------------------------------------------- #}
146
+ {% if atom.doc.features.cli.webhook.enabled===true %}
147
+ {% include "./modes/webhook/index.njk" %}
148
+ {% endif %}
149
+
150
+ {# --------------------------------------------------------------------------
151
+ FUTURE MODES
152
+ --------------------------------------------------------------------------
153
+ Add new modes here by simply including their index.njk
154
+
155
+ Examples:
156
+ - gRPC mode for high-performance RPC
157
+ - GraphQL mode for flexible APIs
158
+ - SSE mode for server-sent events
159
+ -------------------------------------------------------------------------- #}
160
+
161
+ {# {% if atom.doc.features.cli.webhook.enabled===true %}
162
+ {% include "./modes/webhook/index.njk" %}
163
+ {% endif %} #}
164
+
165
+ {# {% if atom.doc.features.cli.grpc.enabled===true %}
166
+ {% include "./modes/grpc/index.njk" %}
167
+ {% endif %} #}
168
+
169
+ {# --------------------------------------------------------------------------
170
+ UNKNOWN MODE HANDLER
171
+ -------------------------------------------------------------------------- #}
172
+ console.error(`Unknown CLI mode: ${cliMode}`);
173
+ console.error(`Available modes: default{% if atom.doc.features.cli.mcp.enabled === true %}, mcp{% endif %}{% if atom.doc.features.cli.http.enabled===true %}, http{% endif %}{% if atom.doc.features.cli.pipeline.enabled===true %}, pipeline{% endif %}{% if atom.doc.features.cli.websocket.enabled===true %}, websocket{% endif %}{% if atom.doc.features.cli.webhook.enabled===true %}, webhook{% endif %}`);
174
+ process.exit(1);
175
+ };
176
+
177
+ {# --------------------------------------------------------------------------
178
+ ERROR HANDLER & RUN
179
+ -------------------------------------------------------------------------- #}
180
+ {% include "./core/run-wrapper.njk" %}
181
+
182
+ {% endif %}
183
+ {# End of cli.enabled check #}
184
+
@@ -0,0 +1,11 @@
1
+ {# ============================================================================
2
+ DEFAULT MODE - EXTEND
3
+ ============================================================================
4
+ Extended CLI mode for fnet: Calls runExtended with Engine context
5
+ ============================================================================ #}
6
+
7
+ if (cliMode === 'default') {
8
+ // Default mode code
9
+ return await runExtended(await argv(), { Engine });
10
+ }
11
+
@@ -0,0 +1,20 @@
1
+ {# ============================================================================
2
+ DEFAULT MODE - STANDARD
3
+ ============================================================================
4
+ Standard CLI mode for fnet: Creates engine instance and runs workflow
5
+ ============================================================================ #}
6
+
7
+ if (cliMode === 'default') {
8
+ // Default mode code
9
+ const engine = new Engine();
10
+ const result = await engine.run(await argv());
11
+
12
+ if (typeof result !== 'undefined') {
13
+ const stdout_format = args['stdout-format'] || args.stdout_format || null;
14
+
15
+ if (stdout_format === 'json') console.log(JSON.stringify(result, null, 2));
16
+ else console.log(result);
17
+ }
18
+ return;
19
+ }
20
+
@@ -0,0 +1,66 @@
1
+ {# ============================================================================
2
+ HTTP MODE - BUILT-IN (Native Node.js HTTP)
3
+ ============================================================================
4
+ Simple REST API server using Node.js built-in http module
5
+ No external dependencies required
6
+ ============================================================================ #}
7
+
8
+ const server = http.createServer(async (req, res) => {
9
+ // CORS headers
10
+ res.setHeader('Access-Control-Allow-Origin', '*');
11
+ res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
12
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
13
+
14
+ // Handle OPTIONS preflight
15
+ if (req.method === 'OPTIONS') {
16
+ res.writeHead(200);
17
+ res.end();
18
+ return;
19
+ }
20
+
21
+ // Only accept POST requests
22
+ if (req.method !== 'POST') {
23
+ res.writeHead(405, { 'Content-Type': 'application/json' });
24
+ res.end(JSON.stringify({ error: 'Method not allowed' }));
25
+ return;
26
+ }
27
+
28
+ // Check path
29
+ const path = '/{{atom.doc.features.cli.http.path or atom.doc.name}}';
30
+ if (req.url !== path) {
31
+ res.writeHead(404, { 'Content-Type': 'application/json' });
32
+ res.end(JSON.stringify({ error: 'Not found' }));
33
+ return;
34
+ }
35
+
36
+ // Parse request body
37
+ let body = '';
38
+ req.on('data', chunk => {
39
+ body += chunk.toString();
40
+ });
41
+
42
+ req.on('end', async () => {
43
+ try {
44
+ const data = JSON.parse(body);
45
+ {% if atom.doc.features.cli.extend===true %}
46
+ const result = await runExtended(data, { Engine });
47
+ {% else %}
48
+ const engine = new Engine();
49
+ const result = await engine.run(data);
50
+ {% endif %}
51
+
52
+ res.writeHead(200, { 'Content-Type': 'application/json' });
53
+ res.end(JSON.stringify(result));
54
+ } catch (error) {
55
+ res.writeHead(500, { 'Content-Type': 'application/json' });
56
+ res.end(JSON.stringify({ error: error.message }));
57
+ }
58
+ });
59
+ });
60
+
61
+ const port = args['cli-port'] || args.cli_port || 3000;
62
+ server.listen(port, () => {
63
+ console.log(`HTTP server started on port ${port} (native http)`);
64
+ });
65
+ return;
66
+
@@ -0,0 +1,9 @@
1
+ {# ============================================================================
2
+ HTTP MODE - IMPORTS
3
+ ============================================================================
4
+ No mode-specific imports needed
5
+ http module is imported in shared imports section
6
+ ============================================================================ #}
7
+
8
+ {# http module imported in shared section #}
9
+