weacpx 0.6.0 → 0.6.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/dist/bridge/bridge-main.js +59 -23
- package/dist/channels/types.d.ts +5 -0
- package/dist/cli.js +328 -158
- package/dist/commands/command-hints.d.ts +11 -0
- package/dist/commands/command-list.d.ts +3 -0
- package/dist/commands/config-clone.d.ts +2 -0
- package/dist/commands/handlers/agent-handler.d.ts +6 -0
- package/dist/commands/handlers/config-handler.d.ts +5 -0
- package/dist/commands/handlers/later-handler.d.ts +21 -0
- package/dist/commands/handlers/orchestration-handler.d.ts +16 -0
- package/dist/commands/handlers/permission-handler.d.ts +9 -0
- package/dist/commands/handlers/session-handler.d.ts +37 -0
- package/dist/commands/handlers/workspace-handler.d.ts +8 -0
- package/dist/commands/help/help-registry.d.ts +4 -0
- package/dist/commands/help/help-types.d.ts +12 -0
- package/dist/commands/parse-command.d.ts +175 -0
- package/dist/commands/router-types.d.ts +144 -0
- package/dist/commands/workspace-name.d.ts +4 -0
- package/dist/commands/workspace-path.d.ts +4 -0
- package/dist/config/agent-templates.d.ts +4 -0
- package/dist/config/config-store.d.ts +13 -0
- package/dist/config/load-config.d.ts +10 -0
- package/dist/config/resolve-agent-command.d.ts +2 -0
- package/dist/formatting/render-text.d.ts +23 -0
- package/dist/orchestration/async-mutex.d.ts +4 -0
- package/dist/orchestration/build-coordinator-prompt.d.ts +66 -0
- package/dist/orchestration/orchestration-service.d.ts +471 -0
- package/dist/orchestration/progress-line-parser.d.ts +19 -0
- package/dist/orchestration/render-delegate-group-result.d.ts +6 -0
- package/dist/orchestration/render-delegate-question-package.d.ts +21 -0
- package/dist/orchestration/render-delegate-result.d.ts +2 -0
- package/dist/orchestration/task-watch-timeouts.d.ts +5 -0
- package/dist/plugin-api.d.ts +1 -0
- package/dist/scheduled/parse-later-time.d.ts +11 -0
- package/dist/scheduled/scheduled-render.d.ts +7 -0
- package/dist/scheduled/scheduled-service.d.ts +41 -0
- package/dist/scheduled/scheduled-types.d.ts +29 -0
- package/dist/sessions/session-service.d.ts +83 -0
- package/dist/state/state-store.d.ts +8 -0
- package/dist/state/types.d.ts +44 -0
- package/dist/transport/tool-event-mode.d.ts +14 -0
- package/dist/transport/types.d.ts +129 -0
- package/dist/util/path.d.ts +4 -0
- package/dist/util/sanitize.d.ts +10 -0
- package/dist/util/text.d.ts +3 -0
- package/dist/version.d.ts +2 -0
- package/dist/weixin/auth/accounts.d.ts +0 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2088,36 +2088,56 @@ var init_private_file = __esm(() => {
|
|
|
2088
2088
|
import_write_file_atomic = __toESM(require_lib(), 1);
|
|
2089
2089
|
});
|
|
2090
2090
|
|
|
2091
|
-
// src/
|
|
2092
|
-
import { access } from "node:fs/promises";
|
|
2093
|
-
import { homedir } from "node:os";
|
|
2091
|
+
// src/util/path.ts
|
|
2094
2092
|
import path from "node:path";
|
|
2095
|
-
|
|
2093
|
+
import { homedir } from "node:os";
|
|
2094
|
+
function normalizePath(input) {
|
|
2096
2095
|
const expanded = expandHome(input);
|
|
2097
2096
|
if (isWindowsLikePath(expanded)) {
|
|
2098
2097
|
return path.win32.normalize(expanded).replace(/\\/g, "/");
|
|
2099
2098
|
}
|
|
2100
2099
|
return path.posix.normalize(expanded.replace(/\\/g, "/"));
|
|
2101
2100
|
}
|
|
2102
|
-
function
|
|
2103
|
-
const normalized =
|
|
2101
|
+
function basenameForPath(input) {
|
|
2102
|
+
const normalized = normalizePath(input);
|
|
2104
2103
|
if (ROOT_PATH_RE.test(normalized)) {
|
|
2105
2104
|
return normalized;
|
|
2106
2105
|
}
|
|
2107
2106
|
const base = path.posix.basename(normalized);
|
|
2108
2107
|
return base || normalized;
|
|
2109
2108
|
}
|
|
2110
|
-
function
|
|
2111
|
-
const normalizedLeft =
|
|
2112
|
-
const normalizedRight =
|
|
2109
|
+
function isSamePath(left, right) {
|
|
2110
|
+
const normalizedLeft = normalizePath(left);
|
|
2111
|
+
const normalizedRight = normalizePath(right);
|
|
2113
2112
|
if (isWindowsLikePath(normalizedLeft) || isWindowsLikePath(normalizedRight)) {
|
|
2114
2113
|
return normalizedLeft.toLowerCase() === normalizedRight.toLowerCase();
|
|
2115
2114
|
}
|
|
2116
2115
|
return normalizedLeft === normalizedRight;
|
|
2117
2116
|
}
|
|
2117
|
+
function isWindowsLikePath(input) {
|
|
2118
|
+
return WINDOWS_DRIVE_PATH_RE.test(input) || WINDOWS_UNC_PATH_RE.test(input);
|
|
2119
|
+
}
|
|
2118
2120
|
function expandHome(input) {
|
|
2119
2121
|
return input.startsWith("~") ? homedir() + input.slice(1) : input;
|
|
2120
2122
|
}
|
|
2123
|
+
var WINDOWS_DRIVE_PATH_RE, WINDOWS_UNC_PATH_RE, ROOT_PATH_RE;
|
|
2124
|
+
var init_path = __esm(() => {
|
|
2125
|
+
WINDOWS_DRIVE_PATH_RE = /^[a-zA-Z]:[\\/]/;
|
|
2126
|
+
WINDOWS_UNC_PATH_RE = /^\\\\/;
|
|
2127
|
+
ROOT_PATH_RE = /^(\/|[a-zA-Z]:\/?)$/;
|
|
2128
|
+
});
|
|
2129
|
+
|
|
2130
|
+
// src/commands/workspace-path.ts
|
|
2131
|
+
import { access } from "node:fs/promises";
|
|
2132
|
+
function normalizeWorkspacePath(input) {
|
|
2133
|
+
return normalizePath(input);
|
|
2134
|
+
}
|
|
2135
|
+
function basenameForWorkspacePath(input) {
|
|
2136
|
+
return basenameForPath(input);
|
|
2137
|
+
}
|
|
2138
|
+
function sameWorkspacePath(left, right) {
|
|
2139
|
+
return isSamePath(left, right);
|
|
2140
|
+
}
|
|
2121
2141
|
async function pathExists(filePath) {
|
|
2122
2142
|
try {
|
|
2123
2143
|
await access(filePath);
|
|
@@ -2126,14 +2146,8 @@ async function pathExists(filePath) {
|
|
|
2126
2146
|
return false;
|
|
2127
2147
|
}
|
|
2128
2148
|
}
|
|
2129
|
-
function isWindowsLikePath(input) {
|
|
2130
|
-
return WINDOWS_DRIVE_PATH_RE.test(input) || WINDOWS_UNC_PATH_RE.test(input);
|
|
2131
|
-
}
|
|
2132
|
-
var WINDOWS_DRIVE_PATH_RE, WINDOWS_UNC_PATH_RE, ROOT_PATH_RE;
|
|
2133
2149
|
var init_workspace_path = __esm(() => {
|
|
2134
|
-
|
|
2135
|
-
WINDOWS_UNC_PATH_RE = /^\\\\/;
|
|
2136
|
-
ROOT_PATH_RE = /^(\/|[a-zA-Z]:\/?)$/;
|
|
2150
|
+
init_path();
|
|
2137
2151
|
});
|
|
2138
2152
|
|
|
2139
2153
|
// src/config/resolve-agent-command.ts
|
|
@@ -9688,8 +9702,10 @@ function readVersion(moduleUrl = import.meta.url) {
|
|
|
9688
9702
|
}
|
|
9689
9703
|
return "unknown";
|
|
9690
9704
|
}
|
|
9691
|
-
var PACKAGE_NAME = "weacpx";
|
|
9692
|
-
var init_version = () => {
|
|
9705
|
+
var PACKAGE_NAME = "weacpx", WEACPX_CORE_VERSION;
|
|
9706
|
+
var init_version = __esm(() => {
|
|
9707
|
+
WEACPX_CORE_VERSION = readVersion();
|
|
9708
|
+
});
|
|
9693
9709
|
|
|
9694
9710
|
// src/orchestration/task-watch-timeouts.ts
|
|
9695
9711
|
var DEFAULT_TASK_WATCH_TIMEOUT_MS = 60000, MAX_TASK_WATCH_TIMEOUT_MS, DEFAULT_TASK_WATCH_POLL_INTERVAL_MS = 1000, MAX_TASK_WATCH_POLL_INTERVAL_MS = 1e4, TASK_WATCH_RPC_TIMEOUT_PADDING_MS = 5000;
|
|
@@ -9713,10 +9729,60 @@ var init_quota_errors = __esm(() => {
|
|
|
9713
9729
|
};
|
|
9714
9730
|
});
|
|
9715
9731
|
|
|
9732
|
+
// src/util/sanitize.ts
|
|
9733
|
+
function sanitizeString(input, options = {}) {
|
|
9734
|
+
const {
|
|
9735
|
+
replacement = "-",
|
|
9736
|
+
collapse = false,
|
|
9737
|
+
trim = false,
|
|
9738
|
+
lowercase: lowercase2 = false,
|
|
9739
|
+
fallback
|
|
9740
|
+
} = options;
|
|
9741
|
+
let result = lowercase2 ? input.toLowerCase() : input;
|
|
9742
|
+
if (options.allow) {
|
|
9743
|
+
const pattern = new RegExp(`[^${options.allow.source.slice(1, -1)}]+`, "g");
|
|
9744
|
+
result = result.replace(pattern, replacement);
|
|
9745
|
+
} else if (options.deny) {
|
|
9746
|
+
result = result.replace(options.deny, replacement);
|
|
9747
|
+
}
|
|
9748
|
+
if (collapse) {
|
|
9749
|
+
const escaped = escapeRegExp(replacement);
|
|
9750
|
+
result = result.replace(new RegExp(`${escaped}+`, "g"), replacement);
|
|
9751
|
+
}
|
|
9752
|
+
if (trim) {
|
|
9753
|
+
const escaped = escapeRegExp(replacement);
|
|
9754
|
+
result = result.replace(new RegExp(`^${escaped}+|${escaped}+$`, "g"), "");
|
|
9755
|
+
}
|
|
9756
|
+
if (fallback !== undefined && result.length === 0) {
|
|
9757
|
+
return fallback;
|
|
9758
|
+
}
|
|
9759
|
+
return result;
|
|
9760
|
+
}
|
|
9761
|
+
function escapeRegExp(s) {
|
|
9762
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9763
|
+
}
|
|
9764
|
+
|
|
9765
|
+
// src/util/text.ts
|
|
9766
|
+
function truncateText(text, maxLength, ellipsis = "…") {
|
|
9767
|
+
if (text.length <= maxLength)
|
|
9768
|
+
return text;
|
|
9769
|
+
return text.slice(0, maxLength - ellipsis.length) + ellipsis;
|
|
9770
|
+
}
|
|
9771
|
+
function escapeForDoubleQuotes(input) {
|
|
9772
|
+
return input.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
9773
|
+
}
|
|
9774
|
+
function quoteIfNeeded(input) {
|
|
9775
|
+
return `"${escapeForDoubleQuotes(input)}"`;
|
|
9776
|
+
}
|
|
9777
|
+
|
|
9716
9778
|
// src/commands/workspace-name.ts
|
|
9717
9779
|
function sanitizeWorkspaceName(input, fallback = "workspace") {
|
|
9718
|
-
|
|
9719
|
-
|
|
9780
|
+
return sanitizeString(input.trim(), {
|
|
9781
|
+
allow: /[a-zA-Z0-9._-]/,
|
|
9782
|
+
replacement: "-",
|
|
9783
|
+
trim: true,
|
|
9784
|
+
fallback
|
|
9785
|
+
});
|
|
9720
9786
|
}
|
|
9721
9787
|
function allocateWorkspaceName(base, existing) {
|
|
9722
9788
|
if (!Object.prototype.hasOwnProperty.call(existing, base))
|
|
@@ -9732,13 +9798,11 @@ function isWorkspaceNameValid(input) {
|
|
|
9732
9798
|
function quoteWorkspaceNameIfNeeded(input) {
|
|
9733
9799
|
if (isWorkspaceNameValid(input))
|
|
9734
9800
|
return input;
|
|
9735
|
-
return
|
|
9801
|
+
return quoteIfNeeded(input);
|
|
9736
9802
|
}
|
|
9737
|
-
var VALID_WORKSPACE_NAME_RE
|
|
9803
|
+
var VALID_WORKSPACE_NAME_RE;
|
|
9738
9804
|
var init_workspace_name = __esm(() => {
|
|
9739
9805
|
VALID_WORKSPACE_NAME_RE = /^[a-zA-Z0-9._-]+$/;
|
|
9740
|
-
UNSAFE_RUN_RE = /[^a-zA-Z0-9._-]+/g;
|
|
9741
|
-
TRIM_DASHES_RE = /^-+|-+$/g;
|
|
9742
9806
|
});
|
|
9743
9807
|
|
|
9744
9808
|
// src/orchestration/orchestration-types.ts
|
|
@@ -10288,7 +10352,7 @@ function renderLaterList(tasks, displaySession) {
|
|
|
10288
10352
|
`).trimEnd();
|
|
10289
10353
|
}
|
|
10290
10354
|
function preview(text) {
|
|
10291
|
-
return text
|
|
10355
|
+
return truncateText(text, LATER_MESSAGE_PREVIEW_CHARS);
|
|
10292
10356
|
}
|
|
10293
10357
|
function formatLocalDateTime(date4) {
|
|
10294
10358
|
const weekdays = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
|
|
@@ -10434,7 +10498,10 @@ class ScheduledTaskService {
|
|
|
10434
10498
|
}
|
|
10435
10499
|
nextId() {
|
|
10436
10500
|
for (let attempt = 0;attempt < 20; attempt += 1) {
|
|
10437
|
-
const id = normalizeId(this.generateId())
|
|
10501
|
+
const id = sanitizeString(normalizeId(this.generateId()), {
|
|
10502
|
+
allow: /[0-9a-z]/,
|
|
10503
|
+
replacement: ""
|
|
10504
|
+
}).slice(0, 6);
|
|
10438
10505
|
if (id.length >= 4 && !this.state.scheduled_tasks[id])
|
|
10439
10506
|
return id;
|
|
10440
10507
|
}
|
|
@@ -10448,12 +10515,16 @@ class ScheduledTaskService {
|
|
|
10448
10515
|
}
|
|
10449
10516
|
}
|
|
10450
10517
|
function normalizeId(input) {
|
|
10451
|
-
return input.trim()
|
|
10518
|
+
return sanitizeString(input.trim(), {
|
|
10519
|
+
deny: /^#/,
|
|
10520
|
+
replacement: "",
|
|
10521
|
+
lowercase: true
|
|
10522
|
+
});
|
|
10452
10523
|
}
|
|
10453
10524
|
var init_scheduled_service = () => {};
|
|
10454
10525
|
|
|
10455
10526
|
// src/plugins/plugin-home.ts
|
|
10456
|
-
import { mkdir as mkdir6, writeFile as writeFile4 } from "node:fs/promises";
|
|
10527
|
+
import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile4 } from "node:fs/promises";
|
|
10457
10528
|
import { homedir as homedir3 } from "node:os";
|
|
10458
10529
|
import { join as join3 } from "node:path";
|
|
10459
10530
|
function coerceMissing(value) {
|
|
@@ -10477,6 +10548,27 @@ function resolvePluginHome(input = {}) {
|
|
|
10477
10548
|
const home = coerceMissing(input.home) ?? coerceMissing(process.env.HOME) ?? homedir3();
|
|
10478
10549
|
return join3(home, ".weacpx", "plugins");
|
|
10479
10550
|
}
|
|
10551
|
+
async function normalizePluginHomeManifest(pluginHome) {
|
|
10552
|
+
const manifestPath = join3(pluginHome, "package.json");
|
|
10553
|
+
let raw;
|
|
10554
|
+
try {
|
|
10555
|
+
raw = await readFile6(manifestPath, "utf8");
|
|
10556
|
+
} catch {
|
|
10557
|
+
return false;
|
|
10558
|
+
}
|
|
10559
|
+
let parsed;
|
|
10560
|
+
try {
|
|
10561
|
+
parsed = JSON.parse(raw);
|
|
10562
|
+
} catch {
|
|
10563
|
+
return false;
|
|
10564
|
+
}
|
|
10565
|
+
const normalized = JSON.stringify(parsed, null, 2) + `
|
|
10566
|
+
`;
|
|
10567
|
+
if (normalized === raw)
|
|
10568
|
+
return false;
|
|
10569
|
+
await writeFile4(manifestPath, normalized, { mode: 384 });
|
|
10570
|
+
return true;
|
|
10571
|
+
}
|
|
10480
10572
|
async function ensurePluginHome(pluginHome) {
|
|
10481
10573
|
await mkdir6(pluginHome, { recursive: true, mode: 448 });
|
|
10482
10574
|
await writeFile4(join3(pluginHome, "package.json"), JSON.stringify({ private: true, type: "module" }, null, 2) + `
|
|
@@ -10515,7 +10607,11 @@ var init_state_dir = () => {};
|
|
|
10515
10607
|
import fs3 from "node:fs";
|
|
10516
10608
|
import path4 from "node:path";
|
|
10517
10609
|
function normalizeAccountId(raw) {
|
|
10518
|
-
return raw.trim()
|
|
10610
|
+
return sanitizeString(raw.trim(), {
|
|
10611
|
+
deny: /[@.]/g,
|
|
10612
|
+
replacement: "-",
|
|
10613
|
+
lowercase: true
|
|
10614
|
+
});
|
|
10519
10615
|
}
|
|
10520
10616
|
function deriveRawAccountId(normalizedId) {
|
|
10521
10617
|
if (normalizedId.endsWith("-im-bot")) {
|
|
@@ -13024,16 +13120,24 @@ class RuntimeMediaStore {
|
|
|
13024
13120
|
}
|
|
13025
13121
|
function sanitizeMediaFileName(fileName, mimeType) {
|
|
13026
13122
|
const base = path7.basename(fileName.trim() || "attachment");
|
|
13027
|
-
const
|
|
13028
|
-
|
|
13123
|
+
const safe = sanitizeString(base, {
|
|
13124
|
+
deny: /[\\/:*?"<>|\s]+/g,
|
|
13125
|
+
replacement: "-",
|
|
13126
|
+
trim: true,
|
|
13127
|
+
fallback: "attachment"
|
|
13128
|
+
});
|
|
13029
13129
|
const ext = path7.extname(safe);
|
|
13030
13130
|
if (ext)
|
|
13031
13131
|
return safe;
|
|
13032
13132
|
return `${safe}${extensionFromMime(mimeType)}`;
|
|
13033
13133
|
}
|
|
13034
13134
|
function safePathSegment(value) {
|
|
13035
|
-
|
|
13036
|
-
|
|
13135
|
+
return sanitizeString(value, {
|
|
13136
|
+
allow: /[A-Za-z0-9._-]/,
|
|
13137
|
+
replacement: "_",
|
|
13138
|
+
trim: true,
|
|
13139
|
+
fallback: "unknown"
|
|
13140
|
+
});
|
|
13037
13141
|
}
|
|
13038
13142
|
async function uniqueFileName(dir, baseName) {
|
|
13039
13143
|
const ext = path7.extname(baseName);
|
|
@@ -16021,7 +16125,7 @@ var init_scheduled_turn = __esm(() => {
|
|
|
16021
16125
|
});
|
|
16022
16126
|
|
|
16023
16127
|
// src/weixin/monitor/consumer-lock.ts
|
|
16024
|
-
import { mkdir as mkdir8, open as open3, readFile as
|
|
16128
|
+
import { mkdir as mkdir8, open as open3, readFile as readFile7, rm as rm6 } from "node:fs/promises";
|
|
16025
16129
|
import { dirname as dirname8, join as join5 } from "node:path";
|
|
16026
16130
|
import { homedir as homedir4 } from "node:os";
|
|
16027
16131
|
function createWeixinConsumerLock(options = {}) {
|
|
@@ -16103,7 +16207,7 @@ function createWeixinConsumerLock(options = {}) {
|
|
|
16103
16207
|
}
|
|
16104
16208
|
async function loadLockMetadata(path14) {
|
|
16105
16209
|
try {
|
|
16106
|
-
const raw = await
|
|
16210
|
+
const raw = await readFile7(path14, "utf8");
|
|
16107
16211
|
const parsed = JSON.parse(raw);
|
|
16108
16212
|
if (!parsed || typeof parsed.pid !== "number" || !parsed.mode || !parsed.configPath || !parsed.statePath) {
|
|
16109
16213
|
return null;
|
|
@@ -16785,7 +16889,7 @@ var init_app_logger = __esm(() => {
|
|
|
16785
16889
|
});
|
|
16786
16890
|
|
|
16787
16891
|
// src/transport/acpx-session-index.ts
|
|
16788
|
-
import { readFile as
|
|
16892
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
16789
16893
|
import { homedir as homedir5 } from "node:os";
|
|
16790
16894
|
import { resolve as resolve2 } from "node:path";
|
|
16791
16895
|
async function resolveSessionAgentCommandFromIndex(session) {
|
|
@@ -16794,7 +16898,7 @@ async function resolveSessionAgentCommandFromIndex(session) {
|
|
|
16794
16898
|
return;
|
|
16795
16899
|
}
|
|
16796
16900
|
try {
|
|
16797
|
-
const raw = await
|
|
16901
|
+
const raw = await readFile11(resolve2(home, ".acpx", "sessions", "index.json"), "utf8");
|
|
16798
16902
|
const parsed = JSON.parse(raw);
|
|
16799
16903
|
const targetCwd = resolve2(session.cwd);
|
|
16800
16904
|
const match = parsed.entries?.find((entry) => entry.name === session.transportSession && entry.cwd === targetCwd && typeof entry.agentCommand === "string" && entry.agentCommand.trim().length > 0);
|
|
@@ -18295,7 +18399,7 @@ async function buildCoordinatorPrompt(input) {
|
|
|
18295
18399
|
|
|
18296
18400
|
`) : input.userText ?? "";
|
|
18297
18401
|
if (input.maxPromptLength && promptText.length > input.maxPromptLength) {
|
|
18298
|
-
promptText = promptText
|
|
18402
|
+
promptText = truncateText(promptText, input.maxPromptLength, "...");
|
|
18299
18403
|
}
|
|
18300
18404
|
return {
|
|
18301
18405
|
promptText,
|
|
@@ -19788,6 +19892,27 @@ function handleHelp(topic) {
|
|
|
19788
19892
|
}
|
|
19789
19893
|
return { text: renderHelpTopic(entry) };
|
|
19790
19894
|
}
|
|
19895
|
+
function handleInvalidCommand(recognizedCommand) {
|
|
19896
|
+
const topicName = recognizedCommand.replace(/^\//, "");
|
|
19897
|
+
const entry = getHelpTopic(topicName);
|
|
19898
|
+
if (entry) {
|
|
19899
|
+
return { text: `命令格式不正确,请参考下面的用法:
|
|
19900
|
+
|
|
19901
|
+
${renderHelpTopic(entry)}` };
|
|
19902
|
+
}
|
|
19903
|
+
return {
|
|
19904
|
+
text: [
|
|
19905
|
+
"无法识别的命令格式。",
|
|
19906
|
+
"",
|
|
19907
|
+
"正确的会话创建格式:",
|
|
19908
|
+
"/session new <别名> --agent <Agent名> --ws <工作区名>",
|
|
19909
|
+
"",
|
|
19910
|
+
"例如:",
|
|
19911
|
+
"/session new demo --agent claude --ws weacpx"
|
|
19912
|
+
].join(`
|
|
19913
|
+
`)
|
|
19914
|
+
};
|
|
19915
|
+
}
|
|
19791
19916
|
function renderHelpIndex() {
|
|
19792
19917
|
const topics = listHelpTopics();
|
|
19793
19918
|
return [
|
|
@@ -20925,18 +21050,7 @@ class CommandRouter {
|
|
|
20925
21050
|
return await this.executeCommand(chatKey, command.kind, startedAt, async () => {
|
|
20926
21051
|
switch (command.kind) {
|
|
20927
21052
|
case "invalid":
|
|
20928
|
-
return
|
|
20929
|
-
text: [
|
|
20930
|
-
"无法识别的命令格式。",
|
|
20931
|
-
"",
|
|
20932
|
-
"正确的会话创建格式:",
|
|
20933
|
-
"/session new <别名> --agent <Agent名> --ws <工作区名>",
|
|
20934
|
-
"",
|
|
20935
|
-
"例如:",
|
|
20936
|
-
"/session new demo --agent claude --ws weacpx"
|
|
20937
|
-
].join(`
|
|
20938
|
-
`)
|
|
20939
|
-
};
|
|
21053
|
+
return handleInvalidCommand(command.recognizedCommand);
|
|
20940
21054
|
case "help":
|
|
20941
21055
|
return handleHelp(command.topic);
|
|
20942
21056
|
case "agents":
|
|
@@ -24588,7 +24702,11 @@ class OrchestrationService {
|
|
|
24588
24702
|
}
|
|
24589
24703
|
workspaceLabelFromCwd(cwd) {
|
|
24590
24704
|
const base = basename2(cwd).trim() || "cwd";
|
|
24591
|
-
return base
|
|
24705
|
+
return sanitizeString(base, {
|
|
24706
|
+
allow: /[a-zA-Z0-9._-]/,
|
|
24707
|
+
replacement: "_",
|
|
24708
|
+
fallback: "cwd"
|
|
24709
|
+
});
|
|
24592
24710
|
}
|
|
24593
24711
|
cwdWorkerSessionPart(cwd) {
|
|
24594
24712
|
const label = this.workspaceLabelFromCwd(cwd);
|
|
@@ -26185,6 +26303,37 @@ class DebouncedStateStore {
|
|
|
26185
26303
|
}
|
|
26186
26304
|
}
|
|
26187
26305
|
|
|
26306
|
+
// src/commands/command-hints.ts
|
|
26307
|
+
function listWeacpxCommandHints() {
|
|
26308
|
+
const hints = [{ name: "/help", description: "查看命令帮助。" }];
|
|
26309
|
+
for (const topic of HELP_TOPICS) {
|
|
26310
|
+
const name = PRIMARY_COMMAND_BY_TOPIC[topic.topic];
|
|
26311
|
+
if (!name) {
|
|
26312
|
+
throw new Error(`command-hints: 未登记 help topic 的主命令: ${topic.topic}`);
|
|
26313
|
+
}
|
|
26314
|
+
hints.push({ name, description: topic.summary });
|
|
26315
|
+
}
|
|
26316
|
+
return hints;
|
|
26317
|
+
}
|
|
26318
|
+
var PRIMARY_COMMAND_BY_TOPIC;
|
|
26319
|
+
var init_command_hints = __esm(() => {
|
|
26320
|
+
init_help_registry();
|
|
26321
|
+
PRIMARY_COMMAND_BY_TOPIC = {
|
|
26322
|
+
session: "/session",
|
|
26323
|
+
native: "/ssn",
|
|
26324
|
+
workspace: "/workspace",
|
|
26325
|
+
agent: "/agent",
|
|
26326
|
+
permission: "/permission",
|
|
26327
|
+
config: "/config",
|
|
26328
|
+
orchestration: "/delegate",
|
|
26329
|
+
mode: "/mode",
|
|
26330
|
+
replymode: "/replymode",
|
|
26331
|
+
status: "/status",
|
|
26332
|
+
cancel: "/cancel",
|
|
26333
|
+
later: "/later"
|
|
26334
|
+
};
|
|
26335
|
+
});
|
|
26336
|
+
|
|
26188
26337
|
// src/run-console.ts
|
|
26189
26338
|
var exports_run_console = {};
|
|
26190
26339
|
__export(exports_run_console, {
|
|
@@ -26299,7 +26448,9 @@ async function runConsole(paths, deps) {
|
|
|
26299
26448
|
abortSignal: shutdownController.signal,
|
|
26300
26449
|
quota: runtime.quota,
|
|
26301
26450
|
logger: runtime.logger,
|
|
26302
|
-
perfTracer: runtime.perfTracer
|
|
26451
|
+
perfTracer: runtime.perfTracer,
|
|
26452
|
+
commandHints: listWeacpxCommandHints(),
|
|
26453
|
+
coreVersion: WEACPX_CORE_VERSION
|
|
26303
26454
|
});
|
|
26304
26455
|
channelStartPromise.catch(() => {});
|
|
26305
26456
|
let channelStartSettled = false;
|
|
@@ -26417,6 +26568,8 @@ async function runCleanupSequence(input) {
|
|
|
26417
26568
|
}
|
|
26418
26569
|
var init_run_console = __esm(() => {
|
|
26419
26570
|
init_consumer_lock();
|
|
26571
|
+
init_command_hints();
|
|
26572
|
+
init_version();
|
|
26420
26573
|
});
|
|
26421
26574
|
|
|
26422
26575
|
// src/transport/acpx-bridge/acpx-bridge-protocol.ts
|
|
@@ -27473,7 +27626,7 @@ var init_node_pty_helper = () => {};
|
|
|
27473
27626
|
// src/transport/acpx-queue-owner-launcher.ts
|
|
27474
27627
|
import { createHash as createHash3 } from "node:crypto";
|
|
27475
27628
|
import { spawn as spawn8 } from "node:child_process";
|
|
27476
|
-
import { readFile as
|
|
27629
|
+
import { readFile as readFile12, unlink } from "node:fs/promises";
|
|
27477
27630
|
import { homedir as homedir8 } from "node:os";
|
|
27478
27631
|
import { join as join13 } from "node:path";
|
|
27479
27632
|
function buildWeacpxMcpServerSpec(input) {
|
|
@@ -27629,7 +27782,7 @@ async function terminateAcpxQueueOwner(sessionId) {
|
|
|
27629
27782
|
const lockPath = queueLockFilePath(sessionId);
|
|
27630
27783
|
let owner;
|
|
27631
27784
|
try {
|
|
27632
|
-
owner = JSON.parse(await
|
|
27785
|
+
owner = JSON.parse(await readFile12(lockPath, "utf8"));
|
|
27633
27786
|
} catch {
|
|
27634
27787
|
return;
|
|
27635
27788
|
}
|
|
@@ -27657,7 +27810,7 @@ function resolveDefaultWeacpxCommand(env) {
|
|
|
27657
27810
|
return "weacpx";
|
|
27658
27811
|
}
|
|
27659
27812
|
function quoteCommandPart(value) {
|
|
27660
|
-
return
|
|
27813
|
+
return quoteIfNeeded(value);
|
|
27661
27814
|
}
|
|
27662
27815
|
var init_acpx_queue_owner_launcher = __esm(() => {
|
|
27663
27816
|
init_spawn_command();
|
|
@@ -27677,7 +27830,6 @@ function permissionModeToFlag(permissionMode) {
|
|
|
27677
27830
|
}
|
|
27678
27831
|
|
|
27679
27832
|
// src/transport/agent-session-list.ts
|
|
27680
|
-
import path15 from "node:path";
|
|
27681
27833
|
function isUnknownFilterCwdOption(output) {
|
|
27682
27834
|
return /(?:unknown|unrecognized) option/i.test(output) && output.includes("--filter-cwd");
|
|
27683
27835
|
}
|
|
@@ -27724,27 +27876,12 @@ function isAgentSessionListResult(value) {
|
|
|
27724
27876
|
function filterAgentSessionListByCwd(result, cwd) {
|
|
27725
27877
|
return {
|
|
27726
27878
|
...result,
|
|
27727
|
-
sessions: result.sessions.filter((session) => session.cwd &&
|
|
27879
|
+
sessions: result.sessions.filter((session) => session.cwd && isSamePath(session.cwd, cwd))
|
|
27728
27880
|
};
|
|
27729
27881
|
}
|
|
27730
|
-
|
|
27731
|
-
|
|
27732
|
-
|
|
27733
|
-
if (isWindowsLikePath2(normalizedLeft) || isWindowsLikePath2(normalizedRight)) {
|
|
27734
|
-
return normalizedLeft.toLowerCase() === normalizedRight.toLowerCase();
|
|
27735
|
-
}
|
|
27736
|
-
return normalizedLeft === normalizedRight;
|
|
27737
|
-
}
|
|
27738
|
-
function normalizeAgentSessionCwd(input) {
|
|
27739
|
-
if (isWindowsLikePath2(input)) {
|
|
27740
|
-
return path15.win32.normalize(input).replace(/\\/g, "/");
|
|
27741
|
-
}
|
|
27742
|
-
return path15.posix.normalize(input.replace(/\\/g, "/"));
|
|
27743
|
-
}
|
|
27744
|
-
function isWindowsLikePath2(input) {
|
|
27745
|
-
return /^[a-zA-Z]:[\\/]/.test(input) || input.startsWith("\\\\");
|
|
27746
|
-
}
|
|
27747
|
-
var init_agent_session_list = () => {};
|
|
27882
|
+
var init_agent_session_list = __esm(() => {
|
|
27883
|
+
init_path();
|
|
27884
|
+
});
|
|
27748
27885
|
|
|
27749
27886
|
// src/transport/acpx-cli/acpx-cli-transport.ts
|
|
27750
27887
|
import { createRequire as createRequire5 } from "node:module";
|
|
@@ -28263,6 +28400,30 @@ var init_acpx_cli_transport = __esm(() => {
|
|
|
28263
28400
|
require4 = createRequire5(import.meta.url);
|
|
28264
28401
|
});
|
|
28265
28402
|
|
|
28403
|
+
// src/util/async.ts
|
|
28404
|
+
function settleWithinTimeout(work, timeoutMs) {
|
|
28405
|
+
return new Promise((resolve3) => {
|
|
28406
|
+
let settled = false;
|
|
28407
|
+
const finish = () => {
|
|
28408
|
+
if (!settled) {
|
|
28409
|
+
settled = true;
|
|
28410
|
+
resolve3();
|
|
28411
|
+
}
|
|
28412
|
+
};
|
|
28413
|
+
const timer = setTimeout(finish, timeoutMs);
|
|
28414
|
+
if (typeof timer.unref === "function") {
|
|
28415
|
+
timer.unref();
|
|
28416
|
+
}
|
|
28417
|
+
work.then(() => {
|
|
28418
|
+
clearTimeout(timer);
|
|
28419
|
+
finish();
|
|
28420
|
+
}, () => {
|
|
28421
|
+
clearTimeout(timer);
|
|
28422
|
+
finish();
|
|
28423
|
+
});
|
|
28424
|
+
});
|
|
28425
|
+
}
|
|
28426
|
+
|
|
28266
28427
|
// src/transport/queue-owner-reaper.ts
|
|
28267
28428
|
import { spawn as spawn10 } from "node:child_process";
|
|
28268
28429
|
async function reapQueueOwners(acpxCommand, targets, deps = {}) {
|
|
@@ -28293,28 +28454,6 @@ async function reapQueueOwners(acpxCommand, targets, deps = {}) {
|
|
|
28293
28454
|
await settleWithinTimeout(Promise.all(unique.map(reapOne)), timeoutMs);
|
|
28294
28455
|
return { terminated, attempted: unique.length };
|
|
28295
28456
|
}
|
|
28296
|
-
function settleWithinTimeout(work, timeoutMs) {
|
|
28297
|
-
return new Promise((resolve3) => {
|
|
28298
|
-
let settled = false;
|
|
28299
|
-
const finish = () => {
|
|
28300
|
-
if (!settled) {
|
|
28301
|
-
settled = true;
|
|
28302
|
-
resolve3();
|
|
28303
|
-
}
|
|
28304
|
-
};
|
|
28305
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
28306
|
-
if (typeof timer.unref === "function") {
|
|
28307
|
-
timer.unref();
|
|
28308
|
-
}
|
|
28309
|
-
work.then(() => {
|
|
28310
|
-
clearTimeout(timer);
|
|
28311
|
-
finish();
|
|
28312
|
-
}, () => {
|
|
28313
|
-
clearTimeout(timer);
|
|
28314
|
-
finish();
|
|
28315
|
-
});
|
|
28316
|
-
});
|
|
28317
|
-
}
|
|
28318
28457
|
async function defaultResolveRecordId(acpxCommand, target) {
|
|
28319
28458
|
const args = [
|
|
28320
28459
|
"--format",
|
|
@@ -29651,107 +29790,107 @@ async function checkRuntime(options = {}) {
|
|
|
29651
29790
|
}
|
|
29652
29791
|
function createRuntimeFsProbe() {
|
|
29653
29792
|
return {
|
|
29654
|
-
stat: async (
|
|
29655
|
-
access: async (
|
|
29793
|
+
stat: async (path15) => await stat3(path15),
|
|
29794
|
+
access: async (path15, mode) => await access4(path15, mode)
|
|
29656
29795
|
};
|
|
29657
29796
|
}
|
|
29658
|
-
async function checkDirectoryCreatable(label,
|
|
29797
|
+
async function checkDirectoryCreatable(label, path15, probe, platform) {
|
|
29659
29798
|
try {
|
|
29660
|
-
const stats = await probe.stat(
|
|
29799
|
+
const stats = await probe.stat(path15);
|
|
29661
29800
|
if (!stats.isDirectory()) {
|
|
29662
29801
|
return {
|
|
29663
29802
|
ok: false,
|
|
29664
|
-
detail: `${label}: ${
|
|
29803
|
+
detail: `${label}: ${path15} (exists but is not a directory)`
|
|
29665
29804
|
};
|
|
29666
29805
|
}
|
|
29667
|
-
await probe.access(
|
|
29806
|
+
await probe.access(path15, directoryAccessMode(platform));
|
|
29668
29807
|
return {
|
|
29669
29808
|
ok: true,
|
|
29670
|
-
detail: `${label}: ${
|
|
29809
|
+
detail: `${label}: ${path15} (writable)`
|
|
29671
29810
|
};
|
|
29672
29811
|
} catch (error2) {
|
|
29673
29812
|
if (!isMissingPathError(error2)) {
|
|
29674
29813
|
return {
|
|
29675
29814
|
ok: false,
|
|
29676
|
-
detail: `${label}: ${
|
|
29815
|
+
detail: `${label}: ${path15} (unusable: ${formatError6(error2)})`
|
|
29677
29816
|
};
|
|
29678
29817
|
}
|
|
29679
|
-
const parentCheck = await checkCreatableAncestorDirectory(
|
|
29818
|
+
const parentCheck = await checkCreatableAncestorDirectory(path15, probe, platform);
|
|
29680
29819
|
if (!parentCheck.ok) {
|
|
29681
29820
|
return {
|
|
29682
29821
|
ok: false,
|
|
29683
|
-
detail: `${label}: ${
|
|
29822
|
+
detail: `${label}: ${path15} (parent not writable: ${parentCheck.blockingPath})`
|
|
29684
29823
|
};
|
|
29685
29824
|
}
|
|
29686
29825
|
return {
|
|
29687
29826
|
ok: true,
|
|
29688
|
-
detail: `${label}: ${
|
|
29827
|
+
detail: `${label}: ${path15} (creatable via ${parentCheck.creatableFrom})`
|
|
29689
29828
|
};
|
|
29690
29829
|
}
|
|
29691
29830
|
}
|
|
29692
|
-
async function checkFileCreatable(label,
|
|
29831
|
+
async function checkFileCreatable(label, path15, probe, platform) {
|
|
29693
29832
|
try {
|
|
29694
|
-
const stats = await probe.stat(
|
|
29833
|
+
const stats = await probe.stat(path15);
|
|
29695
29834
|
if (stats.isDirectory()) {
|
|
29696
29835
|
return {
|
|
29697
29836
|
ok: false,
|
|
29698
|
-
detail: `${label}: ${
|
|
29837
|
+
detail: `${label}: ${path15} (exists but is a directory)`
|
|
29699
29838
|
};
|
|
29700
29839
|
}
|
|
29701
|
-
await probe.access(
|
|
29840
|
+
await probe.access(path15, constants.W_OK);
|
|
29702
29841
|
return {
|
|
29703
29842
|
ok: true,
|
|
29704
|
-
detail: `${label}: ${
|
|
29843
|
+
detail: `${label}: ${path15} (writable)`
|
|
29705
29844
|
};
|
|
29706
29845
|
} catch (error2) {
|
|
29707
29846
|
if (!isMissingPathError(error2)) {
|
|
29708
29847
|
return {
|
|
29709
29848
|
ok: false,
|
|
29710
|
-
detail: `${label}: ${
|
|
29849
|
+
detail: `${label}: ${path15} (unusable: ${formatError6(error2)})`
|
|
29711
29850
|
};
|
|
29712
29851
|
}
|
|
29713
|
-
const parentCheck = await checkCreatableAncestorDirectory(dirname14(
|
|
29852
|
+
const parentCheck = await checkCreatableAncestorDirectory(dirname14(path15), probe, platform);
|
|
29714
29853
|
if (!parentCheck.ok) {
|
|
29715
29854
|
return {
|
|
29716
29855
|
ok: false,
|
|
29717
|
-
detail: `${label}: ${
|
|
29856
|
+
detail: `${label}: ${path15} (parent not writable: ${parentCheck.blockingPath})`
|
|
29718
29857
|
};
|
|
29719
29858
|
}
|
|
29720
29859
|
return {
|
|
29721
29860
|
ok: true,
|
|
29722
|
-
detail: `${label}: ${
|
|
29861
|
+
detail: `${label}: ${path15} (creatable via ${parentCheck.creatableFrom})`
|
|
29723
29862
|
};
|
|
29724
29863
|
}
|
|
29725
29864
|
}
|
|
29726
|
-
async function checkCreatableAncestorDirectory(
|
|
29865
|
+
async function checkCreatableAncestorDirectory(path15, probe, platform) {
|
|
29727
29866
|
try {
|
|
29728
|
-
const stats = await probe.stat(
|
|
29867
|
+
const stats = await probe.stat(path15);
|
|
29729
29868
|
if (!stats.isDirectory()) {
|
|
29730
29869
|
return {
|
|
29731
29870
|
ok: false,
|
|
29732
|
-
creatableFrom:
|
|
29733
|
-
blockingPath:
|
|
29871
|
+
creatableFrom: path15,
|
|
29872
|
+
blockingPath: path15
|
|
29734
29873
|
};
|
|
29735
29874
|
}
|
|
29736
|
-
await probe.access(
|
|
29875
|
+
await probe.access(path15, directoryAccessMode(platform));
|
|
29737
29876
|
return {
|
|
29738
29877
|
ok: true,
|
|
29739
|
-
creatableFrom:
|
|
29878
|
+
creatableFrom: path15
|
|
29740
29879
|
};
|
|
29741
29880
|
} catch (error2) {
|
|
29742
29881
|
if (!isMissingPathError(error2)) {
|
|
29743
29882
|
return {
|
|
29744
29883
|
ok: false,
|
|
29745
|
-
creatableFrom:
|
|
29746
|
-
blockingPath:
|
|
29884
|
+
creatableFrom: path15,
|
|
29885
|
+
blockingPath: path15
|
|
29747
29886
|
};
|
|
29748
29887
|
}
|
|
29749
|
-
const parent = dirname14(
|
|
29750
|
-
if (parent ===
|
|
29888
|
+
const parent = dirname14(path15);
|
|
29889
|
+
if (parent === path15) {
|
|
29751
29890
|
return {
|
|
29752
29891
|
ok: false,
|
|
29753
|
-
creatableFrom:
|
|
29754
|
-
blockingPath:
|
|
29892
|
+
creatableFrom: path15,
|
|
29893
|
+
blockingPath: path15
|
|
29755
29894
|
};
|
|
29756
29895
|
}
|
|
29757
29896
|
const parentCheck = await checkCreatableAncestorDirectory(parent, probe, platform);
|
|
@@ -42853,16 +42992,15 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
42853
42992
|
},
|
|
42854
42993
|
{
|
|
42855
42994
|
name: "task_get",
|
|
42856
|
-
description: "Fetch a single task under the current coordinator,
|
|
42995
|
+
description: "Fetch a single task under the current coordinator: its summary, latest progress, and — once terminal — the worker's final result. Prefer task_watch to follow a task; its terminal result already carries the output, so a follow-up task_get is unnecessary. Reach for task_get to recover a task you lost track of, to inspect one that requires attention, or to re-read the original delegated prompt. The full prompt is included only for needs_confirmation tasks unless you pass includePrompt:true.",
|
|
42857
42996
|
inputSchema: exports_external.object({
|
|
42858
|
-
taskId: exports_external.string().min(1)
|
|
42997
|
+
taskId: exports_external.string().min(1),
|
|
42998
|
+
includePrompt: exports_external.boolean().optional()
|
|
42859
42999
|
}).strict(),
|
|
42860
43000
|
handler: async (args) => await asToolResult(async () => {
|
|
42861
|
-
const
|
|
42862
|
-
|
|
42863
|
-
|
|
42864
|
-
});
|
|
42865
|
-
return createSuccessResult(task ? renderTaskSummary(task) : "Task not found.", { task });
|
|
43001
|
+
const { taskId, includePrompt } = args;
|
|
43002
|
+
const task = await transport.getTask({ coordinatorSession, taskId });
|
|
43003
|
+
return createSuccessResult(task ? renderTaskSummary(task, { includePrompt: includePrompt ?? false }) : "Task not found.", { task });
|
|
42866
43004
|
})
|
|
42867
43005
|
},
|
|
42868
43006
|
{
|
|
@@ -43101,12 +43239,23 @@ function renderTaskWatchResult(result) {
|
|
|
43101
43239
|
const events = result.events.length > 0 ? [
|
|
43102
43240
|
"- Events:",
|
|
43103
43241
|
...result.events.map((event) => {
|
|
43104
|
-
const
|
|
43105
|
-
return ` - #${event.seq} ${event.type} at ${event.at}${
|
|
43242
|
+
const detail2 = event.summary ?? event.message ?? event.status ?? "";
|
|
43243
|
+
return ` - #${event.seq} ${event.type} at ${event.at}${detail2 ? `: ${detail2}` : ""}`;
|
|
43106
43244
|
})
|
|
43107
43245
|
] : ["- Events: none"];
|
|
43108
|
-
const
|
|
43109
|
-
|
|
43246
|
+
const detail = [];
|
|
43247
|
+
if (result.status === "terminal") {
|
|
43248
|
+
const resultText = result.task.resultText?.trim() ?? "";
|
|
43249
|
+
const summary = result.task.summary?.trim() ?? "";
|
|
43250
|
+
if (resultText.length > 0)
|
|
43251
|
+
detail.push(`- Result: ${resultText}`);
|
|
43252
|
+
else if (summary.length > 0)
|
|
43253
|
+
detail.push(`- Summary: ${summary}`);
|
|
43254
|
+
} else if (result.status === "attention_required" && result.task.openQuestion) {
|
|
43255
|
+
detail.push(`- Open question: ${result.task.openQuestion.question}`);
|
|
43256
|
+
}
|
|
43257
|
+
const next = result.status === "terminal" ? "Next: summarize this result for the user." : result.status === "attention_required" ? "Next: resolve the pending question / contested review with the recommended action tool (coordinator_answer_question or coordinator_review_contested_result); call task_get only if you need more detail." : `Next: call task_watch again with afterSeq=${result.nextAfterSeq} to keep watching, preferably as an MCP task if your client supports background task execution.`;
|
|
43258
|
+
return [...header, ...events, ...detail, next].join(`
|
|
43110
43259
|
`);
|
|
43111
43260
|
}
|
|
43112
43261
|
function createSuccessResult(text, structuredContent) {
|
|
@@ -43122,7 +43271,7 @@ function createErrorResult(message) {
|
|
|
43122
43271
|
};
|
|
43123
43272
|
}
|
|
43124
43273
|
function renderDelegateSuccess(result) {
|
|
43125
|
-
const next = result.status === "needs_confirmation" ? `Next: this delegation requires user approval. Tell the user, then call task_approve or task_cancel based on their response.` : result.status === "queued" ? `Next: task "${result.taskId}" is queued (agent at parallel capacity). It will start automatically when a slot frees. Call task_watch to long-poll
|
|
43274
|
+
const next = result.status === "needs_confirmation" ? `Next: this delegation requires user approval. Tell the user, then call task_approve or task_cancel based on their response.` : result.status === "queued" ? `Next: task "${result.taskId}" is queued (agent at parallel capacity). It will start automatically when a slot frees. Call task_watch to long-poll until it runs and then finishes — the terminal watch carries the result. Use task_list only to resurvey in-flight tasks.` : `Next: task "${result.taskId}" is running. Return this taskId to the user, then call task_watch to long-poll until it finishes — the terminal watch carries the worker's result, so no follow-up task_get is needed. Use task_list only to resurvey in-flight tasks.`;
|
|
43126
43275
|
return [`Delegation task "${result.taskId}" created.`, `- Status: ${result.status}`, next].join(`
|
|
43127
43276
|
`);
|
|
43128
43277
|
}
|
|
@@ -43166,7 +43315,7 @@ function renderTaskListItem(task) {
|
|
|
43166
43315
|
].filter(Boolean).map((item) => `; ${item}`).join("");
|
|
43167
43316
|
return `- ${task.taskId} [${task.status}] ${task.targetAgent}${role} -> ${task.workerSession ?? "unassigned"}${group}${source}${summary}${reliability}`;
|
|
43168
43317
|
}
|
|
43169
|
-
function renderTaskSummary(task) {
|
|
43318
|
+
function renderTaskSummary(task, options = {}) {
|
|
43170
43319
|
const header = [
|
|
43171
43320
|
`Task "${task.taskId}"`,
|
|
43172
43321
|
`- Status: ${task.status}`,
|
|
@@ -43181,7 +43330,9 @@ function renderTaskSummary(task) {
|
|
|
43181
43330
|
if (task.status === "needs_confirmation") {
|
|
43182
43331
|
header.push(`- Source: ${task.sourceKind} / ${task.sourceHandle}${task.role ? ` / ${task.role}` : ""}`);
|
|
43183
43332
|
}
|
|
43184
|
-
|
|
43333
|
+
if (task.status === "needs_confirmation" || options.includePrompt) {
|
|
43334
|
+
header.push(`- Task: ${task.task}`);
|
|
43335
|
+
}
|
|
43185
43336
|
if (task.summary.trim().length > 0)
|
|
43186
43337
|
header.push(`- Summary: ${task.summary}`);
|
|
43187
43338
|
if (task.lastProgressSummary)
|
|
@@ -43232,7 +43383,7 @@ function renderTaskApprovalSuccess(task) {
|
|
|
43232
43383
|
return [
|
|
43233
43384
|
`Task "${task.taskId}" approved.`,
|
|
43234
43385
|
`- Current status: ${task.status}`,
|
|
43235
|
-
`Next:
|
|
43386
|
+
`Next: call task_watch to long-poll until the worker finishes — the terminal watch returns the result directly, so no follow-up task_get is needed. Use task_list only to resurvey in-flight tasks.`
|
|
43236
43387
|
].join(`
|
|
43237
43388
|
`);
|
|
43238
43389
|
}
|
|
@@ -43730,13 +43881,24 @@ function renderWatchMcpTaskResult(result, watchTaskId) {
|
|
|
43730
43881
|
const events = result.events.length > 0 ? [
|
|
43731
43882
|
"Events:",
|
|
43732
43883
|
...result.events.map((event) => {
|
|
43733
|
-
const
|
|
43734
|
-
return `- #${event.seq} ${event.type} at ${event.at}${
|
|
43884
|
+
const detail2 = event.summary ?? event.message ?? event.status ?? "";
|
|
43885
|
+
return `- #${event.seq} ${event.type} at ${event.at}${detail2 ? `: ${detail2}` : ""}`;
|
|
43735
43886
|
})
|
|
43736
43887
|
] : ["Events: none"];
|
|
43737
|
-
const
|
|
43888
|
+
const detail = [];
|
|
43889
|
+
if (result.status === "terminal") {
|
|
43890
|
+
const resultText = result.task.resultText.trim();
|
|
43891
|
+
const summary = result.task.summary.trim();
|
|
43892
|
+
if (resultText.length > 0)
|
|
43893
|
+
detail.push(`Result: ${resultText}`);
|
|
43894
|
+
else if (summary.length > 0)
|
|
43895
|
+
detail.push(`Summary: ${summary}`);
|
|
43896
|
+
} else if (result.status === "attention_required" && result.task.openQuestion) {
|
|
43897
|
+
detail.push(`Open question: ${result.task.openQuestion.question}`);
|
|
43898
|
+
}
|
|
43899
|
+
const next = result.status === "terminal" ? "Next: summarize this result for the user." : result.status === "attention_required" ? "Next: resolve the pending question / contested review with the recommended action tool (coordinator_answer_question or coordinator_review_contested_result)." : `Next: call task_watch again with afterSeq=${result.nextAfterSeq} to keep watching.`;
|
|
43738
43900
|
return {
|
|
43739
|
-
content: [{ type: "text", text: [...header, ...events, next].join(`
|
|
43901
|
+
content: [{ type: "text", text: [...header, ...events, ...detail, next].join(`
|
|
43740
43902
|
`) }],
|
|
43741
43903
|
structuredContent: { watchTaskId, ...result }
|
|
43742
43904
|
};
|
|
@@ -44096,8 +44258,14 @@ function inferExternalCoordinatorSession(input) {
|
|
|
44096
44258
|
return `external_${sanitizeMcpClientName(input.clientName)}:${suffix}`;
|
|
44097
44259
|
}
|
|
44098
44260
|
function sanitizeMcpClientName(input) {
|
|
44099
|
-
|
|
44100
|
-
|
|
44261
|
+
return sanitizeString((input ?? "").trim(), {
|
|
44262
|
+
allow: /[a-z0-9._-]/,
|
|
44263
|
+
replacement: "-",
|
|
44264
|
+
lowercase: true,
|
|
44265
|
+
collapse: true,
|
|
44266
|
+
trim: true,
|
|
44267
|
+
fallback: "mcp-host"
|
|
44268
|
+
});
|
|
44101
44269
|
}
|
|
44102
44270
|
|
|
44103
44271
|
// src/mcp/parse-string-flag.ts
|
|
@@ -44222,11 +44390,12 @@ function resolveTemplateChoice(answer, names) {
|
|
|
44222
44390
|
// src/cli-update.ts
|
|
44223
44391
|
init_plugin_home();
|
|
44224
44392
|
import { spawn as spawn4 } from "node:child_process";
|
|
44225
|
-
import { readFile as
|
|
44393
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
44226
44394
|
import { dirname as dirname9, join as join7 } from "node:path";
|
|
44227
44395
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
44228
44396
|
|
|
44229
44397
|
// src/plugins/package-manager.ts
|
|
44398
|
+
init_plugin_home();
|
|
44230
44399
|
import { spawn as spawn3 } from "node:child_process";
|
|
44231
44400
|
async function defaultRunCommand(command, args, options) {
|
|
44232
44401
|
await new Promise((resolve, reject) => {
|
|
@@ -44267,6 +44436,7 @@ async function detectPackageManager(runCommand) {
|
|
|
44267
44436
|
async function installPluginPackage(input) {
|
|
44268
44437
|
const runCommand = input.runCommand ?? defaultRunCommand;
|
|
44269
44438
|
const packageManager = input.packageManager ?? await detectPackageManager();
|
|
44439
|
+
await normalizePluginHomeManifest(input.pluginHome);
|
|
44270
44440
|
const spec = input.version ? `${input.packageName}@${input.version}` : input.packageName;
|
|
44271
44441
|
if (packageManager === "bun") {
|
|
44272
44442
|
await runCommand("bun", ["add", spec], { cwd: input.pluginHome });
|
|
@@ -44504,7 +44674,7 @@ async function readPackageName() {
|
|
|
44504
44674
|
const here = dirname9(fileURLToPath2(import.meta.url));
|
|
44505
44675
|
for (const candidate of [join7(here, "..", "package.json"), join7(here, "..", "..", "package.json")]) {
|
|
44506
44676
|
try {
|
|
44507
|
-
const parsed = JSON.parse(await
|
|
44677
|
+
const parsed = JSON.parse(await readFile8(candidate, "utf8"));
|
|
44508
44678
|
if (typeof parsed.name === "string" && parsed.name.trim())
|
|
44509
44679
|
return parsed.name.trim();
|
|
44510
44680
|
} catch {}
|
|
@@ -45127,7 +45297,7 @@ async function setChannelAccountEnabled(type, accountId, enabled, rawArgs, deps)
|
|
|
45127
45297
|
|
|
45128
45298
|
// src/plugins/plugin-cli.ts
|
|
45129
45299
|
init_plugin_home();
|
|
45130
|
-
import { readFile as
|
|
45300
|
+
import { readFile as readFile10 } from "node:fs/promises";
|
|
45131
45301
|
import { isAbsolute, join as join9, resolve } from "node:path";
|
|
45132
45302
|
init_plugin_loader();
|
|
45133
45303
|
init_validate_plugin();
|
|
@@ -45137,14 +45307,14 @@ init_channel_scope();
|
|
|
45137
45307
|
init_plugin_loader();
|
|
45138
45308
|
init_validate_plugin();
|
|
45139
45309
|
init_known_plugins();
|
|
45140
|
-
import { readFile as
|
|
45310
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
45141
45311
|
import { join as join8 } from "node:path";
|
|
45142
45312
|
function suggestedPluginPackageForChannel(type) {
|
|
45143
45313
|
return findKnownPluginByChannel(type)?.packageName ?? `<npm-package-that-provides-${type}>`;
|
|
45144
45314
|
}
|
|
45145
45315
|
async function readDependencyEntries(pluginHome) {
|
|
45146
45316
|
try {
|
|
45147
|
-
const raw = await
|
|
45317
|
+
const raw = await readFile9(join8(pluginHome, "package.json"), "utf8");
|
|
45148
45318
|
const parsed = JSON.parse(raw);
|
|
45149
45319
|
const out = {};
|
|
45150
45320
|
for (const [name, value] of Object.entries(parsed.dependencies ?? {})) {
|
|
@@ -45242,11 +45412,11 @@ async function inspectPlugins(input) {
|
|
|
45242
45412
|
// src/plugins/plugin-cli.ts
|
|
45243
45413
|
init_known_plugins();
|
|
45244
45414
|
function looksLikePath(spec) {
|
|
45245
|
-
return spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/") ||
|
|
45415
|
+
return spec === "." || spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/") || spec.startsWith(".\\") || spec.startsWith("..\\") || spec.startsWith("\\") || /^[a-zA-Z]:[\\/]/.test(spec) || isAbsolute(spec);
|
|
45246
45416
|
}
|
|
45247
45417
|
async function readDependencyEntries2(pluginHome) {
|
|
45248
45418
|
try {
|
|
45249
|
-
const raw = await
|
|
45419
|
+
const raw = await readFile10(join9(pluginHome, "package.json"), "utf8");
|
|
45250
45420
|
const parsed = JSON.parse(raw);
|
|
45251
45421
|
const out = {};
|
|
45252
45422
|
for (const [name, value] of Object.entries(parsed.dependencies ?? {})) {
|
|
@@ -45272,7 +45442,7 @@ async function resolveLocalPluginName(installSpec, pluginHome, namesBeforeInstal
|
|
|
45272
45442
|
return name;
|
|
45273
45443
|
}
|
|
45274
45444
|
try {
|
|
45275
|
-
const raw = await
|
|
45445
|
+
const raw = await readFile10(join9(installSpec, "package.json"), "utf8");
|
|
45276
45446
|
const parsed = JSON.parse(raw);
|
|
45277
45447
|
if (typeof parsed.name === "string" && parsed.name.trim())
|
|
45278
45448
|
return parsed.name.trim();
|