@marktoflow/gui 2.0.0-alpha.5 → 2.0.2
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.
- package/README.md +48 -180
- package/dist/client/assets/index-DQeR1ew6.css +1 -0
- package/dist/client/assets/index-LbIVPHbD.js +833 -0
- package/dist/client/assets/index-LbIVPHbD.js.map +1 -0
- package/dist/client/index.html +2 -2
- package/dist/client/marktoflow-logo.png +0 -0
- package/dist/server/index.js +31 -5
- package/dist/server/index.js.map +1 -1
- package/dist/server/routes/admin.js +95 -0
- package/dist/server/routes/admin.js.map +1 -0
- package/dist/server/routes/ai.js +2 -2
- package/dist/server/routes/ai.js.map +1 -1
- package/dist/server/routes/collaboration.js +104 -0
- package/dist/server/routes/collaboration.js.map +1 -0
- package/dist/server/routes/execute.js +181 -14
- package/dist/server/routes/execute.js.map +1 -1
- package/dist/server/routes/form.js +160 -0
- package/dist/server/routes/form.js.map +1 -0
- package/dist/server/routes/settings.js +90 -0
- package/dist/server/routes/settings.js.map +1 -0
- package/dist/server/routes/templates.js +106 -0
- package/dist/server/routes/templates.js.map +1 -0
- package/dist/server/routes/versions.js +101 -0
- package/dist/server/routes/versions.js.map +1 -0
- package/dist/server/services/AIService.js +85 -2
- package/dist/server/services/AIService.js.map +1 -1
- package/dist/server/services/ExecutionManager.js +571 -0
- package/dist/server/services/ExecutionManager.js.map +1 -0
- package/dist/server/services/VersionService.js +65 -0
- package/dist/server/services/VersionService.js.map +1 -0
- package/dist/server/services/WorkflowService.js +8 -2
- package/dist/server/services/WorkflowService.js.map +1 -1
- package/dist/server/services/agents/copilot-provider.js +32 -0
- package/dist/server/services/agents/copilot-provider.js.map +1 -1
- package/dist/server/websocket/index.js +42 -0
- package/dist/server/websocket/index.js.map +1 -1
- package/dist/shared/constants.js +9 -0
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/settings.js +51 -0
- package/dist/shared/settings.js.map +1 -0
- package/package.json +14 -10
- package/public/marktoflow-logo.png +0 -0
- package/tests/integration/fixtures/test-workflow.md +6 -0
- package/.turbo/turbo-build.log +0 -42
- package/dist/client/assets/index-CM44OayM.js +0 -704
- package/dist/client/assets/index-CM44OayM.js.map +0 -1
- package/dist/client/assets/index-Dru63gi6.css +0 -1
- package/marktoflow-gui-2.0.0-alpha.5.tgz +0 -0
- package/playwright.config.ts +0 -27
- package/postcss.config.js +0 -6
- package/src/client/App.tsx +0 -520
- package/src/client/components/Canvas/Canvas.tsx +0 -425
- package/src/client/components/Canvas/ExecutionOverlay.tsx +0 -935
- package/src/client/components/Canvas/ForEachNode.tsx +0 -152
- package/src/client/components/Canvas/IfElseNode.tsx +0 -141
- package/src/client/components/Canvas/NodeContextMenu.tsx +0 -192
- package/src/client/components/Canvas/OutputNode.tsx +0 -111
- package/src/client/components/Canvas/ParallelNode.tsx +0 -157
- package/src/client/components/Canvas/StepNode.tsx +0 -106
- package/src/client/components/Canvas/SubWorkflowNode.tsx +0 -141
- package/src/client/components/Canvas/SwitchNode.tsx +0 -185
- package/src/client/components/Canvas/Toolbar.tsx +0 -227
- package/src/client/components/Canvas/TransformNode.tsx +0 -194
- package/src/client/components/Canvas/TriggerNode.tsx +0 -128
- package/src/client/components/Canvas/TryCatchNode.tsx +0 -164
- package/src/client/components/Canvas/WhileNode.tsx +0 -161
- package/src/client/components/Canvas/index.ts +0 -24
- package/src/client/components/Debug/VariableInspector.tsx +0 -148
- package/src/client/components/Editor/InputsEditor.tsx +0 -458
- package/src/client/components/Editor/NewStepWizard.tsx +0 -344
- package/src/client/components/Editor/StepEditor.tsx +0 -532
- package/src/client/components/Editor/YamlEditor.tsx +0 -160
- package/src/client/components/Panels/PropertiesPanel.tsx +0 -589
- package/src/client/components/Prompt/ChangePreview.tsx +0 -281
- package/src/client/components/Prompt/PromptHistoryPanel.tsx +0 -209
- package/src/client/components/Prompt/PromptInput.tsx +0 -110
- package/src/client/components/Settings/ProviderSwitcher.tsx +0 -228
- package/src/client/components/Sidebar/ImportDialog.tsx +0 -257
- package/src/client/components/Sidebar/Sidebar.tsx +0 -362
- package/src/client/components/common/Breadcrumb.tsx +0 -40
- package/src/client/components/common/Button.tsx +0 -68
- package/src/client/components/common/ContextMenu.tsx +0 -202
- package/src/client/components/common/KeyboardShortcuts.tsx +0 -149
- package/src/client/components/common/Modal.tsx +0 -93
- package/src/client/components/common/Tabs.tsx +0 -57
- package/src/client/components/common/ThemeToggle.tsx +0 -63
- package/src/client/components/index.ts +0 -32
- package/src/client/hooks/index.ts +0 -4
- package/src/client/hooks/useAIPrompt.ts +0 -108
- package/src/client/hooks/useCanvas.ts +0 -247
- package/src/client/hooks/useWebSocket.ts +0 -164
- package/src/client/hooks/useWorkflow.ts +0 -138
- package/src/client/main.tsx +0 -10
- package/src/client/stores/agentStore.ts +0 -109
- package/src/client/stores/canvasStore.ts +0 -348
- package/src/client/stores/editorStore.ts +0 -133
- package/src/client/stores/executionStore.ts +0 -502
- package/src/client/stores/index.ts +0 -4
- package/src/client/stores/layoutStore.ts +0 -103
- package/src/client/stores/navigationStore.ts +0 -49
- package/src/client/stores/promptStore.ts +0 -113
- package/src/client/stores/themeStore.ts +0 -75
- package/src/client/stores/workflowStore.ts +0 -185
- package/src/client/styles/globals.css +0 -452
- package/src/client/utils/cn.ts +0 -9
- package/src/client/utils/index.ts +0 -4
- package/src/client/utils/platform.ts +0 -46
- package/src/client/utils/serviceIcons.tsx +0 -97
- package/src/client/utils/stepValidation.ts +0 -155
- package/src/client/utils/workflowToGraph.ts +0 -523
- package/src/server/index.ts +0 -137
- package/src/server/routes/ai.ts +0 -91
- package/src/server/routes/execute.ts +0 -71
- package/src/server/routes/executions.ts +0 -136
- package/src/server/routes/tools.ts +0 -970
- package/src/server/routes/workflows.ts +0 -147
- package/src/server/services/AIService.ts +0 -105
- package/src/server/services/FileWatcher.ts +0 -69
- package/src/server/services/WorkflowService.ts +0 -601
- package/src/server/services/agents/claude-code-provider.ts +0 -320
- package/src/server/services/agents/claude-provider.ts +0 -248
- package/src/server/services/agents/codex-provider.ts +0 -398
- package/src/server/services/agents/copilot-provider.ts +0 -311
- package/src/server/services/agents/demo-provider.ts +0 -184
- package/src/server/services/agents/index.ts +0 -31
- package/src/server/services/agents/ollama-provider.ts +0 -267
- package/src/server/services/agents/prompts.ts +0 -509
- package/src/server/services/agents/registry.ts +0 -310
- package/src/server/services/agents/types.ts +0 -146
- package/src/server/websocket/index.ts +0 -117
- package/src/shared/constants.ts +0 -180
- package/src/shared/types.ts +0 -179
- package/tailwind.config.ts +0 -73
- package/tests/e2e/app.spec.ts +0 -90
- package/tests/e2e/canvas.spec.ts +0 -128
- package/tests/e2e/workflow.spec.ts +0 -185
- package/tests/integration/api.test.ts +0 -452
- package/tests/integration/testApp.ts +0 -31
- package/tests/setup.ts +0 -72
- package/tests/unit/ForEachNode.test.tsx +0 -308
- package/tests/unit/IfElseNode.test.tsx +0 -235
- package/tests/unit/ParallelNode.test.tsx +0 -344
- package/tests/unit/SwitchNode.test.tsx +0 -327
- package/tests/unit/TransformNode.test.tsx +0 -386
- package/tests/unit/TryCatchNode.test.tsx +0 -243
- package/tests/unit/WhileNode.test.tsx +0 -230
- package/tests/unit/agentStore.test.ts +0 -218
- package/tests/unit/canvasStore.test.ts +0 -502
- package/tests/unit/codexProvider.test.ts +0 -399
- package/tests/unit/components.test.tsx +0 -151
- package/tests/unit/executionStore.test.ts +0 -567
- package/tests/unit/layoutStore.test.ts +0 -194
- package/tests/unit/navigationStore.test.ts +0 -152
- package/tests/unit/platform.test.ts +0 -118
- package/tests/unit/serviceIcons.test.ts +0 -197
- package/tests/unit/stepValidation.test.ts +0 -226
- package/tests/unit/themeStore.test.ts +0 -141
- package/tests/unit/workflowToGraph.test.ts +0 -311
- package/tsconfig.json +0 -29
- package/tsconfig.server.json +0 -28
- package/vite.config.ts +0 -31
- package/vitest.config.ts +0 -26
package/src/shared/constants.ts
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
// Shared constants between client and server
|
|
2
|
-
|
|
3
|
-
export const API_VERSION = 'v1';
|
|
4
|
-
export const API_BASE_PATH = '/api';
|
|
5
|
-
|
|
6
|
-
// WebSocket events
|
|
7
|
-
export const WS_EVENTS = {
|
|
8
|
-
// Server -> Client
|
|
9
|
-
WORKFLOW_UPDATED: 'workflow:updated',
|
|
10
|
-
EXECUTION_STARTED: 'execution:started',
|
|
11
|
-
EXECUTION_STEP: 'execution:step',
|
|
12
|
-
EXECUTION_COMPLETED: 'execution:completed',
|
|
13
|
-
AI_PROCESSING: 'ai:processing',
|
|
14
|
-
AI_RESPONSE: 'ai:response',
|
|
15
|
-
|
|
16
|
-
// Client -> Server
|
|
17
|
-
WORKFLOW_SUBSCRIBE: 'workflow:subscribe',
|
|
18
|
-
WORKFLOW_UNSUBSCRIBE: 'workflow:unsubscribe',
|
|
19
|
-
EXECUTION_SUBSCRIBE: 'execution:subscribe',
|
|
20
|
-
EXECUTION_UNSUBSCRIBE: 'execution:unsubscribe',
|
|
21
|
-
} as const;
|
|
22
|
-
|
|
23
|
-
// Available services and their methods
|
|
24
|
-
export const SERVICES = {
|
|
25
|
-
slack: {
|
|
26
|
-
name: 'Slack',
|
|
27
|
-
icon: 'slack',
|
|
28
|
-
methods: [
|
|
29
|
-
'chat.postMessage',
|
|
30
|
-
'chat.update',
|
|
31
|
-
'chat.delete',
|
|
32
|
-
'conversations.list',
|
|
33
|
-
'conversations.create',
|
|
34
|
-
'files.upload',
|
|
35
|
-
'users.info',
|
|
36
|
-
],
|
|
37
|
-
},
|
|
38
|
-
github: {
|
|
39
|
-
name: 'GitHub',
|
|
40
|
-
icon: 'github',
|
|
41
|
-
methods: [
|
|
42
|
-
'pulls.get',
|
|
43
|
-
'pulls.list',
|
|
44
|
-
'pulls.create',
|
|
45
|
-
'pulls.createReview',
|
|
46
|
-
'pulls.listFiles',
|
|
47
|
-
'issues.get',
|
|
48
|
-
'issues.create',
|
|
49
|
-
'issues.createComment',
|
|
50
|
-
'repos.getContent',
|
|
51
|
-
'search.code',
|
|
52
|
-
],
|
|
53
|
-
},
|
|
54
|
-
jira: {
|
|
55
|
-
name: 'Jira',
|
|
56
|
-
icon: 'jira',
|
|
57
|
-
methods: [
|
|
58
|
-
'issues.getIssue',
|
|
59
|
-
'issues.createIssue',
|
|
60
|
-
'issues.editIssue',
|
|
61
|
-
'issues.search',
|
|
62
|
-
'issues.addComment',
|
|
63
|
-
'issues.transition',
|
|
64
|
-
],
|
|
65
|
-
},
|
|
66
|
-
gmail: {
|
|
67
|
-
name: 'Gmail',
|
|
68
|
-
icon: 'gmail',
|
|
69
|
-
methods: [
|
|
70
|
-
'messages.list',
|
|
71
|
-
'messages.get',
|
|
72
|
-
'messages.send',
|
|
73
|
-
'drafts.create',
|
|
74
|
-
'labels.list',
|
|
75
|
-
],
|
|
76
|
-
},
|
|
77
|
-
outlook: {
|
|
78
|
-
name: 'Outlook',
|
|
79
|
-
icon: 'outlook',
|
|
80
|
-
methods: [
|
|
81
|
-
'messages.list',
|
|
82
|
-
'messages.get',
|
|
83
|
-
'messages.send',
|
|
84
|
-
'calendar.events.list',
|
|
85
|
-
'calendar.events.create',
|
|
86
|
-
],
|
|
87
|
-
},
|
|
88
|
-
linear: {
|
|
89
|
-
name: 'Linear',
|
|
90
|
-
icon: 'linear',
|
|
91
|
-
methods: [
|
|
92
|
-
'issues.get',
|
|
93
|
-
'issues.create',
|
|
94
|
-
'issues.update',
|
|
95
|
-
'issues.search',
|
|
96
|
-
'projects.list',
|
|
97
|
-
],
|
|
98
|
-
},
|
|
99
|
-
notion: {
|
|
100
|
-
name: 'Notion',
|
|
101
|
-
icon: 'notion',
|
|
102
|
-
methods: [
|
|
103
|
-
'pages.get',
|
|
104
|
-
'pages.create',
|
|
105
|
-
'pages.update',
|
|
106
|
-
'databases.query',
|
|
107
|
-
'search',
|
|
108
|
-
],
|
|
109
|
-
},
|
|
110
|
-
discord: {
|
|
111
|
-
name: 'Discord',
|
|
112
|
-
icon: 'discord',
|
|
113
|
-
methods: [
|
|
114
|
-
'messages.send',
|
|
115
|
-
'messages.edit',
|
|
116
|
-
'messages.delete',
|
|
117
|
-
'channels.get',
|
|
118
|
-
'webhooks.execute',
|
|
119
|
-
],
|
|
120
|
-
},
|
|
121
|
-
airtable: {
|
|
122
|
-
name: 'Airtable',
|
|
123
|
-
icon: 'airtable',
|
|
124
|
-
methods: [
|
|
125
|
-
'records.list',
|
|
126
|
-
'records.get',
|
|
127
|
-
'records.create',
|
|
128
|
-
'records.update',
|
|
129
|
-
'records.delete',
|
|
130
|
-
],
|
|
131
|
-
},
|
|
132
|
-
confluence: {
|
|
133
|
-
name: 'Confluence',
|
|
134
|
-
icon: 'confluence',
|
|
135
|
-
methods: [
|
|
136
|
-
'pages.list',
|
|
137
|
-
'pages.get',
|
|
138
|
-
'pages.create',
|
|
139
|
-
'pages.update',
|
|
140
|
-
'search',
|
|
141
|
-
],
|
|
142
|
-
},
|
|
143
|
-
http: {
|
|
144
|
-
name: 'HTTP',
|
|
145
|
-
icon: 'http',
|
|
146
|
-
methods: ['request', 'get', 'post', 'put', 'patch', 'delete'],
|
|
147
|
-
},
|
|
148
|
-
claude: {
|
|
149
|
-
name: 'Claude',
|
|
150
|
-
icon: 'claude',
|
|
151
|
-
methods: ['analyze', 'generate', 'summarize', 'chat'],
|
|
152
|
-
},
|
|
153
|
-
opencode: {
|
|
154
|
-
name: 'OpenCode',
|
|
155
|
-
icon: 'opencode',
|
|
156
|
-
methods: ['chat', 'complete', 'analyze'],
|
|
157
|
-
},
|
|
158
|
-
ollama: {
|
|
159
|
-
name: 'Ollama',
|
|
160
|
-
icon: 'ollama',
|
|
161
|
-
methods: ['generate', 'chat', 'embeddings'],
|
|
162
|
-
},
|
|
163
|
-
} as const;
|
|
164
|
-
|
|
165
|
-
// Default node positions
|
|
166
|
-
export const NODE_LAYOUT = {
|
|
167
|
-
VERTICAL_SPACING: 120,
|
|
168
|
-
HORIZONTAL_OFFSET: 250,
|
|
169
|
-
GROUP_PADDING: 40,
|
|
170
|
-
} as const;
|
|
171
|
-
|
|
172
|
-
// Status colors
|
|
173
|
-
export const STATUS_COLORS = {
|
|
174
|
-
pending: { bg: 'bg-gray-400/10', text: 'text-gray-400', border: 'border-gray-400' },
|
|
175
|
-
running: { bg: 'bg-warning/10', text: 'text-warning', border: 'border-warning' },
|
|
176
|
-
completed: { bg: 'bg-success/10', text: 'text-success', border: 'border-success' },
|
|
177
|
-
failed: { bg: 'bg-error/10', text: 'text-error', border: 'border-error' },
|
|
178
|
-
skipped: { bg: 'bg-gray-500/10', text: 'text-gray-500', border: 'border-gray-500' },
|
|
179
|
-
cancelled: { bg: 'bg-gray-500/10', text: 'text-gray-500', border: 'border-gray-500' },
|
|
180
|
-
} as const;
|
package/src/shared/types.ts
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
// Shared types between client and server
|
|
2
|
-
|
|
3
|
-
export interface WorkflowMetadata {
|
|
4
|
-
id: string;
|
|
5
|
-
name: string;
|
|
6
|
-
version?: string;
|
|
7
|
-
description?: string;
|
|
8
|
-
author?: string;
|
|
9
|
-
tags?: string[];
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface WorkflowStep {
|
|
13
|
-
id: string;
|
|
14
|
-
name?: string;
|
|
15
|
-
action?: string;
|
|
16
|
-
workflow?: string;
|
|
17
|
-
inputs: Record<string, unknown>;
|
|
18
|
-
outputVariable?: string;
|
|
19
|
-
conditions?: string[];
|
|
20
|
-
errorHandling?: {
|
|
21
|
-
action: 'stop' | 'continue' | 'retry';
|
|
22
|
-
maxRetries?: number;
|
|
23
|
-
retryDelay?: number;
|
|
24
|
-
fallbackStep?: string;
|
|
25
|
-
};
|
|
26
|
-
timeout?: number;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface WorkflowTool {
|
|
30
|
-
sdk: string;
|
|
31
|
-
auth?: Record<string, string>;
|
|
32
|
-
options?: Record<string, unknown>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface WorkflowInput {
|
|
36
|
-
type: 'string' | 'number' | 'boolean' | 'array' | 'object';
|
|
37
|
-
required?: boolean;
|
|
38
|
-
default?: unknown;
|
|
39
|
-
description?: string;
|
|
40
|
-
validation?: {
|
|
41
|
-
pattern?: string;
|
|
42
|
-
min?: number;
|
|
43
|
-
max?: number;
|
|
44
|
-
enum?: unknown[];
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface WorkflowTrigger {
|
|
49
|
-
type: 'manual' | 'schedule' | 'webhook' | 'event';
|
|
50
|
-
cron?: string;
|
|
51
|
-
path?: string;
|
|
52
|
-
events?: string[];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface Workflow {
|
|
56
|
-
metadata: WorkflowMetadata;
|
|
57
|
-
steps: WorkflowStep[];
|
|
58
|
-
tools?: Record<string, WorkflowTool>;
|
|
59
|
-
inputs?: Record<string, WorkflowInput>;
|
|
60
|
-
triggers?: WorkflowTrigger[];
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface WorkflowListItem {
|
|
64
|
-
path: string;
|
|
65
|
-
name: string;
|
|
66
|
-
description?: string;
|
|
67
|
-
version?: string;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Execution types
|
|
71
|
-
|
|
72
|
-
export type StepStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped';
|
|
73
|
-
export type WorkflowStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
74
|
-
|
|
75
|
-
export interface StepResult {
|
|
76
|
-
stepId: string;
|
|
77
|
-
status: StepStatus;
|
|
78
|
-
output?: unknown;
|
|
79
|
-
error?: string;
|
|
80
|
-
startedAt: Date;
|
|
81
|
-
completedAt?: Date;
|
|
82
|
-
duration?: number;
|
|
83
|
-
retryCount: number;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface WorkflowRun {
|
|
87
|
-
runId: string;
|
|
88
|
-
workflowId: string;
|
|
89
|
-
workflowPath: string;
|
|
90
|
-
status: WorkflowStatus;
|
|
91
|
-
stepResults: StepResult[];
|
|
92
|
-
inputs: Record<string, unknown>;
|
|
93
|
-
outputs: Record<string, unknown>;
|
|
94
|
-
startedAt: Date;
|
|
95
|
-
completedAt?: Date;
|
|
96
|
-
duration?: number;
|
|
97
|
-
error?: string;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Canvas types
|
|
101
|
-
|
|
102
|
-
export interface CanvasNode {
|
|
103
|
-
id: string;
|
|
104
|
-
type: 'step' | 'subworkflow' | 'trigger' | 'output';
|
|
105
|
-
position: { x: number; y: number };
|
|
106
|
-
data: StepNodeData | SubWorkflowNodeData;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export interface StepNodeData {
|
|
110
|
-
id: string;
|
|
111
|
-
name?: string;
|
|
112
|
-
action: string;
|
|
113
|
-
status?: StepStatus;
|
|
114
|
-
retryCount?: number;
|
|
115
|
-
error?: string;
|
|
116
|
-
inputs?: Record<string, unknown>;
|
|
117
|
-
outputVariable?: string;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export interface SubWorkflowNodeData {
|
|
121
|
-
id: string;
|
|
122
|
-
name?: string;
|
|
123
|
-
workflowPath: string;
|
|
124
|
-
stepCount?: number;
|
|
125
|
-
status?: WorkflowStatus;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export interface CanvasEdge {
|
|
129
|
-
id: string;
|
|
130
|
-
source: string;
|
|
131
|
-
target: string;
|
|
132
|
-
type: 'sequence' | 'dataflow';
|
|
133
|
-
label?: string;
|
|
134
|
-
animated?: boolean;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// API types
|
|
138
|
-
|
|
139
|
-
export interface APIResponse<T> {
|
|
140
|
-
data?: T;
|
|
141
|
-
error?: string;
|
|
142
|
-
message?: string;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export interface PromptRequest {
|
|
146
|
-
prompt: string;
|
|
147
|
-
workflow: Workflow;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export interface PromptResponse {
|
|
151
|
-
explanation: string;
|
|
152
|
-
workflow?: Workflow;
|
|
153
|
-
diff?: string;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// WebSocket events
|
|
157
|
-
|
|
158
|
-
export interface WorkflowUpdatedEvent {
|
|
159
|
-
path: string;
|
|
160
|
-
event: 'change' | 'add' | 'remove';
|
|
161
|
-
timestamp: string;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export interface ExecutionStepEvent {
|
|
165
|
-
runId: string;
|
|
166
|
-
stepId: string;
|
|
167
|
-
status: StepStatus;
|
|
168
|
-
output?: unknown;
|
|
169
|
-
error?: string;
|
|
170
|
-
duration?: number;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export interface ExecutionCompletedEvent {
|
|
174
|
-
runId: string;
|
|
175
|
-
status: WorkflowStatus;
|
|
176
|
-
outputs: Record<string, unknown>;
|
|
177
|
-
duration: number;
|
|
178
|
-
error?: string;
|
|
179
|
-
}
|
package/tailwind.config.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import type { Config } from 'tailwindcss';
|
|
2
|
-
|
|
3
|
-
const config: Config = {
|
|
4
|
-
darkMode: 'class',
|
|
5
|
-
content: ['./index.html', './src/client/**/*.{js,ts,jsx,tsx}'],
|
|
6
|
-
theme: {
|
|
7
|
-
extend: {
|
|
8
|
-
colors: {
|
|
9
|
-
// Primary color palette
|
|
10
|
-
primary: {
|
|
11
|
-
DEFAULT: '#ff6d5a',
|
|
12
|
-
light: '#ff8a7a',
|
|
13
|
-
dark: '#e55a48',
|
|
14
|
-
50: '#fff5f3',
|
|
15
|
-
100: '#ffe6e2',
|
|
16
|
-
200: '#ffd0c9',
|
|
17
|
-
300: '#ffb0a4',
|
|
18
|
-
400: '#ff8a7a',
|
|
19
|
-
500: '#ff6d5a',
|
|
20
|
-
600: '#e55a48',
|
|
21
|
-
700: '#c44a3b',
|
|
22
|
-
800: '#a03d31',
|
|
23
|
-
900: '#7d3128',
|
|
24
|
-
},
|
|
25
|
-
canvas: {
|
|
26
|
-
bg: '#1a1a2e',
|
|
27
|
-
'bg-light': '#f5f5f7',
|
|
28
|
-
},
|
|
29
|
-
panel: {
|
|
30
|
-
bg: '#232340',
|
|
31
|
-
'bg-light': '#ffffff',
|
|
32
|
-
},
|
|
33
|
-
node: {
|
|
34
|
-
bg: '#2d2d4a',
|
|
35
|
-
'bg-light': '#ffffff',
|
|
36
|
-
border: '#3d3d5c',
|
|
37
|
-
'border-light': '#e5e5e5',
|
|
38
|
-
},
|
|
39
|
-
// Status colors
|
|
40
|
-
success: '#5cb85c',
|
|
41
|
-
warning: '#f0ad4e',
|
|
42
|
-
error: '#d9534f',
|
|
43
|
-
info: '#5bc0de',
|
|
44
|
-
},
|
|
45
|
-
fontFamily: {
|
|
46
|
-
sans: ['Inter', 'system-ui', 'sans-serif'],
|
|
47
|
-
mono: ['JetBrains Mono', 'Consolas', 'monospace'],
|
|
48
|
-
},
|
|
49
|
-
boxShadow: {
|
|
50
|
-
node: '0 4px 12px rgba(0, 0, 0, 0.3)',
|
|
51
|
-
'node-light': '0 2px 8px rgba(0, 0, 0, 0.1)',
|
|
52
|
-
'node-hover': '0 8px 24px rgba(0, 0, 0, 0.4)',
|
|
53
|
-
},
|
|
54
|
-
animation: {
|
|
55
|
-
pulse: 'pulse 1.5s ease-in-out infinite',
|
|
56
|
-
'flow-edge': 'flowEdge 1s linear infinite',
|
|
57
|
-
},
|
|
58
|
-
keyframes: {
|
|
59
|
-
pulse: {
|
|
60
|
-
'0%, 100%': { opacity: '1' },
|
|
61
|
-
'50%': { opacity: '0.7' },
|
|
62
|
-
},
|
|
63
|
-
flowEdge: {
|
|
64
|
-
'0%': { strokeDashoffset: '24' },
|
|
65
|
-
'100%': { strokeDashoffset: '0' },
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
plugins: [],
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
export default config;
|
package/tests/e2e/app.spec.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { test, expect } from '@playwright/test';
|
|
2
|
-
|
|
3
|
-
test.describe('App', () => {
|
|
4
|
-
test('should load the application', async ({ page }) => {
|
|
5
|
-
await page.goto('/');
|
|
6
|
-
|
|
7
|
-
// Check that the main elements are visible
|
|
8
|
-
await expect(page.locator('text=Marktoflow')).toBeVisible();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
test('should display the sidebar with workflows', async ({ page }) => {
|
|
12
|
-
await page.goto('/');
|
|
13
|
-
|
|
14
|
-
// Check sidebar exists
|
|
15
|
-
const sidebar = page.locator('[class*="w-64"]').first();
|
|
16
|
-
await expect(sidebar).toBeVisible();
|
|
17
|
-
|
|
18
|
-
// Check workflows tab
|
|
19
|
-
await expect(page.locator('button:has-text("Workflows")')).toBeVisible();
|
|
20
|
-
await expect(page.locator('button:has-text("Tools")')).toBeVisible();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
test('should switch between Workflows and Tools tabs', async ({ page }) => {
|
|
24
|
-
await page.goto('/');
|
|
25
|
-
|
|
26
|
-
// Click on Tools tab
|
|
27
|
-
await page.click('button:has-text("Tools")');
|
|
28
|
-
|
|
29
|
-
// Check that tools are visible (looking for tool categories)
|
|
30
|
-
await expect(page.locator('text=Communication')).toBeVisible();
|
|
31
|
-
await expect(page.locator('text=Development')).toBeVisible();
|
|
32
|
-
|
|
33
|
-
// Click back to Workflows
|
|
34
|
-
await page.click('button:has-text("Workflows")');
|
|
35
|
-
|
|
36
|
-
// Check that workflow list items are visible
|
|
37
|
-
await expect(page.locator('text=Code Review')).toBeVisible();
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test('should display connection status', async ({ page }) => {
|
|
41
|
-
await page.goto('/');
|
|
42
|
-
|
|
43
|
-
// Check connection status indicator
|
|
44
|
-
const connectionStatus = page.locator('text=Connected').or(page.locator('text=Disconnected'));
|
|
45
|
-
await expect(connectionStatus).toBeVisible();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test('should show keyboard shortcuts button', async ({ page }) => {
|
|
49
|
-
await page.goto('/');
|
|
50
|
-
|
|
51
|
-
// Check shortcuts button
|
|
52
|
-
await expect(page.locator('button:has-text("Shortcuts")')).toBeVisible();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test('should open keyboard shortcuts modal', async ({ page }) => {
|
|
56
|
-
await page.goto('/');
|
|
57
|
-
|
|
58
|
-
// Click shortcuts button
|
|
59
|
-
await page.click('button:has-text("Shortcuts")');
|
|
60
|
-
|
|
61
|
-
// Check modal is open
|
|
62
|
-
await expect(page.locator('text=Keyboard Shortcuts')).toBeVisible();
|
|
63
|
-
await expect(page.locator('text=General')).toBeVisible();
|
|
64
|
-
await expect(page.locator('text=Canvas')).toBeVisible();
|
|
65
|
-
|
|
66
|
-
// Close modal
|
|
67
|
-
await page.click('button:has-text("Close")');
|
|
68
|
-
|
|
69
|
-
// Modal should be closed
|
|
70
|
-
await expect(page.locator('role=dialog')).not.toBeVisible();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
test('should display toolbar with action buttons', async ({ page }) => {
|
|
74
|
-
await page.goto('/');
|
|
75
|
-
|
|
76
|
-
// Check toolbar buttons
|
|
77
|
-
await expect(page.locator('button:has-text("Add Step")')).toBeVisible();
|
|
78
|
-
await expect(page.locator('button:has-text("Execute")')).toBeVisible();
|
|
79
|
-
await expect(page.locator('button:has-text("Save")')).toBeVisible();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test('should display properties panel', async ({ page }) => {
|
|
83
|
-
await page.goto('/');
|
|
84
|
-
|
|
85
|
-
// Check properties panel
|
|
86
|
-
await expect(page.locator('text=Properties')).toBeVisible();
|
|
87
|
-
await expect(page.locator('button:has-text("Variables")')).toBeVisible();
|
|
88
|
-
await expect(page.locator('button:has-text("History")')).toBeVisible();
|
|
89
|
-
});
|
|
90
|
-
});
|
package/tests/e2e/canvas.spec.ts
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { test, expect } from '@playwright/test';
|
|
2
|
-
|
|
3
|
-
test.describe('Canvas', () => {
|
|
4
|
-
test.beforeEach(async ({ page }) => {
|
|
5
|
-
await page.goto('/');
|
|
6
|
-
// Wait for canvas to be ready
|
|
7
|
-
await page.waitForSelector('.react-flow');
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
test('should display the workflow canvas', async ({ page }) => {
|
|
11
|
-
// Check React Flow canvas is visible
|
|
12
|
-
await expect(page.locator('.react-flow')).toBeVisible();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
test('should display workflow nodes', async ({ page }) => {
|
|
16
|
-
// Check that step nodes are visible (from demo data)
|
|
17
|
-
await expect(page.locator('.react-flow__node').first()).toBeVisible();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
test('should display canvas controls', async ({ page }) => {
|
|
21
|
-
// Check React Flow controls are visible
|
|
22
|
-
await expect(page.locator('.react-flow__controls')).toBeVisible();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test('should display minimap', async ({ page }) => {
|
|
26
|
-
// Check minimap is visible
|
|
27
|
-
await expect(page.locator('.react-flow__minimap')).toBeVisible();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test('should select a node on click', async ({ page }) => {
|
|
31
|
-
// Click on a node
|
|
32
|
-
const node = page.locator('.react-flow__node').first();
|
|
33
|
-
await node.click();
|
|
34
|
-
|
|
35
|
-
// Check node is selected (has selected class)
|
|
36
|
-
await expect(node).toHaveClass(/selected/);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
test('should show node details in properties panel on selection', async ({ page }) => {
|
|
40
|
-
// Click on a step node
|
|
41
|
-
const node = page.locator('.react-flow__node').first();
|
|
42
|
-
await node.click();
|
|
43
|
-
|
|
44
|
-
// Properties panel should show step details
|
|
45
|
-
await expect(page.locator('text=Step')).toBeVisible();
|
|
46
|
-
await expect(page.locator('text=ID')).toBeVisible();
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test('should open step editor on double-click', async ({ page }) => {
|
|
50
|
-
// Double click on a step node
|
|
51
|
-
const stepNode = page.locator('.react-flow__node[data-testid*="step"]').first();
|
|
52
|
-
|
|
53
|
-
// If no step nodes with test id, try clicking any node
|
|
54
|
-
const anyNode = page.locator('.react-flow__node').first();
|
|
55
|
-
await anyNode.dblclick();
|
|
56
|
-
|
|
57
|
-
// Check if editor modal opens (may not for all node types)
|
|
58
|
-
// This is a soft check since some nodes don't open editor
|
|
59
|
-
const editorDialog = page.locator('role=dialog');
|
|
60
|
-
const isVisible = await editorDialog.isVisible().catch(() => false);
|
|
61
|
-
|
|
62
|
-
// Either the editor opened or we clicked on a non-editable node
|
|
63
|
-
expect(true).toBe(true);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
test('should show context menu on right-click', async ({ page }) => {
|
|
67
|
-
// Right click on a step node
|
|
68
|
-
const node = page.locator('.react-flow__node').first();
|
|
69
|
-
await node.click({ button: 'right' });
|
|
70
|
-
|
|
71
|
-
// Context menu should appear (Radix context menu)
|
|
72
|
-
// Wait a bit for menu to render
|
|
73
|
-
await page.waitForTimeout(100);
|
|
74
|
-
|
|
75
|
-
// Check if context menu is visible
|
|
76
|
-
const contextMenu = page.locator('[role="menu"]');
|
|
77
|
-
const isVisible = await contextMenu.isVisible().catch(() => false);
|
|
78
|
-
|
|
79
|
-
// Context menu may or may not appear depending on node type
|
|
80
|
-
expect(true).toBe(true);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
test('should zoom in with controls', async ({ page }) => {
|
|
84
|
-
const zoomInButton = page.locator('.react-flow__controls-button').first();
|
|
85
|
-
await zoomInButton.click();
|
|
86
|
-
|
|
87
|
-
// Canvas should still be functional
|
|
88
|
-
await expect(page.locator('.react-flow')).toBeVisible();
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test('should fit view with controls', async ({ page }) => {
|
|
92
|
-
const fitViewButton = page.locator('.react-flow__controls-fitview');
|
|
93
|
-
if (await fitViewButton.isVisible()) {
|
|
94
|
-
await fitViewButton.click();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Canvas should still be functional
|
|
98
|
-
await expect(page.locator('.react-flow')).toBeVisible();
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
test('should delete selected node with backspace', async ({ page }) => {
|
|
102
|
-
// Select a node
|
|
103
|
-
const node = page.locator('.react-flow__node').first();
|
|
104
|
-
await node.click();
|
|
105
|
-
|
|
106
|
-
// Count nodes before delete
|
|
107
|
-
const nodesBefore = await page.locator('.react-flow__node').count();
|
|
108
|
-
|
|
109
|
-
// Press backspace
|
|
110
|
-
await page.keyboard.press('Backspace');
|
|
111
|
-
|
|
112
|
-
// Count nodes after delete
|
|
113
|
-
const nodesAfter = await page.locator('.react-flow__node').count();
|
|
114
|
-
|
|
115
|
-
// Should have one less node (or same if delete is prevented)
|
|
116
|
-
expect(nodesAfter).toBeLessThanOrEqual(nodesBefore);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
test('should connect nodes by dragging handles', async ({ page }) => {
|
|
120
|
-
// This test would require more complex interaction
|
|
121
|
-
// For now, just verify handles exist
|
|
122
|
-
const sourceHandles = page.locator('.react-flow__handle-bottom');
|
|
123
|
-
const targetHandles = page.locator('.react-flow__handle-top');
|
|
124
|
-
|
|
125
|
-
expect(await sourceHandles.count()).toBeGreaterThan(0);
|
|
126
|
-
expect(await targetHandles.count()).toBeGreaterThan(0);
|
|
127
|
-
});
|
|
128
|
-
});
|