The extension can reload itself, by calling chrome.runtime.reload(), so it's a matter of triggering the extension to do it.
One method that worked for me, is to watch for tabs' onUpdated event and look for a specific URL (you have come up with), e.g. http://localhost/reloadX?id=....
This is the sample code (to be placed in background.js):
var myReloadURL = 'http://localhost/reloadX?id=' + chrome.i18n.getMessage('@@extension_id'); chrome.tabs.onUpdated.addListener(function(tabId, info, tab) { if (info.url === myReloadURL) { chrome.tabs.remove(tabId); chrome.runtime.reload(); } });
Additional permissions (to be declared in manifest.json):
... "permissions": [ ... "tabs", "http://localhost/reloadX?id=*"
myReloadURL is arbitrary and can be any URL, just doesn't have to be a real URL or the resource will be rendered unreachable.
Now, in order to reload your extension, you need to open the following address in Chrome:
http://localhost/reloadX?id=<your_extension_id>
It is up to you to choose how to trigger that on save. It could be an on-save hook in your editor, a custom grunt-watch task (since you seem to be familiar with grunt) etc .
(BTW, you don't need to reload the chrome://extensions page. It suffices to reload the extension.)
chrome://extensions, right ?grunt-watch.