@team-agent/installer 0.3.23 → 0.3.25
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/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/crates/team-agent/src/coordinator/tick.rs +55 -7
- package/crates/team-agent/src/leader/lease.rs +34 -13
- package/crates/team-agent/src/leader/tests/lease_api.rs +79 -0
- package/crates/team-agent/src/lifecycle/helpers.rs +11 -3
- package/crates/team-agent/src/lifecycle/launch.rs +219 -35
- package/crates/team-agent/src/lifecycle/restart/agent.rs +61 -0
- package/crates/team-agent/src/lifecycle/restart/common.rs +66 -1
- package/crates/team-agent/src/lifecycle/restart.rs +19 -2
- package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +994 -0
- package/crates/team-agent/src/messaging/delivery.rs +86 -27
- package/crates/team-agent/src/messaging/helpers.rs +64 -24
- package/crates/team-agent/src/messaging/tests/mod.rs +1 -0
- package/crates/team-agent/src/messaging/tests/spine.rs +157 -4
- package/crates/team-agent/src/messaging/tests/wave2.rs +689 -0
- package/crates/team-agent/src/state/projection.rs +5 -0
- package/crates/team-agent/src/tmux_backend/tests.rs +297 -0
- package/crates/team-agent/src/tmux_backend.rs +145 -5
- package/crates/team-agent/src/transport/test_support.rs +79 -6
- package/crates/team-agent/src/transport.rs +26 -1
- package/npm/install.mjs +90 -25
- package/package.json +4 -4
|
@@ -157,6 +157,13 @@ pub enum Key {
|
|
|
157
157
|
Char(char),
|
|
158
158
|
/// `\x03`。
|
|
159
159
|
CtrlC,
|
|
160
|
+
/// E46 (0.3.24 bug#5): pre-submit Escape to exit bracketed-paste mode on
|
|
161
|
+
/// fresh provider TUIs (claude). When a bracketed paste lands on a TUI
|
|
162
|
+
/// whose composer is still initialising, the framework's plain `Enter`
|
|
163
|
+
/// gets interpreted as paste content, not submit. Sending `Escape` first
|
|
164
|
+
/// closes the paste bracket so the subsequent `Enter` submits.
|
|
165
|
+
/// Real-machine truth source: macmini demo-director repro.
|
|
166
|
+
Escape,
|
|
160
167
|
/// tmux `-X cancel` / `q` / `d`;非 tmux 后端无 copy-mode 概念 → no-op。
|
|
161
168
|
CancelMode,
|
|
162
169
|
}
|
|
@@ -287,7 +294,10 @@ pub enum InjectVerification {
|
|
|
287
294
|
/// `{key}_sent_after_visible_token` 是模板 → 用携带 Key 的 variant 表达。
|
|
288
295
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
289
296
|
pub enum SubmitVerification {
|
|
290
|
-
/// `enter_sent_without_placeholder_check`。
|
|
297
|
+
/// `enter_sent_without_placeholder_check`。MUST-10:此 variant 代表 paste+Enter
|
|
298
|
+
/// 完成且无需 placeholder probe(纯 peer 消息路径)。**保留** ⇒ delivered 语义;
|
|
299
|
+
/// E46 后只有 post-Enter consumption 确认通过(input 清空 / Working 信号)才返回
|
|
300
|
+
/// 此 variant — fresh TUI 未消费走 [`Self::SubmitConsumptionUnverified`]。
|
|
291
301
|
EnterSentWithoutPlaceholderCheck,
|
|
292
302
|
/// `pasted_content_prompt_absent_after_submit`。
|
|
293
303
|
PastedContentPromptAbsentAfterSubmit,
|
|
@@ -297,6 +307,14 @@ pub enum SubmitVerification {
|
|
|
297
307
|
KeySentAfterVisibleToken { key: Key },
|
|
298
308
|
/// `send_keys_failed`。
|
|
299
309
|
SendKeysFailed,
|
|
310
|
+
/// E46 (0.3.24 bug#5, demo-director 卡 bracketed paste): Enter 已发但
|
|
311
|
+
/// post-Enter 接收侧消费信号(input 行清空 / provider 进 Working)在 bounded
|
|
312
|
+
/// resend 上限内未观察到。**delivery 不当作 delivered**;走 submitted_unverified /
|
|
313
|
+
/// failed 路径。区别于
|
|
314
|
+
/// [`Self::PastedContentPromptStillPresentAfterSubmit`](claude paste-prompt
|
|
315
|
+
/// 折叠场景)— 本 variant 是结构化 input-empty 检测,适配 demo-director
|
|
316
|
+
/// 直接渲染文本路径。
|
|
317
|
+
SubmitConsumptionUnverified,
|
|
300
318
|
}
|
|
301
319
|
|
|
302
320
|
/// turn-boundary 观测(tmux_io.py:224-260,09-transport.md 表 §40)。
|
|
@@ -621,6 +639,10 @@ pub fn tmux_key_name(key: Key) -> &'static str {
|
|
|
621
639
|
Key::Char('8') => "8",
|
|
622
640
|
Key::Char('9') => "9",
|
|
623
641
|
Key::CtrlC => "C-c",
|
|
642
|
+
// E46 (0.3.24 bug#5): tmux supports `Escape` as a key name; sending
|
|
643
|
+
// it as a send-keys arg emits `\x1b` to the pane (closes bracketed
|
|
644
|
+
// paste mode on a stuck TUI composer).
|
|
645
|
+
Key::Escape => "Escape",
|
|
624
646
|
Key::CancelMode | Key::Char(_) => "",
|
|
625
647
|
}
|
|
626
648
|
}
|
|
@@ -850,6 +872,9 @@ pub fn submit_verification_wire(v: SubmitVerification) -> String {
|
|
|
850
872
|
format!("{}_sent_after_visible_token", tmux_key_name(key))
|
|
851
873
|
}
|
|
852
874
|
SubmitVerification::SendKeysFailed => "send_keys_failed".to_string(),
|
|
875
|
+
SubmitVerification::SubmitConsumptionUnverified => {
|
|
876
|
+
"submit_consumption_unverified".to_string()
|
|
877
|
+
}
|
|
853
878
|
}
|
|
854
879
|
}
|
|
855
880
|
|
package/npm/install.mjs
CHANGED
|
@@ -6,36 +6,104 @@ import os from "node:os";
|
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
const modulePath = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(modulePath);
|
|
10
11
|
const packageRoot = path.resolve(__dirname, "..");
|
|
11
12
|
const require = createRequire(import.meta.url);
|
|
12
13
|
const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
|
|
13
14
|
const DOCTOR_TIMEOUT_MS = 5000;
|
|
14
15
|
const VERSION_SMOKE_TIMEOUT_MS = 5000;
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (["-h", "--help", "help"].includes(command)) {
|
|
20
|
-
printHelp();
|
|
21
|
-
process.exit(0);
|
|
17
|
+
if (isCliEntrypoint()) {
|
|
18
|
+
main();
|
|
22
19
|
}
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
} else if (command === "uninstall") {
|
|
30
|
-
uninstall(args);
|
|
31
|
-
} else {
|
|
32
|
-
console.error(`unknown command: ${command}`);
|
|
21
|
+
function main() {
|
|
22
|
+
const command = process.argv[2] || "install";
|
|
23
|
+
const args = process.argv.slice(3);
|
|
24
|
+
|
|
25
|
+
if (["-h", "--help", "help"].includes(command)) {
|
|
33
26
|
printHelp();
|
|
34
|
-
process.exit(
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
if (command === "install" || command === "update") {
|
|
32
|
+
install(args);
|
|
33
|
+
} else if (command === "doctor") {
|
|
34
|
+
runDoctor(args);
|
|
35
|
+
} else if (command === "uninstall") {
|
|
36
|
+
uninstall(args);
|
|
37
|
+
} else {
|
|
38
|
+
console.error(`unknown command: ${command}`);
|
|
39
|
+
printHelp();
|
|
40
|
+
process.exit(2);
|
|
41
|
+
}
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function isCliEntrypoint() {
|
|
49
|
+
if (!process.argv[1]) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
return fs.realpathSync(process.argv[1]) === fs.realpathSync(modulePath);
|
|
54
|
+
} catch {
|
|
55
|
+
return path.resolve(process.argv[1]) === modulePath;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function doctorSelfCheckVerdict(doctorBody, spawnMeta = {}) {
|
|
60
|
+
if (spawnMeta.error || spawnMeta.signal) {
|
|
61
|
+
return { kind: "advisory", blockers: [] };
|
|
35
62
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
63
|
+
|
|
64
|
+
let body;
|
|
65
|
+
try {
|
|
66
|
+
body = JSON.parse(doctorBody || "");
|
|
67
|
+
} catch {
|
|
68
|
+
return { kind: "advisory", blockers: [] };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const blockers = [];
|
|
72
|
+
// Doctor JSON source: crates/team-agent/src/cli/mod.rs:2739-2764.
|
|
73
|
+
if (body?.tmux?.installed === false) {
|
|
74
|
+
blockers.push("tmux not installed");
|
|
75
|
+
}
|
|
76
|
+
if (!body?.mcp?.server_command) {
|
|
77
|
+
blockers.push("MCP server command missing");
|
|
78
|
+
}
|
|
79
|
+
const profileSmokeStatus = body?.profile_smoke?.status;
|
|
80
|
+
const profileSmokeNonBlocking =
|
|
81
|
+
profileSmokeStatus === "legacy_team_invalid" || profileSmokeStatus === "not_required";
|
|
82
|
+
if (
|
|
83
|
+
body?.error === "profile_smoke_failed" ||
|
|
84
|
+
(body?.profile_smoke?.ok === false && !profileSmokeNonBlocking)
|
|
85
|
+
) {
|
|
86
|
+
blockers.push("profile smoke failed");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (blockers.length > 0) {
|
|
90
|
+
return { kind: "blockers", blockers };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const noContext =
|
|
94
|
+
body?.ok === false && body?.error === "workspace has no Team Agent spec or runtime context";
|
|
95
|
+
if (body?.ok === true || noContext) {
|
|
96
|
+
return { kind: "ok", blockers: [] };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return { kind: "advisory", blockers: [] };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function doctorSelfCheckLine(verdict) {
|
|
103
|
+
if (verdict.kind === "blockers") {
|
|
104
|
+
return `doctor: found blockers (${verdict.blockers.join("; ")}); run team-agent doctor in your project for details`;
|
|
105
|
+
}
|
|
106
|
+
return "doctor: ok (run team-agent doctor inside a team workspace for a full report)";
|
|
39
107
|
}
|
|
40
108
|
|
|
41
109
|
function printHelp() {
|
|
@@ -116,11 +184,8 @@ function install(argv) {
|
|
|
116
184
|
encoding: "utf8",
|
|
117
185
|
timeout: DOCTOR_TIMEOUT_MS,
|
|
118
186
|
});
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
} else {
|
|
122
|
-
console.log("doctor: has blockers; run `team-agent doctor` after updating PATH");
|
|
123
|
-
}
|
|
187
|
+
const verdict = doctorSelfCheckVerdict(doctor.stdout, doctor);
|
|
188
|
+
console.log(doctorSelfCheckLine(verdict));
|
|
124
189
|
} finally {
|
|
125
190
|
fs.rmSync(doctorWorkspace, { recursive: true, force: true });
|
|
126
191
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@team-agent/installer",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.25",
|
|
4
4
|
"description": "npx installer for Team Agent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"codex",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"team-agent-installer": "npm/install.mjs"
|
|
21
21
|
},
|
|
22
22
|
"optionalDependencies": {
|
|
23
|
-
"@team-agent/cli-darwin-arm64": "0.3.
|
|
24
|
-
"@team-agent/cli-darwin-x64": "0.3.
|
|
25
|
-
"@team-agent/cli-linux-x64": "0.3.
|
|
23
|
+
"@team-agent/cli-darwin-arm64": "0.3.25",
|
|
24
|
+
"@team-agent/cli-darwin-x64": "0.3.25",
|
|
25
|
+
"@team-agent/cli-linux-x64": "0.3.25"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"postinstall": "node npm/bincheck.mjs",
|