opencode-courier 0.2.3 → 0.3.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.
Files changed (50) hide show
  1. package/README.md +124 -20
  2. package/dist/bounded.d.ts +2 -4
  3. package/dist/bounded.js +2 -4
  4. package/dist/cleanup.d.ts +8 -3
  5. package/dist/cleanup.js +24 -12
  6. package/dist/courier.d.ts +116 -11
  7. package/dist/courier.js +239 -55
  8. package/dist/group.d.ts +86 -0
  9. package/dist/group.js +247 -0
  10. package/dist/hub.d.ts +52 -77
  11. package/dist/hub.js +68 -65
  12. package/dist/index.d.ts +4 -8
  13. package/dist/index.js +27 -20
  14. package/dist/json.d.ts +4 -0
  15. package/dist/json.js +11 -0
  16. package/dist/later.d.ts +6 -6
  17. package/dist/later.js +6 -5
  18. package/dist/limits.d.ts +65 -0
  19. package/dist/limits.js +109 -0
  20. package/dist/notices.d.ts +125 -15
  21. package/dist/notices.js +304 -25
  22. package/dist/question/answer.js +6 -9
  23. package/dist/question/lifecycle.d.ts +10 -19
  24. package/dist/question/lifecycle.js +10 -19
  25. package/dist/question/pure.d.ts +3 -4
  26. package/dist/question/pure.js +2 -3
  27. package/dist/question/relay.js +13 -27
  28. package/dist/question/runtime.d.ts +2 -3
  29. package/dist/question/runtime.js +2 -3
  30. package/dist/relay.d.ts +2 -4
  31. package/dist/relay.js +2 -4
  32. package/dist/report.d.ts +48 -0
  33. package/dist/report.js +88 -0
  34. package/dist/roster.d.ts +29 -17
  35. package/dist/roster.js +57 -26
  36. package/dist/skill.d.ts +13 -0
  37. package/dist/skill.js +9 -0
  38. package/dist/stop.d.ts +41 -0
  39. package/dist/stop.js +120 -0
  40. package/dist/tools.d.ts +20 -0
  41. package/dist/tools.js +81 -12
  42. package/dist/tree.d.ts +102 -0
  43. package/dist/tree.js +58 -0
  44. package/dist/version.d.ts +4 -10
  45. package/dist/version.js +4 -10
  46. package/dist/watch.d.ts +55 -18
  47. package/dist/watch.js +219 -34
  48. package/dist/webhook.d.ts +10 -15
  49. package/dist/webhook.js +11 -20
  50. package/package.json +1 -1
package/dist/webhook.js CHANGED
@@ -3,7 +3,7 @@ import { readFileSync } from "node:fs";
3
3
  import { createServer } from "node:http";
4
4
  import { homedir } from "node:os";
5
5
  import { addBounded } from "./bounded.js";
6
- import { num, obj, str } from "./json.js";
6
+ import { isNotFound, num, obj, str } from "./json.js";
7
7
  import { CI_EVENTS, envelope, githubSummary, hookSummary, webhookText } from "./notices.js";
8
8
  import { scanAll } from "./storage.js";
9
9
  const PREFIX = "webhook/";
@@ -14,9 +14,8 @@ const REMEMBERED = 1000;
14
14
  const GITHUB_REPO = /^[\w.-]+\/[\w.-]+$/;
15
15
  const GENERIC_NAME = /^[\w.-]{1,64}$/;
16
16
  /**
17
- * Normalises a topic: `owner/repo` or `owner/repo#12` (optionally prefixed `github:`) is a GitHub
18
- * repository or one of its pull requests or issues; any other name of letters, digits, `.`, `_` and
19
- * `-` is a generic topic, posted to `/hook/<name>`.
17
+ * Normalises a topic: `owner/repo` or `owner/repo#12` (optionally `github:`-prefixed) is a GitHub
18
+ * repo, PR or issue; any other name of letters, digits, `.`, `_` and `-` is posted to `/hook/<name>`.
20
19
  */
21
20
  export function parseTopic(input) {
22
21
  const raw = input.trim();
@@ -69,9 +68,8 @@ function hmac(secret, body, name) {
69
68
  }
70
69
  const SIGNATURE = /^sha256=([0-9a-fA-F]{64})$/;
71
70
  /**
72
- * Checks an `X-Hub-Signature-256` header (`sha256=` and exactly 64 hex digits) in constant time and
73
- * returns the digest in canonical lowercase hex, or undefined when it does not match. Replays are
74
- * keyed by that digest, never by the header text, which could be re-cased or padded.
71
+ * Checks an `X-Hub-Signature-256` header (`sha256=` + 64 hex digits) in constant time, returning the
72
+ * digest in lowercase hex, or undefined; replays are keyed by that digest, never by the header text.
75
73
  */
76
74
  export function checkSignature(secret, body, header, name) {
77
75
  const hex = header?.match(SIGNATURE)?.[1];
@@ -109,9 +107,8 @@ function numbersOf(name, body) {
109
107
  return n === undefined ? [] : [n];
110
108
  }
111
109
  /**
112
- * Maps a GitHub delivery to its topics (`github:owner/repo` and, for pull requests and issues,
113
- * `github:owner/repo#N`) and a summary. Undefined for deliveries nobody should be woken for: pings,
114
- * CI events that have not completed, and pull request or issue actions outside `ITEM_ACTIONS`.
110
+ * Maps a GitHub delivery to its topics (`github:owner/repo`, plus `github:owner/repo#N` for PRs and
111
+ * issues) and a summary; undefined for pings, unfinished CI events and actions outside `ITEM_ACTIONS`.
115
112
  */
116
113
  export function githubEvent(name, payload) {
117
114
  const body = obj(payload);
@@ -143,10 +140,6 @@ export function genericEvent(topic, body) {
143
140
  catch { }
144
141
  return { source: "hook", name: topic, topics: [topic], summary: hookSummary(text) };
145
142
  }
146
- const isNotFound = (error) => {
147
- const tag = error?._tag;
148
- return typeof tag === "string" && tag.includes("NotFound");
149
- };
150
143
  /**
151
144
  * Delivers an event to every session subscribed to one of its topics, once per session. A session
152
145
  * OpenCode no longer knows loses its subscriptions.
@@ -236,9 +229,8 @@ async function deliver(ports, request, event, digest, seen) {
236
229
  return { status: 202, body: `delivered to ${delivered} session(s)` };
237
230
  }
238
231
  /**
239
- * Handles one request: `POST /github` with GitHub's headers, or `POST /hook/<name>` signed over
240
- * the name and the body. Anything not signed with the secret is refused before its body is parsed,
241
- * and a signature already accepted is ignored, so a captured delivery cannot be replayed.
232
+ * Handles one request: `POST /github` with GitHub's headers, or `POST /hook/<name>` signed over name
233
+ * and body; anything unsigned is refused before parsing, and a signature already accepted is ignored.
242
234
  */
243
235
  export async function receive(ports, secret, request, seen = new Set()) {
244
236
  const routed = route(request);
@@ -313,9 +305,8 @@ export function listen(config, ports) {
313
305
  });
314
306
  }
315
307
  /**
316
- * Reads the plugin's `webhook` option. The secret comes from the file named by `secretFile`, or
317
- * else the environment variable named by `secretEnv` (default `COURIER_WEBHOOK_SECRET`); never from
318
- * the option itself, so it stays out of opencode.json. Undefined when the receiver is not configured.
308
+ * Reads the `webhook` option, undefined when the receiver is not configured; the secret comes from
309
+ * `secretFile` or the env var `secretEnv` (default `COURIER_WEBHOOK_SECRET`), never from the option.
319
310
  */
320
311
  export function readConfig(options, env = process.env) {
321
312
  const option = obj(options).webhook;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-courier",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Multi-session orchestration for OpenCode V2: spawn child sessions, be woken by them. No polling.",
5
5
  "license": "MIT",
6
6
  "author": "Ivo Pogace <71701666+ivopogace@users.noreply.github.com>",