Is there a way to watch attribute changes triggered from outside the AngularJS world?

It would be best to make this change inside the directive instead. If, for whatever reason, that's not possible, then there are a couple of options.

Outside the app, get a reference to any DOM element within the app. Using that reference, you can then get a reference to its scope. You could use your element with id d1. For example:

var domElement = document.getElementById('d1');
var scope = angular.element(domElement).scope();

Here are a couple of options:

Option 1

Modify the model instead of making a direct change to the view. In the link function, store the initial attribute value in a scope variable like:

scope.myvalue = attrs.attr1;

Then you can change the value outside the app (using the above reference to scope) like:

scope.$apply(function(){
    scope.myvalue = 1000;
    console.log('attribute changed');
});

Here is a fiddle

Option 2

If the view is manipulated directly with jQuery, I don't know of any use of $observe, $watch, or an isolate scope binding to the attribute that will work, because they all bind to the attribute expression itself, just once, when the link function is first run. Changing the value will cause those bindings to fail. So you'd have to $watch the attribute on the DOM element itself (rather than through attrs):

scope.$watch(function(){         
    return $(el).attr('attr1');    // Set a watch on the actual DOM value
}, function(newVal){
    scope.message = newVal;
});

Then you can change the value outside the app (using the above reference to scope) like:

scope.$apply(function(){
    $("#d1").attr("attr1",1000);
});

Here is a fiddle