feat(cli): folders command, search --all-folders, empty-search hint
Fixes from testing email search (docs/enhancements-2026-07-07.md): - New `folders` agent command lists the account's mailboxes (name, delimiter, selectable), INBOX first, so agents can discover archived mail outside INBOX. - `search --all-folders` sweeps every selectable mailbox; each hit carries a `folder` field, `skipped_folders` reports mailboxes the server refused, and --limit caps visible results across the sweep. The sweep deliberately skips EnsureFolderBaseline so a read-only search never mutates list --new state. - Empty search results include a generic `data.hint` with next steps. The hint is a fixed constant per mode, so the invisibility invariant holds: absent and policy-filtered mail produce byte-identical envelopes (codified in TestSearchEmptyHintIndistinguishableFromFiltered). - Skill and user docs: document `--text` full-text search as best-effort (server-dependent); recommend --subject-contains/--from. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -121,3 +121,47 @@ func TestAccountLsAliasAgentRole(t *testing.T) {
|
||||
t.Fatalf("account ls leaked host/username:\n%s", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSearchAllFoldersConflictsWithFolder(t *testing.T) {
|
||||
adminEnv(t)
|
||||
code, out, _ := run(t, "search", "--account", "x", "--folder", "F", "--all-folders")
|
||||
if code != 2 {
|
||||
t.Fatalf("want usage exit 2, got %d (out=%q)", code, out)
|
||||
}
|
||||
var env map[string]any
|
||||
if err := json.Unmarshal([]byte(out), &env); err != nil {
|
||||
t.Fatalf("usage error must be a JSON envelope, got %q", out)
|
||||
}
|
||||
if env["error"] != true {
|
||||
t.Fatalf("want error envelope: %v", env)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllFoldersRejectedForList(t *testing.T) {
|
||||
adminEnv(t)
|
||||
// --all-folders is only registered for search; list must reject it at
|
||||
// flag-parse time with a JSON usage envelope.
|
||||
code, out, _ := run(t, "list", "--account", "x", "--all-folders")
|
||||
if code != 2 {
|
||||
t.Fatalf("want usage exit 2, got %d (out=%q)", code, out)
|
||||
}
|
||||
var env map[string]any
|
||||
if err := json.Unmarshal([]byte(out), &env); err != nil {
|
||||
t.Fatalf("usage error must be a JSON envelope, got %q", out)
|
||||
}
|
||||
if env["error"] != true {
|
||||
t.Fatalf("want error envelope: %v", env)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFoldersRequiresAccount(t *testing.T) {
|
||||
adminEnv(t)
|
||||
code, out, _ := run(t, "folders")
|
||||
if code != 2 {
|
||||
t.Fatalf("want usage exit 2, got %d (out=%q)", code, out)
|
||||
}
|
||||
var env map[string]any
|
||||
if err := json.Unmarshal([]byte(out), &env); err != nil {
|
||||
t.Fatalf("usage error must be a JSON envelope, got %q", out)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user