feat(explorer): drag-and-drop ABI and source import from acton build/project folders - #1228
feat(explorer): drag-and-drop ABI and source import from acton build/project folders#12281IxI1 wants to merge 4 commits into
Conversation
Registering ABIs one by one is tedious for multi-contract projects: each
file needs a manual pick plus a hand-copied code hash. Let the ABI
catalog accept a whole acton build/ directory instead - drag-and-drop it
anywhere onto the table (or use the new "Import build folder" button)
and every contract registers in one go.
The import pairs build/abi/<Name>.json (raw compiler ABI) with
build/<Name>.json ({code_boc64, hash}) by basename, falling back to the
ABI's contract_name; when same-named artifacts exist in several places,
the one next to the abi/ directory wins, and genuinely different hashes
all attach to the ABI. cache/ (stale versions), logs/, sessions/ and
hidden directories are skipped, hashes are normalized (hex or base64),
duplicates collapse, and ABIs with no matching code artifact surface as
warnings in the result toast. Files that already carry inline
code_hashes (exported extended ABIs) register as-is.
Also drop the top: -4px offset that pushed the "environment" badge
above the vertical center of its row.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
✅ Deploy Preview for acton-staging canceled.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4332fd8c0e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const key = registration.abi.code_hashes[0] | ||
| if (key && seen.has(key)) { | ||
| continue |
There was a problem hiding this comment.
Preserve aliases when deduplicating registrations
When two imported extended ABIs share their first code hash but contain different additional hashes, this drops the entire later registration, so its unique aliases never reach registerCompilerAbis. Overlaps on a non-first hash are conversely retained as conflicting registrations; BrowserMetadataRegistry.getCompilerAbis then returns whichever matching entry appears first in storage. Deduplicate or merge registrations using the complete code_hashes sets rather than only element zero.
Useful? React with 👍 / 👎.
The source catalog's manual form wants one very specific JSON per
contract, and nothing on the page says which file that is. Let the page
take the whole project instead: drag-and-drop the project root (or use
the new "Import project folder" button) and every source artifact found
anywhere in the tree - typically build/sources/<Name>.source.json -
registers in one batch. If none are found, the error explains how to
generate them (acton build --output-sources build/sources).
Artifact detection is shape-based and accepts both the current
{code_hash, verified, bundle} artifact and the legacy bundles-array
emitted by CLIs predating fcb3a1a (feat(verifier): single bundle for
one code hash); the manual form now takes the legacy shape too, since
it shares the parser. Registrations dedupe by code hash.
The ABI catalog's drop importer generalizes to buildImport.ts to host
the shared directory walker and the new source plan; its behavior is
unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 92d7263dc8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return path | ||
| .split("/") | ||
| .slice(0, -1) | ||
| .some(segment => SKIPPED_DIRS.has(segment) || segment.startsWith(".")) |
There was a problem hiding this comment.
Allow source artifacts inside hidden output directories
When --output-sources targets a hidden directory, folder import silently excludes every artifact because this predicate rejects any path segment beginning with .. This is a supported configuration exercised by tests/integration/flags_tests.rs:1463-1470, which generates .studio/sources/simple.source.json; dropping that project therefore reports that no source artifacts were found even though the generated artifact is present. Hidden-directory filtering should not discard recognized source artifacts, or .studio/sources should be explicitly allowed.
Useful? React with 👍 / 👎.
… registry Source deletion always went through the localnet control API (acton_deleteVerifiedSourceArtifact), which does not exist for the browser environment registry actonscan uses - so deleting a source registered on the site always failed with "Failed to delete source artifact" while ABI deletion (which goes through the registry) worked. Route deletion by origin: entries with a backend artifactId keep using the control API, browser-environment entries delete from the metadata registry by code hash. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7528e59ec2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (seenAbiBases.has(candidate.base)) { | ||
| continue |
There was a problem hiding this comment.
Keep same-named ABIs from separate build trees
When the selected directory contains multiple build trees with the same contract artifact basename—for example project-a/build/abi/Wallet.json and project-b/build/abi/Wallet.json—this global basename set skips the later raw ABI before its sibling code artifact can be matched. If those builds have different code hashes or ABI versions, only the first is registered; scope this deduplication to the ABI directory or merge candidates after matching their hashes.
Useful? React with 👍 / 👎.
Three edge cases from review of the drop importer: - Registration dedup now works over the COMPLETE code-hash sets: a later registration sharing any hash with an earlier one merges its remaining hashes into that entry instead of being dropped whole (losing aliases) or slipping through as a conflicting duplicate when the overlap was on a non-first hash. - ABI-candidate dedup keys on dir+basename instead of basename alone, so a drop spanning several build trees keeps same-named contracts with different code hashes; the final hash-set dedup still collapses true duplicates. - .studio/ is exempt from the hidden-directory skip: acton-studio keeps generated source artifacts there (--output-sources .studio/sources), and dropping such a project found nothing. Other dot-dirs (.git etc.) stay skipped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9d86c5fc23
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const existingIndex = hashes | ||
| .map(hash => indexByHash.get(hash)) | ||
| .find((index): index is number => index !== undefined) |
There was a problem hiding this comment.
Merge all overlapping hash groups
When a later extended ABI bridges two previously separate groups—for example registrations with hashes [A, B], [C, D], then [B, C]—this selects only the first matching index and leaves the second group intact, producing entries [A, B, C] and [C, D] that still conflict on C. Fresh evidence in the revised implementation is this single existingIndex lookup; merge every existing group referenced by the incoming hashes and remap all of their hashes to the consolidated entry.
Useful? React with 👍 / 👎.
What
Two commits, one theme — stop cherry-picking JSON files into the catalogs by hand:
/abi): drag-and-drop an actonbuild/directory anywhere onto the table (or click the new Import build folder button) and every contract's ABI registers in one batch, with code hashes filled in automatically./sources): drag-and-drop the whole project root (or click Import project folder) and every source artifact found in the tree — typicallybuild/sources/<Name>.source.json— registers in one batch. If a project has no generated artifacts yet, the error says exactly what to run (acton build --output-sources build/sources).The existing one-file manual forms are unchanged on both pages.
Why
Registering ABIs for a multi-contract project is one file at a time: pick the right JSON out of
build/abi/(not obvious which), then hand-copy the code hash from the matchingbuild/<Name>.json. The source form is worse — it wants one very specific JSON per contract and nothing on the page says which file that is. For a 5-contract project that's ten rounds of guesswork the build output already knows the answers to.How
Shared importer in
explorer-core/src/components/buildImport.ts, used by both catalogs:webkitGetAsEntry, drainingreadEntrieschunks), collecting only.jsonfiles;cache/(stale contract versions),logs/,sessions/,node_modules/,target/,dist/and hidden directories are skipped. Detection is shape-based, not name-based, so stray project JSON is ignored silently.build/abi/<Name>.json(raw compiler ABI) withbuild/<Name>.json({code_boc64, hash}) by basename, falling back to the ABI'scontract_name. When same-named artifacts exist in several places, the one next to theabi/directory wins; genuinely different hashes all attach to the one ABI. Hashes normalize (hex or base64), duplicates collapse, unmatched ABIs surface as warnings in the toast. Files already carrying inlinecode_hashes(exported extended ABIs) register as-is.{code_hash, verified, bundle}and the legacybundlesarray emitted by CLIs predating fcb3a1a (feat(verifier): single bundle for one code hash). The manual form shares the parser, so it now takes legacy artifacts too. Registrations dedupe by code hash.registerCompilerAbis/registerSourcesbatch per drop.Also fixes the
environmentbadge sitting above the vertical center of its row (leftovertop: -4px).Testing
tests/buildImport.test.ts): basename + contract_name matching, sibling-dir preference, multi-hash artifacts, cache/logs filtering, base64 normalization, inline-hash passthrough, dedupe, warning on unmatched ABI; source-artifact discovery in a project tree, legacybundlesshape, code-hash dedupe, skipped dirs, no-artifacts hint.build/<Name>.json, source code hashes cross-match them; the real source artifacts were generated by a pre-fcb3a1a1d CLI, so the legacy path is exercised with production data.bun fmt/bun lint/tsc --noEmit/ fullbun test(169 tests) clean.🤖 Generated with Claude Code