@codyswann/lisa 2.164.1 → 2.165.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/skills/harper-config-yaml/SKILL.md +6 -1
- package/plugins/lisa-harper-fabric/skills/harper-realtime/SKILL.md +187 -0
- package/plugins/lisa-harper-fabric/skills/harper-realtime/agents/openai.yaml +4 -0
- package/plugins/lisa-harper-fabric/skills/harper-resources/SKILL.md +3 -2
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/skills/harper-config-yaml/SKILL.md +6 -1
- package/plugins/lisa-harper-fabric-agy/skills/harper-realtime/SKILL.md +187 -0
- package/plugins/lisa-harper-fabric-agy/skills/harper-resources/SKILL.md +3 -2
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/skills/harper-config-yaml/SKILL.md +6 -1
- package/plugins/lisa-harper-fabric-copilot/skills/harper-realtime/SKILL.md +187 -0
- package/plugins/lisa-harper-fabric-copilot/skills/harper-resources/SKILL.md +3 -2
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/skills/harper-config-yaml/SKILL.md +6 -1
- package/plugins/lisa-harper-fabric-cursor/skills/harper-realtime/SKILL.md +187 -0
- package/plugins/lisa-harper-fabric-cursor/skills/harper-resources/SKILL.md +3 -2
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/harper-fabric/skills/harper-config-yaml/SKILL.md +6 -1
- package/plugins/src/harper-fabric/skills/harper-realtime/SKILL.md +187 -0
- package/plugins/src/harper-fabric/skills/harper-resources/SKILL.md +3 -2
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harper-realtime
|
|
3
|
+
description: This skill should be used when adding or troubleshooting Harper (HarperDB/Fabric) real-time behavior: MQTT topics, WebSocket resource subscriptions, resource publish/subscribe handlers, SSE-style streaming routes, and local subscriber verification. Pairs with harper-resources, harper-config-yaml, harper-schema-graphql, and harper-build-and-deploy.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Harper Realtime
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Harper exposes live data through the same Resource model used for REST and
|
|
11
|
+
GraphQL. Exported tables/resources can be addressed as MQTT topics and WebSocket
|
|
12
|
+
paths, while custom resources can override the messaging handlers when the default
|
|
13
|
+
table behavior is not enough.
|
|
14
|
+
|
|
15
|
+
Use real-time primitives when the product needs pushed state: live feeds, activity
|
|
16
|
+
streams, collaborative views, device telemetry, or status updates. Do not replace
|
|
17
|
+
these with client polling unless the issue explicitly asks for polling.
|
|
18
|
+
|
|
19
|
+
## Resource and topic model
|
|
20
|
+
|
|
21
|
+
- A GraphQL type marked `@table @export` creates a default exported table resource.
|
|
22
|
+
- An exported JavaScript Resource class from `resources.js` creates a resource
|
|
23
|
+
endpoint with the class name as the path/topic root.
|
|
24
|
+
- Resource paths map naturally to subscription targets: collection-level
|
|
25
|
+
subscriptions use the resource name, and record-level subscriptions append the
|
|
26
|
+
record id or path segment.
|
|
27
|
+
- MQTT supports multi-level topics and wildcards. Use `resource/#` for a resource
|
|
28
|
+
subtree and `resource/+/status` for one path segment.
|
|
29
|
+
- WebSocket subscriptions target the REST resource URL. For example,
|
|
30
|
+
`ws://localhost:9926/Activity/123` subscribes to the `Activity` resource record
|
|
31
|
+
with id `123`.
|
|
32
|
+
|
|
33
|
+
Keep the URL/topic names stable. If a UI depends on `Activity/123`, changing the
|
|
34
|
+
resource export name is an API break.
|
|
35
|
+
|
|
36
|
+
## Resource methods
|
|
37
|
+
|
|
38
|
+
The MQTT plugin routes broker messages through Resource methods:
|
|
39
|
+
|
|
40
|
+
| Method | Use |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `subscribe(target, context)` | Authorize and shape subscription reads for a resource or record. |
|
|
43
|
+
| `publish(target, message, context)` | Accept or transform messages written to a topic/resource. |
|
|
44
|
+
| `connect(incomingMessages)` | Customize WebSocket connection behavior for a resource. |
|
|
45
|
+
|
|
46
|
+
For table-backed resources, prefer default behavior until the product needs a
|
|
47
|
+
custom message shape, authorization check, fan-out, or derived event. When
|
|
48
|
+
overriding, preserve built-in table behavior with `super.subscribe(...)` or
|
|
49
|
+
`super.publish(...)` where that behavior is still wanted.
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
export class Activity extends tables.Activity {
|
|
53
|
+
static async publish(target, message, context) {
|
|
54
|
+
const payload = await message;
|
|
55
|
+
await super.publish(target, payload, context);
|
|
56
|
+
return { ...payload, acceptedAt: Date.now() };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For WebSocket-only behavior, implement `connect(incomingMessages)` and return an
|
|
62
|
+
async iterable. Use the default `super.connect()` stream when you only need to
|
|
63
|
+
push extra server messages or clean up on disconnect.
|
|
64
|
+
|
|
65
|
+
## Transport choices
|
|
66
|
+
|
|
67
|
+
| Transport | Best fit | Notes |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| MQTT | Device streams, backend subscribers, wildcard topics, durable clients. | Plain MQTT defaults to port `1883`; MQTTS defaults to `8883`. |
|
|
70
|
+
| MQTT over WebSocket | Browser or edge clients using MQTT semantics. | Uses the HTTP port, default `9926`, with the `mqtt` WebSocket subprotocol. |
|
|
71
|
+
| Resource WebSocket | Browser live views tied to one REST resource path. | Enabled with the `rest` plugin unless `rest.webSocket: false` is set. |
|
|
72
|
+
| SSE/custom streaming route | One-way browser updates when WebSocket is not appropriate. | Implement as a project route; do not assume SSE automatically subscribes to Resource changes. |
|
|
73
|
+
|
|
74
|
+
Authentication is usually required for MQTT. When `mqtt.requireAuthentication` is
|
|
75
|
+
`false`, authorization still applies at the resource/table level, so public
|
|
76
|
+
connections must be explicitly allowed by roles or resource logic.
|
|
77
|
+
|
|
78
|
+
## config.yaml wiring
|
|
79
|
+
|
|
80
|
+
Component-level `config.yaml` enables the app surface:
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
rest: true
|
|
84
|
+
graphqlSchema:
|
|
85
|
+
files: schema.graphql
|
|
86
|
+
jsResource:
|
|
87
|
+
files: resources.js
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The root Harper `harper-config.yaml`, not the component `config.yaml`, owns broker
|
|
91
|
+
ports and MQTT authentication:
|
|
92
|
+
|
|
93
|
+
```yaml
|
|
94
|
+
mqtt:
|
|
95
|
+
network:
|
|
96
|
+
port: 1883
|
|
97
|
+
securePort: 8883
|
|
98
|
+
webSocket: true
|
|
99
|
+
requireAuthentication: true
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Keep the `rest`, `graphqlSchema`, and `jsResource` declarations together when a
|
|
103
|
+
project has a custom component `config.yaml`. Harper does not merge custom
|
|
104
|
+
component config with defaults. See [[harper-config-yaml]].
|
|
105
|
+
|
|
106
|
+
## Filtering and message shape
|
|
107
|
+
|
|
108
|
+
- Prefer record-level subscriptions (`Resource/<id>`) when the UI watches one
|
|
109
|
+
entity; use collection or wildcard subscriptions only when the product needs a
|
|
110
|
+
feed.
|
|
111
|
+
- Keep published messages typed and small. Send the changed record or a compact
|
|
112
|
+
event envelope, not a full page payload.
|
|
113
|
+
- Include stable identifiers in custom events: resource name, id, operation, and
|
|
114
|
+
timestamp are usually enough.
|
|
115
|
+
- Treat inaccessible or unauthenticated subscribe attempts as authorization
|
|
116
|
+
failures, not empty streams.
|
|
117
|
+
- Do not disable the audit log for tables that need real-time messages or
|
|
118
|
+
replication; Harper uses it for live subscriptions.
|
|
119
|
+
|
|
120
|
+
## Fabric and replication
|
|
121
|
+
|
|
122
|
+
For clustered/Fabric deployments, real-time behavior must match the deploy target:
|
|
123
|
+
|
|
124
|
+
- Verify against the same environment that users connect to, not only a local
|
|
125
|
+
single-node process.
|
|
126
|
+
- Use `replicated=true` when deploying a component that needs to run across Fabric
|
|
127
|
+
nodes. See [[harper-build-and-deploy]].
|
|
128
|
+
- Keep event handlers idempotent. A subscriber may reconnect and replay from the
|
|
129
|
+
latest known state.
|
|
130
|
+
- If a bug appears only across nodes, capture the target URL, topic/path, node
|
|
131
|
+
count when known, and the exact publish/subscribe commands in the evidence.
|
|
132
|
+
|
|
133
|
+
## Local verification
|
|
134
|
+
|
|
135
|
+
1. Build generated Harper assets from source:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
bun run build
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
2. Start the component:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
harper dev harper-app
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
3. In another shell, subscribe to a topic or WebSocket path:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx mqtt sub -h localhost -p 1883 -u HDB_ADMIN -P "$HARPER_PASSWORD" -t 'Activity/#' -v
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npx wscat -c ws://localhost:9926/Activity/123
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
4. Publish or mutate the watched record:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npx mqtt pub -h localhost -p 1883 -u HDB_ADMIN -P "$HARPER_PASSWORD" -t 'Activity/123' -m '{"status":"live"}'
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
5. Confirm the subscriber receives the expected message shape and that a normal
|
|
164
|
+
REST/GraphQL read returns the same resulting state.
|
|
165
|
+
|
|
166
|
+
Record the command, topic/path, payload, and observed message in PR evidence. If a
|
|
167
|
+
local Harper binary or credentials are unavailable, report that blocker instead of
|
|
168
|
+
claiming the subscription was verified.
|
|
169
|
+
|
|
170
|
+
## Project conventions
|
|
171
|
+
|
|
172
|
+
- Write resource code in TypeScript under `src/`; `harper-app/resources.js` is a
|
|
173
|
+
generated artifact. See [[harper-resources]].
|
|
174
|
+
- If real-time work changes `config.yaml`, update the project Fabric runbook and
|
|
175
|
+
re-run the smoke path. See [[harper-config-yaml]].
|
|
176
|
+
- Prefer a pushed update over a polling workaround when the issue asks for live
|
|
177
|
+
behavior.
|
|
178
|
+
- For Lisa plugin edits, change `plugins/src/harper-fabric`, run
|
|
179
|
+
`bun run build:plugins`, and commit both source and generated plugin copies.
|
|
180
|
+
|
|
181
|
+
## Sources
|
|
182
|
+
|
|
183
|
+
- [Resources overview](https://docs.harperdb.io/reference/v5/resources/overview)
|
|
184
|
+
- [Resource API](https://docs.harperdb.io/reference/v5/resources/resource-api)
|
|
185
|
+
- [WebSockets](https://docs.harperdb.io/reference/v5/rest/websockets)
|
|
186
|
+
- [MQTT configuration](https://docs.harperdb.io/reference/v4/mqtt/configuration)
|
|
187
|
+
- [Transaction logging](https://docs.harperdb.io/reference/v5/database/transaction)
|
|
@@ -70,8 +70,9 @@ jsResource:
|
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
Resources can also be registered programmatically with `server.resources.set()`.
|
|
73
|
-
See [[harper-config-yaml]] for the extension wiring
|
|
74
|
-
|
|
73
|
+
See [[harper-config-yaml]] for the extension wiring, [[harper-schema-graphql]] for
|
|
74
|
+
how the schema defines the tables resources extend, and [[harper-realtime]] when
|
|
75
|
+
`subscribe`, `publish`, or WebSocket behavior is part of the feature.
|
|
75
76
|
|
|
76
77
|
## Project conventions (TS is source)
|
|
77
78
|
|
|
@@ -52,7 +52,7 @@ unmentioned extensions stay on.
|
|
|
52
52
|
|
|
53
53
|
| Key | Purpose | Common options |
|
|
54
54
|
| --- | --- | --- |
|
|
55
|
-
| `rest` | Auto REST endpoints
|
|
55
|
+
| `rest` | Auto REST endpoints and resource WebSocket subscriptions | `true`, or an object with options such as `webSocket` |
|
|
56
56
|
| `graphqlSchema` | Define tables/types from GraphQL files | `files: '*.graphql'` — see [[harper-schema-graphql]] |
|
|
57
57
|
| `jsResource` | Load custom JS resources | `files: 'resources.js'` — see [[harper-resources]] |
|
|
58
58
|
| `static` | Serve static files over HTTP | `files: 'web/**'`, `urlPath` |
|
|
@@ -61,6 +61,11 @@ unmentioned extensions stay on.
|
|
|
61
61
|
| `dataLoader` | Seed tables from JSON/YAML | `files` |
|
|
62
62
|
| `fastifyRoutes` | Custom Fastify routes | `files: 'routes/*.js'`, `urlPath` |
|
|
63
63
|
|
|
64
|
+
For real-time work, component `config.yaml` keeps `rest`, `graphqlSchema`, and
|
|
65
|
+
`jsResource` enabled so exported resources can be addressed by HTTP/WebSocket and
|
|
66
|
+
MQTT topic paths. Broker ports and MQTT authentication live in the root
|
|
67
|
+
`harper-config.yaml`, not the component file. See [[harper-realtime]].
|
|
68
|
+
|
|
64
69
|
## External components and custom plugins
|
|
65
70
|
|
|
66
71
|
A component you depend on from npm needs a `package:` directive matching a
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harper-realtime
|
|
3
|
+
description: This skill should be used when adding or troubleshooting Harper (HarperDB/Fabric) real-time behavior: MQTT topics, WebSocket resource subscriptions, resource publish/subscribe handlers, SSE-style streaming routes, and local subscriber verification. Pairs with harper-resources, harper-config-yaml, harper-schema-graphql, and harper-build-and-deploy.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Harper Realtime
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Harper exposes live data through the same Resource model used for REST and
|
|
11
|
+
GraphQL. Exported tables/resources can be addressed as MQTT topics and WebSocket
|
|
12
|
+
paths, while custom resources can override the messaging handlers when the default
|
|
13
|
+
table behavior is not enough.
|
|
14
|
+
|
|
15
|
+
Use real-time primitives when the product needs pushed state: live feeds, activity
|
|
16
|
+
streams, collaborative views, device telemetry, or status updates. Do not replace
|
|
17
|
+
these with client polling unless the issue explicitly asks for polling.
|
|
18
|
+
|
|
19
|
+
## Resource and topic model
|
|
20
|
+
|
|
21
|
+
- A GraphQL type marked `@table @export` creates a default exported table resource.
|
|
22
|
+
- An exported JavaScript Resource class from `resources.js` creates a resource
|
|
23
|
+
endpoint with the class name as the path/topic root.
|
|
24
|
+
- Resource paths map naturally to subscription targets: collection-level
|
|
25
|
+
subscriptions use the resource name, and record-level subscriptions append the
|
|
26
|
+
record id or path segment.
|
|
27
|
+
- MQTT supports multi-level topics and wildcards. Use `resource/#` for a resource
|
|
28
|
+
subtree and `resource/+/status` for one path segment.
|
|
29
|
+
- WebSocket subscriptions target the REST resource URL. For example,
|
|
30
|
+
`ws://localhost:9926/Activity/123` subscribes to the `Activity` resource record
|
|
31
|
+
with id `123`.
|
|
32
|
+
|
|
33
|
+
Keep the URL/topic names stable. If a UI depends on `Activity/123`, changing the
|
|
34
|
+
resource export name is an API break.
|
|
35
|
+
|
|
36
|
+
## Resource methods
|
|
37
|
+
|
|
38
|
+
The MQTT plugin routes broker messages through Resource methods:
|
|
39
|
+
|
|
40
|
+
| Method | Use |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `subscribe(target, context)` | Authorize and shape subscription reads for a resource or record. |
|
|
43
|
+
| `publish(target, message, context)` | Accept or transform messages written to a topic/resource. |
|
|
44
|
+
| `connect(incomingMessages)` | Customize WebSocket connection behavior for a resource. |
|
|
45
|
+
|
|
46
|
+
For table-backed resources, prefer default behavior until the product needs a
|
|
47
|
+
custom message shape, authorization check, fan-out, or derived event. When
|
|
48
|
+
overriding, preserve built-in table behavior with `super.subscribe(...)` or
|
|
49
|
+
`super.publish(...)` where that behavior is still wanted.
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
export class Activity extends tables.Activity {
|
|
53
|
+
static async publish(target, message, context) {
|
|
54
|
+
const payload = await message;
|
|
55
|
+
await super.publish(target, payload, context);
|
|
56
|
+
return { ...payload, acceptedAt: Date.now() };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For WebSocket-only behavior, implement `connect(incomingMessages)` and return an
|
|
62
|
+
async iterable. Use the default `super.connect()` stream when you only need to
|
|
63
|
+
push extra server messages or clean up on disconnect.
|
|
64
|
+
|
|
65
|
+
## Transport choices
|
|
66
|
+
|
|
67
|
+
| Transport | Best fit | Notes |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| MQTT | Device streams, backend subscribers, wildcard topics, durable clients. | Plain MQTT defaults to port `1883`; MQTTS defaults to `8883`. |
|
|
70
|
+
| MQTT over WebSocket | Browser or edge clients using MQTT semantics. | Uses the HTTP port, default `9926`, with the `mqtt` WebSocket subprotocol. |
|
|
71
|
+
| Resource WebSocket | Browser live views tied to one REST resource path. | Enabled with the `rest` plugin unless `rest.webSocket: false` is set. |
|
|
72
|
+
| SSE/custom streaming route | One-way browser updates when WebSocket is not appropriate. | Implement as a project route; do not assume SSE automatically subscribes to Resource changes. |
|
|
73
|
+
|
|
74
|
+
Authentication is usually required for MQTT. When `mqtt.requireAuthentication` is
|
|
75
|
+
`false`, authorization still applies at the resource/table level, so public
|
|
76
|
+
connections must be explicitly allowed by roles or resource logic.
|
|
77
|
+
|
|
78
|
+
## config.yaml wiring
|
|
79
|
+
|
|
80
|
+
Component-level `config.yaml` enables the app surface:
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
rest: true
|
|
84
|
+
graphqlSchema:
|
|
85
|
+
files: schema.graphql
|
|
86
|
+
jsResource:
|
|
87
|
+
files: resources.js
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The root Harper `harper-config.yaml`, not the component `config.yaml`, owns broker
|
|
91
|
+
ports and MQTT authentication:
|
|
92
|
+
|
|
93
|
+
```yaml
|
|
94
|
+
mqtt:
|
|
95
|
+
network:
|
|
96
|
+
port: 1883
|
|
97
|
+
securePort: 8883
|
|
98
|
+
webSocket: true
|
|
99
|
+
requireAuthentication: true
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Keep the `rest`, `graphqlSchema`, and `jsResource` declarations together when a
|
|
103
|
+
project has a custom component `config.yaml`. Harper does not merge custom
|
|
104
|
+
component config with defaults. See [[harper-config-yaml]].
|
|
105
|
+
|
|
106
|
+
## Filtering and message shape
|
|
107
|
+
|
|
108
|
+
- Prefer record-level subscriptions (`Resource/<id>`) when the UI watches one
|
|
109
|
+
entity; use collection or wildcard subscriptions only when the product needs a
|
|
110
|
+
feed.
|
|
111
|
+
- Keep published messages typed and small. Send the changed record or a compact
|
|
112
|
+
event envelope, not a full page payload.
|
|
113
|
+
- Include stable identifiers in custom events: resource name, id, operation, and
|
|
114
|
+
timestamp are usually enough.
|
|
115
|
+
- Treat inaccessible or unauthenticated subscribe attempts as authorization
|
|
116
|
+
failures, not empty streams.
|
|
117
|
+
- Do not disable the audit log for tables that need real-time messages or
|
|
118
|
+
replication; Harper uses it for live subscriptions.
|
|
119
|
+
|
|
120
|
+
## Fabric and replication
|
|
121
|
+
|
|
122
|
+
For clustered/Fabric deployments, real-time behavior must match the deploy target:
|
|
123
|
+
|
|
124
|
+
- Verify against the same environment that users connect to, not only a local
|
|
125
|
+
single-node process.
|
|
126
|
+
- Use `replicated=true` when deploying a component that needs to run across Fabric
|
|
127
|
+
nodes. See [[harper-build-and-deploy]].
|
|
128
|
+
- Keep event handlers idempotent. A subscriber may reconnect and replay from the
|
|
129
|
+
latest known state.
|
|
130
|
+
- If a bug appears only across nodes, capture the target URL, topic/path, node
|
|
131
|
+
count when known, and the exact publish/subscribe commands in the evidence.
|
|
132
|
+
|
|
133
|
+
## Local verification
|
|
134
|
+
|
|
135
|
+
1. Build generated Harper assets from source:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
bun run build
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
2. Start the component:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
harper dev harper-app
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
3. In another shell, subscribe to a topic or WebSocket path:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx mqtt sub -h localhost -p 1883 -u HDB_ADMIN -P "$HARPER_PASSWORD" -t 'Activity/#' -v
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npx wscat -c ws://localhost:9926/Activity/123
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
4. Publish or mutate the watched record:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npx mqtt pub -h localhost -p 1883 -u HDB_ADMIN -P "$HARPER_PASSWORD" -t 'Activity/123' -m '{"status":"live"}'
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
5. Confirm the subscriber receives the expected message shape and that a normal
|
|
164
|
+
REST/GraphQL read returns the same resulting state.
|
|
165
|
+
|
|
166
|
+
Record the command, topic/path, payload, and observed message in PR evidence. If a
|
|
167
|
+
local Harper binary or credentials are unavailable, report that blocker instead of
|
|
168
|
+
claiming the subscription was verified.
|
|
169
|
+
|
|
170
|
+
## Project conventions
|
|
171
|
+
|
|
172
|
+
- Write resource code in TypeScript under `src/`; `harper-app/resources.js` is a
|
|
173
|
+
generated artifact. See [[harper-resources]].
|
|
174
|
+
- If real-time work changes `config.yaml`, update the project Fabric runbook and
|
|
175
|
+
re-run the smoke path. See [[harper-config-yaml]].
|
|
176
|
+
- Prefer a pushed update over a polling workaround when the issue asks for live
|
|
177
|
+
behavior.
|
|
178
|
+
- For Lisa plugin edits, change `plugins/src/harper-fabric`, run
|
|
179
|
+
`bun run build:plugins`, and commit both source and generated plugin copies.
|
|
180
|
+
|
|
181
|
+
## Sources
|
|
182
|
+
|
|
183
|
+
- [Resources overview](https://docs.harperdb.io/reference/v5/resources/overview)
|
|
184
|
+
- [Resource API](https://docs.harperdb.io/reference/v5/resources/resource-api)
|
|
185
|
+
- [WebSockets](https://docs.harperdb.io/reference/v5/rest/websockets)
|
|
186
|
+
- [MQTT configuration](https://docs.harperdb.io/reference/v4/mqtt/configuration)
|
|
187
|
+
- [Transaction logging](https://docs.harperdb.io/reference/v5/database/transaction)
|
|
@@ -70,8 +70,9 @@ jsResource:
|
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
Resources can also be registered programmatically with `server.resources.set()`.
|
|
73
|
-
See [[harper-config-yaml]] for the extension wiring
|
|
74
|
-
|
|
73
|
+
See [[harper-config-yaml]] for the extension wiring, [[harper-schema-graphql]] for
|
|
74
|
+
how the schema defines the tables resources extend, and [[harper-realtime]] when
|
|
75
|
+
`subscribe`, `publish`, or WebSocket behavior is part of the feature.
|
|
75
76
|
|
|
76
77
|
## Project conventions (TS is source)
|
|
77
78
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.165.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.165.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.165.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.165.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.165.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|