ai-project-manage-cli 3.0.8 → 3.0.10
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/index.js +112 -6
- package/package.json +6 -3
package/dist/index.js
CHANGED
|
@@ -114,6 +114,10 @@ var requestConfig = {
|
|
|
114
114
|
updateDevStatus: defineEndpoint({
|
|
115
115
|
method: "POST",
|
|
116
116
|
path: "/cli/requirements/update-dev-status"
|
|
117
|
+
}),
|
|
118
|
+
updateTaskStatus: defineEndpoint({
|
|
119
|
+
method: "POST",
|
|
120
|
+
path: "/cli/requirements/update-task-status"
|
|
117
121
|
})
|
|
118
122
|
},
|
|
119
123
|
requirementArtifact: {
|
|
@@ -223,8 +227,10 @@ async function runComment(requirementId, file, model) {
|
|
|
223
227
|
}
|
|
224
228
|
|
|
225
229
|
// src/commands/connect.ts
|
|
230
|
+
import { execSync } from "child_process";
|
|
226
231
|
import { randomUUID } from "crypto";
|
|
227
232
|
import WebSocket from "ws";
|
|
233
|
+
import { Agent } from "@cursor/sdk";
|
|
228
234
|
function runConnect(opts) {
|
|
229
235
|
void (async () => {
|
|
230
236
|
const cfg = await ensureApmConfig();
|
|
@@ -240,6 +246,7 @@ function runConnect(opts) {
|
|
|
240
246
|
console.error(`[apm] \u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84: ${APM_CONFIG_PATH}`);
|
|
241
247
|
process.exit(1);
|
|
242
248
|
}
|
|
249
|
+
const api = createApmApiClient(cfg);
|
|
243
250
|
const url = buildAgentWsUrl(cfg.baseUrl, cfg.token);
|
|
244
251
|
console.error(`[apm] \u8FDE\u63A5 ${url.replace(cfg.token, "<token>")} \u2026`);
|
|
245
252
|
const ws = new WebSocket(url);
|
|
@@ -258,9 +265,88 @@ function runConnect(opts) {
|
|
|
258
265
|
const interval = setInterval(sendHeartbeat, 15e3);
|
|
259
266
|
ws.on("close", () => clearInterval(interval));
|
|
260
267
|
});
|
|
261
|
-
ws.on("message", (data) => {
|
|
268
|
+
ws.on("message", async (data) => {
|
|
262
269
|
const text = typeof data === "string" ? data : data.toString();
|
|
263
|
-
|
|
270
|
+
try {
|
|
271
|
+
const msg = JSON.parse(text);
|
|
272
|
+
if (msg.type !== "JOB") {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const payload = msg.payload;
|
|
276
|
+
try {
|
|
277
|
+
execSync(`apm pull ${payload.requirementId}`, {
|
|
278
|
+
cwd: payload.cwd,
|
|
279
|
+
encoding: "utf8"
|
|
280
|
+
});
|
|
281
|
+
} catch (pullErr) {
|
|
282
|
+
console.error("[apm] apm pull \u5931\u8D25:", pullErr);
|
|
283
|
+
throw pullErr;
|
|
284
|
+
}
|
|
285
|
+
const agent = await Agent.create({
|
|
286
|
+
apiKey: payload.apiKey,
|
|
287
|
+
model: { id: payload.model ?? "default" },
|
|
288
|
+
local: { cwd: payload.cwd }
|
|
289
|
+
});
|
|
290
|
+
await api.cliRequirements.updateDevStatus({
|
|
291
|
+
requirementId: payload.requirementId,
|
|
292
|
+
status: "WORKING"
|
|
293
|
+
});
|
|
294
|
+
const run = await agent.send(payload.prompt);
|
|
295
|
+
for await (const event of run.stream()) {
|
|
296
|
+
if (event.type === "system") {
|
|
297
|
+
console.log("[Ready]", JSON.stringify(event));
|
|
298
|
+
await api.cliRequirements.updateTaskStatus({
|
|
299
|
+
taskId: payload.taskId,
|
|
300
|
+
requirementId: payload.requirementId,
|
|
301
|
+
status: "IN_PROGRESS"
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
if (event.type === "user") {
|
|
305
|
+
console.log(
|
|
306
|
+
`[Input]`,
|
|
307
|
+
JSON.stringify(event.message.content[0].text)
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
if (event.type === "assistant") {
|
|
311
|
+
console.log(`[Output]`, JSON.stringify(event.message.content));
|
|
312
|
+
}
|
|
313
|
+
if (event.type === "thinking") {
|
|
314
|
+
console.log(`[Thinking]`, JSON.stringify(event.text));
|
|
315
|
+
}
|
|
316
|
+
if (event.type === "tool_call") {
|
|
317
|
+
if (event.result) {
|
|
318
|
+
console.log(
|
|
319
|
+
`[ToolCall(${event.call_id}) Result]`,
|
|
320
|
+
JSON.stringify(event.result)
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
console.log(
|
|
324
|
+
`[ToolCall(${event.call_id}) Args]`,
|
|
325
|
+
JSON.stringify(event.args)
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
if (event.type === "task") {
|
|
329
|
+
console.log(`[Task:${event.status}]`);
|
|
330
|
+
console.log("--------------------------------");
|
|
331
|
+
console.log(event.text || "\u65E0");
|
|
332
|
+
console.log("--------------------------------");
|
|
333
|
+
}
|
|
334
|
+
if (event.type === "request") {
|
|
335
|
+
console.log(JSON.stringify(event, null, 2));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
await api.cliRequirements.updateTaskStatus({
|
|
339
|
+
taskId: payload.taskId,
|
|
340
|
+
requirementId: payload.requirementId,
|
|
341
|
+
status: "PENDING_ACCEPTANCE"
|
|
342
|
+
});
|
|
343
|
+
await api.cliRequirements.updateDevStatus({
|
|
344
|
+
requirementId: payload.requirementId,
|
|
345
|
+
status: "IDLE"
|
|
346
|
+
});
|
|
347
|
+
} catch {
|
|
348
|
+
console.error("[apm] \u65E0\u6CD5\u89E3\u6790 WebSocket \u6D88\u606F:", text);
|
|
349
|
+
}
|
|
264
350
|
});
|
|
265
351
|
ws.on("error", (err) => {
|
|
266
352
|
console.error("[apm] WebSocket \u9519\u8BEF:", err.message);
|
|
@@ -516,6 +602,26 @@ function tasksForStatusYaml(tasks) {
|
|
|
516
602
|
executor: t.executorType
|
|
517
603
|
}));
|
|
518
604
|
}
|
|
605
|
+
function escapeForCdata(text) {
|
|
606
|
+
return text.replace(/\]\]>/g, "]]]]><![CDATA[>");
|
|
607
|
+
}
|
|
608
|
+
function defectsToXml(defects) {
|
|
609
|
+
const sorted = [...defects].sort(
|
|
610
|
+
(a, b) => new Date(a.createdAt ?? 0).getTime() - new Date(b.createdAt ?? 0).getTime()
|
|
611
|
+
);
|
|
612
|
+
const lines = ["<defects>"];
|
|
613
|
+
for (const d of sorted) {
|
|
614
|
+
lines.push(` <defect id="${xmlEscape(d.id)}">`);
|
|
615
|
+
lines.push(` <status>${xmlEscape(d.status)}</status>`);
|
|
616
|
+
lines.push(` <current><![CDATA[${escapeForCdata(d.currentState ?? "")}]]></current>`);
|
|
617
|
+
lines.push(
|
|
618
|
+
` <expected><![CDATA[${escapeForCdata(d.expectedEffect ?? "")}]]></expected>`
|
|
619
|
+
);
|
|
620
|
+
lines.push(` </defect>`);
|
|
621
|
+
}
|
|
622
|
+
lines.push("</defects>", "");
|
|
623
|
+
return lines.join("\n");
|
|
624
|
+
}
|
|
519
625
|
async function runPull(requirementId) {
|
|
520
626
|
const cfg = await ensureLoggedConfig();
|
|
521
627
|
const api = createApmApiClient(cfg);
|
|
@@ -560,7 +666,7 @@ async function runPull(requirementId) {
|
|
|
560
666
|
""
|
|
561
667
|
].join("\n");
|
|
562
668
|
writeFileSync3(join4(WORKITEMS_DIR, "reviews.xml"), reviewsXml, "utf8");
|
|
563
|
-
const defectsXml =
|
|
669
|
+
const defectsXml = defectsToXml(data.defects ?? []);
|
|
564
670
|
writeFileSync3(join4(WORKITEMS_DIR, "defect.xml"), defectsXml, "utf8");
|
|
565
671
|
const testCasesXml = unknownArrayToXml(
|
|
566
672
|
"testcases",
|
|
@@ -1116,7 +1222,7 @@ function assertDeployImageTag(tag) {
|
|
|
1116
1222
|
import { platform } from "node:os";
|
|
1117
1223
|
|
|
1118
1224
|
// src/commands/deploy/lib/backend-deploy/command-runner.ts
|
|
1119
|
-
import { execSync } from "child_process";
|
|
1225
|
+
import { execSync as execSync2 } from "child_process";
|
|
1120
1226
|
|
|
1121
1227
|
// src/commands/deploy/lib/backend-deploy/logger.ts
|
|
1122
1228
|
var Logger = class {
|
|
@@ -1142,7 +1248,7 @@ var CommandRunner = class {
|
|
|
1142
1248
|
static exec(command, cwd) {
|
|
1143
1249
|
try {
|
|
1144
1250
|
Logger.info(`\u6267\u884C\u547D\u4EE4: ${command}`);
|
|
1145
|
-
const result =
|
|
1251
|
+
const result = execSync2(command, {
|
|
1146
1252
|
cwd,
|
|
1147
1253
|
encoding: "utf8",
|
|
1148
1254
|
stdio: "pipe"
|
|
@@ -1160,7 +1266,7 @@ var CommandRunner = class {
|
|
|
1160
1266
|
static execWithOutput(command, cwd) {
|
|
1161
1267
|
try {
|
|
1162
1268
|
Logger.info(`\u6267\u884C\u547D\u4EE4: ${command}`);
|
|
1163
|
-
|
|
1269
|
+
execSync2(command, {
|
|
1164
1270
|
cwd,
|
|
1165
1271
|
stdio: "inherit"
|
|
1166
1272
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-project-manage-cli",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.10",
|
|
4
4
|
"description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
"test": "vitest run",
|
|
20
20
|
"test:watch": "vitest",
|
|
21
21
|
"test:init": "vitest run tests/cli-init.test.ts",
|
|
22
|
-
"test:pull": "vitest run tests/cli-pull.test.ts"
|
|
22
|
+
"test:pull": "vitest run tests/cli-pull.test.ts",
|
|
23
|
+
"test:cursor": "vitest run tests/cursor.test.ts"
|
|
24
|
+
|
|
23
25
|
},
|
|
24
26
|
"devDependencies": {
|
|
25
27
|
"@types/node": "^22.0.0",
|
|
@@ -38,6 +40,7 @@
|
|
|
38
40
|
"commander": "~14.0.3",
|
|
39
41
|
"yaml": "~2.8.4",
|
|
40
42
|
"minio": "~8.0.7",
|
|
41
|
-
"dockerode": "~5.0.0"
|
|
43
|
+
"dockerode": "~5.0.0",
|
|
44
|
+
"@cursor/sdk": "~1.0.12"
|
|
42
45
|
}
|
|
43
46
|
}
|