1) giving JS end-users direct access to your terminal is the scariest idea ever, in terms of security, and is 100% impossible without some interfacing server language/framework (php/perl/ruby/c#/python/java/c++/NodeJS), because it is so scary.
exec() on user-input, directly, rather than building an interface in your server language is 100% as scary as giving them access to Apache itself.
3) what you want to do is build out a simple facade/proxy/whatever in your language, for playing the game.
That proxy should take user-input and decide what the user wanted to do (what piece is moving where), and based on those parameters, feed Crafty hard-coded or php-generated parameters (and not the direct-input).
This allows safety, first, but also allows you to build your communication strings any way you want, as long as the php and client agree on format.
4) on compatible browsers, you can run websockets -- the standard is volatile right now, but there are some libraries out there which can swap between websocket, flash and old-school XMLHttpRequests ("AJAX").
For a 100% native, backwards-compatible experience, just use AJAX, and poll the server either on a user-move or asking for Crafty's update.
In fact, if the user goes first, every time, then you can just respond to their request with Crafty's next move.
Next -- cheating:
Don't update the game based on what the user sends you, take what the user sends you and validate that the unit at that position (according to the server) is allowed to move in that fashion, and if not, return an error or exception which the client machine then has to deal with (reverting the move, showing an error, and making the player move again)
I should probably add that if Crafty has a decent error-handling output (eg: it outputs what was moved where and why it's wrong, in a consistent format), then your PHP interface can lean on that to handle validation.
PHP would then figure out what the user meant to do, based on the input parameters, feed a prepared statement into Crafty, and read the result -- if the result succeeded, then get Crafty's turn and feed it back to the player's response, in the format you built for communicating between client and server.
If it failed, then figure out why, and send that back to the client in an agreed-upon fashion (agreed via PHP and JS), so that your client-side app can handle the error and reset the player's turn.
Oh. Also, if you're looking to allow multiple users to play against the same instance of Crafty, or multiple instances of Crafty, or whatever, then I'd suggest a data-storage format, where you can store instances of the game-state by session-id, or by REST-based client-id, or whatever.
JSON could be seriously lightweight for that, in this case.
I won't tell you HOW to structure these things, but from a "don't hack my server and delete my c:/ drive" and a "don't move three times in a row, or teleport your queen to an insta-checkmate, or move any of MY pieces, instead of yours" standpoint, these are the key points you need to address.