@plurnk/plurnk-hooks 1.5.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/.env.defaults ADDED
@@ -0,0 +1,11 @@
1
+ # --- @plurnk/plurnk-hooks : exact command lifecycle hooks ---
2
+
3
+ # Hooks are disabled until both an exact executable and explicit event selection
4
+ # are configured. Arguments are a JSON array; no shell command is interpreted.
5
+ # PLURNK_HOOKS_COMMAND=/usr/bin/node
6
+ # PLURNK_HOOKS_ARGS=["/absolute/path/to/plurnk-hook.mjs"]
7
+ # PLURNK_HOOKS_EVENTS=loop/terminated,loop/proposal,notice/event
8
+
9
+ # One hook process receives one event envelope on stdin. This positive integer
10
+ # bounds each delivery; expiry terminates that process without affecting the loop.
11
+ PLURNK_HOOKS_TIMEOUT_MS=30000
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # @plurnk/plurnk-hooks
2
+
3
+ First-party local command hooks for
4
+ [Plurnk](https://github.com/plurnk/plurnk-service). The module selects existing
5
+ core lifecycle events and delivers each unchanged event envelope to one exact
6
+ executable on stdin. It does not define another event bus or invoke a shell.
7
+
8
+ ## Configure
9
+
10
+ Put the following in `~/.plurnk/.env`:
11
+
12
+ ```dotenv
13
+ PLURNK_HOOKS_COMMAND=/usr/bin/node
14
+ PLURNK_HOOKS_ARGS=["/absolute/path/to/plurnk-hook.mjs"]
15
+ PLURNK_HOOKS_EVENTS=loop/terminated,loop/proposal,notice/event
16
+ ```
17
+
18
+ `PLURNK_HOOKS_ARGS` is a JSON string array. `PLURNK_HOOKS_EVENTS` is an
19
+ explicit comma-separated selection from:
20
+
21
+ ```text
22
+ log/entry
23
+ loop/proposal
24
+ loop/terminated
25
+ notice/event
26
+ stream/concluded
27
+ stream/event
28
+ workspace/branch-batch
29
+ workspace/created
30
+ ```
31
+
32
+ Each process receives one line such as:
33
+
34
+ ```json
35
+ {"workspaceId":42,"method":"loop/terminated","params":{"workerId":7,"loopId":9,"result":{"status":200}}}
36
+ ```
37
+
38
+ Workspace scope and event-owned worker/loop coordinates are passed through;
39
+ the module does not infer missing coordinates. Standard output and error are
40
+ inherited from the daemon. A spawn, stdin, nonzero-exit, signal, or timeout
41
+ failure is reported to daemon diagnostics without changing loop control flow.
42
+ Event payloads retain the core contract and may contain project or model
43
+ content; treat the command and any downstream sink as trusted.
44
+
45
+ ## Test one hook
46
+
47
+ Save this as the script path named in `PLURNK_HOOKS_ARGS`:
48
+
49
+ ```js
50
+ let input = "";
51
+ process.stdin.setEncoding("utf8");
52
+ for await (const chunk of process.stdin) input += chunk;
53
+ const event = JSON.parse(input);
54
+ process.stdout.write(`${event.method} workspace=${String(event.workspaceId)}\n`);
55
+ ```
56
+
57
+ Test it before restarting the daemon:
58
+
59
+ ```sh
60
+ printf '%s\n' '{"workspaceId":42,"method":"loop/terminated","params":{}}' \
61
+ | /usr/bin/node /absolute/path/to/plurnk-hook.mjs
62
+ ```
63
+
64
+ The complete contract and event-to-core mapping live in
65
+ [`SPEC.md`](./SPEC.md). Portable defaults live in
66
+ [`.env.defaults`](./.env.defaults).
package/SPEC.md ADDED
@@ -0,0 +1,48 @@
1
+ # Plurnk command hooks specification
2
+
3
+ ## §hooks-command-delivery Exact command delivery
4
+
5
+ One selected core event starts one configured executable with its configured
6
+ argument array and `shell: false`. The child receives one complete
7
+ `{ workspaceId, method, params }` JSON envelope followed by a newline on stdin.
8
+ The core-supplied workspace scope and payload pass through without inferred
9
+ coordinates or payload translation. The child inherits the daemon's working
10
+ directory and environment; its standard output and error remain visible in the
11
+ daemon's streams.
12
+
13
+ ## §hooks-selection Event selection
14
+
15
+ `PLURNK_HOOKS_EVENTS` is a comma-separated set from the following closed
16
+ inventory. These are core event names, not a hook-local vocabulary or filter
17
+ language.
18
+
19
+ | Exposed event | Owning core notification |
20
+ |---|---|
21
+ | `log/entry` | `{§notifications-log-entry-notify}` |
22
+ | `loop/proposal` | `{§notifications-loop-proposal}` |
23
+ | `loop/terminated` | `{§notifications-loop-terminated}` |
24
+ | `notice/event` | `{§notifications-notice-event}` |
25
+ | `stream/concluded` | `{§notifications-stream-concluded}` |
26
+ | `stream/event` | `{§notifications-stream-event-on-channel-change}` |
27
+ | `workspace/branch-batch` | `{§notifications-workspace-branch-batch}` |
28
+ | `workspace/created` | `{§notifications-workspace-created}` |
29
+
30
+ ## §hooks-failure-isolation Failure isolation
31
+
32
+ Configuration errors fail module construction. Delivery runs outside the core
33
+ subscriber call. Spawn, stdin, nonzero-exit, signal, and timeout failures are
34
+ reported to daemon diagnostics and cannot alter loop state or event dispatch.
35
+ Module close first unsubscribes, then settles admitted deliveries; the required
36
+ positive timeout bounds each child process.
37
+
38
+ ## §hooks-config Operator configuration
39
+
40
+ | Variable | Contract |
41
+ |---|---|
42
+ | `PLURNK_HOOKS_COMMAND` | One executable; absent disables hooks |
43
+ | `PLURNK_HOOKS_ARGS` | Optional JSON string array; invalid JSON or non-string members fail startup |
44
+ | `PLURNK_HOOKS_EVENTS` | Required with a command; explicit comma-separated names from {§hooks-selection} |
45
+ | `PLURNK_HOOKS_TIMEOUT_MS` | Required positive integer delivery bound |
46
+
47
+ Arguments or events without a command, unknown or duplicate event names,
48
+ shell-shaped command text, and malformed timeouts fail at this module boundary.
@@ -0,0 +1,16 @@
1
+ interface HooksSeam {
2
+ subscribeToEvents(handler: (workspaceId: number | null, method: string, params: unknown) => void): () => void;
3
+ }
4
+ export interface ModuleOptions {
5
+ readonly env?: NodeJS.ProcessEnv;
6
+ readonly report?: (message: string, cause: unknown) => void;
7
+ }
8
+ export default class Module {
9
+ #private;
10
+ static init(options?: ModuleOptions): Module;
11
+ private constructor();
12
+ start(seam: HooksSeam): void;
13
+ close(): Promise<void>;
14
+ }
15
+ export {};
16
+ //# sourceMappingURL=Module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Module.d.ts","sourceRoot":"","sources":["../src/Module.ts"],"names":[],"mappings":"AAGA,UAAU,SAAS;IACf,iBAAiB,CACb,OAAO,EAAE,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAC/E,MAAM,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC/D;AAED,MAAM,CAAC,OAAO,OAAO,MAAM;;IAOvB,MAAM,CAAC,IAAI,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,CAK/C;IAED,OAAO,eAGN;IAED,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAkB3B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAI3B;CAyBJ"}
package/dist/Module.js ADDED
@@ -0,0 +1,69 @@
1
+ import { spawn } from "node:child_process";
2
+ import { hookConfig } from "./config.js";
3
+ export default class Module {
4
+ #config;
5
+ #report;
6
+ #active = new Set();
7
+ #unsubscribe = null;
8
+ #started = false;
9
+ static init(options = {}) {
10
+ return new Module(hookConfig(options.env ?? process.env), options.report ?? ((message, cause) => { console.error(`${message}:`, cause); }));
11
+ }
12
+ constructor(config, report) {
13
+ this.#config = config;
14
+ this.#report = report;
15
+ }
16
+ start(seam) {
17
+ if (this.#started)
18
+ throw new Error("hooks module already started");
19
+ this.#started = true;
20
+ if (this.#config === null)
21
+ return;
22
+ this.#unsubscribe = seam.subscribeToEvents((workspaceId, method, params) => {
23
+ if (!this.#config?.events.has(method))
24
+ return;
25
+ let observed;
26
+ observed = this.#deliver({ workspaceId, method, params })
27
+ .catch((cause) => {
28
+ try {
29
+ this.#report(`hook command failed for ${method}`, cause);
30
+ }
31
+ catch (reportCause) {
32
+ console.error(`hook failure reporter failed for ${method}:`, reportCause);
33
+ }
34
+ })
35
+ .finally(() => { this.#active.delete(observed); });
36
+ this.#active.add(observed);
37
+ });
38
+ }
39
+ async close() {
40
+ this.#unsubscribe?.();
41
+ this.#unsubscribe = null;
42
+ await Promise.all(this.#active);
43
+ }
44
+ #deliver(envelope) {
45
+ const config = this.#config;
46
+ if (config === null)
47
+ return Promise.resolve();
48
+ return new Promise((resolve, reject) => {
49
+ const child = spawn(config.command, config.args, {
50
+ shell: false,
51
+ stdio: ["pipe", "inherit", "inherit"],
52
+ signal: AbortSignal.timeout(config.timeoutMs),
53
+ killSignal: "SIGKILL",
54
+ });
55
+ child.once("error", reject);
56
+ child.once("close", (code, signal) => {
57
+ if (code === 0)
58
+ resolve();
59
+ else
60
+ reject(new Error(signal === null
61
+ ? `hook command exited with status ${String(code)}`
62
+ : `hook command exited on ${signal}`));
63
+ });
64
+ child.stdin.once("error", reject);
65
+ child.stdin.end(`${JSON.stringify(envelope)}\n`, "utf8");
66
+ });
67
+ }
68
+ }
69
+ //# sourceMappingURL=Module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Module.js","sourceRoot":"","sources":["../src/Module.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare const HOOK_EVENTS: readonly ["log/entry", "loop/proposal", "loop/terminated", "notice/event", "stream/concluded", "stream/event", "workspace/branch-batch", "workspace/created"];
2
+ export type HookEvent = typeof HOOK_EVENTS[number];
3
+ export interface HookConfig {
4
+ readonly command: string;
5
+ readonly args: string[];
6
+ readonly events: ReadonlySet<HookEvent>;
7
+ readonly timeoutMs: number;
8
+ }
9
+ export declare const hookConfig: (environment?: NodeJS.ProcessEnv) => HookConfig | null;
10
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,YACpB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,wBAAwB,EACxB,mBAAmB,CACb,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAEnD,MAAM,WAAW,UAAU;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC9B;AAwCD,eAAO,MAAM,UAAU,iBAAiB,MAAM,CAAC,UAAU,KAAiB,UAAU,GAAG,IAqBtF,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,69 @@
1
+ export const HOOK_EVENTS = [
2
+ "log/entry",
3
+ "loop/proposal",
4
+ "loop/terminated",
5
+ "notice/event",
6
+ "stream/concluded",
7
+ "stream/event",
8
+ "workspace/branch-batch",
9
+ "workspace/created",
10
+ ];
11
+ const hookArgs = (raw) => {
12
+ if (raw === undefined || raw.length === 0)
13
+ return [];
14
+ let parsed;
15
+ try {
16
+ parsed = JSON.parse(raw);
17
+ }
18
+ catch (cause) {
19
+ throw new Error("PLURNK_HOOKS_ARGS must be a JSON array of strings.", { cause });
20
+ }
21
+ if (!Array.isArray(parsed) || !parsed.every((value) => typeof value === "string")) {
22
+ throw new Error("PLURNK_HOOKS_ARGS must be a JSON array of strings.");
23
+ }
24
+ return parsed;
25
+ };
26
+ const hookEvents = (raw) => {
27
+ if (raw === undefined || raw.trim().length === 0) {
28
+ throw new Error("PLURNK_HOOKS_EVENTS must select at least one event.");
29
+ }
30
+ const known = new Set(HOOK_EVENTS);
31
+ const selected = new Set();
32
+ for (const event of raw.split(",").map((value) => value.trim())) {
33
+ if (!known.has(event))
34
+ throw new Error(`PLURNK_HOOKS_EVENTS names unknown core event '${event}'.`);
35
+ if (selected.has(event)) {
36
+ throw new Error(`PLURNK_HOOKS_EVENTS selects '${event}' more than once.`);
37
+ }
38
+ selected.add(event);
39
+ }
40
+ return selected;
41
+ };
42
+ const hookTimeoutMs = (raw) => {
43
+ const timeoutMs = Number(raw);
44
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1) {
45
+ throw new Error(`PLURNK_HOOKS_TIMEOUT_MS must be a positive integer; got ${JSON.stringify(raw)}.`);
46
+ }
47
+ return timeoutMs;
48
+ };
49
+ export const hookConfig = (environment = process.env) => {
50
+ const timeoutMs = hookTimeoutMs(environment.PLURNK_HOOKS_TIMEOUT_MS);
51
+ const command = environment.PLURNK_HOOKS_COMMAND?.trim() ?? "";
52
+ if (command.length === 0) {
53
+ if ((environment.PLURNK_HOOKS_ARGS?.length ?? 0) > 0
54
+ || (environment.PLURNK_HOOKS_EVENTS?.length ?? 0) > 0) {
55
+ throw new Error("PLURNK_HOOKS configuration has companions but no PLURNK_HOOKS_COMMAND.");
56
+ }
57
+ return null;
58
+ }
59
+ if (/\s/.test(command)) {
60
+ throw new Error("PLURNK_HOOKS_COMMAND must contain one executable; put arguments in PLURNK_HOOKS_ARGS.");
61
+ }
62
+ return {
63
+ command,
64
+ args: hookArgs(environment.PLURNK_HOOKS_ARGS),
65
+ events: hookEvents(environment.PLURNK_HOOKS_EVENTS),
66
+ timeoutMs,
67
+ };
68
+ };
69
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { default as Module } from "./Module.ts";
2
+ export { default } from "./Module.ts";
3
+ export type { ModuleOptions } from "./Module.ts";
4
+ export { hookConfig, HOOK_EVENTS } from "./config.ts";
5
+ export type { HookConfig, HookEvent } from "./config.ts";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { default as Module } from "./Module.js";
2
+ export { default } from "./Module.js";
3
+ export { hookConfig, HOOK_EVENTS } from "./config.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@plurnk/plurnk-hooks",
3
+ "version": "1.5.0",
4
+ "description": "Deliver selected Plurnk lifecycle events to exact local commands.",
5
+ "keywords": [
6
+ "plurnk",
7
+ "hooks",
8
+ "notifications",
9
+ "automation"
10
+ ],
11
+ "homepage": "https://github.com/plurnk/plurnk-service/tree/main/plurnk-hooks#readme",
12
+ "bugs": {
13
+ "url": "https://repo.possumtech.com/plurnk/plurnk-service/issues"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/plurnk/plurnk-service.git",
18
+ "directory": "plurnk-hooks"
19
+ },
20
+ "engines": {
21
+ "node": ">=26"
22
+ },
23
+ "license": "MIT",
24
+ "author": "@wikitopian",
25
+ "type": "module",
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "exports": {
30
+ ".": {
31
+ "plurnk-dev": "./src/index.ts",
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ },
35
+ "./package.json": "./package.json"
36
+ },
37
+ "files": [
38
+ "dist/**/*",
39
+ "README.md",
40
+ "SPEC.md",
41
+ ".env.defaults"
42
+ ],
43
+ "scripts": {
44
+ "test:lint": "tsc --noEmit",
45
+ "test:unit": "node --conditions=plurnk-dev --test \"src/**/*.test.ts\"",
46
+ "test": "npm run test:lint && npm run test:unit",
47
+ "build:clean": "rm -rf dist",
48
+ "build:dist": "tsc -p tsconfig.build.json",
49
+ "build": "npm run build:clean && npm run build:dist",
50
+ "prepack": "npm run build",
51
+ "prepublishOnly": "npm audit --audit-level=moderate && npm test"
52
+ }
53
+ }