@plurnk/plurnk-execs 0.3.0 → 0.4.1
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/README.md +3 -3
- package/SPEC.md +29 -9
- package/dist/BaseExecutor.d.ts +2 -1
- package/dist/BaseExecutor.d.ts.map +1 -1
- package/dist/BaseExecutor.js +10 -0
- package/dist/BaseExecutor.js.map +1 -1
- package/dist/SubprocessExecutor.d.ts +3 -1
- package/dist/SubprocessExecutor.d.ts.map +1 -1
- package/dist/SubprocessExecutor.js +55 -10
- package/dist/SubprocessExecutor.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,10 +9,10 @@ Framework + contract for `@plurnk/plurnk-execs-*` runtime executor packages. Con
|
|
|
9
9
|
|
|
10
10
|
## Exports
|
|
11
11
|
|
|
12
|
-
- `BaseExecutor` — abstract base a `@plurnk/plurnk-execs-*` sibling subclasses: declares its output channels
|
|
13
|
-
- `SubprocessExecutor` — concrete `BaseExecutor` for subprocess runtimes (sh/node/python): spawns via `resolveRuntime`, streams stdout/stderr, honors cancellation, reports exit code
|
|
12
|
+
- `BaseExecutor` — abstract base a `@plurnk/plurnk-execs-*` sibling subclasses: declares its output channels, implements `run(args) → ExecResult`, and optionally overrides `probe()` (env availability) and `effect(target)` (proposal gating).
|
|
13
|
+
- `SubprocessExecutor` — concrete `BaseExecutor` for subprocess runtimes (sh/node/python): spawns via `resolveRuntime`, streams stdout/stderr, honors cancellation (process-group kill on abort), reports exit code, probes its `binary`. Siblings subclass it.
|
|
14
14
|
- `discover(options?)` — scans `node_modules/@plurnk/` for `plurnk.kind === "exec"` packages and builds the runtime-tag registry (fail-hard on tag collision).
|
|
15
|
-
- `ExecArgs`, `ExecResult`, `ChannelDecl`, `ChannelState`, `ExecutorMetadata`, `ExecInfo`, `ExecRegistry`, `Discovery`, `DiscoverOptions` — contract types.
|
|
15
|
+
- `ExecArgs`, `ExecResult`, `ChannelDecl`, `ChannelState`, `ExecutorMetadata`, `RuntimeAvailability`, `Effect`, `ExecInfo`, `ExecRegistry`, `Discovery`, `DiscoverOptions` — contract types.
|
|
16
16
|
- `TelemetryEvent`, `ContentOffset`, `LogCoordinate` — local mirror of grammar's telemetry envelope (the `emit` sink's payload).
|
|
17
17
|
- `resolveRuntime(runtime, command)`, `isKnownRuntime(runtime)`, `KNOWN_RUNTIMES`, `SpawnArgs`, `RuntimeResolver` — subprocess-family helper for the consumer's legacy spawn path (§4).
|
|
18
18
|
|
package/SPEC.md
CHANGED
|
@@ -6,7 +6,7 @@ Contract for `@plurnk/plurnk-execs-*` sibling packages — runtime executors tha
|
|
|
6
6
|
|
|
7
7
|
A runtime executor handles one or more EXEC `runtime` slot values (`sh`, `node`, `python`, `search`, `news`, …). It is a `BaseExecutor` subclass that declares its output channels and implements `run()`; the framework discovers it from its `package.json` `plurnk` block. The consuming scheme owns all I/O and lifecycle machinery (db, channels, subscriptions, AbortController bridging, wake-on-completion) and hands the executor sinks — the executor stays stateless across runs beyond its construction metadata.
|
|
8
8
|
|
|
9
|
-
The framework ships `SubprocessExecutor` (§4), the concrete `BaseExecutor` for subprocess runtimes (sh/node/python)
|
|
9
|
+
The framework ships `SubprocessExecutor` (§4), the concrete `BaseExecutor` for subprocess runtimes (sh/node/python), built on the lower-level `resolveRuntime` / `SpawnArgs` helper. plurnk-service's exec scheme has adopted `SubprocessExecutor`; the discovery-registry + `probe()`/`effect()` consumption is realized in service `0.9.0` (`ExecutorRegistry` boot-discovers and probes siblings; `EffectPolicy` gates the proposal lifecycle).
|
|
10
10
|
|
|
11
11
|
## §2 Executor contract
|
|
12
12
|
|
|
@@ -63,12 +63,32 @@ abstract class BaseExecutor {
|
|
|
63
63
|
|
|
64
64
|
Consumer contract (plurnk-service#181): probe **once at boot, per package** (not per tag — stamp all of a package's tags with the one result), **concurrently under a per-probe timeout**, and **cache**. `probe()` MAY reject; the consumer treats rejection as `{ available: false, detail: <error> }`, so a buggy probe degrades only its runtime. The model is offered a positive list of available runtimes; an attempt at an unavailable one returns **501 carrying `detail`** (so `detail` is model-facing — terse and actionable). A configured default runtime that probes unavailable is a **fail-hard boot error**.
|
|
65
65
|
|
|
66
|
-
### §2.3
|
|
66
|
+
### §2.3 Effect (proposal gating)
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
type Effect = "pure" | "read" | "host";
|
|
70
|
+
|
|
71
|
+
abstract class BaseExecutor {
|
|
72
|
+
effect(target: string | null): Effect { return "host"; } // default: conservative
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`effect()` classifies an invocation's side effect so the consumer can gate the proposal lifecycle per runtime (service#182). The executor declares the **fact**; the consumer owns the **policy** (an `effect → propose/auto` map, deployment-tunable: default `host → propose`, `read`/`pure → auto`).
|
|
77
|
+
|
|
78
|
+
- **`host`** — runs code / mutates the host (subprocess; file-backed sqlite) → propose.
|
|
79
|
+
- **`read`** — observes external state, no host mutation (search) → auto.
|
|
80
|
+
- **`pure`** — no observable side effect (sqlite `:memory:`, transforms) → auto.
|
|
81
|
+
|
|
82
|
+
`effect()` MUST be **pure, synchronous, and cheap** — it runs on the dispatch hot path at propose time. It classifies the **target only** (known pre-`run()`); it MUST NOT inspect the command (parsing SQL/shell to judge intent is a sandbox-escape footgun) and MUST NOT do I/O. Default `host` is conservative — anything unclassifiable is proposed (fail-safe, the mirror of `probe()`'s fail-open default).
|
|
83
|
+
|
|
84
|
+
For `exec`, per-runtime `effect()` supersedes the static `Exec.manifest.flags.proposes`. Auto-run (`read`/`pure`) runtimes may run **inline** — synchronous return rather than entry-then-read-next-turn — while still landing the result as a re-readable entry.
|
|
85
|
+
|
|
86
|
+
### §2.4 Telemetry
|
|
67
87
|
|
|
68
88
|
Runtime failures are emitted as a grammar `TelemetryEvent` via the `emit` sink (plurnk-service#174 Q3); the scheme routes it to the engine's telemetry buffer — the same path grammar's `parse_error` takes. Events are not encoded into `stderr` (that pollutes program output) nor returned on `ExecResult` (that loses mid-run events).
|
|
69
89
|
|
|
70
90
|
- `source`: `"exec:<runtime>"` (e.g. `"exec:search"`) or `"scheme:exec"`.
|
|
71
|
-
- `kind`: producer-minted
|
|
91
|
+
- `kind`: producer-minted, open vocabulary. What the shipped executors actually emit: `SubprocessExecutor` → `spawn_failed` (a failed *start*; a nonzero exit is the program's own result and stays on `stderr`, **not** telemetered); search → `searxng_not_configured` / `searxng_unreachable` / `searxng_timeout` / `searxng_http_<n>` / `external_bang_refused`; sqlite → `sqlite_open_failed` / `sqlite_error`. A cancellation (`signal` abort) is normal flow — **not** emitted.
|
|
72
92
|
- `message`: terse, factual. `position`: typically null at the runtime layer.
|
|
73
93
|
|
|
74
94
|
The envelope is mirrored locally (`TelemetryEvent`, `ContentOffset`, `LogCoordinate`) so the framework needs no `@plurnk/plurnk-grammar` dependency; grammar's `dist/schema/TelemetryEvent.json` is the source of truth.
|
|
@@ -92,7 +112,7 @@ The envelope is mirrored locally (`TelemetryEvent`, `ContentOffset`, `LogCoordin
|
|
|
92
112
|
|
|
93
113
|
A package may claim multiple tags backed by one handler. Tags form a **flat global namespace**; `registry` maps tag → `{ runtime, glyph, packageName }`. Unlike plurnk-mimetypes (last-loaded wins), a tag **collision is fail-hard**: two packages claiming the same runtime is an unresolvable install ambiguity the operator must fix.
|
|
94
114
|
|
|
95
|
-
Each runtime
|
|
115
|
+
Each runtime package's **default export** is its `BaseExecutor` subclass (also a named export — `export { default as Sh }` / `export { default }`); the consumer instantiates it per matched tag with the tag + glyph from the registry.
|
|
96
116
|
|
|
97
117
|
## §4 Subprocess helper (legacy path)
|
|
98
118
|
|
|
@@ -111,16 +131,16 @@ interface SpawnArgs { cmd: string; args: string[]; useShell: boolean; }
|
|
|
111
131
|
|
|
112
132
|
`resolveRuntime` never throws; consumers gate unknown runtimes with `isKnownRuntime` and return 501 before invoking.
|
|
113
133
|
|
|
114
|
-
The framework wraps this in **`SubprocessExecutor extends BaseExecutor`** — declares `{ stdout, stderr }` channels and implements `run()` (spawn via `resolveRuntime`, stream into the channels, honor `signal`, `emit` `spawn_failed` on a failed start, return `{ status, exitCode }`). The `plurnk-execs-sh` / `-node` / `-python` siblings subclass it and differ only in their claimed `runtimes[]` tags.
|
|
134
|
+
The framework wraps this in **`SubprocessExecutor extends BaseExecutor`** — declares `{ stdout, stderr }` channels and implements `run()` (spawn via `resolveRuntime`, stream into the channels, honor `signal`, `emit` `spawn_failed` on a failed start, return `{ status, exitCode }`). Subclasses with their own interpreter table override the **`protected spawnArgs(runtime, command) → SpawnArgs`** hook (default delegates to `resolveRuntime`) — and so inherit run()'s streaming + process-group abort handling. `SpawnArgs.stdin?` lets filter-style runtimes feed their program/input via stdin (`bc`, `tclsh`; or `""` for an `awk` BEGIN with EOF). On abort it kills the whole **process group** (`detached` spawn + `process.kill(-pid, …)`, SIGTERM→SIGKILL grace) so shell grandchildren can't leak (plurnk-execs#4). The `plurnk-execs-sh` / `-node` / `-python` siblings subclass it and differ only in their claimed `runtimes[]` tags and their `binary` getter (for `probe()`). `isKnownRuntime` / `KNOWN_RUNTIMES` are the legacy 501 gate; the discovery registry + `probe()` supersede them once a consumer wires the registry.
|
|
115
135
|
|
|
116
136
|
## §5 Consumer surface (plurnk-service)
|
|
117
137
|
|
|
118
|
-
Per plurnk-service#174, the exec scheme:
|
|
138
|
+
Per plurnk-service#174/#181/#182, realized in service `0.9.0`, the exec scheme:
|
|
119
139
|
|
|
120
|
-
1.
|
|
121
|
-
2.
|
|
140
|
+
1. Boot-discovers executors (`discover()`), `probe()`s each per-package, and offers the model the positive available-runtimes list; an unavailable runtime returns 501 carrying `probe()` `detail`.
|
|
141
|
+
2. Resolves the runtime tag to its executor and runs it through `run()`, seeding the exec entry's channels from `executor.channels`.
|
|
122
142
|
3. Provides the `write` / `setState` / `emit` sinks bound to its channel-write, channel-state, and engine-telemetry machinery; bridges its AbortController to `args.signal`; maps the `ExecResult` to close-status + wake summary.
|
|
123
|
-
4.
|
|
143
|
+
4. Gates the proposal lifecycle by `effect(target)` (`EffectPolicy`: `host → propose`, `read`/`pure → auto`), running auto-run runtimes inline (synchronous return) while still landing the result as a re-readable entry.
|
|
124
144
|
|
|
125
145
|
## §6 Forbidden (for siblings)
|
|
126
146
|
|
package/dist/BaseExecutor.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChannelDecl, ExecArgs, ExecResult, ExecutorMetadata, RuntimeAvailability } from "./types.ts";
|
|
1
|
+
import type { ChannelDecl, Effect, ExecArgs, ExecResult, ExecutorMetadata, RuntimeAvailability } from "./types.ts";
|
|
2
2
|
export default abstract class BaseExecutor {
|
|
3
3
|
readonly runtime: string;
|
|
4
4
|
readonly glyph: string;
|
|
@@ -6,5 +6,6 @@ export default abstract class BaseExecutor {
|
|
|
6
6
|
abstract get channels(): Readonly<Record<string, ChannelDecl>>;
|
|
7
7
|
abstract run(args: ExecArgs): Promise<ExecResult>;
|
|
8
8
|
probe(): Promise<RuntimeAvailability>;
|
|
9
|
+
effect(_target: string | null): Effect;
|
|
9
10
|
}
|
|
10
11
|
//# sourceMappingURL=BaseExecutor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseExecutor.d.ts","sourceRoot":"","sources":["../src/BaseExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"BaseExecutor.d.ts","sourceRoot":"","sources":["../src/BaseExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAWnH,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,YAAY;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,gBAAgB;IAUhD,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAO/D,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAY3C,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAW3C,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;CAGzC"}
|
package/dist/BaseExecutor.js
CHANGED
|
@@ -27,5 +27,15 @@ export default class BaseExecutor {
|
|
|
27
27
|
async probe() {
|
|
28
28
|
return { available: true };
|
|
29
29
|
}
|
|
30
|
+
// Side-effect class of an invocation against `target` (the parsed EXEC
|
|
31
|
+
// target — what run() receives as cwd), for the consumer's proposal-gating
|
|
32
|
+
// policy (service#182). MUST be pure, synchronous, and cheap — it runs on
|
|
33
|
+
// the dispatch hot path at propose time: classify the target only, NEVER
|
|
34
|
+
// the command (parsing SQL/shell to judge intent is a sandbox-escape
|
|
35
|
+
// footgun). Default `host` is the conservative, fail-safe end — anything we
|
|
36
|
+
// can't classify is treated as host code-execution and proposed.
|
|
37
|
+
effect(_target) {
|
|
38
|
+
return "host";
|
|
39
|
+
}
|
|
30
40
|
}
|
|
31
41
|
//# sourceMappingURL=BaseExecutor.js.map
|
package/dist/BaseExecutor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseExecutor.js","sourceRoot":"","sources":["../src/BaseExecutor.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,6EAA6E;AAC7E,6EAA6E;AAC7E,yEAAyE;AACzE,EAAE;AACF,2EAA2E;AAC3E,6EAA6E;AAC7E,2EAA2E;AAC3E,mDAAmD;AACnD,MAAM,CAAC,OAAO,OAAgB,YAAY;IAC7B,OAAO,CAAS;IAChB,KAAK,CAAS;IAEvB,YAAY,EAAE,OAAO,EAAE,KAAK,EAAoB;QAC5C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAgBD,wEAAwE;IACxE,0EAA0E;IAC1E,wEAAwE;IACxE,iEAAiE;IACjE,EAAE;IACF,0EAA0E;IAC1E,yEAAyE;IACzE,2EAA2E;IAC3E,yEAAyE;IACzE,4DAA4D;IAC5D,KAAK,CAAC,KAAK;QACP,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC/B,CAAC;CACJ"}
|
|
1
|
+
{"version":3,"file":"BaseExecutor.js","sourceRoot":"","sources":["../src/BaseExecutor.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,6EAA6E;AAC7E,6EAA6E;AAC7E,yEAAyE;AACzE,EAAE;AACF,2EAA2E;AAC3E,6EAA6E;AAC7E,2EAA2E;AAC3E,mDAAmD;AACnD,MAAM,CAAC,OAAO,OAAgB,YAAY;IAC7B,OAAO,CAAS;IAChB,KAAK,CAAS;IAEvB,YAAY,EAAE,OAAO,EAAE,KAAK,EAAoB;QAC5C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAgBD,wEAAwE;IACxE,0EAA0E;IAC1E,wEAAwE;IACxE,iEAAiE;IACjE,EAAE;IACF,0EAA0E;IAC1E,yEAAyE;IACzE,2EAA2E;IAC3E,yEAAyE;IACzE,4DAA4D;IAC5D,KAAK,CAAC,KAAK;QACP,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC/B,CAAC;IAED,uEAAuE;IACvE,2EAA2E;IAC3E,0EAA0E;IAC1E,yEAAyE;IACzE,qEAAqE;IACrE,4EAA4E;IAC5E,iEAAiE;IACjE,MAAM,CAAC,OAAsB;QACzB,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import BaseExecutor from "./BaseExecutor.ts";
|
|
2
|
-
import type { ChannelDecl, ExecArgs, ExecResult, RuntimeAvailability } from "./types.ts";
|
|
2
|
+
import type { ChannelDecl, Effect, ExecArgs, ExecResult, RuntimeAvailability, SpawnArgs } from "./types.ts";
|
|
3
3
|
export default class SubprocessExecutor extends BaseExecutor {
|
|
4
4
|
get channels(): Readonly<Record<string, ChannelDecl>>;
|
|
5
5
|
protected get binary(): string | null;
|
|
6
|
+
effect(_target: string | null): Effect;
|
|
6
7
|
probe(): Promise<RuntimeAvailability>;
|
|
8
|
+
protected spawnArgs(runtime: string, command: string): SpawnArgs;
|
|
7
9
|
run({ runtime, command, cwd, signal, write, setState, emit }: ExecArgs): Promise<ExecResult>;
|
|
8
10
|
}
|
|
9
11
|
//# sourceMappingURL=SubprocessExecutor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubprocessExecutor.d.ts","sourceRoot":"","sources":["../src/SubprocessExecutor.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAE7C,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"SubprocessExecutor.d.ts","sourceRoot":"","sources":["../src/SubprocessExecutor.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAE7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAgB5G,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,YAAY;IACxD,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAKpD;IAKD,SAAS,KAAK,MAAM,IAAI,MAAM,GAAG,IAAI,CAEpC;IAGQ,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAIhC,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAyBpD,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS;IAIhE,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;CAoE/F"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import BaseExecutor from "./BaseExecutor.js";
|
|
3
3
|
import { resolveRuntime } from "./runtime.js";
|
|
4
|
+
// Grace period between SIGTERM and SIGKILL when tearing down an aborted process
|
|
5
|
+
// group — long enough for a well-behaved process to clean up, bounded so a
|
|
6
|
+
// process ignoring SIGTERM can't wedge cancellation.
|
|
7
|
+
const ABORT_GRACE_MS = 2000;
|
|
4
8
|
// Concrete BaseExecutor for subprocess runtimes (sh, node, python, …). Spawns
|
|
5
9
|
// via resolveRuntime, streams the process's stdout/stderr into the declared
|
|
6
10
|
// channels, honors cancellation, and reports the exit code. The sibling
|
|
@@ -23,6 +27,10 @@ export default class SubprocessExecutor extends BaseExecutor {
|
|
|
23
27
|
get binary() {
|
|
24
28
|
return null;
|
|
25
29
|
}
|
|
30
|
+
// Subprocess runtimes execute code on the host — always `host`.
|
|
31
|
+
effect(_target) {
|
|
32
|
+
return "host";
|
|
33
|
+
}
|
|
26
34
|
async probe() {
|
|
27
35
|
const bin = this.binary;
|
|
28
36
|
if (bin === null)
|
|
@@ -47,36 +55,73 @@ export default class SubprocessExecutor extends BaseExecutor {
|
|
|
47
55
|
: { available: false, detail: `${bin} --version exited ${code}` }));
|
|
48
56
|
});
|
|
49
57
|
}
|
|
58
|
+
// Translate the matched tag + command into spawn args. Default delegates to
|
|
59
|
+
// resolveRuntime (sh/node/python); subclasses with their own interpreter
|
|
60
|
+
// table (e.g. the common-REPL harness) override this — and so inherit run()'s
|
|
61
|
+
// streaming + process-group abort handling rather than reimplementing it.
|
|
62
|
+
spawnArgs(runtime, command) {
|
|
63
|
+
return resolveRuntime(runtime, command);
|
|
64
|
+
}
|
|
50
65
|
run({ runtime, command, cwd, signal, write, setState, emit }) {
|
|
51
|
-
const { cmd, args, useShell } =
|
|
66
|
+
const { cmd, args, useShell, stdin } = this.spawnArgs(runtime, command);
|
|
52
67
|
return new Promise((resolve) => {
|
|
53
|
-
//
|
|
54
|
-
|
|
68
|
+
// Already cancelled before we start — don't launch a doomed process.
|
|
69
|
+
if (signal.aborted) {
|
|
70
|
+
setState("stdout", "errored");
|
|
71
|
+
setState("stderr", "errored");
|
|
72
|
+
resolve({ status: 499, exitCode: -1 });
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
55
75
|
let settled = false;
|
|
76
|
+
let killTimer;
|
|
77
|
+
// `detached` makes the child its own process-group leader, so abort
|
|
78
|
+
// can signal the WHOLE group (`-pid`) — reaching shell grandchildren
|
|
79
|
+
// (e.g. the `sleep` in `sh -c "sleep 30"`) that a bare SIGTERM to the
|
|
80
|
+
// direct child orphans, leaking the process and its stdout pipe. We
|
|
81
|
+
// drive cancellation manually rather than via spawn's `signal`
|
|
82
|
+
// option, which only kills the direct child (plurnk-execs#4).
|
|
83
|
+
const child = spawn(cmd, args, { shell: useShell, cwd: cwd ?? undefined, detached: true });
|
|
84
|
+
// Filter-style runtimes feed their program/input via stdin; closing
|
|
85
|
+
// it also delivers EOF (awk BEGIN-only). Left untouched otherwise.
|
|
86
|
+
if (stdin !== undefined)
|
|
87
|
+
child.stdin?.end(stdin);
|
|
88
|
+
const killGroup = (sig) => {
|
|
89
|
+
if (child.pid === undefined)
|
|
90
|
+
return;
|
|
91
|
+
try {
|
|
92
|
+
process.kill(-child.pid, sig);
|
|
93
|
+
}
|
|
94
|
+
catch { /* group already gone */ }
|
|
95
|
+
};
|
|
96
|
+
const onAbort = () => {
|
|
97
|
+
killGroup("SIGTERM");
|
|
98
|
+
// Escalate if the group ignores SIGTERM. `close` fires once the
|
|
99
|
+
// pipes drain, which now happens because the grandchildren die.
|
|
100
|
+
killTimer = setTimeout(() => killGroup("SIGKILL"), ABORT_GRACE_MS);
|
|
101
|
+
};
|
|
56
102
|
const finish = (result, state) => {
|
|
57
103
|
if (settled)
|
|
58
104
|
return;
|
|
59
105
|
settled = true;
|
|
106
|
+
if (killTimer)
|
|
107
|
+
clearTimeout(killTimer);
|
|
108
|
+
signal.removeEventListener("abort", onAbort);
|
|
60
109
|
setState("stdout", state);
|
|
61
110
|
setState("stderr", state);
|
|
62
111
|
resolve(result);
|
|
63
112
|
};
|
|
64
|
-
|
|
113
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
65
114
|
child.stdout?.on("data", (chunk) => write("stdout", chunk.toString("utf8")));
|
|
66
115
|
child.stderr?.on("data", (chunk) => write("stderr", chunk.toString("utf8")));
|
|
67
116
|
child.on("error", (err) => {
|
|
68
|
-
if (err.code === "ABORT_ERR") {
|
|
69
|
-
finish({ status: 499, exitCode: -1 }, "errored");
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
117
|
// The process could not be started — a framework-level failure
|
|
73
118
|
// the model benefits from seeing as telemetry (a nonzero exit,
|
|
74
119
|
// by contrast, is the program's own result and lives on stderr).
|
|
75
120
|
emit({ source: `exec:${runtime}`, kind: "spawn_failed", message: err.message });
|
|
76
121
|
finish({ status: 500, exitCode: -1 }, "errored");
|
|
77
122
|
});
|
|
78
|
-
child.on("close", (code
|
|
79
|
-
if (
|
|
123
|
+
child.on("close", (code) => {
|
|
124
|
+
if (signal.aborted) {
|
|
80
125
|
finish({ status: 499, exitCode: code ?? -1 }, "errored");
|
|
81
126
|
return;
|
|
82
127
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubprocessExecutor.js","sourceRoot":"","sources":["../src/SubprocessExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,8EAA8E;AAC9E,4EAA4E;AAC5E,wEAAwE;AACxE,6EAA6E;AAC7E,0EAA0E;AAC1E,EAAE;AACF,0EAA0E;AAC1E,2EAA2E;AAC3E,2BAA2B;AAC3B,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,YAAY;IACxD,IAAI,QAAQ;QACR,OAAO;YACH,MAAM,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE;YACnC,MAAM,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE;SACtC,CAAC;IACN,CAAC;IAED,2EAA2E;IAC3E,uEAAuE;IACvE,qEAAqE;IACrE,IAAc,MAAM;QAChB,OAAO,IAAI,CAAC;IAChB,CAAC;IAEQ,KAAK,CAAC,KAAK;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAC7C,OAAO,IAAI,OAAO,CAAsB,CAAC,OAAO,EAAE,EAAE;YAChD,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,IAAI,GAAG,CAAC,CAAsB,EAAQ,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;gBAAC,OAAO,GAAG,IAAI,CAAC;gBAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAAC,CAAC,CAAC,CAAC,CAAC;YACjG,IAAI,GAAG,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC/E,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,GAAG,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAChF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC;gBAC5B,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAG,GAA6B,CAAC,IAAI,KAAK,WAAW;oBACvD,CAAC,CAAC,GAAG,GAAG,kBAAkB;oBAC1B,CAAC,CAAC,GAAG,GAAG,oBAAoB;aACnC,CAAC,CAAC,CAAC;YACJ,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC;gBACvC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE;gBACrE,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,qBAAqB,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;IACP,CAAC;IAED,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAY;QAClE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"SubprocessExecutor.js","sourceRoot":"","sources":["../src/SubprocessExecutor.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ export { default as BaseExecutor } from "./BaseExecutor.ts";
|
|
|
2
2
|
export { default as SubprocessExecutor } from "./SubprocessExecutor.ts";
|
|
3
3
|
export { discover } from "./discover.ts";
|
|
4
4
|
export { KNOWN_RUNTIMES, isKnownRuntime, resolveRuntime } from "./runtime.ts";
|
|
5
|
-
export type { ChannelState, ChannelDecl, ExecutorMetadata, ExecArgs, ExecResult, RuntimeAvailability, ExecInfo, ExecRegistry, Discovery, DiscoverOptions, SpawnArgs, RuntimeResolver, } from "./types.ts";
|
|
5
|
+
export type { ChannelState, ChannelDecl, ExecutorMetadata, ExecArgs, ExecResult, Effect, RuntimeAvailability, ExecInfo, ExecRegistry, Discovery, DiscoverOptions, SpawnArgs, RuntimeResolver, } from "./types.ts";
|
|
6
6
|
export type { TelemetryEvent, ContentOffset, LogCoordinate } from "./TelemetryEvent.ts";
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9E,YAAY,EACR,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,mBAAmB,EACnB,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,eAAe,EACf,SAAS,EACT,eAAe,GAClB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9E,YAAY,EACR,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,MAAM,EACN,mBAAmB,EACnB,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,eAAe,EACf,SAAS,EACT,eAAe,GAClB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export interface ExecResult {
|
|
|
21
21
|
status: number;
|
|
22
22
|
exitCode?: number;
|
|
23
23
|
}
|
|
24
|
+
export type Effect = "pure" | "read" | "host";
|
|
24
25
|
export interface RuntimeAvailability {
|
|
25
26
|
available: boolean;
|
|
26
27
|
detail?: string;
|
|
@@ -45,6 +46,12 @@ export interface SpawnArgs {
|
|
|
45
46
|
args: string[];
|
|
46
47
|
/** When true, the command is interpreted as a shell line (cmd is the whole line, args ignored). */
|
|
47
48
|
useShell: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* When set, written to the child's stdin which is then closed. For filter-style
|
|
51
|
+
* runtimes that read their program/input from stdin (`bc`, `tclsh`) or that need
|
|
52
|
+
* EOF with no input (`awk` BEGIN-only). Omitted = stdin left at its default.
|
|
53
|
+
*/
|
|
54
|
+
stdin?: string;
|
|
48
55
|
}
|
|
49
56
|
/**
|
|
50
57
|
* Translate a runtime tag + command string into spawn args for `node:child_process.spawn`.
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAM3D,MAAM,WAAW,WAAW;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC/B;AAKD,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACjB;AAOD,MAAM,WAAW,QAAQ;IAGrB,OAAO,EAAE,MAAM,CAAC;IAEhB,OAAO,EAAE,MAAM,CAAC;IAGhB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnB,MAAM,EAAE,WAAW,CAAC;IAEpB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEhD,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAGzD,IAAI,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CACzC;AAKD,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAM3D,MAAM,WAAW,WAAW;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC/B;AAKD,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACjB;AAOD,MAAM,WAAW,QAAQ;IAGrB,OAAO,EAAE,MAAM,CAAC;IAEhB,OAAO,EAAE,MAAM,CAAC;IAGhB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnB,MAAM,EAAE,WAAW,CAAC;IAEpB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEhD,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAGzD,IAAI,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CACzC;AAKD,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAQD,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAO9C,MAAM,WAAW,mBAAmB;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,QAAQ;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACvB;AAID,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAEzD,MAAM,WAAW,SAAS;IACtB,QAAQ,EAAE,YAAY,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAG5B,GAAG,CAAC,EAAE,MAAM,CAAC;IAGb,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAID,MAAM,WAAW,SAAS;IACtB,wFAAwF;IACxF,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,mGAAmG;IACnG,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plurnk/plurnk-execs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Framework + contract for the @plurnk/plurnk-execs-* runtime executor family.",
|
|
5
5
|
"keywords": ["plurnk", "exec", "runtime", "executor"],
|
|
6
6
|
"homepage": "https://github.com/plurnk/plurnk-execs#readme",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
],
|
|
35
35
|
"scripts": {
|
|
36
36
|
"test:lint": "tsc --noEmit",
|
|
37
|
-
"test:unit": "node --test src/**/*.test.ts",
|
|
37
|
+
"test:unit": "node --test \"src/**/*.test.ts\"",
|
|
38
38
|
"test": "npm run test:lint && npm run test:unit",
|
|
39
39
|
"build:dist": "tsc -p tsconfig.build.json",
|
|
40
40
|
"build": "npm run build:dist",
|