Custom page for editing custom post type on frontend based on url

You can add custom url structures with add_rewrite_rule for example the proposed structure in your question can be achieved with something like…

add_action( 'init', function() {
    add_rewrite_rule( '^jobs/([^/]+)/edit/?$', 'index.php?post_type=jobs&name=$matches[1]', 'top' );
} );

So now if you visited https://example.com/jobs/job-title-example/edit/ you should see exactly the same as if you were to visit https://example.com/jobs/job-title-example/ this is because we’re telling WordPress to handle the request in a similar way by passing the post_type and name as query parameters. Essentially the same as visiting https://example.com/?post_type=jobs&name=job-title-example.

However, it might be a good idea to build the rewrite rule dynamically based off of the post type properties, something like…

add_action( 'init', function() {
    
    if ( $post_type = get_post_type_object( 'job' ) ) {
        $rewrite = !empty( $post_type->rewrite ) && is_array( $post_type->rewrite ) ? $post_type->rewrite : [];
        $with_front = !empty( $rewrite[ 'with_front' ] ) ? $rewrite[ 'with_front' ] : false;
        $slug = !empty( $rewrite[ 'slug' ] ) ? $rewrite[ 'slug' ] : null;
        $slug = $slug ?: $post_type->name;

        $front="";

        if ( $with_front ) {
            $permalink_structure = get_option( 'permalink_structure' );
            $front = substr( $permalink_structure, 0, strpos( $permalink_structure, '%' ) );
        }

        $slug = $front ? "https://wordpress.stackexchange.com/" . $slug : $slug;

        add_rewrite_rule( '^' . $front . $slug . '/([^/]+)/edit/?$', 'index.php?post_type=" . $post_type->name . "&name=$matches[1]', 'top' );
    }

}, PHP_INT_MAX );

So now if you change your jobs post type rewrite properties the rewrite rule above will adapt automatically.

Always remember to flush your rewrite rules if making any changes.

I would also concider adding a custom query var to use in templates, like so…

add_filter( 'query_vars', function( $vars ) {
    $vars[] = 'frontend_editor';
    return $vars;
} );

And add to your rewrite rule with &frontend_editor=1 like so…

add_action( 'init', function() {
    
    if ( $post_type = get_post_type_object( 'job' ) ) {
        $rewrite = !empty( $post_type->rewrite ) && is_array( $post_type->rewrite ) ? $post_type->rewrite : [];
        $with_front = !empty( $rewrite[ 'with_front' ] ) ? $rewrite[ 'with_front' ] : false;
        $slug = !empty( $rewrite[ 'slug' ] ) ? $rewrite[ 'slug' ] : null;
        $slug = $slug ?: $post_type->name;

        $front="";

        if ( $with_front ) {
            $permalink_structure = get_option( 'permalink_structure' );
            $front = substr( $permalink_structure, 0, strpos( $permalink_structure, '%' ) );
        }

        $slug = $front ? "https://wordpress.stackexchange.com/" . $slug : $slug;

        // We added `frontend_editor` parameter here.
        add_rewrite_rule( '^' . $front . $slug . '/([^/]+)/edit/?$', 'index.php?post_type=" . $post_type->name . "&name=$matches[1]&frontend_editor=1', 'top' );
    }

}, PHP_INT_MAX );

This is essentially the same as visiting:

https://example.com/jobs/job-title-example/?frontend_editor=1

Or

https://example.com/?post_type=jobs&name=job-title-example&frontend_editor=1

In theory you should now be able to update your template to show the editor, for example…

single-jobs.php

<?php get_header(); ?>

<!-- Check if user is authorised to edit current job -->
<?php if ( is_user_logged_in() && (int)get_post_field( 'post_author', get_the_ID() ) === get_current_user_id() ): ?>

    <!-- Check for our edit parameter -->
    <?php if ( get_query_var( 'frontend_editor', false ) ): ?>

        <form action="">
            ...
        </form>

    <?php endif ?>
<?php endif ?>

<?php get_footer(); ?>

I think that should be enough to point you in the right direction. Please note that none of the above code has been tested!