aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/package
AgeCommit message (Collapse)Author
2026-06-21refactor(php-shim): drop reset()/reset_first()/end_arr() array helpersnsfisis
These slice/map wrappers mirrored PHP's internal array pointer and have no clean Rust equivalent. Remove them and replace the lone caller with direct first-element access; the rest were unused imports. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21refactor(php-shim): split filter_var into per-filter functionsnsfisis
Replace the dispatch-on-constant filter_var() and filter_var_with_options() with dedicated filter_var_boolean/url/email/ip and filter_var_int_with_range, dropping the FILTER_VALIDATE_* constants and updating all call sites. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20feat(symfony-process): port full Process class from PHPnsfisis
Faithfully port every method, field and constant of Symfony's Process.php into process.rs, replacing the reduced stub. Add the supporting pipes module (PipesInterface/AbstractPipes/UnixPipes/ WindowsPipes), ProcessUtils and the missing process exceptions (LogicException/InvalidArgumentException) with constructors. Methods now return anyhow::Result where PHP throws, take the env argument and a bool-returning callback, and borrow &mut for status-updating accessors; all callers are updated accordingly. Extend the php-shim with proc_open/proc_close (PHP-compatible signatures), proc_get_status, proc_terminate, posix_kill, uniqid, ftruncate, ftell_stream, fseek3, stream_get_contents3 and env helpers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20fix(path): propagate PathBufnsfisis
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20refactor(php-shim): drop Box wrapping from PhpMixed List/Arraynsfisis
The List and Array variants of PhpMixed boxed their elements unnecessarily. Store PhpMixed values directly and update all callers accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20fix(comparer): return instead of exiting the process on doTree failurensfisis
Composer's doCompare() calls `exit;` when the destination doTree fails, but the source branch handles the identical failure with `return;`. The asymmetry has been present since the class was first written (2413b55c6, 2018) and is almost certainly a bug. Treat it as `return` so a failed local-change detection no longer terminates the whole process. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20feat(package): implement as_package_interface upcastnsfisis
Make the Rust-only as_package_interface a required trait method and return self from each concrete implementation, replacing the todo!() default that PHP needs no equivalent for (implicit subtype coercion). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20feat: resolve trivial todo!() placeholdersnsfisis
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20refactor: auto-fix clippy warningsnsfisis
2026-06-14fix(archiver): resolve infinite recursion in exclude filter dispatchnsfisis
The Phase B port invented an ArchivableFilesFilter trait whose filter impls called self.filter, recursing forever; the name also collided with the real ArchivableFilesFilter FilterIterator class. Composer has no such interface: the finder holds GitExcludeFilter/ComposerExcludeFilter (both extending BaseExcludeFilter) and calls $filter->filter(). Drop the invented trait, type the filters as Box<dyn BaseExcludeFilter>, and implement BaseExcludeFilter on the concrete filters (accessors delegating to inner). Remove the unused generic default methods from the trait so it is dyn-compatible; they remain as inherent methods on BaseExcludeFilterBase, which is where every caller already reaches them. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14refactor(pcre): drop Result from Preg method return typesnsfisis
The Preg methods panic on PCRE failure (per the file header rationale), so their anyhow::Result wrappers never carried an Err. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14refactor(pcre): drop strict-groups Preg variantsnsfisis
Rust's type system already distinguishes participating from non-participating capture groups via Option, so the *StrictGroups methods add no safety here. Remove them and switch callers to the plain variants.
2026-06-12refactor(php-shim): replace literal sprintf calls with format!nsfisis
Convert every sprintf() call with a compile-time literal format string to format!, implementing Display for PhpMixed (delegating to php_to_string) so PhpMixed values render with PHP string semantics through {}. Also merge the format!-wrapped and conditional-literal dynamic sites into single format! calls. Genuinely runtime format strings (table styles, configurable error messages, command synopsis, progress-bar modifiers, regex-built messages) still go through sprintf. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11feat(console): resolve phase-b TODOs in doRun and IO wiringnsfisis
Wire up ConsoleIO with HelperSet/QuestionHelper, register the ErrorHandler with the IO instance, and fall back to a default output in run(). Replace resolved phase-b TODOs across the console, command, io, factory, installer, dependency_resolver, and util modules; reclassify the remaining blockers (typed Symfony command registry, stdin resource caching) as phase-c. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10feat(phase-c): resolve cross-module phase-b TODOsnsfisis
2026-06-10feat(phase-c): resolve exception-handling phase-b TODOsnsfisis
* Catch specific exception types instead of broad/placeholder handling. * Drop the shim Countable trait.
2026-06-09feat(datetime): resolve datetime TODOsnsfisis
Introduce shim functions and constants, replacing the ad-hoc chrono format strings and parse helpers used as phase-b placeholders. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08feat(phase-c): resolve PhpMixed-conversion phase-b TODOsnsfisis
Implement the foundational PhpMixed conversion infrastructure (From<bool|i64|f64|String>, order-sensitive PartialEq matching PHP ===) and resolve the category-G phase-b TODOs that depend on it: - Fix VCS driver cache paths that discarded parsed JSON or diverged on null caches (svn/forgejo/gitlab/git-bitbucket/github). - Wire up real conversions previously stubbed or dropped: suggests platform config, audit ignore-severities, composer_repository search and ProviderInfo, class_loader prefix/classmap merges, locker lock diff comparison, advisory JSON serialization, SPDX license fields. - Make GenericRule take a typed ReasonData; populate RULE_ROOT_REQUIRE with the constraint and convert PhpMixed at the call sites.
2026-06-08refactor(external-packages): drop component segment from symfony pathsnsfisis
Align the Symfony namespace mapping with the documented convention (symfony::component::X -> symfony::X) and remove now-unused console stub files. Update all import paths across the workspace. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08feat(phase-c): resolve reflection/downcast phase-b TODOsnsfisis
Resolve category F phase-b TODOs (class-string, instanceof, get_class, method_exists, __FILE__, Reflection API, downcast). - VcsRepository: dispatch drivers through a VcsDriverKind enum (instantiate/supports/php_class_name) and add constructors to the concrete VCS drivers - repository downcasts via RepositoryInterfaceHandle::downcast_rc and as_any (init/show commands, vcs ValidatingArrayLoader) - BaseCommand::is_self_update_command override replaces an instanceof - Factory::create narrows PartialComposer to ComposerHandle via as_full - InstalledVersions gains set_self_dir/set_installed_is_local_dir, replacing Reflection-based static property mutation - ClassLoader::as_array_iter ports the PHP (array) cast - drop the unnecessary __FILE__ phar branch in self-update application get_class(command) reclassified TODO(plugin); buffer_io StreamableInputInterface downcast and the ValidatingArrayLoader trait redesign left as tracked TODOs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07feat(phase-c): resolve dynamic-dispatch phase-b TODOsnsfisis
Replace the PHP `call_user_func([$obj, $method], ...)` / `$obj->{'get'.$x}()` dynamic dispatches (category E) with static Rust dispatch. - json_config_source: inject the clean-update as a typed `FnOnce(&mut JsonManipulator) -> Result<bool>` closure instead of a method-name string, dropping the call_user_func_array round-trip through PhpMixed args. The auth-config method override moves into the add/remove_config_setting closures. - config_command: dispatch addConfigSetting/addProperty on the concrete JsonConfigSource via match. - locker: select getRequires/getDevRequires and getReplaces/getProvides via match on the existing handle getters (previously stubbed to empty Vec). - create_project_command: reuse the existing get_links_for_type helper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07feat(metadata-minifier): port expand for minified package metadatansfisis
Implement MetadataMinifier::expand with the PHP list-of-arrays signature (Vec<IndexMap>) and wire it into ComposerRepository so composer/2.0 minified package metadata is expanded, resolving the phase-b TODO. minify() is left unported as it is not used in Composer itself. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07refactor(phase-c): share PlatformRepository and RepositorySet via handlesnsfisis
PHP shares a single PlatformRepository by reference across the RepositorySet, createRequest, VersionSelector, and (in show) the installed repository. The port worked with owned values / &mut, so it could not share: create_repository_set silently dropped the platform repo from the pool (PlatformRepository is not Clone), show rebuilt a fresh PlatformRepository per use, and the package discovery / show version selectors were stubbed because VersionSelector wanted an owned RepositorySet. Thread the existing PlatformRepositoryHandle (Rc<RefCell<PlatformRepository>>) through installer.rs and show, restoring the RootPackageRepository + platform repo registration and implementing same_repository via RepositoryInterfaceHandle ptr_eq. Hold package-discovery repos as a shared RepositoryInterfaceHandle, and share RepositorySet as Rc<RefCell<RepositorySet>> in the set caches and VersionSelector (which only reads it), unblocking both stubbed selector sites and dropping show's placeholder set. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06refactor(version-bumper): share caller's VersionParser with ArrayLoadernsfisis
Mirror PHP's "new ArrayLoader($parser)" by passing the existing parser instead of None. VersionParser is stateless, so behavior is unchanged; this drops the phase-b TODO. Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
2026-06-06fix(json-loader): pass decoded config to loader instead of empty mapnsfisis
The Phase B stub discarded the decoded PhpMixed and handed an empty IndexMap to LoaderInterface::load, so nothing was actually loaded. Unbox PhpMixed::Array into the map; mirror PHP's array $config type juggling by raising a TypeError for non-array decode results. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06refactor(operation,link): port __toString to Displaynsfisis
Move __toString ports to std::fmt::Display: convert Link's inherent to_string() and make OperationInterface require Display instead of a to_string() method, with each operation implementing Display. Also fix the operation __toString output to use show(false), matching SolverOperation::__toString() (was show(true)). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06refactor(link): drop phase-b shared-ownership TODOnsfisis
Link is an immutable value object and is never compared by reference identity, so cloning its fields is faithful to PHP. The shared-ownership TODO does not apply. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06fix(array-dumper): emit package links and require Link pretty constraintnsfisis
Resolve the phase-b TODO that left the supported-link-types loop as dead code (links were always an empty Vec), so requires/conflicts/provides/ replaces/require-dev are dumped again via PackageInterface::get_links_for_type, matching the PHP magic-call loop. Every Link in production is constructed with a pretty constraint (all ArrayLoader/AliasPackage/PlatformRepository/InstalledRepository sites pass one), so make Link::pretty_constraint a required String instead of Option<String>. get_pretty_constraint() now returns &str directly rather than anyhow::Result<&str>, dropping the unreachable UnexpectedValueException guard, and all call sites are updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06fix(base-package): move equals to PackageInterfaceHandle for reference identitynsfisis
PHP BasePackage::equals uses === (reference identity), unwrapping AliasPackage on both sides first. A plain &self / &dyn PackageInterface cannot express this, so implement it on the shared handle where the Rc-based identity infrastructure (as_alias, get_alias_of, ptr_eq) already lives, and drop the unimplementable trait stub. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06refactor(archiver): yield PathBuf from ArchivableFilesFinder, drop SplFileInfonsfisis
Migrate ArchivableFilesFinder off Symfony's SplFileInfo onto Path/PathBuf, resolving the phar_archiver TODO(phase-b) that required a .map() adapter to bridge SplFileInfo -> PathBuf. - ArchivableFilesFinder now yields PathBuf; accept() takes &Path; the exclude closure receives &Path and uses Path::canonicalize / is_symlink. The SplFileInfo -> PathBuf conversion happens once at the symfony get_iterator boundary (get_iterator stays SplFileInfo for cache.rs). - symfony Finder::filter callback changed to FnMut(&Path) (sole caller is the finder). - PharArchiver passes the finder straight into ArchivableFilesFilter, mirroring PHP's new ArchivableFilesFilter($files). - ZipArchiver consumes PathBuf items, computing the relative path via strip_prefix(sources) in place of SplFileInfo::getRelativePathname. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06feat(archivable-files-finder): wire exclude closure into Finder::filternsfisis
Add a Finder::filter(Box<dyn FnMut(&SplFileInfo) -> bool>) stub method and route the exclude closure through it, matching PHP's ->in()->filter() chain. FnMut faithfully represents PHP's stateful \Closure. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06fix(dependency-resolver): preserve PHP array keying for alias linksnsfisis
Mirror PHP's array_merge semantics in AliasPackage so self.version provide/replace/conflict links are appended under numeric keys ("0", "1", ...) instead of collapsing onto the target-name key. This keeps both the original and alias-version links and makes Pool::match's contains_key("0") check (= PHP isset($x[0])) work as intended. replace_self_version_dependencies now takes and returns IndexMap<String, Link>, dropping the lossy re-key-by-target in the AliasPackage/RootAliasPackage constructors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06refactor(repository): make read methods fallible and take &mut selfnsfisis
Change RepositoryInterface and WritableRepositoryInterface read methods (find_package, find_packages, get_packages, load_packages, search, get_providers, get_canonical_packages) to take &mut self and return anyhow::Result, so lazy-loading repositories such as ComposerRepository can perform fallible I/O and mutate internal state on access. Update all implementors and call sites to propagate the Result and pass mutable references. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05refactor(json): model JsonFile encode/write options as a typed structnsfisis
Replace the i64 bitmask + encode_with_indent split with a JsonEncodeOptions struct (Default = JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE, default indent). encode/write each get a default form plus an explicit encode_with_options/write_with_options variant, mirroring PHP's optional $options argument. write_with_options always encodes with self.indent, matching PHP write(). Also reconcile call sites with the PHP sources: most ported sites passed 0 where Composer omits the argument (= default flags), so JsonManipulator/ShowCommand and JsonConfigSource now use the default options; only ComposerRepository and Locker genuinely pass 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05feat(filter): share platform req filter via Rc, drop clone_boxnsfisis
PlatformRequirementFilterInterface::clone_box (a todo!() trait-object clone stub) is removed in favor of Rc<dyn ...> shared ownership, matching PHP's by-reference sharing of the single filter object. Box<dyn ...> is replaced with Rc<dyn ...> across the factory, Solver/RuleSetGenerator, VersionSelector, AutoloadGenerator, Installer and the command layer (BaseCommand/PackageDiscoveryTrait and their impls); clone_box call sites become Rc clones. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04feat(loader): wire RootPackageLoader::load end-to-endnsfisis
Resolve the remaining todo!()/placeholder sites in RootPackageLoader::load so the root package loads with real data: - Unbox config at use sites and change load()'s parameter from IndexMap<String, Box<PhpMixed>> to IndexMap<String, PhpMixed>, matching ArrayLoader::load / VersionGuesser::guess_version and dropping the redundant box/unbox round-trip at the factory call site. - Expose replace_version through CompletePackage/RootPackage inherent delegation and a RootPackageHandle method (PHP Package::replaceVersion, inherited), and apply it for the auto-versioned default. - Collect require/require-dev links via getter dispatch and build the pretty-string map feeding extractAliases/StabilityFlags/References. Also reconcile the package repositories type with Config: change CompletePackageInterface::{get,set}_repositories from Vec<IndexMap<String, PhpMixed>> to IndexMap<String, PhpMixed> (PHP's array<int|string, mixed>), wire setRepositories(config.getRepositories()), and dump repositories verbatim as a keyed array (matching PHP ArrayDumper) instead of forcing a list. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04feat(locker): wire get_locked_repository via LockArrayRepositorynsfisis
Implement LockArrayRepository::new/add_package and CanonicalPackagesTrait::get_packages (delegating to inner ArrayRepository), expose add_package on LockArrayRepositoryHandle, and add set_root_package_alias on CompleteAliasPackageHandle. With these in place, Locker::get_locked_repository is fully wired: load each locked package, register it (plus its aliasOf for AliasPackages) in package_by_name, then build CompleteAliasPackage handles for lock-file aliases via as_complete_package() narrowing. Drop the unused RepositoryInterface::clone_box default and the stale inherent LockArrayRepository::clone_box (no callers). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04feat(loader): wire ArrayLoader::load end-to-end ↵nsfisis
(create_object/configure_object/dispatch) Make ArrayLoader::load build and return a fully configured package for both the CompletePackage and RootPackage class strings. - Introduce a private CompleteOrRootPackage enum to model PHP's createObject(): CompletePackage return (RootPackage extends CompletePackage), with accessors for the inner Package, the CompletePackageInterface view, and conversion into a PackageInterfaceHandle. - create_object: instantiate CompletePackage/RootPackage by class string. - load / configure_cached_links: implement the dynamic setter dispatch ($package->{'set'.ucfirst($method)}($links)) via apply_link_setter. - configure_object: wire all ~21 setters (Package inherent + CompletePackageInterface), source/dist with Mirror conversion, suggest self.version replacement, release date, and the branch-alias return (RootAliasPackage/CompleteAliasPackage). The PHP `instanceof CompletePackage` guard in configureObject is dropped: it is unreachable since createObject is private and returns `: CompletePackage`, an invariant now enforced at compile time by the enum. DateTime parsing for `time` keeps its existing approximate scaffold (noted with a TODO). RootPackage.inner is made pub(crate) (matching CompletePackage.inner) so the loader can reach the core Package. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04feat(package): implement PackageInterface accessor layer for ↵nsfisis
Package/CompletePackage/RootPackage Fill the trait-impl todo!() across the package accessor layer so loaded packages are actually usable (the ArrayLoader::load path depends on it): - Package: implement BasePackage/PackageInterface from struct fields and existing inherent methods; Display via get_unique_name. - CompletePackage: delegate PackageInterface to inner Package. - RootPackage: delegate CompletePackageInterface/PackageInterface to inner CompletePackage; RootPackageInterface link setters delegate to Package. Correct three unfaithful trait signatures found during implementation: - get_target_dir returns Option<String> (PHP computes a normalized value; a borrow cannot represent it, and AliasPackage could not implement &str across its aliasOf handle). - RootPackageInterface link setters take IndexMap<String, Link>, matching Package and the real ArrayLoader caller (PHP RootPackage inherits Package::setRequires; the Link[] docblock was imprecise). - get_full_pretty_version takes a DisplayMode enum instead of a raw i64; the match is now exhaustive, so it returns String without an error path. Move mirror conversion to the boundaries: PackageInterface mirror methods use Vec<Mirror> (the typed form, matching the inherent methods), with array<->Mirror conversion done by the producer (ComposerRepository) and consumer (ArrayDumper). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04feat: resolve trivial todo!() sites with existing constructorsnsfisis
Replace todo!("VersionParser::new()") with VersionParser::new() at 6 call sites (array_loader, base_command, create_project_command, vcs_repository, http_downloader x2) and EventDispatcher::io_clone with self.io.clone(). All targets already exist on their types. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03fix(config,loader): wire JsonValidationException catch; drop unportable ↵nsfisis
chain TODOs JsonConfigSource::manipulate_json now downcasts the validate_schema error to JsonValidationException (matching PHP's specific catch), restores the original contents, and surfaces e.get_errors(); other errors propagate. ArrayLoader's two version-parse catch sites only had TODOs for preserving the original exception as 'previous'. shirabe_semver raises generic anyhow errors (not shim exception types), so the existing catch-all is already faithful to PHP's catch (\UnexpectedValueException), and the flat shim exception structs intentionally hold no previous field; the wrapped message already carries the original cause. Remove the stale TODOs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03refactor(downloader,repository,json): drop stale try/catch TODOs; fix svn ↵nsfisis
getFileContent catch type Remove 17 TODO(phase-b) markers across exception-modeling sites where the existing single-Result closure+match already faithfully models the PHP try/catch (catch paths only rethrow, retry, log, or silently ignore and never yield a recoverable value, so a double Result is unnecessary). Fix SvnDriver::get_file_content to catch only RuntimeException (matching PHP's catch RuntimeException) and extract its .message instead of calling e.to_string() on the anyhow::Error, which would panic while the shim exception Display is unimplemented; other errors now propagate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03feat(php-shim): align fwrite/touch2/PHP_OS_FAMILY/PHP_URL_SCHEME with PHPnsfisis
Adjust fwrite to return int|false equivalent (Option<i64>), add touch2 with mtime, implement PHP_OS_FAMILY via std::env::consts::OS, and swap the PHP_URL_HOST placeholders for the now-available PHP_URL_SCHEME. Wire these into locker, filesystem, platform, and remote_filesystem. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01fix(package): port every PHP clone operator to handle dup()nsfisis
2026-05-31feat(resolver): wire url/mirror setters in update_mirror_and_urlsnsfisis
2026-05-29refactor(repository): introduce typed LockArrayRepositoryHandlensfisis
Share LockArrayRepository via Rc<RefCell<_>> while preserving the PHP ?LockArrayRepository type strength: Request.locked_repository, Locker ::get_locked_repository, and the installer create_* helpers now thread the typed handle instead of an owned LockArrayRepository, and pool builder identity check becomes a strict ptr_eq via widening into RepositoryInterfaceHandle. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29refactor(io): unify IOInterface params to Rc<RefCell<dyn _>>nsfisis
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28refactor(repository): introduce Rc<RefCell<_>> handles for repositoriesnsfisis
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27refactor(package): pass package handles by value throughoutnsfisis
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26refactor(io): share IOInterface via Rc<RefCell<dyn _>> handlensfisis
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>