@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
package/readme.md CHANGED
@@ -16,12 +16,18 @@
16
16
 
17
17
  ## Overview
18
18
 
19
- Flownet is a revolutionary development framework that isolates non-functional components, allowing developers to focus solely on functional code. The `@fnet/cli` package provides command-line tools to create, build, and manage Flownet projects.
19
+ Flownet is a low-level flow framework that separates **Core** (your business logic) from **Layers** (infrastructure, dev, build, runtime, and delivery). This separation allows developers to focus on functional code while Flownet automates the surrounding infrastructure. The `@fnet/cli` package provides command-line tools to create, build, and manage Flownet projects.
20
+
21
+ Flownet provides primitives for composing workflows similar to how React provides components for UI development. It emphasizes a **schema-first approach** with **deterministic core**, enabling **multi-runtime portability**.
20
22
 
21
23
  ### Key Features
22
24
 
25
+ - **Core vs Layers Architecture**: Separate your business logic (Core) from infrastructure (Layers) for cleaner, more maintainable code
26
+ - **Nodes & Flows**: Reusable functional units (Nodes) with explicit I/O schemas, orchestrated by Flows
27
+ - **I/O Contracts**: Schema-first contracts define clear input/output expectations for deterministic behavior
28
+ - **Automatic Dependency Detection**: Simplified dependency management across your project
29
+ - **Multi-Runtime Support**: Deploy to Node.js, Bun, Deno, or Python - choose the best runtime for each task
23
30
  - **Language Agnostic**: Support for multiple programming languages (JavaScript, Python) in the same project
24
- - **Runtime Flexibility**: Choose the best runtime for each task (Node.js, Python, Bun)
25
31
  - **Unified Interface**: Consistent commands across different project types
26
32
  - **Tag-Based Configuration**: Powerful conditional configuration with `--ftag` parameter
27
33
  - **Isolated Workspace**: All build artifacts and dependencies are kept in `.workspace` directory
@@ -97,54 +103,95 @@ fbin list
97
103
  fbin uninstall awesome-tool --yes
98
104
  ```
99
105
 
106
+ ## Core Concepts
107
+
108
+ ### Nodes & Flows
109
+
110
+ **Nodes** are reusable functional units that encapsulate business logic with explicit input/output schemas. Each Node:
111
+
112
+ - Has a deterministic, pure function at its core
113
+ - Defines clear I/O contracts (input and output schemas)
114
+ - Can be composed and reused across different Flows
115
+ - Supports automatic dependency detection
116
+
117
+ **Flows** orchestrate Nodes and sub-Flows to create complex workflows. Flows:
118
+
119
+ - Connect multiple Nodes with explicit data contracts
120
+ - Enable multi-runtime portability through schema-first design
121
+ - Support complex data transformations and conditional logic
122
+ - Maintain deterministic behavior across different runtimes
123
+
124
+ ### I/O Contracts
125
+
126
+ Flownet uses schema-first contracts to define clear input and output expectations. This approach:
127
+
128
+ - Ensures deterministic behavior across different runtimes
129
+ - Enables automatic validation and type checking
130
+ - Facilitates multi-runtime portability
131
+ - Improves code clarity and maintainability
132
+
100
133
  ## Project Types
101
134
 
102
135
  Flownet supports two main project types:
103
136
 
104
137
  ### fnode Project
105
138
 
106
- An **fnode project** (Flow Node Project) is a classic/node-style project that focuses on creating reusable components or standalone applications. These projects:
139
+ An **fnode project** (Flow Node Project) is a classic/node-style project that focuses on creating reusable Nodes or standalone applications. These projects:
107
140
 
108
141
  - Use `fnode.yaml` as their configuration file
109
142
  - Typically contain a single code file in the `src` directory
110
143
  - Can be built with different runtimes (Node.js, Python, Bun)
111
144
  - Support multiple programming languages simultaneously
145
+ - Ideal for creating reusable components with explicit I/O contracts
112
146
 
113
147
  ### fnet Project
114
148
 
115
- An **fnet project** (Flow Project) is a workflow-oriented project that focuses on orchestrating multiple components. These projects:
149
+ An **fnet project** (Flow Project) is a workflow-oriented project that focuses on orchestrating multiple Nodes and Flows. These projects:
116
150
 
117
151
  - Use `fnet.yaml` as their configuration file
118
- - Define workflows that connect multiple components
152
+ - Define workflows that connect multiple Nodes and sub-Flows
119
153
  - Support complex data flows and transformations
154
+ - Enable multi-runtime deployment strategies
155
+ - Ideal for building complex business logic orchestrations
120
156
 
121
157
  ## CLI Tools
122
158
 
123
- Flownet provides four main CLI tools:
159
+ Flownet provides five main CLI tools:
124
160
 
125
- - **`fnode`**: For Node/classic projects (uses `fnode.yaml`)
126
- - **`fnet`**: For Workflow projects (uses `fnet.yaml`)
161
+ - **`fnode`**: For Node/classic projects (uses `fnode.yaml`) - create and manage reusable Nodes
162
+ - **`fnet`**: For Workflow projects (uses `fnet.yaml`) - create and manage Flows that orchestrate Nodes
127
163
  - **`frun`**: Unified interface that works with both project types (auto-detects project file)
128
164
  - **`fbin`**: Binary management system for installing, compiling, and managing CLI tools
165
+ - **`fservice`**: Service management for deploying and running Flownet applications
129
166
 
130
- ## Multi-Language Support
167
+ ## Multi-Language & Multi-Runtime Support
131
168
 
132
- Flownet supports multiple programming languages simultaneously within the same project:
169
+ Flownet supports multiple programming languages and runtimes simultaneously within the same project:
133
170
 
134
171
  ```text
135
172
  my-project/
136
173
  ├── src/
137
- │ ├── index.js # JavaScript implementation (used by both Node.js and Bun)
174
+ │ ├── index.js # JavaScript implementation (used by Node.js and Bun)
138
175
  │ └── index.py # Python implementation
139
176
  ├── fnode.yaml # Project configuration file
140
177
  └── .workspace/ # Build infrastructure (managed by CLI)
141
178
  ```
142
179
 
143
- This allows you to:
180
+ ### Supported Runtimes
181
+
182
+ - **Node.js**: JavaScript/TypeScript execution with full npm ecosystem support
183
+ - **Bun**: Fast JavaScript runtime with improved performance
184
+ - **Deno**: Secure JavaScript/TypeScript runtime with built-in tooling
185
+ - **Python**: Python 3.x for data processing and scientific computing
186
+
187
+ ### Multi-Runtime Portability
188
+
189
+ Thanks to Flownet's schema-first approach and deterministic core:
144
190
 
145
- - Write your core logic once and migrate it to other languages as needed
146
- - Choose the best language for each specific use case
147
- - Use JavaScript with Node.js for quick development, Python for data processing, and JavaScript with Bun for improved performance
191
+ - Write your core logic once and deploy to multiple runtimes
192
+ - Choose the best runtime for each specific use case
193
+ - Migrate between runtimes without changing your business logic
194
+ - Use JavaScript with Node.js for quick development, Python for data processing, and Bun for improved performance
148
195
 
149
196
  ## Tag-Based Configuration
150
197
 
@@ -1,6 +1,6 @@
1
- import getValue from "get-value";
2
- import setValue from "set-value";
3
- import print from "./print.js";
1
+ // import getValue from "get-value";
2
+ // import setValue from "set-value";
3
+ import { setProperty, getProperty } from "dot-prop";
4
4
 
5
5
  export default class Object {
6
6
  #property;
@@ -14,14 +14,14 @@ export default class Object {
14
14
  this.#context = context;
15
15
 
16
16
  this.get = (path, options) => {
17
- return getValue(this.#property, path, options);
17
+ return getProperty(this.#property, path, options);
18
18
  }
19
19
 
20
20
  this.set = (path, value, options) => {
21
- return setValue(this.#property, path, value, options);
21
+ return setProperty(this.#property, path, value, options);
22
22
  }
23
23
 
24
- this.print = print;
24
+ this.print = console.log;
25
25
  }
26
26
 
27
27
  get module() {
@@ -29,19 +29,19 @@ export default class Object {
29
29
  }
30
30
 
31
31
  getModule(path) {
32
- return getValue(this.#module, path);
32
+ return getProperty(this.#module, path);
33
33
  }
34
34
 
35
35
  setModule(path, module) {
36
36
  if (typeof module !== "function") throw new Error("Module must be a function");
37
- return setValue(this.#module, path, module);
37
+ return setProperty(this.#module, path, module);
38
38
  }
39
39
 
40
40
  get getValue() {
41
- return getValue;
41
+ return getProperty;
42
42
  }
43
43
 
44
44
  get setValue() {
45
- return setValue;
45
+ return setProperty;
46
46
  }
47
47
  }
@@ -72,14 +72,14 @@
72
72
  {% if atom.doc.features.cli.enabled %}
73
73
  {% if atom.doc.features.project.format ==='cjs' %}
74
74
  ,"cli": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.dir}}/index.cjs"
75
- {% if atom.doc.features.cli.mcp.enabled===true %}
75
+ {% if atom.doc.features.cli.mcp.enabled === true %}
76
76
  ,"mcp": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.dir}}/index.cjs --cli-mode=mcp"
77
77
  ,"mcp-inspect": "bunx @modelcontextprotocol/inspector bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.dir}}/index.cjs --cli-mode=mcp"
78
78
  {% endif %}
79
79
  {% else %}
80
80
  ,"cli": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.output.file}}"
81
- ,"cli:dev": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.input.file}}"
82
- {% if atom.doc.features.cli.mcp.enabled===true %}
81
+ ,"cli:dev": "NODE_PRESERVE_SYMLINKS=1 bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.input.file}}"
82
+ {% if atom.doc.features.cli.mcp.enabled === true %}
83
83
  ,"cli:mcp": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.output.file}} --cli-mode=mcp"
84
84
  ,"cli:mcp:inspect": "bunx @modelcontextprotocol/inspector bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.output.file}} --cli-mode=mcp"
85
85
  ,"cli:mcp:dev": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.input.file}} --cli-mode=mcp"
@@ -89,6 +89,9 @@
89
89
  ,"cli:compile": "fbin compile {{atom.doc.features.cli.output.file}} -o .bin/{{atom.doc['npm::bin'] or atom.doc['name'] or atom['id']}} --yes"
90
90
  ,"cli:compile:dev": "fbin compile {{atom.doc.features.cli.input.file}} -o .bin/{{atom.doc['npm::bin'] or atom.doc['name'] or atom['id']}} --yes"
91
91
  ,"cli:install": "fbin install ./.bin/{{atom.doc['npm::bin'] or atom.doc['name'] or atom['id']}} --yes"
92
+ ,"cli:install:symlink": "fbin install ./.bin/{{atom.doc['npm::bin'] or atom.doc['name'] or atom['id']}} --yes --symlink"
93
+ ,"cli:uninstall": "fbin uninstall {{atom.doc['npm::bin'] or atom.doc['name'] or atom['id']}} --yes"
94
+
92
95
  {% endif %}
93
96
 
94
97
  {% if atom.doc.features.app.enabled %}
@@ -1,319 +1,9 @@
1
1
  {% if atom.doc.features.cli.enabled===true %}
2
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 %}
3
+ {% if atom.doc.features.cli.template.version ==='v1' %}
4
+ {% include "./index.js.v1.njk" %}
5
+ {% else %}
6
+ {% include "./v2/index.js.njk" %}
7
+ {% endif %}
11
8
 
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 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
- import argsParser from 'yargs-parser';
275
-
276
- const run = async () => {
277
- const args = argsParser(process.argv.slice(2));
278
- const cliMode = args['cli-mode'] || args.cli_mode || 'default';
279
-
280
- {{ defaultModeExtended() }}
281
-
282
- {% if atom.doc.features.cli.mcp.enabled===true %}
283
- {{ mcpModeCodeExtended('runExtended') }}
284
- {% endif %}
285
-
286
- {% if atom.doc.features.cli.http.enabled===true %}
287
- {{ httpModeCodeExpress('runExtended', ', { Engine }') }}
288
- {% endif %}
289
-
290
- console.error(`Unknown CLI mode: ${cliMode}`);
291
- process.exit(1);
292
- };
293
-
294
- {{ runWithThenCatch() }}
295
- {% else %}
296
- {# TYPE 2 #}
297
- import argsParser from 'yargs-parser';
298
- const run = async () => {
299
- const args =argsParser(process.argv.slice(2));
300
- const cliMode = args['cli-mode'] || args.cli_mode || 'default';
301
- const engine = new Engine();
302
-
303
- {{ defaultModeEngine('engine') }}
304
-
305
- {% if atom.doc.features.cli.mcp.enabled===true %}
306
- {{ mcpModeCodeEngine('engine') }}
307
- {% endif %}
308
-
309
- {% if atom.doc.features.cli.http.enabled===true %}
310
- {{ httpModeCodeExpress('engine.run', '') }}
311
- {% endif %}
312
-
313
- console.error(`Unknown CLI mode: ${cliMode}`);
314
- process.exit(1);
315
- };
316
-
317
- {{ runWithCatch() }}
318
9
  {% endif %}
319
- {% endif %}