Structuring Code for Cursor and Other AI Tools

I think this is a post that’s going to evolve over time. That’s partly because I don’t yet–as I’m starting this–understand what I’m talking about. But the thinking here is that while most of the talk of the tubes has been about whether AI can code the way we do, I think the biggest present-day potential win is to find a way to code (and organize code) in a way that makes it easy for AI to digest and do the right thing.

Part of it is establishing the right context. The Cursor IDE gives you more control over context of any aided-coding tool I’ve seen and I still have a lot of experimentation to do to see how far that can be pushed.

Give AI a Chance

But I also think it’s important to think about making requests for code in a way that an AI is likely to get right. I suspect that the basic rule there is going to be keeping things enclosed in very simple functions.

The other thing I’m thinking about is how best to create tests for these functions. Of course, I’d like the AI to write the tests at the same time that it writes the functions themselves.

So I asked Cursor to create a function for me. I wasn’t thinking too clearly when I asked, because I wound up asking for something that there’s (duh) already a native core WordPress function for. That said, I convinced myself I’d actually been really clever about because now part of the test was whether the AI would recognize that the native code just needed to be wrapped in the function.

The prompt:

write a function for a WordPress plugin that returns true if the current user can manage users and false if not.

As an aside, I learned that when you use control-K to bring up the prompting box, you can use arrow keys to move up and down through your prompt history (which it gives you a hint for, so I’m not exactly telling you something you couldn’t have found out on your own). I’m pretty sure this will prove useful in life.

Anyway, the code:

function pz_can_manage_users() {
    return current_user_can('manage_options');
}

Honestly, I think it’s pretty impressive that AI picked up that my request described an already-existent function. We shouldn’t overlook, however, that it is testing the wrong capability. The manage_options capability shows whether you are allowed to make changes to settings in the Settings submenus.

So that’s a problem. So then, for kicks, I asked:

now write a function that tests whether pz_can_manage_users works properly.

And the resulting code was:

function test_pz_can_manage_users() {
    // Test with admin user
    $admin_id = get_user_by('role', 'administrator')->ID;
    wp_set_current_user($admin_id);
    if (!pz_can_manage_users()) {
        error_log('Failed: Admin user should be able to manage users');
        return false;
    }

    // Test with subscriber user
    $subscriber = wp_create_user('test_subscriber', 'password', 'test@example.com');
    if (is_wp_error($subscriber)) {
        error_log('Failed: Could not create test subscriber');
        return false;
    }
    wp_set_current_user($subscriber);
    if (pz_can_manage_users()) {
        error_log('Failed: Subscriber should not be able to manage users');
        wp_delete_user($subscriber);
        return false;
    }

    // Cleanup
    wp_delete_user($subscriber);
    return true;
}

Given that the original function is testing for the wrong capability, but a capability that admins have and subscribers don’t, the test function will pass pz_can_manage_users() with flying colors, even though it’s totally not correct.

I prompted Cursor to fix the first function and it did so correctly. I note also that it did correctly adopt the ‘pz’ prefix I use for functions that aren’t cordoned off within class definitions.

I prompted:

in the test function, please add a check for the case where a subscriber has been granted the capabilities to add and delete users.

And this was added to the test function:

  // Test subscriber with elevated permissions
    $subscriber_user = new WP_User($subscriber);
    $subscriber_user->add_cap('create_users');
    if (!pz_can_manage_users()) {
        error_log('Failed: Subscriber with create_users capability should be able to manage users');
        wp_delete_user($subscriber);
        return false;
    }

No doubt you’ve noticed that this isn’t explicitly checking for all the capabilities involved in managing users, but I think it’s probably OK to use create_users as a proxy for the full set.

So, mixed results, but lots of typing saved and, since I’m always forgetting my core system calls, it’s nice that Cursor is capable of figuring out when one can be used and suggesting it with the right syntax (if, in this case, not the right capability to test).

Constrained requests

Overall, I think where I want to land with PeakZebra’s code is having pretty much every AI-addressable change request handled by way of creating a callback function and having the right amount of context that the AI can understand what the callback function needs to do (and can do) given the way the codebase is designed. Experiments to come…


Join the waitlist…

PeakZebra is currently in active development. Sign up for the newsletter and be the first to know when PeakZebra reaches early release! Plus occasional previews and progress updates.

Please enable JavaScript in your browser to complete this form.