@marktoflow/gui 2.0.0-alpha.4 → 2.0.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 (194) hide show
  1. package/README.md +48 -170
  2. package/client.log +0 -0
  3. package/dist/client/assets/index-DQeR1ew6.css +1 -0
  4. package/dist/client/assets/index-LbIVPHbD.js +833 -0
  5. package/dist/client/assets/index-LbIVPHbD.js.map +1 -0
  6. package/dist/client/index.html +2 -2
  7. package/dist/client/marktoflow-logo.png +0 -0
  8. package/dist/server/{server/index.js → index.js} +53 -6
  9. package/dist/server/index.js.map +1 -0
  10. package/dist/server/routes/admin.js +95 -0
  11. package/dist/server/routes/admin.js.map +1 -0
  12. package/dist/server/{server/routes → routes}/ai.js +2 -2
  13. package/dist/server/{server/routes → routes}/ai.js.map +1 -1
  14. package/dist/server/routes/collaboration.js +104 -0
  15. package/dist/server/routes/collaboration.js.map +1 -0
  16. package/dist/server/routes/execute.js +230 -0
  17. package/dist/server/routes/execute.js.map +1 -0
  18. package/dist/server/routes/executions.js +125 -0
  19. package/dist/server/routes/executions.js.map +1 -0
  20. package/dist/server/routes/form.js +160 -0
  21. package/dist/server/routes/form.js.map +1 -0
  22. package/dist/server/routes/settings.js +90 -0
  23. package/dist/server/routes/settings.js.map +1 -0
  24. package/dist/server/routes/templates.js +106 -0
  25. package/dist/server/routes/templates.js.map +1 -0
  26. package/dist/server/routes/versions.js +101 -0
  27. package/dist/server/routes/versions.js.map +1 -0
  28. package/dist/server/{server/routes → routes}/workflows.js +37 -1
  29. package/dist/server/routes/workflows.js.map +1 -0
  30. package/dist/server/services/AIService.js +152 -0
  31. package/dist/server/services/AIService.js.map +1 -0
  32. package/dist/server/services/ExecutionManager.js +571 -0
  33. package/dist/server/services/ExecutionManager.js.map +1 -0
  34. package/dist/server/services/VersionService.js +65 -0
  35. package/dist/server/services/VersionService.js.map +1 -0
  36. package/dist/server/{server/services → services}/WorkflowService.js +166 -17
  37. package/dist/server/services/WorkflowService.js.map +1 -0
  38. package/dist/server/{server/services → services}/agents/copilot-provider.js +32 -0
  39. package/dist/server/services/agents/copilot-provider.js.map +1 -0
  40. package/dist/server/{server/websocket → websocket}/index.js +54 -0
  41. package/dist/server/websocket/index.js.map +1 -0
  42. package/dist/{server/shared → shared}/constants.js +9 -0
  43. package/dist/shared/constants.js.map +1 -0
  44. package/dist/shared/settings.js +51 -0
  45. package/dist/shared/settings.js.map +1 -0
  46. package/package.json +32 -14
  47. package/public/marktoflow-logo.png +0 -0
  48. package/scripts/flatten-dist.js +69 -0
  49. package/server.log +0 -0
  50. package/tests/integration/fixtures/test-workflow.md +6 -0
  51. package/.turbo/turbo-build.log +0 -26
  52. package/dist/client/assets/index-C90Y_aBX.js +0 -678
  53. package/dist/client/assets/index-C90Y_aBX.js.map +0 -1
  54. package/dist/client/assets/index-CRWeQ3NN.css +0 -1
  55. package/dist/server/server/index.js.map +0 -1
  56. package/dist/server/server/routes/execute.js +0 -63
  57. package/dist/server/server/routes/execute.js.map +0 -1
  58. package/dist/server/server/routes/workflows.js.map +0 -1
  59. package/dist/server/server/services/AIService.js +0 -69
  60. package/dist/server/server/services/AIService.js.map +0 -1
  61. package/dist/server/server/services/WorkflowService.js.map +0 -1
  62. package/dist/server/server/services/agents/copilot-provider.js.map +0 -1
  63. package/dist/server/server/websocket/index.js.map +0 -1
  64. package/dist/server/shared/constants.js.map +0 -1
  65. package/playwright.config.ts +0 -27
  66. package/postcss.config.js +0 -6
  67. package/src/client/App.tsx +0 -520
  68. package/src/client/components/Canvas/Canvas.tsx +0 -423
  69. package/src/client/components/Canvas/ExecutionOverlay.tsx +0 -847
  70. package/src/client/components/Canvas/ForEachNode.tsx +0 -128
  71. package/src/client/components/Canvas/IfElseNode.tsx +0 -126
  72. package/src/client/components/Canvas/NodeContextMenu.tsx +0 -188
  73. package/src/client/components/Canvas/OutputNode.tsx +0 -111
  74. package/src/client/components/Canvas/ParallelNode.tsx +0 -140
  75. package/src/client/components/Canvas/StepNode.tsx +0 -106
  76. package/src/client/components/Canvas/SubWorkflowNode.tsx +0 -141
  77. package/src/client/components/Canvas/SwitchNode.tsx +0 -164
  78. package/src/client/components/Canvas/Toolbar.tsx +0 -189
  79. package/src/client/components/Canvas/TransformNode.tsx +0 -185
  80. package/src/client/components/Canvas/TriggerNode.tsx +0 -128
  81. package/src/client/components/Canvas/TryCatchNode.tsx +0 -164
  82. package/src/client/components/Canvas/WhileNode.tsx +0 -129
  83. package/src/client/components/Canvas/index.ts +0 -24
  84. package/src/client/components/Editor/InputsEditor.tsx +0 -458
  85. package/src/client/components/Editor/NewStepWizard.tsx +0 -344
  86. package/src/client/components/Editor/StepEditor.tsx +0 -532
  87. package/src/client/components/Editor/YamlEditor.tsx +0 -160
  88. package/src/client/components/Panels/PropertiesPanel.tsx +0 -589
  89. package/src/client/components/Prompt/ChangePreview.tsx +0 -281
  90. package/src/client/components/Prompt/PromptHistoryPanel.tsx +0 -209
  91. package/src/client/components/Prompt/PromptInput.tsx +0 -108
  92. package/src/client/components/Sidebar/Sidebar.tsx +0 -343
  93. package/src/client/components/common/Breadcrumb.tsx +0 -40
  94. package/src/client/components/common/Button.tsx +0 -68
  95. package/src/client/components/common/ContextMenu.tsx +0 -202
  96. package/src/client/components/common/KeyboardShortcuts.tsx +0 -143
  97. package/src/client/components/common/Modal.tsx +0 -93
  98. package/src/client/components/common/Tabs.tsx +0 -57
  99. package/src/client/components/common/ThemeToggle.tsx +0 -63
  100. package/src/client/components/index.ts +0 -32
  101. package/src/client/hooks/index.ts +0 -4
  102. package/src/client/hooks/useAIPrompt.ts +0 -108
  103. package/src/client/hooks/useCanvas.ts +0 -247
  104. package/src/client/hooks/useWebSocket.ts +0 -164
  105. package/src/client/hooks/useWorkflow.ts +0 -138
  106. package/src/client/main.tsx +0 -10
  107. package/src/client/stores/canvasStore.ts +0 -348
  108. package/src/client/stores/editorStore.ts +0 -133
  109. package/src/client/stores/executionStore.ts +0 -440
  110. package/src/client/stores/index.ts +0 -4
  111. package/src/client/stores/layoutStore.ts +0 -103
  112. package/src/client/stores/navigationStore.ts +0 -49
  113. package/src/client/stores/promptStore.ts +0 -113
  114. package/src/client/stores/themeStore.ts +0 -75
  115. package/src/client/stores/workflowStore.ts +0 -177
  116. package/src/client/styles/globals.css +0 -346
  117. package/src/client/utils/cn.ts +0 -9
  118. package/src/client/utils/index.ts +0 -4
  119. package/src/client/utils/serviceIcons.tsx +0 -97
  120. package/src/client/utils/stepValidation.ts +0 -155
  121. package/src/client/utils/workflowToGraph.ts +0 -299
  122. package/src/server/index.ts +0 -114
  123. package/src/server/routes/ai.ts +0 -91
  124. package/src/server/routes/execute.ts +0 -71
  125. package/src/server/routes/tools.ts +0 -970
  126. package/src/server/routes/workflows.ts +0 -106
  127. package/src/server/services/AIService.ts +0 -105
  128. package/src/server/services/FileWatcher.ts +0 -69
  129. package/src/server/services/WorkflowService.ts +0 -441
  130. package/src/server/services/agents/claude-code-provider.ts +0 -320
  131. package/src/server/services/agents/claude-provider.ts +0 -248
  132. package/src/server/services/agents/codex-provider.ts +0 -398
  133. package/src/server/services/agents/copilot-provider.ts +0 -311
  134. package/src/server/services/agents/demo-provider.ts +0 -184
  135. package/src/server/services/agents/index.ts +0 -31
  136. package/src/server/services/agents/ollama-provider.ts +0 -267
  137. package/src/server/services/agents/prompts.ts +0 -509
  138. package/src/server/services/agents/registry.ts +0 -310
  139. package/src/server/services/agents/types.ts +0 -146
  140. package/src/server/websocket/index.ts +0 -104
  141. package/src/shared/constants.ts +0 -180
  142. package/src/shared/types.ts +0 -179
  143. package/tailwind.config.ts +0 -73
  144. package/tests/e2e/app.spec.ts +0 -90
  145. package/tests/e2e/canvas.spec.ts +0 -128
  146. package/tests/e2e/workflow.spec.ts +0 -185
  147. package/tests/integration/api.test.ts +0 -452
  148. package/tests/integration/testApp.ts +0 -31
  149. package/tests/setup.ts +0 -72
  150. package/tests/unit/ForEachNode.test.tsx +0 -218
  151. package/tests/unit/IfElseNode.test.tsx +0 -188
  152. package/tests/unit/ParallelNode.test.tsx +0 -264
  153. package/tests/unit/SwitchNode.test.tsx +0 -252
  154. package/tests/unit/TransformNode.test.tsx +0 -386
  155. package/tests/unit/TryCatchNode.test.tsx +0 -243
  156. package/tests/unit/WhileNode.test.tsx +0 -226
  157. package/tests/unit/canvasStore.test.ts +0 -502
  158. package/tests/unit/codexProvider.test.ts +0 -399
  159. package/tests/unit/components.test.tsx +0 -151
  160. package/tests/unit/executionStore.test.ts +0 -527
  161. package/tests/unit/layoutStore.test.ts +0 -194
  162. package/tests/unit/navigationStore.test.ts +0 -152
  163. package/tests/unit/serviceIcons.test.ts +0 -197
  164. package/tests/unit/stepValidation.test.ts +0 -226
  165. package/tests/unit/themeStore.test.ts +0 -141
  166. package/tests/unit/workflowToGraph.test.ts +0 -289
  167. package/tsconfig.json +0 -29
  168. package/tsconfig.server.json +0 -28
  169. package/vite.config.ts +0 -31
  170. package/vitest.config.ts +0 -26
  171. /package/dist/server/{server/routes → routes}/tools.js +0 -0
  172. /package/dist/server/{server/routes → routes}/tools.js.map +0 -0
  173. /package/dist/server/{server/services → services}/FileWatcher.js +0 -0
  174. /package/dist/server/{server/services → services}/FileWatcher.js.map +0 -0
  175. /package/dist/server/{server/services → services}/agents/claude-code-provider.js +0 -0
  176. /package/dist/server/{server/services → services}/agents/claude-code-provider.js.map +0 -0
  177. /package/dist/server/{server/services → services}/agents/claude-provider.js +0 -0
  178. /package/dist/server/{server/services → services}/agents/claude-provider.js.map +0 -0
  179. /package/dist/server/{server/services → services}/agents/codex-provider.js +0 -0
  180. /package/dist/server/{server/services → services}/agents/codex-provider.js.map +0 -0
  181. /package/dist/server/{server/services → services}/agents/demo-provider.js +0 -0
  182. /package/dist/server/{server/services → services}/agents/demo-provider.js.map +0 -0
  183. /package/dist/server/{server/services → services}/agents/index.js +0 -0
  184. /package/dist/server/{server/services → services}/agents/index.js.map +0 -0
  185. /package/dist/server/{server/services → services}/agents/ollama-provider.js +0 -0
  186. /package/dist/server/{server/services → services}/agents/ollama-provider.js.map +0 -0
  187. /package/dist/server/{server/services → services}/agents/prompts.js +0 -0
  188. /package/dist/server/{server/services → services}/agents/prompts.js.map +0 -0
  189. /package/dist/server/{server/services → services}/agents/registry.js +0 -0
  190. /package/dist/server/{server/services → services}/agents/registry.js.map +0 -0
  191. /package/dist/server/{server/services → services}/agents/types.js +0 -0
  192. /package/dist/server/{server/services → services}/agents/types.js.map +0 -0
  193. /package/dist/{server/shared → shared}/types.js +0 -0
  194. /package/dist/{server/shared → shared}/types.js.map +0 -0
@@ -0,0 +1,125 @@
1
+ /**
2
+ * API routes for execution history
3
+ */
4
+ import { Router } from 'express';
5
+ import { getStateStore } from '../index.js';
6
+ export const executionRoutes = Router();
7
+ /**
8
+ * GET /api/executions
9
+ * List all executions with optional filtering
10
+ */
11
+ executionRoutes.get('/', (req, res) => {
12
+ try {
13
+ const stateStore = getStateStore();
14
+ const { workflowId, status, limit, offset } = req.query;
15
+ // Helper to extract string from query param
16
+ const getString = (val) => {
17
+ if (typeof val === 'string')
18
+ return val;
19
+ if (Array.isArray(val) && val.length > 0 && typeof val[0] === 'string')
20
+ return val[0];
21
+ return undefined;
22
+ };
23
+ const workflowIdStr = getString(workflowId);
24
+ const statusStr = getString(status);
25
+ const limitNum = parseInt(getString(limit) || '50', 10);
26
+ const offsetNum = getString(offset) ? parseInt(getString(offset), 10) : undefined;
27
+ const executions = stateStore.listExecutions({
28
+ workflowId: workflowIdStr,
29
+ status: statusStr,
30
+ limit: limitNum,
31
+ offset: offsetNum,
32
+ });
33
+ res.json(executions);
34
+ }
35
+ catch (error) {
36
+ console.error('Error listing executions:', error);
37
+ res.status(500).json({
38
+ error: 'Failed to list executions',
39
+ message: error instanceof Error ? error.message : 'Unknown error',
40
+ });
41
+ }
42
+ });
43
+ /**
44
+ * GET /api/executions/:runId
45
+ * Get details for a specific execution
46
+ */
47
+ executionRoutes.get('/:runId', (req, res) => {
48
+ try {
49
+ const stateStore = getStateStore();
50
+ const runId = Array.isArray(req.params.runId) ? req.params.runId[0] : req.params.runId;
51
+ const execution = stateStore.getExecution(runId);
52
+ if (!execution) {
53
+ res.status(404).json({ error: 'Execution not found' });
54
+ return;
55
+ }
56
+ res.json(execution);
57
+ }
58
+ catch (error) {
59
+ console.error('Error getting execution:', error);
60
+ res.status(500).json({
61
+ error: 'Failed to get execution',
62
+ message: error instanceof Error ? error.message : 'Unknown error',
63
+ });
64
+ }
65
+ });
66
+ /**
67
+ * GET /api/executions/:runId/checkpoints
68
+ * Get checkpoints for a specific execution
69
+ */
70
+ executionRoutes.get('/:runId/checkpoints', (req, res) => {
71
+ try {
72
+ const stateStore = getStateStore();
73
+ const runId = Array.isArray(req.params.runId) ? req.params.runId[0] : req.params.runId;
74
+ const checkpoints = stateStore.getCheckpoints(runId);
75
+ res.json(checkpoints);
76
+ }
77
+ catch (error) {
78
+ console.error('Error getting checkpoints:', error);
79
+ res.status(500).json({
80
+ error: 'Failed to get checkpoints',
81
+ message: error instanceof Error ? error.message : 'Unknown error',
82
+ });
83
+ }
84
+ });
85
+ /**
86
+ * GET /api/executions/:runId/stats
87
+ * Get execution statistics
88
+ */
89
+ executionRoutes.get('/:runId/stats', (req, res) => {
90
+ try {
91
+ const stateStore = getStateStore();
92
+ const runId = Array.isArray(req.params.runId) ? req.params.runId[0] : req.params.runId;
93
+ const execution = stateStore.getExecution(runId);
94
+ if (!execution) {
95
+ res.status(404).json({ error: 'Execution not found' });
96
+ return;
97
+ }
98
+ const checkpoints = stateStore.getCheckpoints(runId);
99
+ const completedSteps = checkpoints.filter((c) => c.status === 'completed').length;
100
+ const failedSteps = checkpoints.filter((c) => c.status === 'failed').length;
101
+ const stats = {
102
+ runId,
103
+ workflowId: execution.workflowId,
104
+ status: execution.status,
105
+ totalSteps: execution.totalSteps,
106
+ completedSteps,
107
+ failedSteps,
108
+ currentStep: execution.currentStep,
109
+ duration: execution.completedAt && execution.startedAt
110
+ ? execution.completedAt.getTime() - execution.startedAt.getTime()
111
+ : null,
112
+ startedAt: execution.startedAt,
113
+ completedAt: execution.completedAt,
114
+ };
115
+ res.json(stats);
116
+ }
117
+ catch (error) {
118
+ console.error('Error getting execution stats:', error);
119
+ res.status(500).json({
120
+ error: 'Failed to get execution stats',
121
+ message: error instanceof Error ? error.message : 'Unknown error',
122
+ });
123
+ }
124
+ });
125
+ //# sourceMappingURL=executions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executions.js","sourceRoot":"","sources":["../../../../src/server/routes/executions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Form routes for human-in-the-loop workflows
3
+ *
4
+ * Handles form rendering and submission for workflows paused with wait steps.
5
+ */
6
+ import { Router } from 'express';
7
+ const router = Router();
8
+ // ExecutionManager instance (set via setExecutionManager)
9
+ let executionManager = null;
10
+ /**
11
+ * Set the ExecutionManager instance (called from server/index.ts)
12
+ */
13
+ export function setExecutionManager(manager) {
14
+ executionManager = manager;
15
+ }
16
+ /**
17
+ * GET /form/:runId/:stepId/:token
18
+ * Retrieve form schema and render form page
19
+ */
20
+ router.get('/:runId/:stepId/:token', async (req, res) => {
21
+ try {
22
+ const runId = String(req.params.runId);
23
+ const stepId = String(req.params.stepId);
24
+ const token = String(req.params.token);
25
+ if (!executionManager) {
26
+ res.status(503).json({
27
+ error: 'Service unavailable',
28
+ message: 'ExecutionManager not initialized',
29
+ });
30
+ return;
31
+ }
32
+ // Get execution status to verify it's waiting
33
+ const status = executionManager.getExecutionStatus(runId);
34
+ if (!status) {
35
+ res.status(404).json({
36
+ error: 'Not found',
37
+ message: `Execution ${runId} not found`,
38
+ });
39
+ return;
40
+ }
41
+ if (status.status !== 'running') {
42
+ res.status(400).json({
43
+ error: 'Invalid state',
44
+ message: `Execution is not running (status: ${status.status})`,
45
+ });
46
+ return;
47
+ }
48
+ // Find the step that's waiting for form input
49
+ const waitingStep = status.stepResults.find(sr => sr.stepId === stepId && sr.status === 'completed');
50
+ if (!waitingStep || !waitingStep.output) {
51
+ res.status(404).json({
52
+ error: 'Not found',
53
+ message: `No waiting step found for ${stepId}`,
54
+ });
55
+ return;
56
+ }
57
+ const stepOutput = waitingStep.output;
58
+ // Verify token matches
59
+ if (stepOutput.resumeToken !== token) {
60
+ res.status(403).json({
61
+ error: 'Forbidden',
62
+ message: 'Invalid resume token',
63
+ });
64
+ return;
65
+ }
66
+ // Verify mode is form
67
+ if (stepOutput.mode !== 'form') {
68
+ res.status(400).json({
69
+ error: 'Invalid mode',
70
+ message: `Step is not in form mode (mode: ${stepOutput.mode})`,
71
+ });
72
+ return;
73
+ }
74
+ // Return form schema
75
+ res.json({
76
+ runId,
77
+ stepId,
78
+ workflowId: status.workflowId,
79
+ workflowPath: status.workflowPath,
80
+ fields: stepOutput.fields || {},
81
+ submitUrl: `/api/form/${runId}/${stepId}/${token}`,
82
+ });
83
+ }
84
+ catch (error) {
85
+ res.status(500).json({
86
+ error: 'Failed to get form',
87
+ message: error instanceof Error ? error.message : 'Unknown error',
88
+ });
89
+ }
90
+ });
91
+ /**
92
+ * POST /form/:runId/:stepId/:token
93
+ * Submit form data and resume workflow execution
94
+ */
95
+ router.post('/:runId/:stepId/:token', async (req, res) => {
96
+ try {
97
+ const runId = String(req.params.runId);
98
+ const stepId = String(req.params.stepId);
99
+ const token = String(req.params.token);
100
+ const formData = req.body;
101
+ if (!executionManager) {
102
+ res.status(503).json({
103
+ error: 'Service unavailable',
104
+ message: 'ExecutionManager not initialized',
105
+ });
106
+ return;
107
+ }
108
+ // Verify execution exists and is waiting
109
+ const status = executionManager.getExecutionStatus(runId);
110
+ if (!status) {
111
+ res.status(404).json({
112
+ error: 'Not found',
113
+ message: `Execution ${runId} not found`,
114
+ });
115
+ return;
116
+ }
117
+ if (status.status !== 'running') {
118
+ res.status(400).json({
119
+ error: 'Invalid state',
120
+ message: `Execution is not running (status: ${status.status})`,
121
+ });
122
+ return;
123
+ }
124
+ // Find the waiting step
125
+ const waitingStep = status.stepResults.find(sr => sr.stepId === stepId && sr.status === 'completed');
126
+ if (!waitingStep || !waitingStep.output) {
127
+ res.status(404).json({
128
+ error: 'Not found',
129
+ message: `No waiting step found for ${stepId}`,
130
+ });
131
+ return;
132
+ }
133
+ const stepOutput = waitingStep.output;
134
+ // Verify token
135
+ if (stepOutput.resumeToken !== token) {
136
+ res.status(403).json({
137
+ error: 'Forbidden',
138
+ message: 'Invalid resume token',
139
+ });
140
+ return;
141
+ }
142
+ // TODO: Validate form data against field schema
143
+ // Resume execution with form data
144
+ await executionManager.resumeExecution(runId, stepId, formData);
145
+ res.json({
146
+ success: true,
147
+ runId,
148
+ stepId,
149
+ message: 'Form submitted successfully. Workflow execution resumed.',
150
+ });
151
+ }
152
+ catch (error) {
153
+ res.status(500).json({
154
+ error: 'Failed to submit form',
155
+ message: error instanceof Error ? error.message : 'Unknown error',
156
+ });
157
+ }
158
+ });
159
+ export { router as formRoutes };
160
+ //# sourceMappingURL=form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.js","sourceRoot":"","sources":["../../../../src/server/routes/form.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import { Router } from 'express';
2
+ import { readFile, writeFile, mkdir } from 'fs/promises';
3
+ import { existsSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { homedir } from 'os';
6
+ import { DEFAULT_SETTINGS, deepMergeSettings, } from '../../shared/settings.js';
7
+ let settingsDir = join(homedir(), '.marktoflow');
8
+ /**
9
+ * Override the settings directory (used for testing).
10
+ */
11
+ export function setSettingsDir(dir) {
12
+ settingsDir = dir;
13
+ }
14
+ function getSettingsFile() {
15
+ return join(settingsDir, 'settings.json');
16
+ }
17
+ async function ensureSettingsDir() {
18
+ if (!existsSync(settingsDir)) {
19
+ await mkdir(settingsDir, { recursive: true });
20
+ }
21
+ }
22
+ async function readSettings() {
23
+ await ensureSettingsDir();
24
+ try {
25
+ const raw = await readFile(getSettingsFile(), 'utf-8');
26
+ const saved = JSON.parse(raw);
27
+ return deepMergeSettings(DEFAULT_SETTINGS, saved);
28
+ }
29
+ catch {
30
+ // File doesn't exist or is invalid — write defaults and return them
31
+ await writeFile(getSettingsFile(), JSON.stringify(DEFAULT_SETTINGS, null, 2));
32
+ return { ...DEFAULT_SETTINGS };
33
+ }
34
+ }
35
+ async function writeSettings(settings) {
36
+ await ensureSettingsDir();
37
+ await writeFile(getSettingsFile(), JSON.stringify(settings, null, 2));
38
+ }
39
+ const router = Router();
40
+ // GET /api/settings — return full settings (merged with defaults)
41
+ router.get('/', async (_req, res) => {
42
+ try {
43
+ const settings = await readSettings();
44
+ res.json(settings);
45
+ }
46
+ catch (error) {
47
+ res.status(500).json({
48
+ error: 'Failed to read settings',
49
+ message: error instanceof Error ? error.message : 'Unknown error',
50
+ });
51
+ }
52
+ });
53
+ // PUT /api/settings — full replace (used for reset-all)
54
+ router.put('/', async (req, res) => {
55
+ try {
56
+ const settings = deepMergeSettings(DEFAULT_SETTINGS, req.body);
57
+ await writeSettings(settings);
58
+ res.json(settings);
59
+ }
60
+ catch (error) {
61
+ res.status(500).json({
62
+ error: 'Failed to write settings',
63
+ message: error instanceof Error ? error.message : 'Unknown error',
64
+ });
65
+ }
66
+ });
67
+ // PATCH /api/settings/:category — partial update of one category
68
+ router.patch('/:category', async (req, res) => {
69
+ try {
70
+ const category = req.params.category;
71
+ if (!(category in DEFAULT_SETTINGS)) {
72
+ return res.status(400).json({ error: `Unknown settings category: ${category}` });
73
+ }
74
+ const settings = await readSettings();
75
+ const current = settings[category];
76
+ const merged = { ...current, ...req.body };
77
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
+ settings[category] = merged;
79
+ await writeSettings(settings);
80
+ res.json(settings);
81
+ }
82
+ catch (error) {
83
+ res.status(500).json({
84
+ error: 'Failed to update settings',
85
+ message: error instanceof Error ? error.message : 'Unknown error',
86
+ });
87
+ }
88
+ });
89
+ export { router as settingsRoutes };
90
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../../src/server/routes/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA6B,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,GAGlB,MAAM,0BAA0B,CAAC;AAElC,IAAI,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,WAAW,GAAG,GAAG,CAAC;AACpB,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,iBAAiB;IAC9B,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,MAAM,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY;IACzB,MAAM,iBAAiB,EAAE,CAAC;IAE1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,EAAE,OAAO,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,OAAO,iBAAiB,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;QACpE,MAAM,SAAS,CAAC,eAAe,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9E,OAAO,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACjC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,QAAsB;IACjD,MAAM,iBAAiB,EAAE,CAAC;IAC1B,MAAM,SAAS,CAAC,eAAe,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,MAAM,GAAe,MAAM,EAAE,CAAC;AAEpC,kEAAkE;AAClE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;IAClC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;QACtC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,yBAAyB;YAChC,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAClE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,wDAAwD;AACxD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACjC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/D,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC9B,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,0BAA0B;YACjC,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAClE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,iEAAiE;AACjE,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC5C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAA4B,CAAC;QAEzD,IAAI,CAAC,CAAC,QAAQ,IAAI,gBAAgB,CAAC,EAAE,CAAC;YACpC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,QAAQ,EAAE,EAAE,CAAC,CAAC;QACnF,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3C,8DAA8D;QAC7D,QAAgB,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;QAErC,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC9B,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,2BAA2B;YAClC,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAClE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,CAAC"}
@@ -0,0 +1,106 @@
1
+ import { Router } from 'express';
2
+ import { readdir, readFile } from 'fs/promises';
3
+ import { join } from 'path';
4
+ export const templateRoutes = Router();
5
+ let cachedTemplates = null;
6
+ // Get template list (seeded from examples/)
7
+ templateRoutes.get('/', async (req, res) => {
8
+ try {
9
+ if (cachedTemplates) {
10
+ res.json({ templates: filterTemplates(cachedTemplates, req.query) });
11
+ return;
12
+ }
13
+ const examplesDir = join(process.cwd(), 'examples');
14
+ const templates = [];
15
+ try {
16
+ const dirs = await readdir(examplesDir, { withFileTypes: true });
17
+ for (const dir of dirs) {
18
+ if (!dir.isDirectory())
19
+ continue;
20
+ const workflowPath = join(examplesDir, dir.name, 'workflow.md');
21
+ try {
22
+ const content = await readFile(workflowPath, 'utf-8');
23
+ const name = dir.name.replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
24
+ // Extract description from frontmatter
25
+ const descMatch = content.match(/description:\s*['""]?(.+?)['""]?\s*$/m);
26
+ const tagsMatch = content.match(/tags:\s*\[([^\]]+)\]/);
27
+ const tags = tagsMatch ? tagsMatch[1].split(',').map((t) => t.trim().replace(/['"]/g, '')) : [];
28
+ templates.push({
29
+ id: dir.name,
30
+ name,
31
+ description: descMatch?.[1] || `${name} workflow template`,
32
+ category: inferCategory(dir.name, tags),
33
+ tags,
34
+ path: workflowPath,
35
+ });
36
+ }
37
+ catch {
38
+ // Skip directories without workflow.md
39
+ }
40
+ }
41
+ }
42
+ catch {
43
+ // examples dir doesn't exist
44
+ }
45
+ // Add built-in templates
46
+ templates.push({ id: 'blank', name: 'Blank Workflow', description: 'Start from scratch', category: 'basic', tags: ['starter'], path: '' }, { id: 'api-integration', name: 'API Integration', description: 'Connect to any REST API', category: 'integration', tags: ['http', 'api'], path: '' }, { id: 'data-pipeline', name: 'Data Pipeline', description: 'ETL workflow with transform steps', category: 'data', tags: ['transform', 'etl'], path: '' });
47
+ cachedTemplates = templates;
48
+ res.json({ templates: filterTemplates(templates, req.query) });
49
+ }
50
+ catch (error) {
51
+ res.status(500).json({
52
+ error: 'Failed to list templates',
53
+ message: error instanceof Error ? error.message : 'Unknown error',
54
+ });
55
+ }
56
+ });
57
+ // Get template content
58
+ templateRoutes.get('/:id', async (req, res) => {
59
+ try {
60
+ const templates = cachedTemplates || [];
61
+ const template = templates.find((t) => t.id === req.params.id);
62
+ if (!template) {
63
+ res.status(404).json({ error: 'Template not found' });
64
+ return;
65
+ }
66
+ let content = '';
67
+ if (template.path) {
68
+ content = await readFile(template.path, 'utf-8');
69
+ }
70
+ res.json({ template, content });
71
+ }
72
+ catch (error) {
73
+ res.status(500).json({
74
+ error: 'Failed to get template',
75
+ message: error instanceof Error ? error.message : 'Unknown error',
76
+ });
77
+ }
78
+ });
79
+ function inferCategory(name, tags) {
80
+ const all = [name, ...tags].join(' ').toLowerCase();
81
+ if (all.includes('review') || all.includes('pr'))
82
+ return 'development';
83
+ if (all.includes('slack') || all.includes('notification'))
84
+ return 'communication';
85
+ if (all.includes('incident') || all.includes('pager'))
86
+ return 'operations';
87
+ if (all.includes('sprint') || all.includes('standup'))
88
+ return 'agile';
89
+ if (all.includes('data') || all.includes('etl'))
90
+ return 'data';
91
+ return 'general';
92
+ }
93
+ function filterTemplates(templates, query) {
94
+ let filtered = templates;
95
+ if (query.category) {
96
+ filtered = filtered.filter((t) => t.category === query.category);
97
+ }
98
+ if (query.search) {
99
+ const search = query.search.toLowerCase();
100
+ filtered = filtered.filter((t) => t.name.toLowerCase().includes(search) ||
101
+ t.description.toLowerCase().includes(search) ||
102
+ t.tags.some((tag) => tag.toLowerCase().includes(search)));
103
+ }
104
+ return filtered;
105
+ }
106
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../../src/server/routes/templates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import { Router } from 'express';
2
+ import { VersionService } from '../services/VersionService.js';
3
+ export const versionRoutes = Router();
4
+ // List versions for a workflow
5
+ versionRoutes.get('/:path(*)/versions', (req, res) => {
6
+ try {
7
+ const workflowPath = req.params.path;
8
+ const versions = VersionService.listVersions(workflowPath);
9
+ res.json({ versions });
10
+ }
11
+ catch (error) {
12
+ res.status(500).json({
13
+ error: 'Failed to list versions',
14
+ message: error instanceof Error ? error.message : 'Unknown error',
15
+ });
16
+ }
17
+ });
18
+ // Create a version snapshot
19
+ versionRoutes.post('/:path(*)/versions', (req, res) => {
20
+ try {
21
+ const workflowPath = req.params.path;
22
+ const { content, message, author, isAutoSave } = req.body;
23
+ if (!content) {
24
+ res.status(400).json({ error: 'Content is required' });
25
+ return;
26
+ }
27
+ const version = VersionService.createVersion(workflowPath, content, message, author, isAutoSave);
28
+ res.json({ version });
29
+ }
30
+ catch (error) {
31
+ res.status(500).json({
32
+ error: 'Failed to create version',
33
+ message: error instanceof Error ? error.message : 'Unknown error',
34
+ });
35
+ }
36
+ });
37
+ // Get a specific version
38
+ versionRoutes.get('/:path(*)/versions/:versionId', (req, res) => {
39
+ try {
40
+ const workflowPath = req.params.path;
41
+ const versionId = req.params.versionId;
42
+ const version = VersionService.getVersion(workflowPath, versionId);
43
+ if (!version) {
44
+ res.status(404).json({ error: 'Version not found' });
45
+ return;
46
+ }
47
+ res.json({ version });
48
+ }
49
+ catch (error) {
50
+ res.status(500).json({
51
+ error: 'Failed to get version',
52
+ message: error instanceof Error ? error.message : 'Unknown error',
53
+ });
54
+ }
55
+ });
56
+ // Restore a version
57
+ versionRoutes.post('/:path(*)/versions/:versionId/restore', (req, res) => {
58
+ try {
59
+ const workflowPath = req.params.path;
60
+ const versionId = req.params.versionId;
61
+ const version = VersionService.getVersion(workflowPath, versionId);
62
+ if (!version) {
63
+ res.status(404).json({ error: 'Version not found' });
64
+ return;
65
+ }
66
+ // Create a new version that restores this content
67
+ const restored = VersionService.createVersion(workflowPath, version.content, `Restored from version ${version.version}`, req.body.author || 'system');
68
+ res.json({ version: restored, restoredContent: version.content });
69
+ }
70
+ catch (error) {
71
+ res.status(500).json({
72
+ error: 'Failed to restore version',
73
+ message: error instanceof Error ? error.message : 'Unknown error',
74
+ });
75
+ }
76
+ });
77
+ // Compare two versions
78
+ versionRoutes.get('/:path(*)/versions/compare', (req, res) => {
79
+ try {
80
+ const workflowPath = req.params.path;
81
+ const v1 = req.query.v1;
82
+ const v2 = req.query.v2;
83
+ if (!v1 || !v2) {
84
+ res.status(400).json({ error: 'v1 and v2 query parameters are required' });
85
+ return;
86
+ }
87
+ const diff = VersionService.compareVersions(workflowPath, v1, v2);
88
+ if (!diff) {
89
+ res.status(404).json({ error: 'One or both versions not found' });
90
+ return;
91
+ }
92
+ res.json({ diff });
93
+ }
94
+ catch (error) {
95
+ res.status(500).json({
96
+ error: 'Failed to compare versions',
97
+ message: error instanceof Error ? error.message : 'Unknown error',
98
+ });
99
+ }
100
+ });
101
+ //# sourceMappingURL=versions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"versions.js","sourceRoot":"","sources":["../../../../src/server/routes/versions.ts"],"names":[],"mappings":"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"}