TUI (spec 3.4.0): the spinner line is the progress phase; /team shows the tree with each agent's phase, context and messages; /team open (a subagent's session, read-only), /team findings, /context <subagent>
ci / check (push) Waiting to run
ci / check (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
10 files changed
+117
-15
No files matched your search
+1
-1
@@ -54,7 +54,7 @@ describe("end to end", () => {
|
||||
expect(fake!.requests[0].messages[0].content).toContain("Permission mode: edit")
|
||||
// knowledge_search/get are offered once any knowledge base has documents, and the suite shares
|
||||
// one LEMBAS_HOME: another file's base must not decide this list (found in the full run).
|
||||
expect(fake!.requests[0].tools.map((t: any) => t.function.name).filter((n: string) => !n.startsWith("knowledge_"))).toEqual(["read", "write", "edit", "multiedit", "apply_patch", "glob", "grep", "list", "bash", "job_output", "job_list", "job_stop", "job_send", "web_search", "web_fetch", "task", "team_add", "team_send", "team_read", "team_stop", "plan_write", "plan_update", "ask_user", "plan_submit", "memory", "session_search", "notes_search", "note_view", "note_manage", "skills_list", "skill_view", "skill_manage", "settings", "recall"])
|
||||
expect(fake!.requests[0].tools.map((t: any) => t.function.name).filter((n: string) => !n.startsWith("knowledge_"))).toEqual(["read", "write", "edit", "multiedit", "apply_patch", "glob", "grep", "list", "bash", "job_output", "job_list", "job_stop", "job_send", "web_search", "web_fetch", "task", "team_add", "team_send", "team_read", "team_stop", "team_whoami", "team_findings", "team_decide", "team_assign", "team_replace", "plan_write", "plan_update", "ask_user", "plan_submit", "memory", "session_search", "notes_search", "note_view", "note_manage", "skills_list", "skill_view", "skill_manage", "settings", "recall"])
|
||||
const ends = events.filter((e) => e.type === "tool_end")
|
||||
expect(ends.map((e) => e.type === "tool_end" && e.result.title)).toEqual(["hello.txt · 1–1 of 1", "hello.txt +1 −1"])
|
||||
const sid = store.sessions(1)[0]!.id
|
||||
|
||||
@@ -372,14 +372,14 @@ test("thinking is one line — its text is not shown; the provider's count of it
|
||||
expect(await t.until("SECRET-INNER-STEP")).toBe(true)
|
||||
})
|
||||
|
||||
test("while it thinks: the thought says only Thinking…; the line at the bottom has the verb, the task's time and tokens", async () => {
|
||||
test("while it thinks: the thought says only Thinking…; the line at the bottom has the phase (progress.md), the task's time and tokens", async () => {
|
||||
t = await tui([{ gapMs: 1500, chunks: [delta({ reasoning_content: "Weighing it up: HIDDEN-WHILE-THINKING and more words here." }), delta({ content: "Done thinking." })] }])
|
||||
await t.input.typeText("go")
|
||||
t.input.pressEnter()
|
||||
expect(await t.until("~15 tokens")).toBe(true)
|
||||
const frame = t.frame()
|
||||
expect(frame).toMatch(/^\s*Thinking\.{1,3}\s*$/m)
|
||||
expect(frame).toMatch(/(pondering|contemplating|musing|cogitating|ruminating|deliberating|mulling|reflecting|reasoning|analyzing|synthesizing|formulating)… \d+s · ~15 tokens · esc to stop/)
|
||||
expect(frame).toMatch(/Thinking · \d+s · turn \d+s · ~15 tokens · esc to stop/)
|
||||
expect(frame).not.toContain("HIDDEN-WHILE-THINKING")
|
||||
expect(await t.until("Done thinking.")).toBe(true)
|
||||
expect(t.frame()).toMatch(/Thought for \d\.\ds · ~15 tokens/)
|
||||
@@ -397,7 +397,7 @@ test("the line at the bottom counts the whole task: the clock and the tokens go
|
||||
// The spinner line redraws on its own tick, slower than the reply's text: on a slow machine the
|
||||
// frame that first shows "Half" can still carry the line from before. The 1.2 s gap holds this
|
||||
// state, so wait for the line within it rather than reading the first frame.
|
||||
const counted = /writing… \d+s · ~4\d tokens · esc to stop/
|
||||
const counted = /Writing(: [\d.]+ tok\/s)? · \d+s · turn \d+s · ~4\d tokens · esc to stop/
|
||||
for (let i = 0; i < 20 && !counted.test(t.frame()); i++) await Bun.sleep(50), await t.settle()
|
||||
expect(t.frame()).toMatch(counted)
|
||||
expect(await t.until("way.")).toBe(true)
|
||||
@@ -922,10 +922,12 @@ test("while the server reads a long prompt: the line at the bottom says how far
|
||||
t = await tui([{ gapMs: 500, chunks: [pp(0, 0), pp(80000, 160000), delta({ content: "Read it all." }, "stop")] }])
|
||||
await t.input.typeText("go")
|
||||
t.input.pressEnter()
|
||||
expect(await t.until("reading the prompt 64% · 90k of 140k · ~1m 40s left")).toBe(true)
|
||||
// At 100 columns the line is cut in its middle; its start and its end are what is checked.
|
||||
expect(await t.until("~1m 40s left")).toBe(true)
|
||||
expect(t.frame()).toContain("Reading the prompt: 90000 / 140000 tokens (64%")
|
||||
expect(await t.until("Read it all.")).toBe(true)
|
||||
await t.settle()
|
||||
expect(t.frame()).not.toContain("reading the prompt")
|
||||
expect(t.frame()).not.toContain("Reading the prompt")
|
||||
})
|
||||
|
||||
test("a mouse wheel that arrives as a burst of ↑ scrolls the transcript; one ↑ still walks history", async () => {
|
||||
|
||||
Reference in new issue
Block a user