u-foo 2.3.12 → 2.3.14
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/package.json +1 -1
- package/src/agent/defaultBootstrap.js +28 -3
- package/src/agent/internalRunner.js +126 -124
- package/src/agent/ptyRunner.js +70 -8
- package/src/agent/ucodeBootstrap.js +23 -1
- package/src/agent/ufooAgent.js +7 -36
- package/src/chat/daemonMessageRouter.js +3 -1
- package/src/chat/dashboardKeyController.js +1 -1
- package/src/chat/dashboardView.js +1 -1
- package/src/chat/index.js +1 -1
- package/src/chat/inputListenerController.js +196 -54
- package/src/chat/layout.js +18 -2
- package/src/code/tui.js +405 -50
- package/src/config.js +1 -0
- package/src/daemon/ops.js +57 -12
- package/src/agent/cliRunner.js +0 -706
- package/src/agent/normalizeOutput.js +0 -41
package/src/daemon/ops.js
CHANGED
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
const {
|
|
15
15
|
createSession: createHostSession,
|
|
16
16
|
} = require("../terminal/adapters/hostAdapter");
|
|
17
|
+
const { resolveDefaultManualBootstrap } = require("../agent/defaultBootstrap");
|
|
17
18
|
|
|
18
19
|
function normalizeLaunchAgent(agent = "") {
|
|
19
20
|
const value = String(agent || "").trim().toLowerCase();
|
|
@@ -44,6 +45,43 @@ function toTmuxBinary(agent = "") {
|
|
|
44
45
|
return "";
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
function applyDefaultManagedBootstrap(projectRoot, normalizedAgent, args = [], extraEnv = {}) {
|
|
49
|
+
const agentType = toBusAgentType(normalizedAgent);
|
|
50
|
+
if (!agentType || agentType === "ufoo-code") {
|
|
51
|
+
return {
|
|
52
|
+
args: Array.isArray(args) ? args.slice() : [],
|
|
53
|
+
extraEnv: extraEnv && typeof extraEnv === "object" ? { ...extraEnv } : {},
|
|
54
|
+
applied: false,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const currentArgs = Array.isArray(args) ? args.slice() : [];
|
|
59
|
+
const currentExtraEnv = extraEnv && typeof extraEnv === "object" ? { ...extraEnv } : {};
|
|
60
|
+
const resolved = resolveDefaultManualBootstrap({
|
|
61
|
+
projectRoot,
|
|
62
|
+
agentType,
|
|
63
|
+
args: currentArgs,
|
|
64
|
+
env: {
|
|
65
|
+
...process.env,
|
|
66
|
+
...currentExtraEnv,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (!resolved || resolved.mode === "skip") {
|
|
71
|
+
return { args: currentArgs, extraEnv: currentExtraEnv, applied: false };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
args: Array.isArray(resolved.args) ? resolved.args : currentArgs,
|
|
76
|
+
extraEnv: {
|
|
77
|
+
...currentExtraEnv,
|
|
78
|
+
...(resolved.env && typeof resolved.env === "object" ? resolved.env : {}),
|
|
79
|
+
UFOO_SKIP_DEFAULT_BOOTSTRAP: "1",
|
|
80
|
+
},
|
|
81
|
+
applied: true,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
47
85
|
function resolveUfooRunnerPath() {
|
|
48
86
|
return path.resolve(__dirname, "../../bin/ufoo.js");
|
|
49
87
|
}
|
|
@@ -116,7 +154,7 @@ function resolveHostLaunchContext(options = {}) {
|
|
|
116
154
|
|
|
117
155
|
function resolveConfiguredLaunchMode(configuredMode = "", options = {}) {
|
|
118
156
|
const mode = normalizeOptionalString(configuredMode);
|
|
119
|
-
if (mode === "internal" || mode === "tmux" || mode === "terminal" || mode === "host") {
|
|
157
|
+
if (mode === "internal" || mode === "internal-pty" || mode === "tmux" || mode === "terminal" || mode === "host") {
|
|
120
158
|
return mode;
|
|
121
159
|
}
|
|
122
160
|
const hostContext = resolveHostLaunchContext(options);
|
|
@@ -518,7 +556,9 @@ async function spawnManagedHostAgent(
|
|
|
518
556
|
subscriberId = "";
|
|
519
557
|
}
|
|
520
558
|
|
|
521
|
-
const
|
|
559
|
+
const hostBootstrap = applyDefaultManagedBootstrap(projectRoot, normalizedAgent, extraArgs, extraEnv);
|
|
560
|
+
const args = hostBootstrap.args;
|
|
561
|
+
const hostExtraEnv = hostBootstrap.extraEnv;
|
|
522
562
|
const argText = args.length > 0 ? ` ${args.map(shellEscape).join(" ")}` : "";
|
|
523
563
|
|
|
524
564
|
const titleCmd = buildTitleCmd(nickname);
|
|
@@ -538,8 +578,8 @@ async function spawnManagedHostAgent(
|
|
|
538
578
|
env.UFOO_NICKNAME = nickname;
|
|
539
579
|
}
|
|
540
580
|
// Parse extraEnv string (e.g., "UFOO_UCODE_BOOTSTRAP_FILE=/path/to/file") and add to env
|
|
541
|
-
if (
|
|
542
|
-
for (const [key, value] of Object.entries(
|
|
581
|
+
if (hostExtraEnv && typeof hostExtraEnv === "object") {
|
|
582
|
+
for (const [key, value] of Object.entries(hostExtraEnv)) {
|
|
543
583
|
if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(String(key || ""))) {
|
|
544
584
|
env[String(key)] = String(value ?? "");
|
|
545
585
|
}
|
|
@@ -645,7 +685,9 @@ async function spawnInternalAgent(
|
|
|
645
685
|
? (count > 1 ? `${nickname}-${i + 1}` : nickname)
|
|
646
686
|
: "";
|
|
647
687
|
const providerSessionId = typeof options.providerSessionId === "string" ? options.providerSessionId.trim() : "";
|
|
648
|
-
const usePty =
|
|
688
|
+
const usePty = typeof options.usePty === "boolean"
|
|
689
|
+
? options.usePty
|
|
690
|
+
: process.env.UFOO_INTERNAL_PTY !== "0";
|
|
649
691
|
const launchMode = usePty ? "internal-pty" : "internal";
|
|
650
692
|
|
|
651
693
|
// 传递 launch_mode 和 parent PID 到 join
|
|
@@ -657,8 +699,9 @@ async function spawnInternalAgent(
|
|
|
657
699
|
const finalNickname = joinResult.nickname || requestedNickname || "";
|
|
658
700
|
bus.saveBusData();
|
|
659
701
|
|
|
702
|
+
const managedBootstrap = applyDefaultManagedBootstrap(projectRoot, normalizedAgent, extraArgs, extraEnv);
|
|
660
703
|
const runnerCmd = usePty ? "agent-pty-runner" : "agent-runner";
|
|
661
|
-
const args =
|
|
704
|
+
const args = managedBootstrap.args;
|
|
662
705
|
const child = spawn(process.execPath, [runner, runnerCmd, agent, ...args], {
|
|
663
706
|
// 关键改动:不使用 detached,daemon 作为父进程
|
|
664
707
|
detached: false,
|
|
@@ -666,7 +709,7 @@ async function spawnInternalAgent(
|
|
|
666
709
|
cwd: projectRoot,
|
|
667
710
|
env: {
|
|
668
711
|
...process.env,
|
|
669
|
-
...(extraEnv && typeof extraEnv === "object" ? extraEnv : {}),
|
|
712
|
+
...(managedBootstrap.extraEnv && typeof managedBootstrap.extraEnv === "object" ? managedBootstrap.extraEnv : {}),
|
|
670
713
|
UFOO_INTERNAL_AGENT: "1",
|
|
671
714
|
UFOO_INTERNAL_PTY: usePty ? "1" : "0",
|
|
672
715
|
UFOO_SUBSCRIBER_ID: subscriberId, // 直接传递 subscriber ID
|
|
@@ -888,7 +931,8 @@ async function launchAgent(projectRoot, agent, count = 1, nickname = "", process
|
|
|
888
931
|
throw new Error(`unsupported agent type: ${agent}`);
|
|
889
932
|
}
|
|
890
933
|
|
|
891
|
-
if (mode === "internal") {
|
|
934
|
+
if (mode === "internal" || mode === "internal-pty") {
|
|
935
|
+
const usePty = mode === "internal-pty";
|
|
892
936
|
const result = await spawnInternalAgent(
|
|
893
937
|
projectRoot,
|
|
894
938
|
normalizedAgent,
|
|
@@ -896,9 +940,10 @@ async function launchAgent(projectRoot, agent, count = 1, nickname = "", process
|
|
|
896
940
|
nickname,
|
|
897
941
|
processManager,
|
|
898
942
|
launchEnvObject,
|
|
899
|
-
extraArgs
|
|
943
|
+
extraArgs,
|
|
944
|
+
{ usePty }
|
|
900
945
|
);
|
|
901
|
-
return { mode
|
|
946
|
+
return { mode, launchScope, subscriberIds: result.subscriberIds };
|
|
902
947
|
}
|
|
903
948
|
if (mode === "tmux") {
|
|
904
949
|
// Check if tmux is available
|
|
@@ -1129,7 +1174,7 @@ async function resumeAgents(projectRoot, target = "", processManager = null) {
|
|
|
1129
1174
|
const args = buildResumeArgs(item.agent, sessionId);
|
|
1130
1175
|
let reused = false;
|
|
1131
1176
|
let resumedId = item.id;
|
|
1132
|
-
if (mode === "internal") {
|
|
1177
|
+
if (mode === "internal" || mode === "internal-pty") {
|
|
1133
1178
|
// Internal agents have no terminal/pane to reattach. Start a fresh
|
|
1134
1179
|
// daemon-managed runner and replace the old recoverable registration.
|
|
1135
1180
|
// The provider session is still reused via the normal provider args.
|
|
@@ -1142,7 +1187,7 @@ async function resumeAgents(projectRoot, target = "", processManager = null) {
|
|
|
1142
1187
|
processManager,
|
|
1143
1188
|
{ UFOO_SKIP_SESSION_PROBE: "1" },
|
|
1144
1189
|
args,
|
|
1145
|
-
{ replaceAgentId: item.id, providerSessionId: sessionId }
|
|
1190
|
+
{ replaceAgentId: item.id, providerSessionId: sessionId, usePty: mode === "internal-pty" }
|
|
1146
1191
|
);
|
|
1147
1192
|
resumedId = launchResult.subscriberIds && launchResult.subscriberIds[0]
|
|
1148
1193
|
? launchResult.subscriberIds[0]
|