ai-project-manage-cli 7.1.27 → 7.1.28
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 +62 -2
- package/dist/webide-message-worker.js +191 -71
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -314,6 +314,10 @@ var init_request_config = __esm({
|
|
|
314
314
|
});
|
|
315
315
|
|
|
316
316
|
// src/api/client.ts
|
|
317
|
+
var client_exports = {};
|
|
318
|
+
__export(client_exports, {
|
|
319
|
+
createApmApiClient: () => createApmApiClient
|
|
320
|
+
});
|
|
317
321
|
import { createApiClient } from "listpage-http";
|
|
318
322
|
function createApmApiClient(cfg) {
|
|
319
323
|
const baseURL = `${cfg.baseUrl.trim().replace(/\/+$/, "")}/api/v1`;
|
|
@@ -7424,6 +7428,17 @@ var EventSession = class {
|
|
|
7424
7428
|
});
|
|
7425
7429
|
this.markDirty(this.events.length - 1);
|
|
7426
7430
|
}
|
|
7431
|
+
/** CLI 本地准备步骤(工作区/分支/文档等),写入日志供 WebIDE 查看 */
|
|
7432
|
+
addCliStep(step, text, status = "ok") {
|
|
7433
|
+
this.events.push({
|
|
7434
|
+
type: "cli_step",
|
|
7435
|
+
step,
|
|
7436
|
+
status,
|
|
7437
|
+
text,
|
|
7438
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
7439
|
+
});
|
|
7440
|
+
this.markDirty(this.events.length - 1);
|
|
7441
|
+
}
|
|
7427
7442
|
formatEvent(event) {
|
|
7428
7443
|
switch (event.type) {
|
|
7429
7444
|
case "assistant": {
|
|
@@ -8351,7 +8366,7 @@ async function runCursorAgent(cfg, ctx, options) {
|
|
|
8351
8366
|
customTools,
|
|
8352
8367
|
enableSandbox
|
|
8353
8368
|
});
|
|
8354
|
-
const eventSession = new EventSession(prompt);
|
|
8369
|
+
const eventSession = options?.eventSession ?? new EventSession(prompt);
|
|
8355
8370
|
const syncRemoteLog = options?.createRemoteLogSync ? options.createRemoteLogSync(agent.agentId) : options?.skipRemoteLogSync ? noopRemoteLogSync : createThrottledCursorMessageLogSync(
|
|
8356
8371
|
cfg,
|
|
8357
8372
|
logCtx(ctx, agent.agentId),
|
|
@@ -8630,10 +8645,27 @@ function spawnWebIdeMessageWorker(cfg, msg) {
|
|
|
8630
8645
|
workerData: { cfg, msg }
|
|
8631
8646
|
});
|
|
8632
8647
|
const registry = getWebIdeTerminalRegistry(cfg);
|
|
8648
|
+
let settled = false;
|
|
8633
8649
|
let resolveDone;
|
|
8634
8650
|
const done = new Promise((resolve8) => {
|
|
8635
8651
|
resolveDone = resolve8;
|
|
8636
8652
|
});
|
|
8653
|
+
const failIfStillQueued = async (reason) => {
|
|
8654
|
+
if (settled) return;
|
|
8655
|
+
try {
|
|
8656
|
+
const { createApmApiClient: createApmApiClient2 } = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
8657
|
+
const api = createApmApiClient2(cfg);
|
|
8658
|
+
await api.cli.webideSetMessageError({
|
|
8659
|
+
id: msg.messageId,
|
|
8660
|
+
error: reason
|
|
8661
|
+
});
|
|
8662
|
+
} catch (err) {
|
|
8663
|
+
console.error(
|
|
8664
|
+
`[apm] webide worker \u5931\u8D25\u5199\u7EC8\u6001\u5931\u8D25 messageId=${msg.messageId}:`,
|
|
8665
|
+
err instanceof Error ? err.message : err
|
|
8666
|
+
);
|
|
8667
|
+
}
|
|
8668
|
+
};
|
|
8637
8669
|
worker.on("message", (m) => {
|
|
8638
8670
|
if (m?.type === "terminal-rpc") {
|
|
8639
8671
|
const rpc = m;
|
|
@@ -8693,6 +8725,7 @@ function spawnWebIdeMessageWorker(cfg, msg) {
|
|
|
8693
8725
|
return;
|
|
8694
8726
|
}
|
|
8695
8727
|
if (m?.type === "done" || m?.type === "error") {
|
|
8728
|
+
settled = true;
|
|
8696
8729
|
if (m.type === "error") {
|
|
8697
8730
|
console.error(
|
|
8698
8731
|
`[apm] webide worker error messageId=${m.messageId}: ${m.error}`
|
|
@@ -8703,9 +8736,18 @@ function spawnWebIdeMessageWorker(cfg, msg) {
|
|
|
8703
8736
|
});
|
|
8704
8737
|
worker.on("error", (err) => {
|
|
8705
8738
|
console.error("[apm] webide worker crashed:", err);
|
|
8706
|
-
|
|
8739
|
+
void failIfStillQueued(
|
|
8740
|
+
`WebIDE worker \u5D29\u6E83: ${err instanceof Error ? err.message : String(err)}`
|
|
8741
|
+
).finally(() => resolveDone());
|
|
8707
8742
|
});
|
|
8708
8743
|
worker.on("exit", (code) => {
|
|
8744
|
+
if (!settled && code !== 0) {
|
|
8745
|
+
console.error(`[apm] webide worker exit code=${code}`);
|
|
8746
|
+
void failIfStillQueued(`WebIDE worker \u5F02\u5E38\u9000\u51FA code=${code}`).finally(
|
|
8747
|
+
() => resolveDone()
|
|
8748
|
+
);
|
|
8749
|
+
return;
|
|
8750
|
+
}
|
|
8709
8751
|
if (code !== 0) {
|
|
8710
8752
|
console.error(`[apm] webide worker exit code=${code}`);
|
|
8711
8753
|
}
|
|
@@ -9012,6 +9054,24 @@ function attachWsHandlers(ws, ctx, onOpen) {
|
|
|
9012
9054
|
if (pendingCancels.has(msg2.messageId)) {
|
|
9013
9055
|
activeRuns.delete(msg2.messageId);
|
|
9014
9056
|
pendingCancels.delete(msg2.messageId);
|
|
9057
|
+
const cancelTask = (async () => {
|
|
9058
|
+
try {
|
|
9059
|
+
const api = createApmApiClient(cfg);
|
|
9060
|
+
await api.cli.webideUpdateMessageStatus({
|
|
9061
|
+
id: msg2.messageId,
|
|
9062
|
+
status: "CANCELLED"
|
|
9063
|
+
});
|
|
9064
|
+
} catch (err) {
|
|
9065
|
+
console.error(
|
|
9066
|
+
`[apm] webide-message \u9884\u53D6\u6D88\u5199\u7EC8\u6001\u5931\u8D25 messageId=${msg2.messageId}:`,
|
|
9067
|
+
err instanceof Error ? err.message : err
|
|
9068
|
+
);
|
|
9069
|
+
}
|
|
9070
|
+
})();
|
|
9071
|
+
activeTasks.add(cancelTask);
|
|
9072
|
+
void cancelTask.finally(() => {
|
|
9073
|
+
activeTasks.delete(cancelTask);
|
|
9074
|
+
});
|
|
9015
9075
|
return;
|
|
9016
9076
|
}
|
|
9017
9077
|
const task2 = (async () => {
|
|
@@ -1362,6 +1362,17 @@ var EventSession = class {
|
|
|
1362
1362
|
});
|
|
1363
1363
|
this.markDirty(this.events.length - 1);
|
|
1364
1364
|
}
|
|
1365
|
+
/** CLI 本地准备步骤(工作区/分支/文档等),写入日志供 WebIDE 查看 */
|
|
1366
|
+
addCliStep(step, text, status = "ok") {
|
|
1367
|
+
this.events.push({
|
|
1368
|
+
type: "cli_step",
|
|
1369
|
+
step,
|
|
1370
|
+
status,
|
|
1371
|
+
text,
|
|
1372
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1373
|
+
});
|
|
1374
|
+
this.markDirty(this.events.length - 1);
|
|
1375
|
+
}
|
|
1365
1376
|
formatEvent(event) {
|
|
1366
1377
|
switch (event.type) {
|
|
1367
1378
|
case "assistant": {
|
|
@@ -2360,7 +2371,7 @@ async function runCursorAgent(cfg, ctx, options) {
|
|
|
2360
2371
|
customTools,
|
|
2361
2372
|
enableSandbox
|
|
2362
2373
|
});
|
|
2363
|
-
const eventSession = new EventSession(prompt);
|
|
2374
|
+
const eventSession = options?.eventSession ?? new EventSession(prompt);
|
|
2364
2375
|
const syncRemoteLog = options?.createRemoteLogSync ? options.createRemoteLogSync(agent.agentId) : options?.skipRemoteLogSync ? noopRemoteLogSync : createThrottledCursorMessageLogSync(
|
|
2365
2376
|
cfg,
|
|
2366
2377
|
logCtx(ctx, agent.agentId),
|
|
@@ -2707,13 +2718,14 @@ async function upsertLogHeader(cfg, ctx, patch) {
|
|
|
2707
2718
|
...patch
|
|
2708
2719
|
});
|
|
2709
2720
|
}
|
|
2710
|
-
function createThrottledWebIdeMessageLogSync(cfg, ctx, onError) {
|
|
2721
|
+
function createThrottledWebIdeMessageLogSync(cfg, ctx, onError, options) {
|
|
2711
2722
|
let lastRunAt = 0;
|
|
2712
2723
|
let timer;
|
|
2713
2724
|
let latestSession;
|
|
2714
2725
|
let syncChain = Promise.resolve();
|
|
2715
2726
|
let minio;
|
|
2716
2727
|
let bucket = "";
|
|
2728
|
+
let firstLogNotified = false;
|
|
2717
2729
|
const ensureMinio = async () => {
|
|
2718
2730
|
if (minio) return;
|
|
2719
2731
|
const storage = await fetchDeployArtifactStorage(createApmApiClient(cfg));
|
|
@@ -2727,6 +2739,16 @@ function createThrottledWebIdeMessageLogSync(cfg, ctx, onError) {
|
|
|
2727
2739
|
bucket = storage.bucket;
|
|
2728
2740
|
await minio.ensureBucket(bucket);
|
|
2729
2741
|
};
|
|
2742
|
+
const notifyFirstLog = async () => {
|
|
2743
|
+
if (firstLogNotified) return;
|
|
2744
|
+
firstLogNotified = true;
|
|
2745
|
+
try {
|
|
2746
|
+
await options?.onFirstLogSynced?.();
|
|
2747
|
+
} catch (err) {
|
|
2748
|
+
firstLogNotified = false;
|
|
2749
|
+
onError(err);
|
|
2750
|
+
}
|
|
2751
|
+
};
|
|
2730
2752
|
const syncDirtyEventsOnce = async (session) => {
|
|
2731
2753
|
const events = session.getDirtyEvents();
|
|
2732
2754
|
if (events.length === 0) return;
|
|
@@ -2739,6 +2761,7 @@ function createThrottledWebIdeMessageLogSync(cfg, ctx, onError) {
|
|
|
2739
2761
|
eventCount: session.getEventCount()
|
|
2740
2762
|
});
|
|
2741
2763
|
session.clearDirtyIfUnchanged(events);
|
|
2764
|
+
await notifyFirstLog();
|
|
2742
2765
|
} catch (err) {
|
|
2743
2766
|
onError(err);
|
|
2744
2767
|
}
|
|
@@ -3768,98 +3791,189 @@ async function handleWebIdeInboundMessage(cfg, msg, signal, options) {
|
|
|
3768
3791
|
`[apm] webide-message action=${msg.action} taskId=${taskId} messageId=${messageId}`
|
|
3769
3792
|
);
|
|
3770
3793
|
await updateStatus(cfg, messageId, "TYPING");
|
|
3794
|
+
const eventSession = new EventSession(msg.content);
|
|
3795
|
+
const prepAgentId = loadWebIdeAgentId(workdir, taskId) ?? "webide-cli-prep";
|
|
3796
|
+
const logSyncRef = {
|
|
3797
|
+
current: createThrottledWebIdeMessageLogSync(
|
|
3798
|
+
cfg,
|
|
3799
|
+
{ taskId, messageId, agentId: prepAgentId },
|
|
3800
|
+
(err) => {
|
|
3801
|
+
console.warn(
|
|
3802
|
+
"[apm] WebIDE \u65E5\u5FD7\u540C\u6B65\u5931\u8D25:",
|
|
3803
|
+
err instanceof Error ? err.message : err
|
|
3804
|
+
);
|
|
3805
|
+
}
|
|
3806
|
+
)
|
|
3807
|
+
};
|
|
3808
|
+
const syncPrepLog = async () => {
|
|
3809
|
+
const sync = logSyncRef.current;
|
|
3810
|
+
if (!sync) return;
|
|
3811
|
+
sync.schedule(eventSession);
|
|
3812
|
+
await sync.flush(eventSession);
|
|
3813
|
+
};
|
|
3814
|
+
const runPrepStep = async (step, work, formatOk) => {
|
|
3815
|
+
eventSession.addCliStep(step, "\u8FDB\u884C\u4E2D\u2026", "running");
|
|
3816
|
+
await syncPrepLog();
|
|
3817
|
+
try {
|
|
3818
|
+
const result = await work();
|
|
3819
|
+
eventSession.addCliStep(step, formatOk(result), "ok");
|
|
3820
|
+
await syncPrepLog();
|
|
3821
|
+
return result;
|
|
3822
|
+
} catch (err) {
|
|
3823
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
3824
|
+
eventSession.addCliStep(step, detail, "error");
|
|
3825
|
+
await syncPrepLog();
|
|
3826
|
+
throw err;
|
|
3827
|
+
}
|
|
3828
|
+
};
|
|
3771
3829
|
try {
|
|
3772
3830
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3831
|
+
await runPrepStep(
|
|
3832
|
+
"\u521D\u59CB\u5316\u5DE5\u4F5C\u533A",
|
|
3833
|
+
async () => {
|
|
3834
|
+
const { didInit } = await ensureWorkspaceInitialized(workdir);
|
|
3835
|
+
if (!didInit) {
|
|
3836
|
+
assertApmGitignoredInRepo(workdir);
|
|
3837
|
+
}
|
|
3838
|
+
return didInit;
|
|
3839
|
+
},
|
|
3840
|
+
(didInit) => didInit ? "\u5DF2\u521D\u59CB\u5316\u5DE5\u4F5C\u533A" : "\u5DE5\u4F5C\u533A\u5DF2\u5C31\u7EEA"
|
|
3841
|
+
);
|
|
3777
3842
|
const cliVersion = readCliVersion();
|
|
3778
3843
|
if (shouldSyncSkillsForCliVersion(workdir, cliVersion)) {
|
|
3779
3844
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3780
|
-
|
|
3781
|
-
|
|
3845
|
+
await runPrepStep(
|
|
3846
|
+
"\u540C\u6B65 Skills",
|
|
3847
|
+
async () => {
|
|
3848
|
+
await syncWorkspaceSkills(cfg, workdir);
|
|
3849
|
+
markSkillsSyncedForCliVersion(workdir, cliVersion);
|
|
3850
|
+
return cliVersion;
|
|
3851
|
+
},
|
|
3852
|
+
(version) => `\u5DF2\u540C\u6B65\u81F3 CLI ${version}`
|
|
3782
3853
|
);
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
await enrichWorkspaceReposRemoteUrls(workspaceRepos);
|
|
3789
|
-
} catch (err) {
|
|
3790
|
-
console.warn(
|
|
3791
|
-
"[apm] \u8865\u9F50 workspace-repos remoteUrl \u5931\u8D25:",
|
|
3792
|
-
err instanceof Error ? err.message : err
|
|
3854
|
+
} else {
|
|
3855
|
+
eventSession.addCliStep(
|
|
3856
|
+
"\u540C\u6B65 Skills",
|
|
3857
|
+
`\u7248\u672C\u4E00\u81F4\uFF08${cliVersion}\uFF09\uFF0C\u8DF3\u8FC7`,
|
|
3858
|
+
"skip"
|
|
3793
3859
|
);
|
|
3860
|
+
await syncPrepLog();
|
|
3794
3861
|
}
|
|
3862
|
+
await runPrepStep(
|
|
3863
|
+
"\u5DE5\u4F5C\u533A\u4ED3\u5E93\u6E05\u5355",
|
|
3864
|
+
async () => {
|
|
3865
|
+
const workspaceRepos = resolveWorkspaceRepos(workdir);
|
|
3866
|
+
try {
|
|
3867
|
+
await enrichWorkspaceReposRemoteUrls(workspaceRepos);
|
|
3868
|
+
} catch (err) {
|
|
3869
|
+
console.warn(
|
|
3870
|
+
"[apm] \u8865\u9F50 workspace-repos remoteUrl \u5931\u8D25:",
|
|
3871
|
+
err instanceof Error ? err.message : err
|
|
3872
|
+
);
|
|
3873
|
+
}
|
|
3874
|
+
return workspaceRepos;
|
|
3875
|
+
},
|
|
3876
|
+
(repos) => `kind=${repos.kind} repos=${repos.repos.length}`
|
|
3877
|
+
);
|
|
3795
3878
|
if (shouldRunBranch(branchCacheKey, workdir)) {
|
|
3796
3879
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3880
|
+
await runPrepStep(
|
|
3881
|
+
"\u51C6\u5907\u7279\u6027\u5206\u652F",
|
|
3882
|
+
async () => runTaskBranch(taskId, { cwd: workdir }),
|
|
3883
|
+
(branchResult) => {
|
|
3884
|
+
markBranchDone(branchCacheKey, workdir);
|
|
3885
|
+
return `kind=${branchResult.kind} branch=${branchResult.branch} repos=${branchResult.repos.length}`;
|
|
3886
|
+
}
|
|
3801
3887
|
);
|
|
3802
3888
|
} else {
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
);
|
|
3889
|
+
eventSession.addCliStep("\u51C6\u5907\u7279\u6027\u5206\u652F", "\u5DF2\u7F13\u5B58\uFF0C\u8DF3\u8FC7", "skip");
|
|
3890
|
+
await syncPrepLog();
|
|
3806
3891
|
}
|
|
3807
3892
|
if (shouldEnsureWebIdePullRequests(msg.action)) {
|
|
3808
3893
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3894
|
+
await runPrepStep(
|
|
3895
|
+
"\u6D4B\u8BD5\u524D\u63A8\u9001",
|
|
3896
|
+
async () => pushWorkspaceRepos(workdir),
|
|
3897
|
+
(pushed) => `\u5DF2 push ${pushed} \u4E2A\u4ED3\u5E93`
|
|
3812
3898
|
);
|
|
3813
3899
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3814
|
-
await
|
|
3900
|
+
await runPrepStep(
|
|
3901
|
+
"\u786E\u4FDD PR",
|
|
3902
|
+
async () => {
|
|
3903
|
+
await ensureWebIdePullRequests(cfg, taskId, workdir);
|
|
3904
|
+
return true;
|
|
3905
|
+
},
|
|
3906
|
+
() => "PR \u68C0\u67E5\u5B8C\u6210"
|
|
3907
|
+
);
|
|
3815
3908
|
}
|
|
3816
3909
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3817
3910
|
const api = createApmApiClient(cfg);
|
|
3818
3911
|
let projectId = null;
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
projectId
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3912
|
+
await runPrepStep(
|
|
3913
|
+
"\u540C\u6B65\u9879\u76EE\u6587\u6863",
|
|
3914
|
+
async () => {
|
|
3915
|
+
try {
|
|
3916
|
+
const baseline = await api.cli.projectBaseBranch({ taskId });
|
|
3917
|
+
projectId = baseline.projectId?.trim() || null;
|
|
3918
|
+
if (!projectId) {
|
|
3919
|
+
return { synced: false, reason: "\u65E0 projectId" };
|
|
3920
|
+
}
|
|
3921
|
+
const docs = await syncProjectDocumentsPull(workdir, void 0, {
|
|
3922
|
+
projectId
|
|
3923
|
+
});
|
|
3924
|
+
return {
|
|
3925
|
+
synced: docs.synced,
|
|
3926
|
+
downloaded: docs.downloaded,
|
|
3927
|
+
deleted: docs.deleted
|
|
3928
|
+
};
|
|
3929
|
+
} catch (err) {
|
|
3930
|
+
console.warn(
|
|
3931
|
+
"[apm] WebIDE \u9879\u76EE\u6587\u6863\u540C\u6B65\u5931\u8D25:",
|
|
3932
|
+
err instanceof Error ? err.message : err
|
|
3829
3933
|
);
|
|
3934
|
+
return {
|
|
3935
|
+
synced: false,
|
|
3936
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
3937
|
+
};
|
|
3830
3938
|
}
|
|
3831
|
-
}
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
"[apm] WebIDE \u9879\u76EE\u6587\u6863\u540C\u6B65\u5931\u8D25:",
|
|
3839
|
-
err instanceof Error ? err.message : err
|
|
3840
|
-
);
|
|
3841
|
-
}
|
|
3842
|
-
try {
|
|
3843
|
-
const attachments = await api.cli.webideListAttachments({ taskId });
|
|
3844
|
-
const names = await syncWebIdeAttachments(
|
|
3845
|
-
cfg,
|
|
3846
|
-
taskId,
|
|
3847
|
-
workdir,
|
|
3848
|
-
attachments ?? []
|
|
3849
|
-
);
|
|
3850
|
-
if (names.length > 0) {
|
|
3851
|
-
console.log(
|
|
3852
|
-
`[apm] webide \u9644\u4EF6\u5DF2\u5C31\u7EEA count=${names.length} dir=.apm/webide/${taskId}/attachments`
|
|
3853
|
-
);
|
|
3939
|
+
},
|
|
3940
|
+
(result) => {
|
|
3941
|
+
if ("reason" in result && result.reason) {
|
|
3942
|
+
return `\u8DF3\u8FC7\uFF1A${result.reason}`;
|
|
3943
|
+
}
|
|
3944
|
+
if (!result.synced) return "\u65E0\u9700\u540C\u6B65";
|
|
3945
|
+
return `downloaded=${result.downloaded ?? 0} deleted=${result.deleted ?? 0}`;
|
|
3854
3946
|
}
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3947
|
+
);
|
|
3948
|
+
await runPrepStep(
|
|
3949
|
+
"\u540C\u6B65\u4EFB\u52A1\u9644\u4EF6",
|
|
3950
|
+
async () => {
|
|
3951
|
+
try {
|
|
3952
|
+
const attachments = await api.cli.webideListAttachments({ taskId });
|
|
3953
|
+
const names = await syncWebIdeAttachments(
|
|
3954
|
+
cfg,
|
|
3955
|
+
taskId,
|
|
3956
|
+
workdir,
|
|
3957
|
+
attachments ?? []
|
|
3958
|
+
);
|
|
3959
|
+
return names;
|
|
3960
|
+
} catch (err) {
|
|
3961
|
+
console.warn(
|
|
3962
|
+
"[apm] WebIDE \u9644\u4EF6\u540C\u6B65\u5931\u8D25:",
|
|
3963
|
+
err instanceof Error ? err.message : err
|
|
3964
|
+
);
|
|
3965
|
+
return [];
|
|
3966
|
+
}
|
|
3967
|
+
},
|
|
3968
|
+
(names) => names.length > 0 ? `\u5DF2\u540C\u6B65 ${names.length} \u4E2A\u9644\u4EF6` : "\u65E0\u9644\u4EF6\u6216\u540C\u6B65\u8DF3\u8FC7"
|
|
3969
|
+
);
|
|
3970
|
+
eventSession.addCliStep(
|
|
3971
|
+
"\u542F\u52A8 Cursor Agent",
|
|
3972
|
+
"\u51C6\u5907 resume/create\u2026",
|
|
3973
|
+
"running"
|
|
3974
|
+
);
|
|
3975
|
+
await syncPrepLog();
|
|
3861
3976
|
const savedAgentId = loadWebIdeAgentId(workdir, taskId);
|
|
3862
|
-
const logSyncRef = { current: null };
|
|
3863
3977
|
const outcome = await runCursorAgent(
|
|
3864
3978
|
cfg,
|
|
3865
3979
|
{
|
|
@@ -3874,8 +3988,8 @@ async function handleWebIdeInboundMessage(cfg, msg, signal, options) {
|
|
|
3874
3988
|
},
|
|
3875
3989
|
{
|
|
3876
3990
|
signal,
|
|
3877
|
-
// IDE 重启/异常中断后 Cursor 可能仍认为旧 run active;强制清残留再 send
|
|
3878
3991
|
forceSend: true,
|
|
3992
|
+
eventSession,
|
|
3879
3993
|
appendMessageContent: (content) => appendContent(cfg, messageId, content),
|
|
3880
3994
|
askQuestionExecute: createWebIdeAskQuestionExecute({
|
|
3881
3995
|
cfg,
|
|
@@ -3883,7 +3997,6 @@ async function handleWebIdeInboundMessage(cfg, msg, signal, options) {
|
|
|
3883
3997
|
signal
|
|
3884
3998
|
}),
|
|
3885
3999
|
enableWebIdePlanTools: true,
|
|
3886
|
-
// 本地 SDK sandbox 会拦截 custom-user-tools MCP,WebIDE 先关闭
|
|
3887
4000
|
enableSandbox: false,
|
|
3888
4001
|
taskId,
|
|
3889
4002
|
terminalRpc: options?.terminalRpc,
|
|
@@ -3903,7 +4016,14 @@ async function handleWebIdeInboundMessage(cfg, msg, signal, options) {
|
|
|
3903
4016
|
},
|
|
3904
4017
|
onRunStarted: async ({ agentId, runId }) => {
|
|
3905
4018
|
saveWebIdeAgentId(workdir, taskId, agentId);
|
|
4019
|
+
eventSession.addCliStep(
|
|
4020
|
+
"\u542F\u52A8 Cursor Agent",
|
|
4021
|
+
`agentId=${agentId} runId=${runId}`,
|
|
4022
|
+
"ok"
|
|
4023
|
+
);
|
|
4024
|
+
logSyncRef.current?.schedule(eventSession);
|
|
3906
4025
|
await logSyncRef.current?.markRun(runId, "running");
|
|
4026
|
+
await logSyncRef.current?.flush(eventSession);
|
|
3907
4027
|
}
|
|
3908
4028
|
}
|
|
3909
4029
|
);
|