Resource Watch Channel
A resource watch channel delivers filesystem change events for a single URI subtree. Watches are short-lived and per-connection — they exist purely to push resourceWatch/changed actions back to the caller while at least one subscriber is connected.
Watches sit on top of the same bidirectional resource* family used by resourceRead, resourceWrite, and friends. Either peer MAY initiate a watch: a host uses it to observe a client-published virtual://... resource (or a per-session filesystem provider), and a client uses it to observe host-side files.
ahp-resource-watch:/<id>The id is receiver-assigned. The receiver allocates a fresh watch channel URI for every successful createResourceWatch call and returns it on CreateResourceWatchResult.channel; callers MUST treat the URI as opaque.
Subscribers receive a ResourceWatchState snapshot describing what is being watched:
ResourceWatchState { root: URI recursive: boolean excludes?: { items: string[] } includes?: { items: string[] }}The state never mutates over the life of a watch — it is captured at createResourceWatch time and returned verbatim on every subscribe and reconnect. Change events flow through the action stream (see below), not through state mutations.
Lifecycle
Section titled “Lifecycle”- Open — the caller sends
createResourceWatchonahp-root://with the root URI to watch and anyrecursive/includes/excludesfilters. The receiver allocates anahp-resource-watch:/<id>URI and returns it. - Subscribe — the caller
subscribes to that channel URI to start receivingresourceWatch/changedactions. The snapshot returned bysubscribecontains the watch descriptor. - Receive events — the receiver dispatches
resourceWatch/changedactions whenever files underrootchange. Events are batched: each action carrieschanges.items[]. - Close — the caller
unsubscribes from the channel. There is no explicit dispose command: the receiver MUST release the underlying watcher once every subscriber on every connection has unsubscribed (or those connections have dropped).
sequenceDiagram autonumber participant H as Host (caller) participant C as Client (receiver)
H->>C: createResourceWatch { channel: "ahp-root://", uri, recursive } C-->>H: { channel: "ahp-resource-watch:/abc" } H->>C: subscribe { channel: "ahp-resource-watch:/abc" } C-->>H: { snapshot: { state: { root, recursive, ... } } } Note over C: file changes detected C-->>H: action { resourceWatch/changed, changes: { items: [...] } } C-->>H: action { resourceWatch/changed, changes: { items: [...] } } H->>C: unsubscribe { channel: "ahp-resource-watch:/abc" } Note over C: no remaining subscribers — watcher releasedActions
Section titled “Actions”The channel emits exactly one action:
| Action | Direction | Meaning |
|---|---|---|
resourceWatch/changed |
receiver → caller | A batch of ResourceChange entries. Each entry has a uri and a type of 'added', 'updated', or 'deleted'. |
Subscribers consume resourceWatch/changed directly off the action stream — the reducer keeps no history.
Permission
Section titled “Permission”The receiver MUST gate createResourceWatch through the same permission flow as the rest of the resource* family. If access is denied, return PermissionDenied (-32009) with a resourceRequest payload describing the access that would be needed (see resourceRequest).
Methods and events on this channel
Section titled “Methods and events on this channel”Commands
Section titled “Commands”| Method | Channel | Why |
|---|---|---|
createResourceWatch |
ahp-root:// |
Connection-level command that opens the watcher and returns the channel URI. Symmetrical: client → server or server → client. |
subscribe / unsubscribe |
ahp-resource-watch:/<id> |
Standard subscription lifecycle. Unsubscribing the last subscriber releases the watcher. |
Actions
Section titled “Actions”| Action | Direction |
|---|---|
resourceWatch/changed |
receiver → caller (over the standard action envelope) |