用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/CodySwannGT/lisa --skill harper-realtime命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
This skill should be used for any non-trivial request — features, bugs, stories, epics, spikes, or multi-step tasks. It accepts a ticket URL (Jira, Linear, GitHub), a file path containing a spec, or a plain-text prompt. It assembles an agent team, breaks the work into structured tasks, and manages the full lifecycle from research through implementation, code review, deploy, and empirical verification.
any non-trivial request —…
This skill should be used for any non-trivial request — features, bugs, stories, epics, spikes, or multi-step tasks. It accepts a ticket URL (Jira, Linear, GitHub), a file path containing a spec, or a plain-text prompt. It assembles an agent team, breaks the work into structured tasks, and manages the full lifecycle from research through implementation, code review, deploy, and empirical verification.
基于 SOC 职业分类
正在显示 SKILL.md
| name | harper-realtime |
| description | adding or troubleshooting… |
Harper exposes live data through the same Resource model used for REST and GraphQL. Exported tables/resources can be addressed as MQTT topics and WebSocket paths, while custom resources can override the messaging handlers when the default table behavior is not enough.
Use real-time primitives when the product needs pushed state: live feeds, activity streams, collaborative views, device telemetry, or status updates. Do not replace these with client polling unless the issue explicitly asks for polling.
@table @export creates a default exported table resource.resources.js creates a resource
endpoint with the class name as the path/topic root.resource/# for a resource
subtree and resource/+/status for one path segment.ws://localhost:9926/Activity/123 subscribes to the Activity resource record
with id 123.Keep the URL/topic names stable. If a UI depends on Activity/123, changing the
resource export name is an API break.
The MQTT plugin routes broker messages through Resource methods:
| Method | Use |
|---|---|
subscribe(target, context) | Authorize and shape subscription reads for a resource or record. |
publish(target, message, context) | Accept or transform messages written to a topic/resource. |
connect(incomingMessages) | Customize WebSocket connection behavior for a resource. |
For table-backed resources, prefer default behavior until the product needs a
custom message shape, authorization check, fan-out, or derived event. When
overriding, preserve built-in table behavior with super.subscribe(...) or
super.publish(...) where that behavior is still wanted.
export class Activity extends tables.Activity {
static async publish(target, message, context) {
const payload = await message;
await super.publish(target, payload, context);
return { ...payload, acceptedAt: Date.now() };
}
}
For WebSocket-only behavior, implement connect(incomingMessages) and return an
async iterable. Use the default super.connect() stream when you only need to
push extra server messages or clean up on disconnect.
| Transport | Best fit | Notes |
|---|---|---|
| MQTT | Device streams, backend subscribers, wildcard topics, durable clients. | Plain MQTT defaults to port 1883; MQTTS defaults to 8883. |
| MQTT over WebSocket | Browser or edge clients using MQTT semantics. | Uses the HTTP port, default 9926, with the mqtt WebSocket subprotocol. |
| Resource WebSocket | Browser live views tied to one REST resource path. | Enabled with the rest plugin unless rest.webSocket: false is set. |
| 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. |
Authentication is usually required for MQTT. When mqtt.requireAuthentication is
false, authorization still applies at the resource/table level, so public
connections must be explicitly allowed by roles or resource logic.
Component-level config.yaml enables the app surface:
rest: true
graphqlSchema:
files: schema.graphql
jsResource:
files: resources.js
The root Harper harper-config.yaml, not the component config.yaml, owns broker
ports and MQTT authentication:
mqtt:
network:
port: 1883
securePort: 8883
webSocket: true
requireAuthentication: true
Keep the rest, graphqlSchema, and jsResource declarations together when a
project has a custom component config.yaml. Harper does not merge custom
component config with defaults. See [[harper-config-yaml]].
Resource/<id>) when the UI watches one
entity; use collection or wildcard subscriptions only when the product needs a
feed.For clustered/Fabric deployments, real-time behavior must match the deploy target:
replicated=true when deploying a component that needs to run across Fabric
nodes. See [[harper-build-and-deploy]].Build generated Harper assets from source:
bun run build
Start the component:
harper dev harper-app
In another shell, subscribe to a topic or WebSocket path:
npx mqtt sub -h localhost -p 1883 -u HDB_ADMIN -P "$HARPER_PASSWORD" -t 'Activity/#' -v
npx wscat -c ws://localhost:9926/Activity/123
Publish or mutate the watched record:
npx mqtt pub -h localhost -p 1883 -u HDB_ADMIN -P "$HARPER_PASSWORD" -t 'Activity/123' -m '{"status":"live"}'
Confirm the subscriber receives the expected message shape and that a normal REST/GraphQL read returns the same resulting state.
Record the command, topic/path, payload, and observed message in PR evidence. If a local Harper binary or credentials are unavailable, report that blocker instead of claiming the subscription was verified.
src/; harper-app/resources.js is a
generated artifact. See [[harper-resources]].config.yaml, update the project Fabric runbook and
re-run the smoke path. See [[harper-config-yaml]].plugins/src/harper-fabric, run
bun run build:plugins, and commit both source and generated plugin copies.