@agentplugged/claw 0.1.0 → 0.2.0
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/dist/cli.js +3 -7
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -5
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +0 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -40
- package/dist/index.js.map +1 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +363 -77
- package/dist/router/index.js.map +1 -1
- package/dist/router/logger.d.ts +3 -0
- package/dist/router/logger.d.ts.map +1 -1
- package/dist/router/logger.js +8 -5
- package/dist/router/logger.js.map +1 -1
- package/dist/router/types.d.ts +6 -9
- package/dist/router/types.d.ts.map +1 -1
- package/dist/sidecar/auth.d.ts.map +1 -1
- package/dist/sidecar/auth.js +7 -11
- package/dist/sidecar/auth.js.map +1 -1
- package/dist/sidecar/index.js +104 -21
- package/dist/sidecar/index.js.map +1 -1
- package/dist/sidecar/routes/addons.d.ts.map +1 -1
- package/dist/sidecar/routes/addons.js +3 -13
- package/dist/sidecar/routes/addons.js.map +1 -1
- package/dist/sidecar/routes/api-keys.d.ts +4 -0
- package/dist/sidecar/routes/api-keys.d.ts.map +1 -0
- package/dist/sidecar/routes/api-keys.js +221 -0
- package/dist/sidecar/routes/api-keys.js.map +1 -0
- package/dist/sidecar/routes/bindings.d.ts +5 -0
- package/dist/sidecar/routes/bindings.d.ts.map +1 -0
- package/dist/sidecar/routes/bindings.js +64 -0
- package/dist/sidecar/routes/bindings.js.map +1 -0
- package/dist/sidecar/routes/channels.d.ts.map +1 -1
- package/dist/sidecar/routes/channels.js +71 -75
- package/dist/sidecar/routes/channels.js.map +1 -1
- package/dist/sidecar/routes/crons.d.ts +5 -0
- package/dist/sidecar/routes/crons.d.ts.map +1 -0
- package/dist/sidecar/routes/crons.js +81 -0
- package/dist/sidecar/routes/crons.js.map +1 -0
- package/dist/sidecar/routes/health.d.ts.map +1 -1
- package/dist/sidecar/routes/health.js +1 -5
- package/dist/sidecar/routes/health.js.map +1 -1
- package/dist/sidecar/routes/kitchen-proxy.d.ts +5 -0
- package/dist/sidecar/routes/kitchen-proxy.d.ts.map +1 -0
- package/dist/sidecar/routes/kitchen-proxy.js +29 -0
- package/dist/sidecar/routes/kitchen-proxy.js.map +1 -0
- package/dist/sidecar/routes/memory.d.ts +0 -2
- package/dist/sidecar/routes/memory.d.ts.map +1 -1
- package/dist/sidecar/routes/memory.js +116 -113
- package/dist/sidecar/routes/memory.js.map +1 -1
- package/dist/sidecar/routes/metrics.js +5 -5
- package/dist/sidecar/routes/restart.d.ts.map +1 -1
- package/dist/sidecar/routes/restart.js +11 -2
- package/dist/sidecar/routes/restart.js.map +1 -1
- package/dist/sidecar/routes/router-config.d.ts +0 -1
- package/dist/sidecar/routes/router-config.d.ts.map +1 -1
- package/dist/sidecar/routes/router-config.js +2 -139
- package/dist/sidecar/routes/router-config.js.map +1 -1
- package/dist/sidecar/routes/skills.d.ts.map +1 -1
- package/dist/sidecar/routes/skills.js +23 -19
- package/dist/sidecar/routes/skills.js.map +1 -1
- package/dist/sidecar/routes/soul.d.ts +11 -0
- package/dist/sidecar/routes/soul.d.ts.map +1 -1
- package/dist/sidecar/routes/soul.js +59 -34
- package/dist/sidecar/routes/soul.js.map +1 -1
- package/dist/sidecar/routes/system.d.ts +7 -0
- package/dist/sidecar/routes/system.d.ts.map +1 -0
- package/dist/sidecar/routes/system.js +49 -0
- package/dist/sidecar/routes/system.js.map +1 -0
- package/dist/sidecar/routes/team.d.ts.map +1 -1
- package/dist/sidecar/routes/team.js +121 -74
- package/dist/sidecar/routes/team.js.map +1 -1
- package/dist/sidecar/routes/update.d.ts.map +1 -1
- package/dist/sidecar/routes/update.js +24 -10
- package/dist/sidecar/routes/update.js.map +1 -1
- package/dist/sidecar/routes/workflow.d.ts +8 -0
- package/dist/sidecar/routes/workflow.d.ts.map +1 -0
- package/dist/sidecar/routes/workflow.js +232 -0
- package/dist/sidecar/routes/workflow.js.map +1 -0
- package/dist/sidecar/utils.d.ts +14 -0
- package/dist/sidecar/utils.d.ts.map +1 -1
- package/dist/sidecar/utils.js +35 -1
- package/dist/sidecar/utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -35,6 +35,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.handleUpdate = handleUpdate;
|
|
37
37
|
const utils_1 = require("../utils");
|
|
38
|
+
/** Strict semver pattern — prevents command injection via version field */
|
|
39
|
+
const SEMVER_PATTERN = /^[0-9]+\.[0-9]+\.[0-9]+(-[a-z0-9._-]+)?(\+[a-z0-9._-]+)?$/i;
|
|
38
40
|
function handleUpdate(config) {
|
|
39
41
|
return async (req, res) => {
|
|
40
42
|
let body = {};
|
|
@@ -45,10 +47,17 @@ function handleUpdate(config) {
|
|
|
45
47
|
catch {
|
|
46
48
|
// Body is optional
|
|
47
49
|
}
|
|
50
|
+
// SECURITY: validate version format to prevent command injection
|
|
51
|
+
if (body.version && !SEMVER_PATTERN.test(body.version)) {
|
|
52
|
+
(0, utils_1.sendError)(res, 422, "Invalid version format. Expected semver (e.g., 1.2.3)");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
48
55
|
const steps = [];
|
|
49
|
-
const run = async (step,
|
|
56
|
+
const run = async (step, command, args) => {
|
|
50
57
|
try {
|
|
51
|
-
const { stdout, stderr } = await (0, utils_1.
|
|
58
|
+
const { stdout, stderr } = await (0, utils_1.execSafeCommand)(command, args, {
|
|
59
|
+
timeout: 120_000, // npm install can be slow
|
|
60
|
+
});
|
|
52
61
|
steps.push({ step, result: stdout || stderr || "ok", success: true });
|
|
53
62
|
return true;
|
|
54
63
|
}
|
|
@@ -63,18 +72,23 @@ function handleUpdate(config) {
|
|
|
63
72
|
};
|
|
64
73
|
try {
|
|
65
74
|
// 1. Update @agentplugged/claw package
|
|
66
|
-
const
|
|
67
|
-
|
|
75
|
+
const packageSpec = body.version
|
|
76
|
+
? `@agentplugged/claw@${body.version}`
|
|
77
|
+
: "@agentplugged/claw@latest";
|
|
78
|
+
await run("update_claw", "npm", ["install", "-g", packageSpec]);
|
|
68
79
|
// 2. Pull latest config if git-managed
|
|
69
|
-
await run("pull_config",
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
await run("pull_config", "git", [
|
|
81
|
+
"-C", config.runtimeDir,
|
|
82
|
+
"pull", "--ff-only",
|
|
83
|
+
]);
|
|
84
|
+
// 3. Restart all services (safe — no shell)
|
|
85
|
+
await run("restart_openclaw", "sudo", ["systemctl", "restart", "openclaw"]);
|
|
86
|
+
await run("restart_router", "sudo", ["systemctl", "restart", "claw-router"]);
|
|
87
|
+
await run("restart_sidecar", "sudo", ["systemctl", "restart", "claw-sidecar"]);
|
|
74
88
|
// 4. Get new version
|
|
75
89
|
let newVersion = "unknown";
|
|
76
90
|
try {
|
|
77
|
-
const { stdout } = await (0, utils_1.
|
|
91
|
+
const { stdout } = await (0, utils_1.execSafeCommand)("claw", ["--version"]);
|
|
78
92
|
newVersion = stdout.trim();
|
|
79
93
|
}
|
|
80
94
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/sidecar/routes/update.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/sidecar/routes/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ClawConfig } from "../../config";
|
|
2
|
+
import { RouteHandler } from "./health";
|
|
3
|
+
export declare function handleGetWorkflow(config: ClawConfig): RouteHandler;
|
|
4
|
+
export declare function handleCreateTicket(config: ClawConfig): RouteHandler;
|
|
5
|
+
export declare function handleMoveTicket(config: ClawConfig): RouteHandler;
|
|
6
|
+
export declare function handleEditTicket(config: ClawConfig): RouteHandler;
|
|
7
|
+
export declare function handleDeleteTicket(config: ClawConfig): RouteHandler;
|
|
8
|
+
//# sourceMappingURL=workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../../src/sidecar/routes/workflow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AA2BxC,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAiDlE;AAMD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CA4CnE;AAMD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAwCjE;AAMD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAyCjE;AAMD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAgCnE"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.handleGetWorkflow = handleGetWorkflow;
|
|
37
|
+
exports.handleCreateTicket = handleCreateTicket;
|
|
38
|
+
exports.handleMoveTicket = handleMoveTicket;
|
|
39
|
+
exports.handleEditTicket = handleEditTicket;
|
|
40
|
+
exports.handleDeleteTicket = handleDeleteTicket;
|
|
41
|
+
const utils_1 = require("../utils");
|
|
42
|
+
const kitchen_proxy_1 = require("./kitchen-proxy");
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Helpers
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Reads the teamId from the sidecar config directory.
|
|
48
|
+
* The teamId is stored by the deploy endpoint when a team is scaffolded.
|
|
49
|
+
*/
|
|
50
|
+
async function getTeamId(config) {
|
|
51
|
+
try {
|
|
52
|
+
const fs = await Promise.resolve().then(() => __importStar(require("fs/promises")));
|
|
53
|
+
const path = await Promise.resolve().then(() => __importStar(require("path")));
|
|
54
|
+
const teamIdPath = path.join(config.dataDir, "team-id");
|
|
55
|
+
const teamId = (await fs.readFile(teamIdPath, "utf-8")).trim();
|
|
56
|
+
return teamId || null;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// GET /workflow — proxy to ClawKitchen tickets endpoint, return kanban board
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
function handleGetWorkflow(config) {
|
|
66
|
+
return async (_req, res) => {
|
|
67
|
+
const teamId = await getTeamId(config);
|
|
68
|
+
if (!teamId) {
|
|
69
|
+
(0, utils_1.sendJson)(res, 200, {
|
|
70
|
+
columns: {},
|
|
71
|
+
ticketCount: 0,
|
|
72
|
+
error: "No team deployed — no workflow available",
|
|
73
|
+
});
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const result = await (0, kitchen_proxy_1.proxyToKitchen)("GET", `/api/teams/${encodeURIComponent(teamId)}/tickets`);
|
|
78
|
+
if (result.status !== 200) {
|
|
79
|
+
(0, utils_1.sendError)(res, result.status, `Kitchen returned ${result.status}: ${JSON.stringify(result.data)}`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// ClawKitchen returns tickets as a flat array — group by status (column)
|
|
83
|
+
const tickets = Array.isArray(result.data)
|
|
84
|
+
? result.data
|
|
85
|
+
: result.data?.tickets ?? [];
|
|
86
|
+
const columns = {};
|
|
87
|
+
for (const ticket of tickets) {
|
|
88
|
+
const col = ticket.status ?? "inbox";
|
|
89
|
+
if (!columns[col])
|
|
90
|
+
columns[col] = [];
|
|
91
|
+
columns[col].push(ticket);
|
|
92
|
+
}
|
|
93
|
+
const ticketCount = tickets.length;
|
|
94
|
+
(0, utils_1.sendJson)(res, 200, { columns, ticketCount });
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
(0, utils_1.sendError)(res, 502, `Failed to reach ClawKitchen: ${err.message}`);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
// POST /workflow/tickets — dispatch a new ticket via ClawRecipes
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
function handleCreateTicket(config) {
|
|
105
|
+
return async (req, res) => {
|
|
106
|
+
const teamId = await getTeamId(config);
|
|
107
|
+
if (!teamId) {
|
|
108
|
+
(0, utils_1.sendError)(res, 422, "No team deployed — cannot create tickets");
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
let body;
|
|
112
|
+
try {
|
|
113
|
+
body = (await (0, utils_1.parseBody)(req));
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
(0, utils_1.sendError)(res, 400, "Invalid JSON body");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const title = body.title;
|
|
120
|
+
if (!title || typeof title !== "string" || title.trim().length === 0) {
|
|
121
|
+
(0, utils_1.sendError)(res, 422, "title is required");
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const result = await (0, kitchen_proxy_1.proxyToKitchen)("POST", `/api/teams/${encodeURIComponent(teamId)}/tickets`, {
|
|
126
|
+
title: title.trim(),
|
|
127
|
+
assignee: body.assignee ?? undefined,
|
|
128
|
+
priority: body.priority ?? "medium",
|
|
129
|
+
description: body.description ?? "",
|
|
130
|
+
labels: body.labels ?? [],
|
|
131
|
+
});
|
|
132
|
+
(0, utils_1.sendJson)(res, result.status, result.data);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
(0, utils_1.sendError)(res, 502, `Failed to reach ClawKitchen: ${err.message}`);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
// POST /workflow/move — move ticket between columns via Kitchen API
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
function handleMoveTicket(config) {
|
|
143
|
+
return async (req, res) => {
|
|
144
|
+
const teamId = await getTeamId(config);
|
|
145
|
+
if (!teamId) {
|
|
146
|
+
(0, utils_1.sendError)(res, 422, "No team deployed — cannot move tickets");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
let body;
|
|
150
|
+
try {
|
|
151
|
+
body = (await (0, utils_1.parseBody)(req));
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
(0, utils_1.sendError)(res, 400, "Invalid JSON body");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const ticketId = body.ticketId;
|
|
158
|
+
const to = body.to;
|
|
159
|
+
if (!ticketId || !to) {
|
|
160
|
+
(0, utils_1.sendError)(res, 422, "ticketId and to are required");
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const result = await (0, kitchen_proxy_1.proxyToKitchen)("POST", `/api/teams/${encodeURIComponent(teamId)}/tickets/move`, { ticketId, to });
|
|
165
|
+
(0, utils_1.sendJson)(res, result.status, result.data);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
(0, utils_1.sendError)(res, 502, `Failed to reach ClawKitchen: ${err.message}`);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
// ---------------------------------------------------------------------------
|
|
173
|
+
// PATCH /workflow/tickets/:id — edit ticket via Kitchen API
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
function handleEditTicket(config) {
|
|
176
|
+
return async (req, res) => {
|
|
177
|
+
const teamId = await getTeamId(config);
|
|
178
|
+
if (!teamId) {
|
|
179
|
+
(0, utils_1.sendError)(res, 422, "No team deployed — cannot edit tickets");
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const url = req.url ?? "";
|
|
183
|
+
const idMatch = url.match(/\/workflow\/tickets\/([A-Z]+-\d+)$/);
|
|
184
|
+
if (!idMatch) {
|
|
185
|
+
(0, utils_1.sendError)(res, 400, "Invalid ticket ID in URL");
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const ticketId = idMatch[1];
|
|
189
|
+
let body;
|
|
190
|
+
try {
|
|
191
|
+
body = (await (0, utils_1.parseBody)(req));
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
(0, utils_1.sendError)(res, 400, "Invalid JSON body");
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const result = await (0, kitchen_proxy_1.proxyToKitchen)("PATCH", `/api/teams/${encodeURIComponent(teamId)}/tickets/${encodeURIComponent(ticketId)}`, body);
|
|
199
|
+
(0, utils_1.sendJson)(res, result.status, result.data);
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
(0, utils_1.sendError)(res, 502, `Failed to reach ClawKitchen: ${err.message}`);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
// DELETE /workflow/tickets/:id — delete ticket via Kitchen API
|
|
208
|
+
// ---------------------------------------------------------------------------
|
|
209
|
+
function handleDeleteTicket(config) {
|
|
210
|
+
return async (req, res) => {
|
|
211
|
+
const teamId = await getTeamId(config);
|
|
212
|
+
if (!teamId) {
|
|
213
|
+
(0, utils_1.sendError)(res, 422, "No team deployed — cannot delete tickets");
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const url = req.url ?? "";
|
|
217
|
+
const idMatch = url.match(/\/workflow\/tickets\/([A-Z]+-\d+)$/);
|
|
218
|
+
if (!idMatch) {
|
|
219
|
+
(0, utils_1.sendError)(res, 400, "Invalid ticket ID in URL");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const ticketId = idMatch[1];
|
|
223
|
+
try {
|
|
224
|
+
const result = await (0, kitchen_proxy_1.proxyToKitchen)("DELETE", `/api/teams/${encodeURIComponent(teamId)}/tickets/${encodeURIComponent(ticketId)}`);
|
|
225
|
+
(0, utils_1.sendJson)(res, result.status, result.data);
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
(0, utils_1.sendError)(res, 502, `Failed to reach ClawKitchen: ${err.message}`);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../../src/sidecar/routes/workflow.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,8CAiDC;AAMD,gDA4CC;AAMD,4CAwCC;AAMD,4CAyCC;AAMD,gDAgCC;AAlQD,oCAA0D;AAE1D,mDAAiD;AAEjD,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;GAGG;AACH,KAAK,UAAU,SAAS,CAAC,MAAkB;IACzC,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,wDAAa,aAAa,GAAC,CAAC;QACvC,MAAM,IAAI,GAAG,wDAAa,MAAM,GAAC,CAAC;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/D,OAAO,MAAM,IAAI,IAAI,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,6EAA6E;AAC7E,8EAA8E;AAE9E,SAAgB,iBAAiB,CAAC,MAAkB;IAClD,OAAO,KAAK,EAAE,IAAqB,EAAE,GAAmB,EAAiB,EAAE;QACzE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAA,gBAAQ,EAAC,GAAG,EAAE,GAAG,EAAE;gBACjB,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,CAAC;gBACd,KAAK,EAAE,0CAA0C;aAClD,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAc,EACjC,KAAK,EACL,cAAc,kBAAkB,CAAC,MAAM,CAAC,UAAU,CACnD,CAAC;YAEF,IAAI,MAAM,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC1B,IAAA,iBAAS,EACP,GAAG,EACH,MAAM,CAAC,MAAM,EACb,oBAAoB,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CACpE,CAAC;gBACF,OAAO;YACT,CAAC;YAED,yEAAyE;YACzE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;gBACxC,CAAC,CAAC,MAAM,CAAC,IAAI;gBACb,CAAC,CAAE,MAAM,CAAC,IAAgC,EAAE,OAAO,IAAI,EAAE,CAAC;YAE5D,MAAM,OAAO,GAA8B,EAAE,CAAC;YAC9C,KAAK,MAAM,MAAM,IAAI,OAAyC,EAAE,CAAC;gBAC/D,MAAM,GAAG,GAAI,MAAM,CAAC,MAAiB,IAAI,OAAO,CAAC;gBACjD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;oBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;gBACrC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;YAED,MAAM,WAAW,GAAI,OAAqB,CAAC,MAAM,CAAC;YAClD,IAAA,gBAAQ,EAAC,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAA,iBAAS,EACP,GAAG,EACH,GAAG,EACH,gCAAiC,GAAa,CAAC,OAAO,EAAE,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,iEAAiE;AACjE,8EAA8E;AAE9E,SAAgB,kBAAkB,CAAC,MAAkB;IACnD,OAAO,KAAK,EAAE,GAAoB,EAAE,GAAmB,EAAiB,EAAE;QACxE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAA,iBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,0CAA0C,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QAED,IAAI,IAA6B,CAAC;QAClC,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,IAAA,iBAAS,EAAC,GAAG,CAAC,CAA4B,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,IAAA,iBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAA2B,CAAC;QAC/C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrE,IAAA,iBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAc,EACjC,MAAM,EACN,cAAc,kBAAkB,CAAC,MAAM,CAAC,UAAU,EAClD;gBACE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;gBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS;gBACpC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,QAAQ;gBACnC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;gBACnC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;aAC1B,CACF,CAAC;YAEF,IAAA,gBAAQ,EAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAA,iBAAS,EACP,GAAG,EACH,GAAG,EACH,gCAAiC,GAAa,CAAC,OAAO,EAAE,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,oEAAoE;AACpE,8EAA8E;AAE9E,SAAgB,gBAAgB,CAAC,MAAkB;IACjD,OAAO,KAAK,EAAE,GAAoB,EAAE,GAAmB,EAAiB,EAAE;QACxE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAA,iBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,wCAAwC,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,IAAI,IAA6B,CAAC;QAClC,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,IAAA,iBAAS,EAAC,GAAG,CAAC,CAA4B,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,IAAA,iBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAA8B,CAAC;QACrD,MAAM,EAAE,GAAG,IAAI,CAAC,EAAwB,CAAC;QAEzC,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,EAAE,CAAC;YACrB,IAAA,iBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,8BAA8B,CAAC,CAAC;YACpD,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAc,EACjC,MAAM,EACN,cAAc,kBAAkB,CAAC,MAAM,CAAC,eAAe,EACvD,EAAE,QAAQ,EAAE,EAAE,EAAE,CACjB,CAAC;YAEF,IAAA,gBAAQ,EAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAA,iBAAS,EACP,GAAG,EACH,GAAG,EACH,gCAAiC,GAAa,CAAC,OAAO,EAAE,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,4DAA4D;AAC5D,8EAA8E;AAE9E,SAAgB,gBAAgB,CAAC,MAAkB;IACjD,OAAO,KAAK,EAAE,GAAoB,EAAE,GAAmB,EAAiB,EAAE;QACxE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAA,iBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,wCAAwC,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAChE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAA,iBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,0BAA0B,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAE5B,IAAI,IAA6B,CAAC;QAClC,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,IAAA,iBAAS,EAAC,GAAG,CAAC,CAA4B,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,IAAA,iBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAc,EACjC,OAAO,EACP,cAAc,kBAAkB,CAAC,MAAM,CAAC,YAAY,kBAAkB,CAAC,QAAQ,CAAC,EAAE,EAClF,IAAI,CACL,CAAC;YAEF,IAAA,gBAAQ,EAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAA,iBAAS,EACP,GAAG,EACH,GAAG,EACH,gCAAiC,GAAa,CAAC,OAAO,EAAE,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,+DAA+D;AAC/D,8EAA8E;AAE9E,SAAgB,kBAAkB,CAAC,MAAkB;IACnD,OAAO,KAAK,EAAE,GAAoB,EAAE,GAAmB,EAAiB,EAAE;QACxE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAA,iBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,0CAA0C,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAChE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAA,iBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,0BAA0B,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAE5B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAc,EACjC,QAAQ,EACR,cAAc,kBAAkB,CAAC,MAAM,CAAC,YAAY,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CACnF,CAAC;YAEF,IAAA,gBAAQ,EAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAA,iBAAS,EACP,GAAG,EACH,GAAG,EACH,gCAAiC,GAAa,CAAC,OAAO,EAAE,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/sidecar/utils.d.ts
CHANGED
|
@@ -2,8 +2,22 @@ import { IncomingMessage, ServerResponse } from "http";
|
|
|
2
2
|
export declare function parseBody(req: IncomingMessage): Promise<unknown>;
|
|
3
3
|
export declare function sendJson(res: ServerResponse, status: number, data: unknown): void;
|
|
4
4
|
export declare function sendError(res: ServerResponse, status: number, message: string): void;
|
|
5
|
+
/**
|
|
6
|
+
* Execute a shell command (legacy — avoid for user-controlled inputs).
|
|
7
|
+
*/
|
|
5
8
|
export declare function execCommand(cmd: string): Promise<{
|
|
6
9
|
stdout: string;
|
|
7
10
|
stderr: string;
|
|
8
11
|
}>;
|
|
12
|
+
/**
|
|
13
|
+
* Execute a command safely using execFile (no shell interpolation).
|
|
14
|
+
* Arguments are passed as an array — immune to command injection.
|
|
15
|
+
*/
|
|
16
|
+
export declare function execSafeCommand(command: string, args: string[], options?: {
|
|
17
|
+
env?: NodeJS.ProcessEnv;
|
|
18
|
+
timeout?: number;
|
|
19
|
+
}): Promise<{
|
|
20
|
+
stdout: string;
|
|
21
|
+
stderr: string;
|
|
22
|
+
}>;
|
|
9
23
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/sidecar/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/sidecar/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAMvD,wBAAgB,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAgChE;AAED,wBAAgB,QAAQ,CACtB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,GACZ,IAAI,CAON;AAED,wBAAgB,SAAS,CACvB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAmB7C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAuB7C"}
|
package/dist/sidecar/utils.js
CHANGED
|
@@ -4,12 +4,21 @@ exports.parseBody = parseBody;
|
|
|
4
4
|
exports.sendJson = sendJson;
|
|
5
5
|
exports.sendError = sendError;
|
|
6
6
|
exports.execCommand = execCommand;
|
|
7
|
+
exports.execSafeCommand = execSafeCommand;
|
|
7
8
|
const child_process_1 = require("child_process");
|
|
8
|
-
const EXEC_TIMEOUT_MS =
|
|
9
|
+
const EXEC_TIMEOUT_MS = 45_000;
|
|
10
|
+
const MAX_BODY_SIZE = 10 * 1024 * 1024; // 10 MB
|
|
9
11
|
function parseBody(req) {
|
|
10
12
|
return new Promise((resolve, reject) => {
|
|
11
13
|
const chunks = [];
|
|
14
|
+
let totalSize = 0;
|
|
12
15
|
req.on("data", (chunk) => {
|
|
16
|
+
totalSize += chunk.length;
|
|
17
|
+
if (totalSize > MAX_BODY_SIZE) {
|
|
18
|
+
req.destroy();
|
|
19
|
+
reject(new Error("Request body too large"));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
13
22
|
chunks.push(chunk);
|
|
14
23
|
});
|
|
15
24
|
req.on("end", () => {
|
|
@@ -39,6 +48,9 @@ function sendJson(res, status, data) {
|
|
|
39
48
|
function sendError(res, status, message) {
|
|
40
49
|
sendJson(res, status, { error: message });
|
|
41
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Execute a shell command (legacy — avoid for user-controlled inputs).
|
|
53
|
+
*/
|
|
42
54
|
function execCommand(cmd) {
|
|
43
55
|
return new Promise((resolve, reject) => {
|
|
44
56
|
const child = (0, child_process_1.exec)(cmd, { timeout: EXEC_TIMEOUT_MS }, (error, stdout, stderr) => {
|
|
@@ -54,4 +66,26 @@ function execCommand(cmd) {
|
|
|
54
66
|
child.on("error", reject);
|
|
55
67
|
});
|
|
56
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Execute a command safely using execFile (no shell interpolation).
|
|
71
|
+
* Arguments are passed as an array — immune to command injection.
|
|
72
|
+
*/
|
|
73
|
+
function execSafeCommand(command, args, options) {
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
const child = (0, child_process_1.execFile)(command, args, {
|
|
76
|
+
timeout: options?.timeout ?? EXEC_TIMEOUT_MS,
|
|
77
|
+
env: options?.env ?? process.env,
|
|
78
|
+
}, (error, stdout, stderr) => {
|
|
79
|
+
if (error && !stdout) {
|
|
80
|
+
reject(error);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
resolve({
|
|
84
|
+
stdout: stdout.trim(),
|
|
85
|
+
stderr: stderr.trim(),
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
child.on("error", reject);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
57
91
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/sidecar/utils.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/sidecar/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED