aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/tests
AgeCommit message (Collapse)Author
2026-06-29feat(audit): implement get_packages non-locked branchnsfisis
Port AuditCommand::getPackages's non-locked path: build an InstalledRepository from the local repository and return its packages, filtered by RootPackage requires when --no-dev is set. The prior TODO(phase-c) assumption (InstalledRepository::new vs get_local_repository type mismatch) no longer holds since both sides use RepositoryInterfaceHandle. Enables the two previously ignored audit command tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29feat(package): implement RootAliasPackage root getters via owned returnsnsfisis
It is faithful to PHP's by-value array/string semantics. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29fix(advisory): pass IO as shared handle to Auditor::auditnsfisis
Auditor::audit took io as &mut dyn IOInterface, forcing the audit and installer post-audit call sites to hold a borrow_mut() on the shared IO RefCell for the whole call. During advisory fetching the repositories write to their own clones of the same handle, so the borrow_mut() collided with their borrow() and panicked with 'RefCell already mutably borrowed' on 'audit --locked'. Take the Rc<RefCell<dyn IOInterface>> handle instead so writes borrow briefly and never overlap. Un-ignore the locked-audit regression test that this unblocks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29refactor(json): replace seld/jsonlint with serde_jsonnsfisis
Validate JSON syntax with serde_json's parse errors in JsonFile, and detect duplicate keys in ConfigValidator with a hand-written serde visitor, dropping the now-unused JsonParser/Lexer/DuplicateKeyException ports. ParsingException is kept as the thrown error type and downcast signal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28test(show): clarify ignore reason for empty platform sectionnsfisis
The platform: section is empty because PlatformRepository::get_packages routes to ArrayRepository::initialize instead of its own initialize, which needs the still-todo!() runtime::constant() shim. Record the real blocker. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28fix(repository): flatten InstalledRepository and unwrap filter repos in shownsfisis
flattenRepositories must recurse into InstalledRepository (which extends CompositeRepository in PHP) and ShowCommand must unwrap FilterRepository when categorizing repos. Without this, installed/locked/platform packages all fell through to the "available" bucket, dropping the version column and per-section grouping. Un-ignores 10 show_command tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28fix(installer): execute install/update/uninstall ops in execute_batchnsfisis
execute_batch only awaited prepare(), leaving the install/update/ uninstall + cleanup + repo.write promise chain as a todo!() stub, so packages were downloaded to cache but never installed into the target directory. Wire the operation step (mirroring PHP's promise chain), propagate errors from the install/update/uninstall wrappers instead of swallowing them with .ok()?, and write the repo after each op. Un-ignore the create-project functional tests and the install/remove command tests this unblocks. The remaining --no-install case still fails on a separate install-path bug; its ignore reason is updated to match.
2026-06-28test(installer): port InstallerTest unit and integration harnessnsfisis
Port composer/tests/Composer/Test/InstallerTest.php. testInstaller (the provideInstaller cases) is fully ported and passes; the three integration tests port doTestIntegration in full (the .test fixture loader, FactoryMock, the in-process console Application with install/update commands, and the PHPUnit assertStringMatchesFormat matcher) and remain #[ignore]'d since the install pipeline is not yet executable end-to-end. Add test-only `__`-seams to the concrete types the test depends on, since their consumers (e.g. Locker takes the concrete InstallationManager) and the subclass-style mocks have no trait to mock: InstallationManager (recording mock + as_any), Factory (__create_mock), VersionGuesser, and InstalledFilesystemRepository. The production path (mock: false) is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28test(functional): port AllFunctionalTest integration harnessnsfisis
Implements the todo!() stubs in all_functional_test.rs by faithfully porting parseTestFile, cleanOutput and the inline %regex% EXPECT matcher, plus a subprocess runner that drives CARGO_BIN_EXE_shirabe (in place of PHP's composer.phar) over the reused Fixtures/functional .test files. The five fixtures are wired as individual #[serial] #[ignore] tests with per-fixture reasons: the two create-project cases need network + a real git clone, and the three update cases need the not-yet-implemented Plugin API. test_build_phar stays an ignored stub since Rust has no phar build. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28refactor: add linternsfisis
2026-06-28test(json): drop JsonFormatterTest stubnsfisis
JsonFormatter is intentionally unported in crates/shirabe/src/json, so the ignored todo!() stub test serves no purpose. Remove the file and its module declaration. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28test(downloader): cfg-gate XzDownloaderTest skip on Windows/32bitnsfisis
Replace the todo!() markTestSkipped placeholders in set_up with a compile-time cfg gate on the test function, mirroring PHP's setUp skips on Windows and 32bit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28test(command): port HomeCommandTest useCaseProvider casesnsfisis
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28test(command): port DiagnoseCommandTest casesnsfisis
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28test(tests): use mockall for hand-written interface mocksnsfisis
Replace hand-written mock/stub structs that re-implemented PHPUnit mock-builder behavior (record-and-verify, manual call counters, unreachable!() guards) with mockall::mock! locals across: - package/loader: MockLoader, VersionGuesserMock - command: ArchiveManager/RepositoryManager/EventDispatcher mocks - util: ConfigSource/AuthJson mocks (auth_helper, bitbucket, github, forgejo, gitlab) - repository/vcs: github_driver NullConfigSource - installer: CountingInstaller, RecordingBinaryInstaller, and the DownloadManager mock (formerly common/downloader_stub.rs, now deleted) - downloader: download_manager create_downloader_mock Verification (counts/args) now lives in mockall expectations checked on drop. installation_manager BinaryInstaller is left hand-written because its as_binary_presence_interface seam returns Some(&mut self), which mockall cannot express; io_stub and io_mock are left as-is. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28test(util/git): port interactive Bitbucket OAuth runCommand testnsfisis
Implement the four privateBitbucketWithOauthProvider cases that were stubbed as an ignored todo!(). Extend IOStub with per-question askAndHideAnswer responses and auth pre-seeding so the stateful OAuth flow can be driven without willReturnCallback, and inject a mock HttpDownloader plus no-op config sources to mirror PHPUnit's Config mock. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28test(repository): port testRepositoryWritesInstalledPhpnsfisis
Implement the previously-ignored test, which dumps installed.php via FilesystemRepository::write and byte-matches the Composer fixture. The package link setters needed by configureLinks are now reachable through the __set_provides/__set_replaces test hatches, so the PHP getPackage + configureLinks shape can be reproduced faithfully. Also switch both InstallationManager stubs in this file to a single mockall mock, replacing the hand-rolled impls and call counter. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28test(console): correct inaccurate test skip reasonsnsfisis
setCatchErrors is an old-Symfony compatibility shim that exists in neither Composer's PHP class nor Shirabe, and setAutoExit(false) is the default in Shirabe, so neither is a reason a test is unportable. Drop those mentions and point the application_test ignores at the real blocker: do_run's script-command registration is still a todo!(). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28test(console): port DocumentationTest::testCommandnsfisis
Add __base_application accessor on ApplicationHandle so the test can build an ApplicationDescription the way console commands do. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28test(package/archiver): port testGitExcludesnsfisis
Process::fromShellCommandline and ZipArchive are now ported, so the git pipeline + zip reading have faithful equivalents. Kept #[ignore]d: the finder applies .gitattributes rules through BaseExcludeFilter::generate_pattern, whose (?=$|/) look-ahead regexes the regex crate cannot compile (same blocker as test_manual_excludes); also needs a git executable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28test(package/version): port testFindRecommendedRequireVersionnsfisis
Ported faithfully via PackageHandle::new + __set_extra (now available on PackageHandle). Kept #[ignore]d: date-based cases expose a shirabe_semver normalize divergence (v20121020 -> 20121020.0.0.0), not a test-port issue. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28test(downloader): port Fossil/Hg testRemovensfisis
The FilesystemMock seam (already used by FileDownloaderTest) intercepts removeDirectoryAsync before any rm -rf, so the prior execute_async blocker no longer applies. getDownloaderMock gains the optional filesystem param. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28test(factory): port testDefaultValuesAreAsExpectednsfisis
The IOMock and ConfigStubBuilder helpers now cover the writeError verification and the get('disable-tls')=>true stub the PHP test needs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28test(config): port testProhibitedUrlsWarningVerifyPeernsfisis
The IOMock helper is now available, so the verify_peer/verify_peer_name SSL warning case can be exercised instead of left as todo!(). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28test(command/status): port testLocallyModifiedPackagesnsfisis
Replace the todo!() stub with a faithful port of StatusCommandTest's data-provided locally-modified-packages cases (source/dist), kept #[ignore]d since install does not yet populate vendor/ offline. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28test(util): port MetadataMinifier expand testnsfisis
minify is intentionally unported, so only the expand half of testMinifyExpand() is exercised. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27feat(installer): register default installers after Composer Rc is builtnsfisis
LibraryInstaller and PluginInstaller upgrade the Composer back-reference in their constructors, so they could not be built inside Rc::new_cyclic where the weak handle is not yet upgradeable. Defer create_default_ installers until after the cyclic Rc is established, where the weak handle resolves, and implement it to register Library -> Plugin -> Metapackage with a single shared BinaryInstaller. To share one BinaryInstaller (as Composer does), LibraryInstaller's binary_installer becomes Rc<RefCell<dyn BinaryInstallerInterface>> instead of an owned Box; PluginInstaller and the __set_binary_installer test seam follow. This clears "Unknown installer type: metapackage". Un-ignores the six remove tests that now pass; the remaining install/remove tests are re-labeled for the next blocker (InstallationManager::execute_batch still leaves the install/cleanup/repo.write promise chain as a todo!() stub, so package operations do not actually execute). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27feat(command/update): port UpdateCommand input definitionnsfisis
Replace the empty set_definition stub with the full InputArgument/ InputOption set from Composer's UpdateCommand. The symfony input modeling was already complete; this was the last command still passing an empty definition, which made it reject its own options. Un-ignores test_no_security_blocking_allows_insecure_packages (now passing) and re-labels the six remaining update tests with their actual blockers (regex porting, resolver temporary-constraint, interactive mode, bump-after-update solver pool) since the old "empty InputDefinition" reason no longer applies. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27refactor(http): present reqwest instead of faking curl_versionnsfisis
- StreamContextFactory: User-Agent reports the HTTP stack as "reqwest" - RequestProxy::supports_secure_proxy: always true (reqwest+rustls can always TLS to a proxy); drop the now-dead curl<7.52 guard in get_curl_options - DiagnoseCommand::get_curl_version: phase-D TODO placeholder Empirically verified: reqwest sends no default User-Agent (shirabe sets it explicitly) and accepts https:// proxy URLs. init+install output stays byte-identical to Composer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27fix(json): encode empty stdClass fields as {} not []nsfisis
Empty PhpMixed::Array now serializes as [], so the several places that build a PHP `new \stdClass` via an empty Array were emitting [] where Composer writes {}. Use PhpMixed::Object for those empty-object cases: - InitCommand: require / require-dev - Locker::fixupJsonDataType: stability-flags / platform / platform-dev - JsonConfigSource fallback: require/config keys that must stay objects Align the affected test expectations with Composer: JsonFile::read() decodes with assoc=true, collapsing the on-disk {} back to [], so reads expect []. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27test: serialize env-var-dependent testsnsfisis
Several tests read process-global env vars and set/clear them via TearDown but were not #[serial], so parallel execution could race. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27test: port Composer tests unblocked by mockall, add seamsnsfisis
Port 11 categories of previously-ignored Composer tests now reachable with the mockall crate: DownloadManager, VCS/Perforce/File downloaders, VersionSelector, PlatformRepository, Auditor, installer/FilesystemRepository, RootPackageLoader, util auth/http, commands, and Cache. Extract test seams additively on concrete structs as *Interface traits (Runtime, HhvmDetector, VersionGuesser, RepositorySet, Perforce, BinaryInstaller) plus mock-field seams (Cache, Filesystem); consumers take trait objects. Mocks are defined locally in the test crates via mockall::mock!, since automock-generated mocks are cfg(test)-gated and invisible across the integration-test boundary. dataProviders are ported in full; tests blocked by unported shims stay #[ignore] with documented reasons rather than reduced or weakened. Fix product bugs surfaced by the ports: - util/github: use the exception code, not the HTTP status, for 401/403 - advisory: serialize empty audit maps as [] to match PHP json_encode - repository/filesystem and downloader/file: fix RefCell double-borrow panics Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27fix(command/show): match PHP null/isset semantics in package outputnsfisis
Three porting mismatches caused show/info output to diverge from PHP: - "not found" hint appended " in /composer.json" whenever the working-dir key existed; PHP uses isset(), which is false for the null default. Now only appended when the value is non-null. - printPackages and generatePackageTree inserted "" for a missing description instead of null, so isset() rendered a spurious trailing space (and JSON emitted "" instead of null). Both now preserve null. Un-ignores the eight rendering-gap tests these fix (plus one already passing), and rewrites the remaining ignore reasons to name the real blocker (package categorization, --no-dev filtering, RefCell borrow, installer resolution) instead of a stale generic message. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27fix(json): include property name in required-property errorsnsfisis
The jsonschema crate reports a missing required property against its parent object, leaving the instance path empty at the root. This skipped the "PROPERTY : MESSAGE" formatting that Composer produces. Append the missing property name to the path so the output shape matches. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27refactor(composer): hold managers behind *Interface traitsnsfisis
Composer/PartialComposer exposed its RepositoryManager, InstallationManager, EventDispatcher, Locker, DownloadManager, AutoloadGenerator and ArchiveManager as concrete types, but Composer's public setters (setDownloadManager() etc.) let plugins swap in subclasses. Introduce a *Interface trait per manager and store each as Rc<RefCell<dyn ...Interface>> so a replacement is honored. Only Composer's slots and the sinks fed from its accessors become trait objects; managers injected concretely at construction keep their concrete references, matching PHP semantics. Fluent setters on the affected classes now return () and Locker::update_hash is de-generified to a boxed FnOnce so the traits stay object-safe. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27test(command): port install/reinstall/require/update tester testsnsfisis
The ApplicationTester harness is in place, so port the four command test bodies that were todo!() stubs and replace the stale "requires ApplicationTester ... not implemented" ignore reasons with the actual remaining Phase-C blockers. test_install_command_errors now passes; the rest stay #[ignore] pending installer registration, the update command InputDefinition, and the InstallationManager::execute port. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27fix(validate-command): release Composer borrow before dispatching CommandEventnsfisis
Holding a RefMut<Composer> across execute() conflicted with the shared borrow taken inside EventDispatcher::get_script_listeners, panicking with "RefCell already mutably borrowed". All accessors used here take &self, so a shared borrow suffices. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27refactor: fix compiler warnings and clippy warningsnsfisis
2026-06-26feat(show-command): port the real configure() input definitionnsfisis
ShowCommand::configure registered an empty set_definition (placeholder), so every show invocation failed with option/argument-does-not-exist. Port the full argument/option list (package, version, --all/--locked/--installed/--platform/ --available/--self/--tree/--latest/--outdated/--format/... ) from PHP ShowCommand::configure. Completion-suggestion closures and the format allowed-value list are dropped to match the current InputArgument/InputOption API. Un-ignores 14 ShowCommandTest cases; the remaining 28 keep faithful bodies but stay ignored (show-rendering output gaps and remote-HTTP paths), reasons updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26fix(remove-command,pool-builder): drop Composer re-entrancy and ↵nsfisis
PRE_POOL_CREATE todo RemoveCommand::execute held composer_full_mut across deactivate_installed_plugins and event dispatch, both of which re-enter the same RefCell (composer.rs:500/446); it only uses &self getters, so borrow it immutably. PoolBuilder dispatched PluginEvents::PRE_POOL_CREATE by building an event that required moving the (unclonable) repositories/Request — left as todo!(). The event is purely plugin-facing and its result is never read in the no-plugin path (Pool::new reads self.packages directly), so skip it with a TODO(plugin) note. Removes the composer.rs re-entrancy and two todo!()s from the remove install path; remove's tests now reach the unregistered-installers blocker (factory.rs). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26fix(check-platform-reqs-command): add PlatformRepository to existing compositensfisis
execute nested the already-built InstalledRepository inside a second InstalledRepository, tripping the assertion that an InstalledRepository may not contain another. PHP adds a PlatformRepository to the existing composite via addRepository; do the same. Un-ignores CheckPlatformReqsCommandTest::test_failed_platform_requirement. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26test(command): port ↵nsfisis
show/remove/global/audit/check-platform-reqs/status/self-update/validate tests Faithfully port the remaining stubbed command test bodies from their PHP counterparts (expected values verbatim). Newly passing: remove (6), global (2), check-platform-reqs (1), status (1), audit (1), self-update (1). Tests whose ported bodies reach a genuine unported src path keep faithful bodies but stay #[ignore] with precise reasons. Dominant blockers surfaced: - ShowCommand::configure stub (empty set_definition) blocks all 42 show tests - Composer-handle RefCell re-entrancy in the Installer (composer.rs:500) and Factory::create_composer (composer.rs:446) paths - check_platform_reqs nests InstalledRepository in InstalledRepository - audit's non-locked branch (audit_command.rs:285) and write_error3 re-entrancy Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26feat(symfony-style): implement is_console_output_interface, apply real table ↵nsfisis
style is_console_output_interface downcasts dyn OutputInterface to the concrete ConsoleOutput (the sole ConsoleOutputInterface implementor) via AsAny, mirroring the existing ConsoleSectionOutput check. create_table now passes the customized TableStyle directly through StyleName::Style instead of discarding it. Un-ignores LicensesCommandTest::test_format_summary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26test(base-dependency-command): correct why-not ignore reason to trigger_errornsfisis
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26refactor(symfony-table): model rows/cells with enums instead of PhpMixednsfisis
The Table helper modeled a row's cells as PhpMixed and recovered the concrete TableCell/TableSeparator types via runtime instance_of, leaving the entire mixed/array bridge (to_row_vec, cell_colspan, row_get, ...) as todo!(). Replace that with proper Row/Cell enums: Row = HeaderDivider | Separator(TableSeparator) | Cells(Vec<Cell>) Cell = Null | Value(String) | Cell(TableCell) | Separator(TableSeparator) The internal header/body boundary that PHP detects by object identity ($divider === $row) becomes the dedicated Row::HeaderDivider variant. Style arguments (PHP string|TableStyle) become a StyleName enum, so Table::new no longer panics in resolve_style's instance_of stub; TableStyle derives Clone so named styles resolve from the registry. PhpMixed-based callers (SymfonyStyle::table, render_table, auditor's sanitize) bridge via From<PhpMixed> for Cell/Row at the boundary. Un-ignores LicensesCommandTest text-format cases (4) and BaseDependencyCommandTest::why; output matches PHP exactly. Removes ~15 impl todo!()s in the Table helper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26test(config-command): un-ignore test_config_reads_repos_by_numeric_indexnsfisis
Unblocked by the Config::merge list-form repositories fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26fix(dump-autoload-command): borrow Composer immutably in executensfisis
execute only calls &self getters on the Composer, but borrowed it via composer_full_mut. The held RefMut deadlocked the re-entrant shared borrow taken by EventDispatcher::dispatch -> get_script_listeners -> PartialComposerHandle::borrow_partial, panicking on every invocation. Un-ignores all 12 DumpAutoloadCommandTest cases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26fix(repository-command,config): delimited Preg pattern and list-form reposnsfisis
RepositoryCommand's JSON-arg detection used the un-delimited regex r"^\s*\{"; the PHP source is the delimited '{^\s*\{}', which compile_php_pattern requires. Config::merge only extracted repositories from PhpMixed::Array; a JSON array decodes to PhpMixed::List (an array with integer keys in PHP) and was silently dropped. Handle List by mapping to integer string keys. Un-ignores all 10 remaining RepositoryCommandTest cases (16/16 pass). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26test(command): port command test bodies from Composer PHPUnit suitensfisis
Faithfully port repository, base_dependency, exec, dump_autoload, run_script, licenses command tests from their PHP counterparts (expected values verbatim). Newly passing: repository (6), base_dependency (5), exec (2). Tests whose ported bodies hit a genuine unported path (HTTP/curl, event-dispatch re-entrancy, spl_autoload_register, php_uname, instance_of, un-delimited Preg patterns, Config::merge dropping list repos) keep faithful bodies but stay #[ignore] with precise reasons; no assertions weakened. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26test(search-command): port testInvalidFormat/testInvalidFlags; ignore ↵nsfisis
testSearch (HTTP layer) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>