@pixelbyte-software/pixcode 1.35.0 → 1.35.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.
- package/LICENSE +718 -718
- package/README.de.md +248 -248
- package/README.ja.md +240 -240
- package/README.ko.md +240 -240
- package/README.md +303 -303
- package/README.ru.md +248 -248
- package/README.tr.md +250 -250
- package/README.zh-CN.md +240 -240
- package/dist/api-docs.html +548 -548
- package/dist/assets/{index-Djuh0wHV.js → index-CBdsvGSR.js} +133 -133
- package/dist/clear-cache.html +85 -85
- package/dist/convert-icons.md +52 -52
- package/dist/generate-icons.js +48 -48
- package/dist/icons/codex-white.svg +3 -3
- package/dist/icons/codex.svg +3 -3
- package/dist/icons/cursor-white.svg +11 -11
- package/dist/icons/qwen-logo.svg +14 -14
- package/dist/index.html +58 -58
- package/dist/manifest.json +60 -60
- package/dist/openapi.yaml +1693 -1693
- package/dist/sw.js +124 -124
- package/dist-server/server/cli.js +96 -96
- package/dist-server/server/daemon/manager.js +33 -33
- package/dist-server/server/daemon-manager.js +64 -64
- package/dist-server/server/modules/orchestration/preview/preview-proxy.js +3 -3
- package/dist-server/server/modules/orchestration/preview/preview-proxy.js.map +1 -1
- package/dist-server/server/routes/commands.js +25 -25
- package/dist-server/server/routes/git.js +17 -17
- package/dist-server/server/routes/taskmaster.js +419 -419
- package/package.json +180 -180
- package/scripts/fix-node-pty.js +67 -67
- package/scripts/smoke/a2a-roundtrip.mjs +167 -167
- package/scripts/smoke/orchestration-api.mjs +172 -172
- package/scripts/smoke/orchestration-live-run.mjs +176 -176
- package/server/claude-sdk.js +898 -898
- package/server/cli.js +935 -935
- package/server/constants/config.js +4 -4
- package/server/cursor-cli.js +342 -342
- package/server/daemon/manager.js +564 -564
- package/server/daemon-manager.js +959 -959
- package/server/database/json-store.js +197 -197
- package/server/gemini-cli.js +535 -535
- package/server/gemini-response-handler.js +79 -79
- package/server/index.js +3135 -3135
- package/server/load-env.js +34 -34
- package/server/middleware/auth.js +173 -173
- package/server/modules/orchestration/a2a/adapter-registry.ts +108 -108
- package/server/modules/orchestration/a2a/adapters/abstract-a2a.adapter.ts +55 -55
- package/server/modules/orchestration/a2a/adapters/claude-code.adapter.ts +284 -284
- package/server/modules/orchestration/a2a/adapters/codex.adapter.ts +244 -244
- package/server/modules/orchestration/a2a/adapters/cursor.adapter.ts +249 -249
- package/server/modules/orchestration/a2a/adapters/gemini.adapter.ts +248 -248
- package/server/modules/orchestration/a2a/adapters/opencode.adapter.ts +248 -248
- package/server/modules/orchestration/a2a/adapters/qwen.adapter.ts +248 -248
- package/server/modules/orchestration/a2a/agent-card.ts +55 -55
- package/server/modules/orchestration/a2a/auth.middleware.ts +29 -29
- package/server/modules/orchestration/a2a/bus.ts +46 -46
- package/server/modules/orchestration/a2a/routes.ts +577 -577
- package/server/modules/orchestration/a2a/task-store.ts +178 -178
- package/server/modules/orchestration/a2a/types.ts +125 -125
- package/server/modules/orchestration/a2a/validator.ts +113 -113
- package/server/modules/orchestration/index.ts +66 -66
- package/server/modules/orchestration/preview/port-watcher.ts +112 -112
- package/server/modules/orchestration/preview/preview-proxy.ts +60 -60
- package/server/modules/orchestration/preview/types.ts +19 -19
- package/server/modules/orchestration/tasks/orchestration-task-store.ts +45 -45
- package/server/modules/orchestration/tasks/orchestration-task.routes.ts +73 -73
- package/server/modules/orchestration/tasks/orchestration-task.service.ts +145 -145
- package/server/modules/orchestration/tasks/orchestration-task.types.ts +29 -29
- package/server/modules/orchestration/workflows/built-in-workflows.ts +127 -127
- package/server/modules/orchestration/workflows/workflow-runner.ts +1206 -1206
- package/server/modules/orchestration/workflows/workflow-store.ts +97 -97
- package/server/modules/orchestration/workflows/workflow.routes.ts +169 -169
- package/server/modules/orchestration/workflows/workflow.types.ts +70 -70
- package/server/modules/orchestration/workflows/workspace-target.ts +120 -120
- package/server/modules/orchestration/workspace/docker-workspace.ts +135 -135
- package/server/modules/orchestration/workspace/path-safety.ts +55 -55
- package/server/modules/orchestration/workspace/types.ts +52 -52
- package/server/modules/orchestration/workspace/workspace-manager.ts +97 -97
- package/server/modules/orchestration/workspace/worktree-workspace.ts +125 -125
- package/server/modules/providers/index.ts +2 -2
- package/server/modules/providers/list/claude/claude-auth.provider.ts +145 -145
- package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -135
- package/server/modules/providers/list/claude/claude-sessions.provider.ts +306 -306
- package/server/modules/providers/list/claude/claude.provider.ts +15 -15
- package/server/modules/providers/list/codex/codex-auth.provider.ts +115 -115
- package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -135
- package/server/modules/providers/list/codex/codex-sessions.provider.ts +319 -319
- package/server/modules/providers/list/codex/codex.provider.ts +15 -15
- package/server/modules/providers/list/cursor/cursor-auth.provider.ts +143 -143
- package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -108
- package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +421 -421
- package/server/modules/providers/list/cursor/cursor.provider.ts +15 -15
- package/server/modules/providers/list/gemini/gemini-auth.provider.ts +163 -163
- package/server/modules/providers/list/gemini/gemini-mcp.provider.ts +110 -110
- package/server/modules/providers/list/gemini/gemini-sessions.provider.ts +227 -227
- package/server/modules/providers/list/gemini/gemini.provider.ts +15 -15
- package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +232 -232
- package/server/modules/providers/list/qwen/qwen-sessions.provider.ts +265 -265
- package/server/modules/providers/provider.registry.ts +40 -40
- package/server/modules/providers/provider.routes.ts +819 -819
- package/server/modules/providers/services/mcp.service.ts +86 -86
- package/server/modules/providers/services/provider-auth.service.ts +26 -26
- package/server/modules/providers/services/sessions.service.ts +45 -45
- package/server/modules/providers/shared/base/abstract.provider.ts +20 -20
- package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -151
- package/server/modules/providers/tests/mcp.test.ts +293 -293
- package/server/openai-codex.js +462 -462
- package/server/opencode-cli.js +459 -459
- package/server/opencode-response-handler.js +107 -107
- package/server/projects.js +3105 -3105
- package/server/routes/agent.js +1365 -1365
- package/server/routes/auth.js +138 -138
- package/server/routes/codex.js +19 -19
- package/server/routes/commands.js +554 -554
- package/server/routes/cursor.js +52 -52
- package/server/routes/gemini.js +24 -24
- package/server/routes/git.js +1488 -1488
- package/server/routes/mcp-utils.js +31 -31
- package/server/routes/messages.js +61 -61
- package/server/routes/network.js +120 -120
- package/server/routes/plugins.js +318 -318
- package/server/routes/projects.js +915 -915
- package/server/routes/settings.js +286 -286
- package/server/routes/taskmaster.js +1496 -1496
- package/server/routes/telegram.js +125 -125
- package/server/routes/user.js +123 -123
- package/server/services/install-jobs.js +571 -571
- package/server/services/notification-orchestrator.js +242 -242
- package/server/services/provider-credentials.js +189 -189
- package/server/services/telegram/bot.js +279 -279
- package/server/services/telegram/translations.js +170 -170
- package/server/sessionManager.js +225 -225
- package/server/shared/interfaces.ts +54 -54
- package/server/shared/types.ts +172 -172
- package/server/shared/utils.ts +193 -193
- package/server/tsconfig.json +36 -36
- package/server/utils/colors.js +21 -21
- package/server/utils/commandParser.js +303 -303
- package/server/utils/frontmatter.js +18 -18
- package/server/utils/gitConfig.js +34 -34
- package/server/utils/mcp-detector.js +147 -147
- package/server/utils/plugin-loader.js +457 -457
- package/server/utils/plugin-process-manager.js +184 -184
- package/server/utils/runtime-paths.js +37 -37
- package/server/utils/taskmaster-websocket.js +128 -128
- package/server/utils/url-detection.js +71 -71
- package/server/vite-daemon.js +78 -78
- package/shared/modelConstants.js +162 -162
- package/shared/networkHosts.js +22 -22
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
import type { RequestHandler, Router } from 'express';
|
|
2
|
-
import express from 'express';
|
|
3
|
-
|
|
4
|
-
import { getKnownPreviewPort } from '@/modules/orchestration/preview/port-watcher.js';
|
|
5
|
-
|
|
6
|
-
function buildTargetUrl(port: number, path: string): string {
|
|
7
|
-
const event = getKnownPreviewPort(port);
|
|
8
|
-
const host = event?.host ?? '127.0.0.1';
|
|
9
|
-
return `http://${host}:${port}${path}`;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function proxyHandler(): RequestHandler {
|
|
13
|
-
return async (req, res) => {
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
upstream.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (lower === '
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
router.
|
|
58
|
-
router.use(
|
|
59
|
-
return router;
|
|
60
|
-
}
|
|
1
|
+
import type { RequestHandler, Router } from 'express';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
|
|
4
|
+
import { getKnownPreviewPort } from '@/modules/orchestration/preview/port-watcher.js';
|
|
5
|
+
|
|
6
|
+
function buildTargetUrl(port: number, path: string): string {
|
|
7
|
+
const event = getKnownPreviewPort(port);
|
|
8
|
+
const host = event?.host ?? '127.0.0.1';
|
|
9
|
+
return `http://${host}:${port}${path}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function proxyHandler(): RequestHandler {
|
|
13
|
+
return async (req, res) => {
|
|
14
|
+
const portParam = req.params.port ?? req.params[0];
|
|
15
|
+
const rawPort = Array.isArray(portParam) ? portParam[0] : portParam;
|
|
16
|
+
const port = Number.parseInt(rawPort, 10);
|
|
17
|
+
if (!Number.isFinite(port) || port <= 0 || !getKnownPreviewPort(port)) {
|
|
18
|
+
res.status(404).json({
|
|
19
|
+
error: {
|
|
20
|
+
code: 'PREVIEW_PORT_NOT_FOUND',
|
|
21
|
+
message: 'Preview port is not registered for an orchestration task.',
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const path = req.originalUrl.replace(/^\/preview\/\d+/, '') || '/';
|
|
28
|
+
const target = buildTargetUrl(port, path);
|
|
29
|
+
try {
|
|
30
|
+
const upstream = await fetch(target, {
|
|
31
|
+
method: req.method,
|
|
32
|
+
headers: {
|
|
33
|
+
accept: req.header('accept') ?? '*/*',
|
|
34
|
+
'user-agent': req.header('user-agent') ?? 'pixcode-preview-proxy',
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
res.status(upstream.status);
|
|
38
|
+
upstream.headers.forEach((value, key) => {
|
|
39
|
+
const lower = key.toLowerCase();
|
|
40
|
+
if (lower === 'content-encoding' || lower === 'content-length') return;
|
|
41
|
+
if (lower === 'x-frame-options' || lower === 'content-security-policy') return;
|
|
42
|
+
res.setHeader(key, value);
|
|
43
|
+
});
|
|
44
|
+
res.send(Buffer.from(await upstream.arrayBuffer()));
|
|
45
|
+
} catch (error) {
|
|
46
|
+
res.status(502).json({
|
|
47
|
+
error: {
|
|
48
|
+
code: 'PREVIEW_PROXY_FAILED',
|
|
49
|
+
message: error instanceof Error ? error.message : String(error),
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function createPreviewProxyRouter(): Router {
|
|
57
|
+
const router = express.Router();
|
|
58
|
+
router.use(/^\/(\d+)(?:\/.*)?$/, proxyHandler());
|
|
59
|
+
return router;
|
|
60
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
export interface PortEvent {
|
|
2
|
-
taskId: string;
|
|
3
|
-
workspaceId?: string;
|
|
4
|
-
port: number;
|
|
5
|
-
host: string;
|
|
6
|
-
url: string;
|
|
7
|
-
processName?: string;
|
|
8
|
-
confidence: 'low' | 'medium' | 'high';
|
|
9
|
-
detectedAt: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface PreviewArtifactData {
|
|
13
|
-
url: string;
|
|
14
|
-
proxiedUrl: string;
|
|
15
|
-
port: number;
|
|
16
|
-
host: string;
|
|
17
|
-
processName?: string;
|
|
18
|
-
confidence: 'low' | 'medium' | 'high';
|
|
19
|
-
}
|
|
1
|
+
export interface PortEvent {
|
|
2
|
+
taskId: string;
|
|
3
|
+
workspaceId?: string;
|
|
4
|
+
port: number;
|
|
5
|
+
host: string;
|
|
6
|
+
url: string;
|
|
7
|
+
processName?: string;
|
|
8
|
+
confidence: 'low' | 'medium' | 'high';
|
|
9
|
+
detectedAt: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface PreviewArtifactData {
|
|
13
|
+
url: string;
|
|
14
|
+
proxiedUrl: string;
|
|
15
|
+
port: number;
|
|
16
|
+
host: string;
|
|
17
|
+
processName?: string;
|
|
18
|
+
confidence: 'low' | 'medium' | 'high';
|
|
19
|
+
}
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import os from 'node:os';
|
|
3
|
-
|
|
4
|
-
import { JsonStore } from '@/database/json-store.js';
|
|
5
|
-
import type { OrchestrationTask } from '@/modules/orchestration/tasks/orchestration-task.types.js';
|
|
6
|
-
|
|
7
|
-
function defaultPath(): string {
|
|
8
|
-
return process.env.ORCHESTRATION_TASKS_PATH ??
|
|
9
|
-
path.join(os.homedir(), '.pixcode', 'orchestration-tasks.json');
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export class OrchestrationTaskStore {
|
|
13
|
-
private store: JsonStore;
|
|
14
|
-
|
|
15
|
-
constructor(filePath = defaultPath()) {
|
|
16
|
-
this.store = new JsonStore(filePath, { orchestration_tasks: [] });
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
get(id: string): OrchestrationTask | undefined {
|
|
20
|
-
return this.store.findWhere('orchestration_tasks', (r: OrchestrationTask) => r.id === id) ?? undefined;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
getByA2ATaskId(a2aTaskId: string): OrchestrationTask | undefined {
|
|
24
|
-
return this.store.findWhere('orchestration_tasks', (r: OrchestrationTask) => r.a2aTaskId === a2aTaskId) ?? undefined;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
getByTaskMasterId(taskmasterId: string): OrchestrationTask | undefined {
|
|
28
|
-
return this.store.findWhere('orchestration_tasks', (r: OrchestrationTask) => r.taskmasterId === taskmasterId) ?? undefined;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
list(projectId?: string): OrchestrationTask[] {
|
|
32
|
-
const tasks = this.store.filterWhere('orchestration_tasks', () => true) as OrchestrationTask[];
|
|
33
|
-
const sorted = tasks.sort((a, b) => b.createdAt - a.createdAt);
|
|
34
|
-
return projectId ? sorted.filter((task) => task.projectId === projectId) : sorted;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
set(task: OrchestrationTask): void {
|
|
38
|
-
const existing = this.store.findWhere('orchestration_tasks', (r: OrchestrationTask) => r.id === task.id);
|
|
39
|
-
if (existing) {
|
|
40
|
-
this.store.updateWhere('orchestration_tasks', (r: OrchestrationTask) => r.id === task.id, task);
|
|
41
|
-
} else {
|
|
42
|
-
this.store.insert('orchestration_tasks', task, { autoId: false });
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
|
|
4
|
+
import { JsonStore } from '@/database/json-store.js';
|
|
5
|
+
import type { OrchestrationTask } from '@/modules/orchestration/tasks/orchestration-task.types.js';
|
|
6
|
+
|
|
7
|
+
function defaultPath(): string {
|
|
8
|
+
return process.env.ORCHESTRATION_TASKS_PATH ??
|
|
9
|
+
path.join(os.homedir(), '.pixcode', 'orchestration-tasks.json');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class OrchestrationTaskStore {
|
|
13
|
+
private store: JsonStore;
|
|
14
|
+
|
|
15
|
+
constructor(filePath = defaultPath()) {
|
|
16
|
+
this.store = new JsonStore(filePath, { orchestration_tasks: [] });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get(id: string): OrchestrationTask | undefined {
|
|
20
|
+
return this.store.findWhere('orchestration_tasks', (r: OrchestrationTask) => r.id === id) ?? undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getByA2ATaskId(a2aTaskId: string): OrchestrationTask | undefined {
|
|
24
|
+
return this.store.findWhere('orchestration_tasks', (r: OrchestrationTask) => r.a2aTaskId === a2aTaskId) ?? undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getByTaskMasterId(taskmasterId: string): OrchestrationTask | undefined {
|
|
28
|
+
return this.store.findWhere('orchestration_tasks', (r: OrchestrationTask) => r.taskmasterId === taskmasterId) ?? undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
list(projectId?: string): OrchestrationTask[] {
|
|
32
|
+
const tasks = this.store.filterWhere('orchestration_tasks', () => true) as OrchestrationTask[];
|
|
33
|
+
const sorted = tasks.sort((a, b) => b.createdAt - a.createdAt);
|
|
34
|
+
return projectId ? sorted.filter((task) => task.projectId === projectId) : sorted;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
set(task: OrchestrationTask): void {
|
|
38
|
+
const existing = this.store.findWhere('orchestration_tasks', (r: OrchestrationTask) => r.id === task.id);
|
|
39
|
+
if (existing) {
|
|
40
|
+
this.store.updateWhere('orchestration_tasks', (r: OrchestrationTask) => r.id === task.id, task);
|
|
41
|
+
} else {
|
|
42
|
+
this.store.insert('orchestration_tasks', task, { autoId: false });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
import express, { type Router } from 'express';
|
|
2
|
-
import { orchestrationTaskService } from '@/modules/orchestration/tasks/orchestration-task.service.js';
|
|
3
|
-
|
|
4
|
-
export function createOrchestrationTaskRouter(): Router {
|
|
5
|
-
const router = express.Router();
|
|
6
|
-
router.use(express.json({ limit: '2mb' }));
|
|
7
|
-
|
|
8
|
-
router.get('/tasks', (req, res) => {
|
|
9
|
-
const projectId = typeof req.query.projectId === 'string' ? req.query.projectId : undefined;
|
|
10
|
-
res.json({ tasks: orchestrationTaskService.list(projectId) });
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
router.post('/tasks', (req, res) => {
|
|
14
|
-
const projectId = typeof req.body?.projectId === 'string' ? req.body.projectId : 'default';
|
|
15
|
-
const title = typeof req.body?.title === 'string' ? req.body.title.trim() : '';
|
|
16
|
-
const description = typeof req.body?.description === 'string' ? req.body.description : undefined;
|
|
17
|
-
const taskmasterId = typeof req.body?.taskmasterId === 'string' ? req.body.taskmasterId : undefined;
|
|
18
|
-
|
|
19
|
-
if (!title) {
|
|
20
|
-
res.status(400).json({ error: { code: 'TITLE_REQUIRED', message: 'title is required' } });
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const task = orchestrationTaskService.create({ projectId, title, description, taskmasterId });
|
|
25
|
-
res.status(201).json(task);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
router.post('/tasks/import-taskmaster', (req, res) => {
|
|
29
|
-
const projectId = typeof req.body?.projectId === 'string' ? req.body.projectId : 'default';
|
|
30
|
-
const entries = Array.isArray(req.body?.tasks) ? req.body.tasks : [];
|
|
31
|
-
const imported = entries
|
|
32
|
-
.map((entry: unknown) => {
|
|
33
|
-
if (!entry || typeof entry !== 'object') return null;
|
|
34
|
-
const record = entry as Record<string, unknown>;
|
|
35
|
-
const taskmasterId = typeof record.id === 'string' ? record.id : undefined;
|
|
36
|
-
const title = typeof record.title === 'string' ? record.title : undefined;
|
|
37
|
-
const description = typeof record.description === 'string' ? record.description : undefined;
|
|
38
|
-
if (!taskmasterId || !title) return null;
|
|
39
|
-
return orchestrationTaskService.upsertFromTaskMaster({ projectId, title, description, taskmasterId });
|
|
40
|
-
})
|
|
41
|
-
.filter(Boolean);
|
|
42
|
-
|
|
43
|
-
res.json({ tasks: imported, count: imported.length });
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
router.post('/tasks/:id/dispatch', async (req, res) => {
|
|
47
|
-
try {
|
|
48
|
-
const adapterId = typeof req.body?.adapterId === 'string' ? req.body.adapterId : '';
|
|
49
|
-
const isolation = req.body?.isolation;
|
|
50
|
-
if (!adapterId) {
|
|
51
|
-
res.status(400).json({ error: { code: 'ADAPTER_REQUIRED', message: 'adapterId is required' } });
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
const task = await orchestrationTaskService.dispatch(req.params.id, { adapterId, isolation });
|
|
55
|
-
res.json(task);
|
|
56
|
-
} catch (error) {
|
|
57
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
58
|
-
const status = message === 'TASK_NOT_FOUND' ? 404 : 400;
|
|
59
|
-
res.status(status).json({ error: { code: 'DISPATCH_FAILED', message } });
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
router.post('/tasks/:id/cancel', (req, res) => {
|
|
64
|
-
try {
|
|
65
|
-
const task = orchestrationTaskService.cancel(req.params.id);
|
|
66
|
-
res.json(task);
|
|
67
|
-
} catch {
|
|
68
|
-
res.status(404).json({ error: { code: 'TASK_NOT_FOUND', message: req.params.id } });
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
return router;
|
|
73
|
-
}
|
|
1
|
+
import express, { type Router } from 'express';
|
|
2
|
+
import { orchestrationTaskService } from '@/modules/orchestration/tasks/orchestration-task.service.js';
|
|
3
|
+
|
|
4
|
+
export function createOrchestrationTaskRouter(): Router {
|
|
5
|
+
const router = express.Router();
|
|
6
|
+
router.use(express.json({ limit: '2mb' }));
|
|
7
|
+
|
|
8
|
+
router.get('/tasks', (req, res) => {
|
|
9
|
+
const projectId = typeof req.query.projectId === 'string' ? req.query.projectId : undefined;
|
|
10
|
+
res.json({ tasks: orchestrationTaskService.list(projectId) });
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
router.post('/tasks', (req, res) => {
|
|
14
|
+
const projectId = typeof req.body?.projectId === 'string' ? req.body.projectId : 'default';
|
|
15
|
+
const title = typeof req.body?.title === 'string' ? req.body.title.trim() : '';
|
|
16
|
+
const description = typeof req.body?.description === 'string' ? req.body.description : undefined;
|
|
17
|
+
const taskmasterId = typeof req.body?.taskmasterId === 'string' ? req.body.taskmasterId : undefined;
|
|
18
|
+
|
|
19
|
+
if (!title) {
|
|
20
|
+
res.status(400).json({ error: { code: 'TITLE_REQUIRED', message: 'title is required' } });
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const task = orchestrationTaskService.create({ projectId, title, description, taskmasterId });
|
|
25
|
+
res.status(201).json(task);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
router.post('/tasks/import-taskmaster', (req, res) => {
|
|
29
|
+
const projectId = typeof req.body?.projectId === 'string' ? req.body.projectId : 'default';
|
|
30
|
+
const entries = Array.isArray(req.body?.tasks) ? req.body.tasks : [];
|
|
31
|
+
const imported = entries
|
|
32
|
+
.map((entry: unknown) => {
|
|
33
|
+
if (!entry || typeof entry !== 'object') return null;
|
|
34
|
+
const record = entry as Record<string, unknown>;
|
|
35
|
+
const taskmasterId = typeof record.id === 'string' ? record.id : undefined;
|
|
36
|
+
const title = typeof record.title === 'string' ? record.title : undefined;
|
|
37
|
+
const description = typeof record.description === 'string' ? record.description : undefined;
|
|
38
|
+
if (!taskmasterId || !title) return null;
|
|
39
|
+
return orchestrationTaskService.upsertFromTaskMaster({ projectId, title, description, taskmasterId });
|
|
40
|
+
})
|
|
41
|
+
.filter(Boolean);
|
|
42
|
+
|
|
43
|
+
res.json({ tasks: imported, count: imported.length });
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
router.post('/tasks/:id/dispatch', async (req, res) => {
|
|
47
|
+
try {
|
|
48
|
+
const adapterId = typeof req.body?.adapterId === 'string' ? req.body.adapterId : '';
|
|
49
|
+
const isolation = req.body?.isolation;
|
|
50
|
+
if (!adapterId) {
|
|
51
|
+
res.status(400).json({ error: { code: 'ADAPTER_REQUIRED', message: 'adapterId is required' } });
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const task = await orchestrationTaskService.dispatch(req.params.id, { adapterId, isolation });
|
|
55
|
+
res.json(task);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
58
|
+
const status = message === 'TASK_NOT_FOUND' ? 404 : 400;
|
|
59
|
+
res.status(status).json({ error: { code: 'DISPATCH_FAILED', message } });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
router.post('/tasks/:id/cancel', (req, res) => {
|
|
64
|
+
try {
|
|
65
|
+
const task = orchestrationTaskService.cancel(req.params.id);
|
|
66
|
+
res.json(task);
|
|
67
|
+
} catch {
|
|
68
|
+
res.status(404).json({ error: { code: 'TASK_NOT_FOUND', message: req.params.id } });
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return router;
|
|
73
|
+
}
|