Summary
The CLI subcommand naming and the SDK method naming have drifted apart enough that you can't grep from one to the other. Tested on run402@1.53.0 / @run402/sdk@1.53.0.
This is a developer-experience bug, not a functional one — but it bites every time someone reads a CLI example in llms-cli.txt and tries to write the SDK equivalent. The natural reaction is r.contracts.setAlert(...) (mirror of run402 contracts set-alert), which throws TypeError. The fix is mechanical (aliases) and would save users time.
Mismatches discovered
Each CLI command's matching SDK method:
| CLI subcommand |
SDK method |
contracts set-alert |
contracts.setLowBalanceAlert |
contracts set-recovery |
contracts.setRecovery ✓ |
contracts provision-wallet |
contracts.provisionWallet ✓ |
contracts get-wallet |
contracts.getWallet ✓ |
contracts list-wallets |
contracts.listWallets ✓ |
contracts delete |
contracts.deleteWallet |
contracts status |
contracts.callStatus |
billing balance |
billing.checkBalance |
billing tier-checkout |
billing.tierCheckout ✓ |
billing buy-email-pack |
billing.buyEmailPack ✓ |
billing create-email |
billing.createEmailAccount |
billing link-wallet |
billing.linkWallet ✓ |
billing auto-recharge |
billing.setAutoRecharge |
auth magic-link |
auth.requestMagicLink |
auth verify |
auth.verifyMagicLink |
auth set-password |
auth.setUserPassword |
auth promote-user |
auth.promote |
auth demote-user |
auth.demote |
email create |
email.createMailbox |
email status / email info |
email.getMailbox / email.resolveMailbox |
email delete |
email.deleteMailbox |
email get-raw |
email.getRaw ✓ |
image generate |
ai.generateImage (also a different namespace from image!) |
projects schema |
projects.getSchema |
projects usage |
projects.getUsage |
projects quote |
projects.getQuote |
sender-domain register |
senderDomain.register ✓ |
sender-domain inbound-enable |
senderDomain.enableInbound |
sender-domain inbound-disable |
senderDomain.disableInbound |
Repro
import { run402 } from \"@run402/sdk@1.53.0/node\";
const r = run402();
console.log(typeof r.contracts.setAlert); // undefined
console.log(typeof r.billing.balance); // undefined
console.log(typeof r.auth.magicLink); // undefined
console.log(typeof r.email.create); // undefined
console.log(typeof r.image); // undefined (it's r.ai.generateImage)
Suggested fix
Cheap option: add alias bindings in each namespace constructor:
class Contracts {
// existing
setAlert = this.setLowBalanceAlert;
delete = this.deleteWallet;
}
class Billing {
balance = this.checkBalance;
createEmail = this.createEmailAccount;
autoRecharge = this.setAutoRecharge;
}
// etc.
Better: settle on one casing convention (camelCase, mirroring CLI kebab-case verbatim) and emit deprecation warnings on the legacy names for one minor release.
Why filing this separately from the doc table issue
The doc-table-incomplete issue (filed separately) is about which methods exist; this one is about what they're called. Even after the doc table is fixed, a user reading run402 contracts set-alert ... and writing r.contracts.setAlert(...) will still hit a TypeError.
Summary
The CLI subcommand naming and the SDK method naming have drifted apart enough that you can't grep from one to the other. Tested on
run402@1.53.0/@run402/sdk@1.53.0.This is a developer-experience bug, not a functional one — but it bites every time someone reads a CLI example in
llms-cli.txtand tries to write the SDK equivalent. The natural reaction isr.contracts.setAlert(...)(mirror ofrun402 contracts set-alert), which throwsTypeError. The fix is mechanical (aliases) and would save users time.Mismatches discovered
Each CLI command's matching SDK method:
contracts set-alertcontracts.setLowBalanceAlertcontracts set-recoverycontracts.setRecovery✓contracts provision-walletcontracts.provisionWallet✓contracts get-walletcontracts.getWallet✓contracts list-walletscontracts.listWallets✓contracts deletecontracts.deleteWalletcontracts statuscontracts.callStatusbilling balancebilling.checkBalancebilling tier-checkoutbilling.tierCheckout✓billing buy-email-packbilling.buyEmailPack✓billing create-emailbilling.createEmailAccountbilling link-walletbilling.linkWallet✓billing auto-rechargebilling.setAutoRechargeauth magic-linkauth.requestMagicLinkauth verifyauth.verifyMagicLinkauth set-passwordauth.setUserPasswordauth promote-userauth.promoteauth demote-userauth.demoteemail createemail.createMailboxemail status/email infoemail.getMailbox/email.resolveMailboxemail deleteemail.deleteMailboxemail get-rawemail.getRaw✓image generateai.generateImage(also a different namespace fromimage!)projects schemaprojects.getSchemaprojects usageprojects.getUsageprojects quoteprojects.getQuotesender-domain registersenderDomain.register✓sender-domain inbound-enablesenderDomain.enableInboundsender-domain inbound-disablesenderDomain.disableInboundRepro
Suggested fix
Cheap option: add alias bindings in each namespace constructor:
Better: settle on one casing convention (camelCase, mirroring CLI kebab-case verbatim) and emit deprecation warnings on the legacy names for one minor release.
Why filing this separately from the doc table issue
The doc-table-incomplete issue (filed separately) is about which methods exist; this one is about what they're called. Even after the doc table is fixed, a user reading
run402 contracts set-alert ...and writingr.contracts.setAlert(...)will still hit aTypeError.