Generate a complete Facet + Target + Repo + Interface + Modifiers scaffold following Crane conventions
Generates a complete Facet-Target-Repo scaffold for new Crane features following conventions.
npx claudepluginhub cyotee/cyotee-claude-plugin-crane<FeatureName>Generate a complete set of files for a new Crane feature following the Facet-Target-Repo pattern.
The user provides a feature name in PascalCase (e.g., MyFeature).
Determine output directory:
contracts/ directory structureGenerate the following files:
I{FeatureName}.sol)// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
interface I{FeatureName} {
// Events
// Errors
// View functions
// State-changing functions
}
{FeatureName}Repo.sol)// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
import {I{FeatureName}} from "./interfaces/I{FeatureName}.sol";
library {FeatureName}Repo {
bytes32 internal constant STORAGE_SLOT = keccak256(abi.encode("crane.feature.{featurename}"));
struct Storage {
// Add storage fields
}
function _layout(bytes32 slot_) internal pure returns (Storage storage layout_) {
assembly { layout_.slot := slot_ }
}
function _layout() internal pure returns (Storage storage) {
return _layout(STORAGE_SLOT);
}
function _initialize(Storage storage layout_) internal {
// Initialize storage
}
function _initialize() internal {
_initialize(_layout());
}
}
{FeatureName}Target.sol)// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
import {I{FeatureName}} from "./interfaces/I{FeatureName}.sol";
import {{FeatureName}Repo} from "./{FeatureName}Repo.sol";
abstract contract {FeatureName}Target is I{FeatureName} {
// Implement interface functions using Repo
}
{FeatureName}Facet.sol)// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
import {IFacet} from "@crane/contracts/interfaces/IFacet.sol";
import {I{FeatureName}} from "./interfaces/I{FeatureName}.sol";
import {{FeatureName}Target} from "./{FeatureName}Target.sol";
contract {FeatureName}Facet is {FeatureName}Target, IFacet {
function facetName() external pure returns (string memory) {
return type({FeatureName}Facet).name;
}
function facetInterfaces() external pure returns (bytes4[] memory interfaces_) {
interfaces_ = new bytes4[](1);
interfaces_[0] = type(I{FeatureName}).interfaceId;
}
function facetFuncs() external pure returns (bytes4[] memory funcs_) {
// Return function selectors
}
function facetMetadata() external pure returns (
string memory name_,
bytes4[] memory interfaces_,
bytes4[] memory funcs_
) {
name_ = this.facetName();
interfaces_ = this.facetInterfaces();
funcs_ = this.facetFuncs();
}
}
{FeatureName}Modifiers.sol) - Optional// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
import {{FeatureName}Repo} from "./{FeatureName}Repo.sol";
abstract contract {FeatureName}Modifiers {
// Add modifiers that delegate to Repo guard functions
}
Create directory structure:
{output-dir}/
├── interfaces/
│ └── I{FeatureName}.sol
├── {FeatureName}Repo.sol
├── {FeatureName}Target.sol
├── {FeatureName}Facet.sol
└── {FeatureName}Modifiers.sol (if needed)
Verify compilation:
forge build to verify no syntax errorsInform the user: