ai-project-manage-cli 7.1.4 → 7.1.6
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 +163 -23
- package/dist/webide-message-worker.js +1022 -434
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -465,6 +465,10 @@ var requestConfig = {
|
|
|
465
465
|
method: "PUT",
|
|
466
466
|
path: "/cli/webide/plan"
|
|
467
467
|
}),
|
|
468
|
+
webideReplaceTestCases: defineEndpoint({
|
|
469
|
+
method: "PUT",
|
|
470
|
+
path: "/cli/webide/test-cases"
|
|
471
|
+
}),
|
|
468
472
|
branchBaseline: defineEndpoint({
|
|
469
473
|
method: "GET",
|
|
470
474
|
path: "/cli/tasks/branch-baseline"
|
|
@@ -497,6 +501,10 @@ var requestConfig = {
|
|
|
497
501
|
method: "POST",
|
|
498
502
|
path: "/cli/pull-requests"
|
|
499
503
|
}),
|
|
504
|
+
createWebIdeDraftPullRequest: defineEndpoint({
|
|
505
|
+
method: "POST",
|
|
506
|
+
path: "/cli/webide/draft-pull-requests"
|
|
507
|
+
}),
|
|
500
508
|
getRepositoryProjectDocumentManifest: defineEndpoint({
|
|
501
509
|
method: "GET",
|
|
502
510
|
path: "/cli/repository-project-documents/manifest"
|
|
@@ -6342,16 +6350,16 @@ var EventSession = class {
|
|
|
6342
6350
|
return;
|
|
6343
6351
|
}
|
|
6344
6352
|
if (formatedEvent.type === "tool_call") {
|
|
6345
|
-
const
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6353
|
+
const callId = typeof formatedEvent.call_id === "string" ? formatedEvent.call_id.trim() : "";
|
|
6354
|
+
if (callId) {
|
|
6355
|
+
const existingIndex = this.events.findIndex(
|
|
6356
|
+
(e) => e.type === "tool_call" && typeof e.call_id === "string" && e.call_id === callId
|
|
6357
|
+
);
|
|
6358
|
+
if (existingIndex >= 0) {
|
|
6359
|
+
mergeToolCallEvent(this.events[existingIndex], formatedEvent);
|
|
6360
|
+
this.markDirty(existingIndex);
|
|
6361
|
+
return;
|
|
6362
|
+
}
|
|
6355
6363
|
}
|
|
6356
6364
|
this.events.push(formatedEvent);
|
|
6357
6365
|
this.markDirty(this.events.length - 1);
|
|
@@ -6413,15 +6421,18 @@ var EventSession = class {
|
|
|
6413
6421
|
type: "thinking",
|
|
6414
6422
|
content: event.text || event.content || ""
|
|
6415
6423
|
};
|
|
6416
|
-
case "tool_call":
|
|
6424
|
+
case "tool_call": {
|
|
6425
|
+
const raw = event;
|
|
6426
|
+
const callId = String(raw.call_id ?? raw.callId ?? "").trim();
|
|
6417
6427
|
return {
|
|
6418
6428
|
type: "tool_call",
|
|
6419
6429
|
args: event.args,
|
|
6420
6430
|
result: event.result,
|
|
6421
6431
|
status: event.status,
|
|
6422
|
-
call_id:
|
|
6432
|
+
call_id: callId,
|
|
6423
6433
|
name: event.name
|
|
6424
6434
|
};
|
|
6435
|
+
}
|
|
6425
6436
|
case "task":
|
|
6426
6437
|
return {
|
|
6427
6438
|
type: "task",
|
|
@@ -6486,6 +6497,24 @@ var EventSession = class {
|
|
|
6486
6497
|
return this.events.map((event) => formatLogEvent(event.type, event)).join("\n");
|
|
6487
6498
|
}
|
|
6488
6499
|
};
|
|
6500
|
+
function mergeToolCallEvent(existing, incoming) {
|
|
6501
|
+
if (incoming.name) {
|
|
6502
|
+
existing.name = incoming.name;
|
|
6503
|
+
}
|
|
6504
|
+
if (incoming.status) {
|
|
6505
|
+
existing.status = incoming.status;
|
|
6506
|
+
}
|
|
6507
|
+
if (incoming.args != null && typeof incoming.args === "object" && !Array.isArray(incoming.args) && Object.keys(incoming.args).length > 0) {
|
|
6508
|
+
existing.args = { ...existing.args ?? {}, ...incoming.args };
|
|
6509
|
+
}
|
|
6510
|
+
if (incoming.result != null) {
|
|
6511
|
+
if (typeof incoming.result === "object" && !Array.isArray(incoming.result) && typeof existing.result === "object" && existing.result != null && !Array.isArray(existing.result)) {
|
|
6512
|
+
existing.result = { ...existing.result, ...incoming.result };
|
|
6513
|
+
} else {
|
|
6514
|
+
existing.result = incoming.result;
|
|
6515
|
+
}
|
|
6516
|
+
}
|
|
6517
|
+
}
|
|
6489
6518
|
function formatLogEvent(type, event) {
|
|
6490
6519
|
if (type === "input") {
|
|
6491
6520
|
return `## \u7528\u6237\u8F93\u5165
|
|
@@ -6814,11 +6843,99 @@ function createUpsertWebIdePlanTool(options) {
|
|
|
6814
6843
|
};
|
|
6815
6844
|
}
|
|
6816
6845
|
|
|
6846
|
+
// src/commands/connect/webide-test-case-tools.ts
|
|
6847
|
+
function asString2(value) {
|
|
6848
|
+
return typeof value === "string" ? value.trim() : "";
|
|
6849
|
+
}
|
|
6850
|
+
function asStringArray(value) {
|
|
6851
|
+
if (!Array.isArray(value)) return [];
|
|
6852
|
+
return value.map((item) => typeof item === "string" ? item.trim() : String(item)).filter(Boolean);
|
|
6853
|
+
}
|
|
6854
|
+
function parseCases(raw) {
|
|
6855
|
+
if (!Array.isArray(raw)) return [];
|
|
6856
|
+
const cases = [];
|
|
6857
|
+
for (const [index, item] of raw.entries()) {
|
|
6858
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
6859
|
+
const row = item;
|
|
6860
|
+
const name = asString2(row.name);
|
|
6861
|
+
if (!name) continue;
|
|
6862
|
+
const steps = asStringArray(row.steps);
|
|
6863
|
+
if (steps.length === 0) continue;
|
|
6864
|
+
cases.push({
|
|
6865
|
+
name,
|
|
6866
|
+
description: asString2(row.description),
|
|
6867
|
+
steps,
|
|
6868
|
+
sortOrder: typeof row.sortOrder === "number" && Number.isFinite(row.sortOrder) ? row.sortOrder : index
|
|
6869
|
+
});
|
|
6870
|
+
}
|
|
6871
|
+
return cases;
|
|
6872
|
+
}
|
|
6873
|
+
function createUpsertWebIdeTestCasesTool(options) {
|
|
6874
|
+
const { cfg, taskId } = options;
|
|
6875
|
+
return {
|
|
6876
|
+
description: "Persist generated automated test cases for this WebIDE task (full replace) and mark the workflow TEST_READY. Call once with the complete case list after reviewing the task and code changes.",
|
|
6877
|
+
inputSchema: {
|
|
6878
|
+
type: "object",
|
|
6879
|
+
properties: {
|
|
6880
|
+
cases: {
|
|
6881
|
+
type: "array",
|
|
6882
|
+
description: "Complete list of test cases to store on the platform",
|
|
6883
|
+
items: {
|
|
6884
|
+
type: "object",
|
|
6885
|
+
properties: {
|
|
6886
|
+
name: {
|
|
6887
|
+
type: "string",
|
|
6888
|
+
description: "Short stable case id / name"
|
|
6889
|
+
},
|
|
6890
|
+
description: {
|
|
6891
|
+
type: "string",
|
|
6892
|
+
description: "What this case verifies (Chinese ok)"
|
|
6893
|
+
},
|
|
6894
|
+
steps: {
|
|
6895
|
+
type: "array",
|
|
6896
|
+
items: { type: "string" },
|
|
6897
|
+
description: "Ordered human-readable steps"
|
|
6898
|
+
},
|
|
6899
|
+
sortOrder: {
|
|
6900
|
+
type: "number",
|
|
6901
|
+
description: "Optional display order (0-based)"
|
|
6902
|
+
}
|
|
6903
|
+
},
|
|
6904
|
+
required: ["name", "description", "steps"]
|
|
6905
|
+
}
|
|
6906
|
+
}
|
|
6907
|
+
},
|
|
6908
|
+
required: ["cases"]
|
|
6909
|
+
},
|
|
6910
|
+
execute: async (args) => {
|
|
6911
|
+
const cases = parseCases(args.cases);
|
|
6912
|
+
if (cases.length === 0) {
|
|
6913
|
+
throw new Error(
|
|
6914
|
+
"UpsertWebIdeTestCases \u7F3A\u5C11\u6709\u6548 cases\uFF08\u6BCF\u6761\u9700 name \u4E0E\u975E\u7A7A steps\uFF09"
|
|
6915
|
+
);
|
|
6916
|
+
}
|
|
6917
|
+
const api = createApmApiClient(cfg);
|
|
6918
|
+
const result = await api.cli.webideReplaceTestCases({ taskId, cases });
|
|
6919
|
+
console.log(
|
|
6920
|
+
`[apm] UpsertWebIdeTestCases taskId=${taskId} count=${cases.length}`
|
|
6921
|
+
);
|
|
6922
|
+
return JSON.stringify(
|
|
6923
|
+
{ ok: true, count: result.count ?? cases.length },
|
|
6924
|
+
null,
|
|
6925
|
+
2
|
|
6926
|
+
);
|
|
6927
|
+
}
|
|
6928
|
+
};
|
|
6929
|
+
}
|
|
6930
|
+
|
|
6817
6931
|
// src/commands/connect/cursor-custom-tools.ts
|
|
6818
6932
|
var PLAN_MODE_ASK_QUESTION_HINT = `[SDK \u73AF\u5883\u8BF4\u660E]
|
|
6819
6933
|
AskQuestion \u5DF2\u901A\u8FC7 MCP \u670D\u52A1\u5668 custom-user-tools \u6CE8\u518C\uFF0C\u5DE5\u5177\u540D\u4E3A AskQuestion\u3002
|
|
6820
6934
|
\u9700\u8981\u5411\u7528\u6237\u786E\u8BA4\u65F6\uFF0C\u8BF7\u8C03\u7528 AskQuestion\uFF08\u7ECF CallMcpTool / custom-user-tools\uFF09\uFF0C\u4E0D\u8981\u5047\u8BBE IDE \u5185\u7F6E AskQuestion \u4E0D\u53EF\u7528\u3002
|
|
6821
6935
|
\u975E\u5FC5\u987B\u7684\u95EE\u9898\u53EF\u8DF3\u8FC7\uFF0C\u76F4\u63A5\u5B8C\u6210 createPlan\u3002`;
|
|
6936
|
+
var WORKSPACE_BOUNDARY_HINT = `[\u5DE5\u4F5C\u533A\u8FB9\u754C]
|
|
6937
|
+
\u6240\u6709\u6587\u4EF6\u8BFB\u5199\u3001\u641C\u7D22\uFF08Grep/Glob/Read\uFF09\u3001Shell \u5FC5\u987B\u4E25\u683C\u9650\u5236\u5728\u5F53\u524D\u5DE5\u4F5C\u533A cwd \u5185\u3002
|
|
6938
|
+
\u7981\u6B62\u8BBF\u95EE\u5DE5\u4F5C\u533A\u5916\u8DEF\u5F84\uFF08\u5982\u5176\u5B83\u9879\u76EE\u3001~/.cursor\u3001agent-transcripts\u3001\u7CFB\u7EDF\u76EE\u5F55\u7B49\uFF09\u3002`;
|
|
6822
6939
|
function createCursorCustomTools(cfg, messageId, options) {
|
|
6823
6940
|
const tools = {
|
|
6824
6941
|
...createAppendMessageCustomTools(
|
|
@@ -6840,6 +6957,10 @@ function createCursorCustomTools(cfg, messageId, options) {
|
|
|
6840
6957
|
cfg,
|
|
6841
6958
|
taskId: options.taskId
|
|
6842
6959
|
});
|
|
6960
|
+
tools.UpsertWebIdeTestCases = createUpsertWebIdeTestCasesTool({
|
|
6961
|
+
cfg,
|
|
6962
|
+
taskId: options.taskId
|
|
6963
|
+
});
|
|
6843
6964
|
}
|
|
6844
6965
|
return tools;
|
|
6845
6966
|
}
|
|
@@ -6851,6 +6972,11 @@ function withPlanModeToolHint(prompt, mode) {
|
|
|
6851
6972
|
|
|
6852
6973
|
${PLAN_MODE_ASK_QUESTION_HINT}`;
|
|
6853
6974
|
}
|
|
6975
|
+
function withWorkspaceBoundaryHint(prompt) {
|
|
6976
|
+
return `${prompt.trim()}
|
|
6977
|
+
|
|
6978
|
+
${WORKSPACE_BOUNDARY_HINT}`;
|
|
6979
|
+
}
|
|
6854
6980
|
|
|
6855
6981
|
// src/commands/connect/local-agent-store.ts
|
|
6856
6982
|
import { mkdirSync as mkdirSync10 } from "node:fs";
|
|
@@ -6896,7 +7022,8 @@ async function obtainAgent(ctx) {
|
|
|
6896
7022
|
local: {
|
|
6897
7023
|
cwd: ctx.cwd,
|
|
6898
7024
|
store: createWorkspaceLocalAgentStore(ctx.workdir),
|
|
6899
|
-
...ctx.customTools ? { customTools: ctx.customTools } : {}
|
|
7025
|
+
...ctx.customTools ? { customTools: ctx.customTools } : {},
|
|
7026
|
+
...ctx.enableSandbox ? { sandboxOptions: { enabled: true } } : {}
|
|
6900
7027
|
},
|
|
6901
7028
|
...ctx.mode ? { mode: ctx.mode } : {}
|
|
6902
7029
|
// mcpServers: createPlaywrightMcpServers(),
|
|
@@ -6905,14 +7032,14 @@ async function obtainAgent(ctx) {
|
|
|
6905
7032
|
const savedAgentId = explicitAgentId || (ctx.user ? loadSessionAgentId(ctx.workdir, ctx.sessionId, ctx.user) : void 0);
|
|
6906
7033
|
if (savedAgentId) {
|
|
6907
7034
|
try {
|
|
6908
|
-
const
|
|
7035
|
+
const agent = await Agent.resume(savedAgentId, agentOptions);
|
|
6909
7036
|
console.log(
|
|
6910
7037
|
`[apm] \u590D\u7528 Agent user=${ctx.user} agentId=${savedAgentId}${explicitAgentId ? "\uFF08\u53C2\u6570\u6307\u5B9A\uFF09" : ""}`
|
|
6911
7038
|
);
|
|
6912
7039
|
if (ctx.user) {
|
|
6913
|
-
saveSessionAgentId(ctx.workdir, ctx.sessionId, ctx.user,
|
|
7040
|
+
saveSessionAgentId(ctx.workdir, ctx.sessionId, ctx.user, agent.agentId);
|
|
6914
7041
|
}
|
|
6915
|
-
return { agent
|
|
7042
|
+
return { agent, resumed: true };
|
|
6916
7043
|
} catch (err) {
|
|
6917
7044
|
console.warn(
|
|
6918
7045
|
`[apm] \u590D\u7528 Agent \u5931\u8D25\uFF08agentId=${savedAgentId}\uFF09\uFF0C\u56DE\u9000\u4E3A\u65B0\u5EFA:`,
|
|
@@ -6923,11 +7050,19 @@ async function obtainAgent(ctx) {
|
|
|
6923
7050
|
}
|
|
6924
7051
|
}
|
|
6925
7052
|
}
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
7053
|
+
try {
|
|
7054
|
+
const agent = await Agent.create(agentOptions);
|
|
7055
|
+
if (ctx.user) {
|
|
7056
|
+
saveSessionAgentId(ctx.workdir, ctx.sessionId, ctx.user, agent.agentId);
|
|
7057
|
+
}
|
|
7058
|
+
return { agent, resumed: false };
|
|
7059
|
+
} catch (err) {
|
|
7060
|
+
if (ctx.enableSandbox && err instanceof Error && /sandbox/i.test(err.message)) {
|
|
7061
|
+
console.warn("[apm] sandbox \u4E0D\u53EF\u7528\uFF0C\u56DE\u9000\u4E3A\u65E0 sandbox:", err.message);
|
|
7062
|
+
return obtainAgent({ ...ctx, enableSandbox: false });
|
|
7063
|
+
}
|
|
7064
|
+
throw err;
|
|
6929
7065
|
}
|
|
6930
|
-
return { agent, resumed: false };
|
|
6931
7066
|
}
|
|
6932
7067
|
async function runCursorAgent(cfg, ctx, options) {
|
|
6933
7068
|
const signal = options?.signal;
|
|
@@ -6947,9 +7082,13 @@ async function runCursorAgent(cfg, ctx, options) {
|
|
|
6947
7082
|
enableWebIdePlanTools: options?.enableWebIdePlanTools,
|
|
6948
7083
|
taskId: options?.taskId
|
|
6949
7084
|
});
|
|
6950
|
-
const
|
|
7085
|
+
const enableSandbox = Boolean(options?.enableSandbox);
|
|
7086
|
+
let prompt = withPlanModeToolHint(ctx.prompt, ctx.mode);
|
|
7087
|
+
if (enableSandbox) {
|
|
7088
|
+
prompt = withWorkspaceBoundaryHint(prompt);
|
|
7089
|
+
}
|
|
6951
7090
|
console.log(
|
|
6952
|
-
`[apm] Cursor Agent \u5F00\u59CB messageId=${ctx.messageId} sessionId=${ctx.sessionId} cwd=${workdir}`
|
|
7091
|
+
`[apm] Cursor Agent \u5F00\u59CB messageId=${ctx.messageId} sessionId=${ctx.sessionId} cwd=${workdir} sandbox=${enableSandbox}`
|
|
6953
7092
|
);
|
|
6954
7093
|
const { agent, resumed } = await obtainAgent({
|
|
6955
7094
|
apiKey,
|
|
@@ -6960,7 +7099,8 @@ async function runCursorAgent(cfg, ctx, options) {
|
|
|
6960
7099
|
user: ctx.user,
|
|
6961
7100
|
mode: ctx.mode,
|
|
6962
7101
|
resumeAgentId: ctx.resumeAgentId,
|
|
6963
|
-
customTools
|
|
7102
|
+
customTools,
|
|
7103
|
+
enableSandbox
|
|
6964
7104
|
});
|
|
6965
7105
|
const eventSession = new EventSession(prompt);
|
|
6966
7106
|
const syncRemoteLog = options?.createRemoteLogSync ? options.createRemoteLogSync(agent.agentId) : options?.skipRemoteLogSync ? noopRemoteLogSync : createThrottledCursorMessageLogSync(
|