That architecture from the external chat is clean, idiomatic, and fits into
the FSO Engine seamlessly. The debounced `fs.watch` combined with `delete
require.cache` gives you true hot-reloading without dropping the Express
process.
Now, we just need to wire the VM side to accept that registration and dispatch
the execution.
Here are the surgical updates to `runtime.js` in your `ast-vm` workspace to
complete the loop.
---
### The `runtime.js` Patch
Open `/mnt/mesh_shared/src/ast-vm/runtime.js` and make the following
additions:
#### 1. Add the Registry to the Constructor
In `constructor(filePath, maxBackups = 3)`:
```javascript
// The external environment state
this.shadowRegistry = {};
// Dynamic Delegated Commands (from external microservices)
this.delegatedCommands = {};
```
---
#### 2. Add `/register` and `/unregister` to `startDebugServer`
Inside `startDebugServer(port = 8080)`:
```javascript
else if (req.method === 'POST' && req.url === '/register') {
getBody().then(data => {
const { verb, endpoint, start_msg, timeout, fail_msg } =
data;
if (!verb || !endpoint) {
res.statusCode = 400;
return res.end(JSON.stringify({ error: 'Missing verb
or endpoint' }));
}
const upperVerb = verb.toUpperCase();
this.delegatedCommands[upperVerb] = {
endpoint,
start_msg: start_msg || `You attempt to
${verb.toLowerCase()}...`,
timeout: timeout || 2000,
fail_msg: fail_msg || `Nothing happens.`
};
console.log(`
[SYS] Registered external command: ${upperVerb} -> ${endpoint}`);
res.end(JSON.stringify({ status: 'registered', verb:
upperVerb }));
});
}
else if (req.method === 'POST' && req.url === '/unregister') {
getBody().then(data => {
const upperVerb = (data.verb || '').toUpperCase();
delete this.delegatedCommands[upperVerb];
console.log(`
[SYS] Unregistered external command: ${upperVerb}`);
res.end(JSON.stringify({ status: 'unregistered', verb:
upperVerb }));
});
}
```
---
#### 3. Intercept and Dispatch in `processInput`
Inside `processInput(input, targetVar)`, right in the `if (targetVar ===
'__AUTO_CMD__')` block, check for delegated commands before falling back to
globals:
```javascript
// Check local room actions/exits first
if (this.vm.actions && this.vm.actions[cleanVerb]) {
targetLabel = this.vm.actions[cleanVerb];
}
// Check dynamically registered external commands!
else if (this.delegatedCommands[cleanVerb]) {
this.executeDelegatedCommand(cleanVerb, cleanWords.slice(1),
targetVar);
return; // Return early; the async dispatcher will re-prompt
when finished
}
// Fall back to built-in globals
else if (this.vm.globals && this.vm.globals[cleanVerb]) {
targetLabel = this.vm.globals[cleanVerb];
}
```
---