Conversation
feat(PE-8543): undername ownership
# [3.19.0-alpha.11](v3.19.0-alpha.10...v3.19.0-alpha.11) (2025-09-12) ### Bug Fixes * **cli:** fix lint in cli ([329759e](329759e)) * **cli:** update cli docs ([e1dc35e](e1dc35e)) * **cli:** update cli interfaces for transferRecord ([3f553f1](3f553f1)) * **cli:** update cli with proper commands for setRecord ([93bf8f5](93bf8f5)) * **files:** remove extraneous file ([e63135a](e63135a)) * **todo:** add todo on unused param ([32f502b](32f502b)) ### Features * **undername ownership:** add undername ownship tooling ([3aa520f](3aa520f))
fix(readme): update readme with undername ownership rules
WalkthroughIntroduces ANT record ownership transfer and per-record metadata across API, types, CLI, and docs. Adds a new CLI command ( Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant CLI as CLI (transfer-record)
participant ANT as ANT Client
participant Proc as ANT Process
U->>CLI: transfer-record --process-id --undername --recipient
CLI->>ANT: transferRecord({ undername, recipient }, opts)
ANT->>Proc: Write(Action: Transfer-Record, Tags: Sub-Domain, Recipient)
Proc-->>ANT: Result (AoMessageResult)
ANT-->>CLI: Result
CLI-->>U: Output success/error
sequenceDiagram
autonumber
participant U as User
participant CLI as CLI (set-*-record)
participant ANT as ANT Client
participant Proc as ANT Process
rect rgba(200,230,255,0.2)
note right of U: Providing metadata (owner, displayName, logo, description, keywords)
U->>CLI: set base/undername with metadata
CLI->>ANT: setBaseNameRecord/setUndernameRecord({...metadata...})
ANT->>ANT: Build tags incl. Record-Owner, Display-Name, Logo, Description, Keywords
end
ANT->>Proc: Write(Action: Set-Record, Tags + TTL/TxId)
Proc-->>ANT: Result
ANT-->>CLI: Result
CLI-->>U: Output success/error
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
❌ Your project status has failed because the head coverage (16.13%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #549 +/- ##
==========================================
- Coverage 16.41% 16.13% -0.29%
==========================================
Files 32 32
Lines 9382 9547 +165
Branches 69 69
==========================================
Hits 1540 1540
- Misses 7840 8005 +165
Partials 2 2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
# [3.20.0-alpha.1](v3.19.0...v3.20.0-alpha.1) (2025-09-23) ### Bug Fixes * **cli:** fix lint in cli ([329759e](329759e)) * **cli:** update cli docs ([e1dc35e](e1dc35e)) * **cli:** update cli interfaces for transferRecord ([3f553f1](3f553f1)) * **cli:** update cli with proper commands for setRecord ([93bf8f5](93bf8f5)) * **files:** remove extraneous file ([e63135a](e63135a)) * **note:** use CAUTION instead of CRITICAL ([3710979](3710979)) * **readme:** update readme with undername ownership rules ([df41a56](df41a56)) * **readme:** use h3 instead of h4 ([5b3232c](5b3232c)) * **todo:** add todo on unused param ([32f502b](32f502b)) ### Features * **undername ownership:** add undername ownship tooling ([3aa520f](3aa520f))
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/cli/commands/antCommands.ts (1)
50-59: Confirmation prompts don’t abort on “No”
assertConfirmationPromptreturns a boolean, but its result is ignored, so user cancellations don’t stop execution.Apply this pattern in all four places:
- if (!o.skipConfirmation) { - await assertConfirmationPrompt( + if (!o.skipConfirmation) { + const confirmed = await assertConfirmationPrompt( `Are you sure you want to set this record on the ANT process ${writeAnt.processId}?\n${JSON.stringify( recordParams, null, 2, )}`, o, ); + if (!confirmed) throw new Error('Action cancelled by user.'); }- if (!o.skipConfirmation) { - await assertConfirmationPrompt( + if (!o.skipConfirmation) { + const confirmed = await assertConfirmationPrompt( `Are you sure you want to set this base name on the ANT process ${writeAnt.processId}?\n${JSON.stringify( params, null, 2, )}`, o, ); + if (!confirmed) throw new Error('Action cancelled by user.'); }- if (!o.skipConfirmation) { - await assertConfirmationPrompt( + if (!o.skipConfirmation) { + const confirmed = await assertConfirmationPrompt( `Are you sure you want to set this undername on the ANT process ${writeAnt.processId}?\n${JSON.stringify( params, null, 2, )}`, o, ); + if (!confirmed) throw new Error('Action cancelled by user.'); }- if (!o.skipConfirmation) { - await assertConfirmationPrompt( + if (!o.skipConfirmation) { + const confirmed = await assertConfirmationPrompt( `Are you sure you want to transfer ownership of "${undername}" to "${recipient}" on ANT process ${writeAnt.processId}?\n${JSON.stringify( { undername, recipient }, null, 2, )}`, o, ); + if (!confirmed) throw new Error('Action cancelled by user.'); }Also applies to: 81-90, 114-123, 139-148
🧹 Nitpick comments (8)
.cursor/rules/cli-command-creation.mdc (1)
7-7: Tighten wording; capitalize APIsMinor copy tweak for consistency and tone.
-When creating new apis on classes, ask if you should add them to the CLI as well. +When creating new APIs on classes, ask whether to add them to the CLI as well..cursor/rules/documentation.mdc (1)
7-9: Doc rule copy polishMinor capitalization and directive tweak.
-When creating and modifying APIs, ensure to check the README.md to see if those docs need updating. +When creating or modifying APIs, ensure README.md is updated accordingly.-When creating those APIs match them with jsdoc appropriately. +Ensure new/changed APIs have matching JSDoc.CLI.md (1)
192-192: Add a brief usage snippet for transfer-recordInclude flags to reduce guesswork.
Example to append near the command list:
transfer-record --process-id <antId> --undername <name> --recipient <address> [--skip-confirmation]src/cli/commands/antCommands.ts (2)
61-65: Reuse the existing writeAnt instanceAvoid re-instantiating the writer; use the one you already created.
- return writeANTFromOptions(o).setRecord( + return writeAnt.setRecord( recordParams, customTagsFromOptions(o), );- return writeANTFromOptions(o).setBaseNameRecord( + return writeAnt.setBaseNameRecord( params, customTagsFromOptions(o), );- return writeANTFromOptions(o).setUndernameRecord( + return writeAnt.setUndernameRecord( params, customTagsFromOptions(o), );- return writeANTFromOptions(o).transferRecord( + return writeAnt.transferRecord( { undername, recipient }, customTagsFromOptions(o), );Also applies to: 92-96, 125-129, 150-153
134-136: Validate non-empty inputsBlock empty strings to prevent accidental transfers/updates with blank names or recipients.
const undername = requiredStringFromOptions(o, 'undername'); const recipient = requiredStringFromOptions(o, 'recipient'); + if (undername.trim() === '') throw new Error('--undername must be non-empty'); + if (recipient.trim() === '') throw new Error('--recipient must be non-empty');src/cli/utils.ts (1)
800-828: Trim and sanitize metadata fieldsFilter whitespace-only values and empty keywords for cleaner payloads.
export function antRecordMetadataFromOptions< @@ ): { owner?: string; displayName?: string; logo?: string; description?: string; keywords?: string[]; } { - return { - ...(options.owner != null && - options.owner !== '' && { owner: options.owner }), - ...(options.displayName != null && - options.displayName !== '' && { displayName: options.displayName }), - ...(options.logo != null && options.logo !== '' && { logo: options.logo }), - ...(options.description != null && - options.description !== '' && { description: options.description }), - ...(options.keywords != null && - options.keywords.length > 0 && { keywords: options.keywords }), - }; + const owner = options.owner?.trim(); + const displayName = options.displayName?.trim(); + const logo = options.logo?.trim(); + const description = options.description?.trim(); + const keywords = + options.keywords?.map((k) => k.trim()).filter((k) => k.length > 0) ?? []; + + return { + ...(owner && { owner }), + ...(displayName && { displayName }), + ...(logo && { logo }), + ...(description && { description }), + ...(keywords.length > 0 && { keywords }), + }; }README.md (2)
2378-2381: Fix variable name in examples (setBaseNameRecord).Use
arnsRecord(declared) instead ofarnsName.Apply this diff:
-const ant = await ANT.init({ processId: arnsName.processId }); +const ant = await ANT.init({ processId: arnsRecord.processId });
2410-2413: Fix variable name in examples (setUndernameRecord).Use
arnsRecord(declared) instead ofarnsName.Apply this diff:
-const ant = await ANT.init({ processId: arnsName.processId }); +const ant = await ANT.init({ processId: arnsRecord.processId });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
.cursor/rules/cli-command-creation.mdc(1 hunks).cursor/rules/documentation.mdc(1 hunks).gitignore(1 hunks)CHANGELOG.md(0 hunks)CLI.md(1 hunks)README.md(7 hunks)package.json(1 hunks)src/cli/cli.ts(4 hunks)src/cli/commands/antCommands.ts(7 hunks)src/cli/options.ts(4 hunks)src/cli/types.ts(1 hunks)src/cli/utils.ts(1 hunks)src/common/ant.ts(5 hunks)src/types/ant.ts(3 hunks)
💤 Files with no reviewable changes (1)
- CHANGELOG.md
🧰 Additional context used
🧬 Code graph analysis (4)
src/types/ant.ts (1)
src/types/common.ts (1)
AoWriteAction(243-248)
src/common/ant.ts (2)
src/types/ant.ts (2)
AoANTSetUndernameRecordParams(353-355)AoANTSetBaseNameRecordParams(342-351)src/types/common.ts (2)
WriteOptions(70-74)AoMessageResult(80-85)
src/cli/cli.ts (3)
src/cli/commands/antCommands.ts (2)
setAntUndernameCLICommand(98-129)transferRecordOwnershipCLICommand(131-154)src/cli/utils.ts (1)
makeCommand(137-154)src/cli/options.ts (1)
transferRecordOwnershipOptions(483-488)
src/cli/commands/antCommands.ts (2)
src/cli/utils.ts (5)
antRecordMetadataFromOptions(800-828)assertConfirmationPrompt(596-603)writeANTFromOptions(630-639)customTagsFromOptions(419-445)requiredStringFromOptions(648-657)src/cli/types.ts (1)
CLIWriteOptionsFromAoAntParams(91-93)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build / test (esm)
- GitHub Check: build / test (integration)
🔇 Additional comments (20)
.gitignore (1)
22-22: LGTM: ignore AppleDouble filesAdding ._* prevents committing macOS AppleDouble artifacts across the tree. Good catch.
package.json (2)
84-85: Summary mismatch: trailing comma existsThe JSON here is valid; a trailing comma after example:vite is already present.
84-85: Verify CLI shebang is preserved in the built/published bin
- src/cli/cli.ts starts with #!/usr/bin/env node.
- package.json "bin" → ./lib/esm/cli/cli.js.
- lib/esm/cli/cli.js is missing in this branch so I cannot confirm the build preserves the shebang; no tsconfig sets compilerOptions.preserveShebang.
- Action: ensure the build outputs ./lib/esm/cli/cli.js with the leading shebang and executable bit (or enable preserveShebang / configure your bundler), and confirm the published package's bin file contains the shebang.
src/cli/commands/antCommands.ts (1)
150-153: Summary mismatch: no metadata passed to transferAI summary mentions metadata with transfer, but the call only sends
{ undername, recipient }.src/cli/types.ts (1)
175-175: Module option is wired end-to-end.Verified: optionMap.module is defined and included in antStateOptions (src/cli/options.ts); the spawn-ant action passes options.module into spawnANT (src/cli/cli.ts); spawnANT accepts/uses the module parameter (src/utils/ao.ts).
src/cli/options.ts (5)
259-266: Additions look good; metadata flags are clear.
--ownerand--display-namealign with the new per-record metadata model.
304-307: Good: explicit module override surfaced to CLI.No concerns; alias and description are clear.
456-456: Correct to include module in spawn options.Matches wiring in cli.ts where
options.moduleis forwarded tospawnANT.
463-469: Base-name metadata options wired correctly.Order and grouping make sense; keeps write-action options last.
482-488: Ownership transfer option group looks correct.Minimal and consistent:
processId,undername,recipientplus write tags.src/cli/cli.ts (4)
27-29: New ANT commands import: OK.Wires
setAntUndernameCLICommandandtransferRecordOwnershipCLICommand.
770-771: PropagatingmoduletospawnANTis correct.Conditional spread avoids altering defaults.
898-903: set-ant-undername command wiring: OK.Options and action handler match utils contract.
905-911: Newtransfer-recordcommand is well-scoped.Options and confirmation flow mirror other ANT actions.
src/types/ant.ts (2)
68-87: Schema extensions for record-level metadata: LGTM.Constraints and optionality are reasonable; aligns with README guidance.
336-340: New AoANTWrite.transferRecord type: matches CLI/API intent.Type signature is appropriate.
README.md (2)
2089-2110: Module selection docs/CLI: solid addition.Examples clearly show default vs custom module usage.
2688-2714: transferRecord docs/CLI: clear and matches API.No issues spotted.
src/common/ant.ts (2)
1058-1088: Tag construction for metadata is careful and filtered.Filtering out
undefinedavoids empty tags;KeywordsJSON encoding is correct.
1571-1590: Action tag vs declared handler: confirm contract expectation.Here you emit
Action: Transfer-Record. Ensure the ANT contract implements the matching handler name expected byAntWriteHandlers(see types/ant.ts comment). If the contract usesTransfer-Record, keep it and update the handler list; otherwise, adjust the Action string.
| 'transferRecordOwnership', | ||
| ] as const; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
🧩 Analysis chain
Handler name mismatch: align with action/method naming.
AntWriteHandlers adds "transferRecordOwnership" but the send path uses Action "Transfer-Record" and the public API method is transferRecord(...). This inconsistency can break handler validation and confuse integrators.
Apply this diff to align handler naming with the API:
- 'transferRecordOwnership',
+ 'transferRecord',🏁 Script executed:
#!/bin/bash
# Verify naming consistency across the repo
rg -nP -C2 '(Transfer-Record|transferRecordOwnership|transferRecord\b)' --type=ts --type=mdLength of output: 3656
🏁 Script executed:
#!/bin/bash
# Verify and show relevant occurrences for handler name consistency
files=(
"src/types/ant.ts"
"src/common/ant.ts"
"src/cli/options.ts"
"src/cli/commands/antCommands.ts"
"src/cli/cli.ts"
)
for f in "${files[@]}"; do
if [ -f "$f" ]; then
echo "----- $f -----"
nl -ba "$f" | sed -n '1,220p'
echo
else
echo "----- $f (missing) -----"
fi
done
echo "----- rg matches (context) -----"
rg -nP -C2 '(Transfer-Record|transferRecordOwnership|transferRecord\b)' --hidden || true
echo
echo "----- locate AntWriteHandlers definition -----"
rg -n --hidden 'AntWriteHandlers' || true
echo
echo "----- show src/types/ant.ts around 180-360 if present -----"
if [ -f "src/types/ant.ts" ]; then
nl -ba src/types/ant.ts | sed -n '170,360p'
fiLength of output: 4454
Align handler name with API/action: use 'transferRecord'
AntWriteHandlers contains 'transferRecordOwnership' (src/types/ant.ts:197) while the public API method is transferRecord and the Action tag is 'Transfer-Record' — rename the handler to 'transferRecord'.
- 'transferRecordOwnership',
+ 'transferRecord',📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 'transferRecordOwnership', | |
| ] as const; | |
| 'transferRecord', | |
| ] as const; |
🤖 Prompt for AI Agents
In src/types/ant.ts around lines 197 to 198, the AntWriteHandlers array contains
'transferRecordOwnership' which must be renamed to 'transferRecord' to match the
public API method and Action tag; update the literal in the as-const array to
'transferRecord' and then search-and-replace any type references, handler keys,
usages, and tests to the new name so types and runtime handler maps remain
consistent.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
CHANGELOG.md (1)
19-19: Fix typo in Features entry.“ownship” → “ownership”.
Apply this diff:
-* **undername ownership:** add undername ownship tooling ([3aa520f](https://github.com/ar-io/ar-io-sdk/commit/3aa520f3ef2ee9606f74bd9692d287e557a64881)) +* **undername ownership:** add undername ownership tooling ([3aa520f](https://github.com/ar-io/ar-io-sdk/commit/3aa520f3ef2ee9606f74bd9692d287e557a64881))
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
CHANGELOG.md(1 hunks)package.json(2 hunks)src/version.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/version.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- package.json
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
CHANGELOG.md
4-4: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
🔇 Additional comments (1)
CHANGELOG.md (1)
4-4: Resolve markdownlint MD001 (heading increment) or silence it consistently.CHANGELOG.md uses "###" under top-level "#". Choose one option and confirm with markdownlint in CI (verification here not possible — markdownlint not installed).
File: CHANGELOG.md — lines 4 and 17
Option A diff:
-### Bug Fixes +## Bug Fixes @@ -### Features +## FeaturesOption B diff:
+<!-- markdownlint-disable MD001 --> # [3.20.0-alpha.1](https://github.com/ar-io/ar-io-sdk/compare/v3.19.0...v3.20.0-alpha.1) (2025-09-23)Run to confirm:
#!/bin/bash # Run markdownlint on this file to confirm MD001 status if command -v markdownlint >/dev/null; then markdownlint CHANGELOG.md || true else echo "markdownlint not installed in this environment." fi
| @@ -1,3 +1,23 @@ | |||
| # [3.20.0-alpha.1](https://github.com/ar-io/ar-io-sdk/compare/v3.19.0...v3.20.0-alpha.1) (2025-09-23) | |||
There was a problem hiding this comment.
🧩 Analysis chain
Align version with PR intent (alpha vs stable).
PR title targets v3.20.0 on main, but header uses 3.20.0-alpha.1. Use stable 3.20.0 (and update compare link) unless you truly intend a pre-release on main.
Apply this diff:
-# [3.20.0-alpha.1](https://github.com/ar-io/ar-io-sdk/compare/v3.19.0...v3.20.0-alpha.1) (2025-09-23)
+# [3.20.0](https://github.com/ar-io/ar-io-sdk/compare/v3.19.0...v3.20.0) (2025-09-23)Verify tag/compare exist before merging:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
repo="ar-io/ar-io-sdk"
for tag in "v3.20.0" "v3.20.0-alpha.1" "v3.19.0"; do
echo "Checking tag $tag ..."
gh api "/repos/$repo/git/refs/tags/$tag" >/dev/null 2>&1 && echo " ✓ exists" || echo " ✗ missing"
done
echo "Checking compare URL ..."
gh api "/repos/$repo/compare/v3.19.0...v3.20.0" >/dev/null 2>&1 && echo " ✓ compare ok" || echo " ✗ compare missing"Length of output: 160
Align CHANGELOG header with intended release (compare URL missing)
CHANGELOG.md (lines 1-1) shows 3.20.0-alpha.1 while the PR targets v3.20.0. Verification: tags v3.19.0, v3.20.0, and v3.20.0-alpha.1 exist, but the compare URL v3.19.0...v3.20.0 is missing.
- If this is a stable release: replace the header and update the compare link — apply the diff below only after the compare URL resolves.
-# [3.20.0-alpha.1](https://github.com/ar-io/ar-io-sdk/compare/v3.19.0...v3.20.0-alpha.1) (2025-09-23)
+# [3.20.0](https://github.com/ar-io/ar-io-sdk/compare/v3.19.0...v3.20.0) (2025-09-23)- If this is a pre-release: keep 3.20.0-alpha.1 and make sure PR title/branch indicate a pre-release.
Do not merge until the compare URL (v3.19.0...v3.20.0) is valid.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # [3.20.0-alpha.1](https://github.com/ar-io/ar-io-sdk/compare/v3.19.0...v3.20.0-alpha.1) (2025-09-23) | |
| # [3.20.0](https://github.com/ar-io/ar-io-sdk/compare/v3.19.0...v3.20.0) (2025-09-23) |
|
🎉 This PR is included in version 3.20.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Includes undername ownership APIs.
Summary by CodeRabbit
New Features
Documentation
Chores