@plurnk/plurnk-execs 1.3.12 → 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 +4 -0
- package/README.md +78 -36
- package/SPEC.md +386 -260
- package/dist/BaseExecutor.d.ts.map +1 -1
- package/dist/BaseExecutor.js +12 -13
- package/dist/BaseExecutor.js.map +1 -1
- package/dist/ErrorDetail.d.ts +8 -0
- package/dist/ErrorDetail.d.ts.map +1 -0
- package/dist/ErrorDetail.js +25 -0
- package/dist/ErrorDetail.js.map +1 -0
- package/dist/Notice.d.ts +3 -0
- package/dist/Notice.d.ts.map +1 -0
- package/dist/Notice.js +2 -0
- package/dist/Notice.js.map +1 -0
- package/dist/RuntimeTag.d.ts +5 -0
- package/dist/RuntimeTag.d.ts.map +1 -0
- package/dist/RuntimeTag.js +28 -0
- package/dist/RuntimeTag.js.map +1 -0
- package/dist/SubprocessExecutor.d.ts +1 -1
- package/dist/SubprocessExecutor.d.ts.map +1 -1
- package/dist/SubprocessExecutor.js +67 -20
- package/dist/SubprocessExecutor.js.map +1 -1
- package/dist/advertise.d.ts +4 -0
- package/dist/advertise.d.ts.map +1 -1
- package/dist/advertise.js +4 -2
- package/dist/advertise.js.map +1 -1
- package/dist/discover.d.ts.map +1 -1
- package/dist/discover.js +52 -84
- package/dist/discover.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/dist/policy.d.ts +1 -0
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +21 -20
- package/dist/policy.js.map +1 -1
- package/dist/runtime.js +1 -1
- package/dist/runtime.js.map +1 -1
- package/dist/tokenizeArgv.d.ts +5 -0
- package/dist/tokenizeArgv.d.ts.map +1 -0
- package/dist/tokenizeArgv.js +69 -0
- package/dist/tokenizeArgv.js.map +1 -0
- package/dist/types.d.ts +6 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +11 -15
- package/dist/TelemetryEvent.d.ts +0 -18
- package/dist/TelemetryEvent.d.ts.map +0 -1
- package/dist/TelemetryEvent.js +0 -2
- package/dist/TelemetryEvent.js.map +0 -1
package/.env.defaults
CHANGED
|
@@ -10,3 +10,7 @@
|
|
|
10
10
|
# Absent ⇒ the runtime stays enabled. e.g.:
|
|
11
11
|
# PLURNK_EXECS_PYTHON=0
|
|
12
12
|
# PLURNK_EXECS_BC=0
|
|
13
|
+
|
|
14
|
+
# Maximum source characters retained from third-party diagnostics in a failed
|
|
15
|
+
# operation's model-facing Problem detail. Empty/unset leaves them unbounded.
|
|
16
|
+
PLURNK_EXECS_ERROR_DETAIL_LIMIT=512
|
package/README.md
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
# plurnk-execs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Lean framework and contract for `@plurnk/plurnk-execs-*` runtime packages. Core
|
|
4
|
+
uses it to discover EXEC tags, admit calls, and stream each runtime's output
|
|
5
|
+
under its own tag-addressed scheme. The default service manifest, not this
|
|
6
|
+
framework, owns the standard installed leaf set ({§bundled-set}).
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install @plurnk/plurnk-execs
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Install executor leaves beside the framework to assemble a standalone host.
|
|
15
|
+
Any compatible third-party leaf remains discoverable without changing the
|
|
16
|
+
framework or service.
|
|
4
17
|
|
|
5
18
|
## Documentation
|
|
6
19
|
|
|
7
|
-
- [`SPEC.md`](./SPEC.md) —
|
|
8
|
-
-
|
|
20
|
+
- [`SPEC.md`](./SPEC.md) — authoritative executor author and consumer contract.
|
|
21
|
+
- [plurnk-contracts](https://github.com/plurnk/plurnk-service/tree/main/plurnk-contracts) — EXEC AST and shared runtime-neutral contracts.
|
|
22
|
+
- [plurnk-schemes](https://github.com/plurnk/plurnk-service/tree/main/plurnk-schemes) — universal operation results and derived output-scheme contract.
|
|
9
23
|
|
|
10
24
|
## Write an executor
|
|
11
25
|
|
|
12
|
-
|
|
26
|
+
Publish a package under any scope with `plurnk.kind === "exec"`, one or more
|
|
27
|
+
runtime declarations, and a default-exported `BaseExecutor` subclass.
|
|
13
28
|
|
|
14
|
-
###
|
|
29
|
+
### Declare runtime tags
|
|
15
30
|
|
|
16
31
|
```json
|
|
17
32
|
{
|
|
@@ -21,58 +36,85 @@ Ship an executor by publishing a package — **under any scope** (`@acme/whateve
|
|
|
21
36
|
{
|
|
22
37
|
"name": "cobol",
|
|
23
38
|
"glyph": "🗄",
|
|
24
|
-
"example": "<<EXEC[cobol]:DISPLAY 'HI'.:EXEC"
|
|
25
|
-
"documentation": "# cobol\n\nGnuCOBOL `cobc -xj`. Fixed-format source; the body is one program…"
|
|
39
|
+
"example": "<<EXEC[cobol]:DISPLAY 'HI'.:EXEC"
|
|
26
40
|
}
|
|
27
41
|
]
|
|
28
42
|
}
|
|
29
43
|
}
|
|
30
44
|
```
|
|
31
45
|
|
|
32
|
-
One package may claim
|
|
46
|
+
One package may claim several tags; the consumer instantiates and probes each
|
|
47
|
+
tag independently. A name uses lowercase URI-scheme syntax
|
|
48
|
+
`[a-z][a-z0-9+.-]*`; `only` is reserved by runtime policy. `example` is a
|
|
49
|
+
compact verbatim `plurnk` snippet, and every line in it must be a complete
|
|
50
|
+
`<<`-delimited operation. A `docs/<tag>.md` file supplies the full reference
|
|
51
|
+
material. See {§executor-runtime-declaration}.
|
|
52
|
+
|
|
53
|
+
### Implement the executor
|
|
54
|
+
|
|
55
|
+
| Runtime shape | Base class | Author-owned hooks |
|
|
56
|
+
| --------------------- | -------------------- | --------------------------------------------------------------------------------------- |
|
|
57
|
+
| Subprocess | `SubprocessExecutor` | `spawnArgs()` and normally `binary`; stdout/stderr, abort, env, and exit are inherited. |
|
|
58
|
+
| Logical or in-process | `BaseExecutor` | `channels`, `run()`, and optional `probe()` / `effect()`. |
|
|
33
59
|
|
|
34
|
-
|
|
60
|
+
`run()` receives only the inputs and consumer-owned sinks in
|
|
61
|
+
{§executor-sinks}. Return a universal result; expected failures carry RFC 9457
|
|
62
|
+
Problem Details and leave affected channels `errored`. Honor `signal`, write
|
|
63
|
+
only declared channels, and retain no state between runs.
|
|
35
64
|
|
|
36
|
-
|
|
65
|
+
`effect(target)` declares one admission fact for the consumer-canonical logical
|
|
66
|
+
target. `host` is proposal-gated; `read` and `pure` are automatically accepted.
|
|
67
|
+
The consumer preserves the fact rather than asking again after target
|
|
68
|
+
materialization. All three then use the same background stream path—automatic
|
|
69
|
+
acceptance is not a same-turn result. See {§executor-effect}.
|
|
37
70
|
|
|
38
|
-
|
|
39
|
-
- **Logical / in-process runtimes** (sqlite, search, wasm, jq): subclass **`BaseExecutor`** directly and implement:
|
|
40
|
-
- `get channels()` — the output channels you write, each `{ mimetype, defaultState? }`.
|
|
41
|
-
- `run(args) → ExecResult` — do the work, resolve `{ status }`. Never throw for an expected failure — `emit` telemetry and set the channel to `errored` instead.
|
|
42
|
-
- `probe(signal?)` *(optional)* — `{ available, detail? }`; defaults to available. Override when you depend on an external binary or config (the `detail` is model-facing on a 501). If you spawn a child (or open a connection) to check, hand it `signal` so a resolved/timed-out probe reaps it — no stray write EPIPEs after teardown (plurnk-execs#16).
|
|
43
|
-
- `effect(target)` *(optional)* — `"pure" | "read" | "host"`; the consumer maps it to its proposal policy (host → propose, read/pure → auto-run inline). Classify the **target only**, never the command. Defaults to `host` (the safe end).
|
|
71
|
+
### Understand the target
|
|
44
72
|
|
|
45
|
-
|
|
73
|
+
The EXEC `(target)` slot is runtime-specific:
|
|
46
74
|
|
|
47
|
-
|
|
75
|
+
| Runtime family | Typical mapping |
|
|
76
|
+
| -------------- | ----------------------------------------------------------------- |
|
|
77
|
+
| Data | Target is input; body is the program (`jq`, SQLite, WebAssembly). |
|
|
78
|
+
| Executable | Target is the program; body is its stdin (shell, Python). |
|
|
48
79
|
|
|
49
|
-
|
|
80
|
+
The consumer supplies both `cwd` and a resolved `target`; the leaf maps them
|
|
81
|
+
to its tool rather than reconstructing filesystem or scheme policy.
|
|
50
82
|
|
|
51
|
-
|
|
83
|
+
### Address output
|
|
52
84
|
|
|
53
|
-
|
|
54
|
-
|
|
85
|
+
The runtime tag is also the output scheme. A subprocess result is therefore
|
|
86
|
+
read at an address such as `sh:///1/2/3#stdout`, while a structured result may
|
|
87
|
+
be `sqlite:///1/2/3#results`. `exec://` is not an output address. Executors only
|
|
88
|
+
produce channels; the consumer owns storage and every later READ/FIND. See
|
|
89
|
+
{§executor-output-address}.
|
|
55
90
|
|
|
56
|
-
|
|
91
|
+
## Discovery and policy
|
|
57
92
|
|
|
58
|
-
|
|
93
|
+
`discover(options?)` scans scoped and unscoped packages under the nearest
|
|
94
|
+
`node_modules`, applies trust before executable hooks, applies boot policy, and
|
|
95
|
+
returns `{ registry, packageAttributions, skipped, disabled }`. Tag collisions
|
|
96
|
+
fail hard. Static attribution is normalized once per represented package; an
|
|
97
|
+
executor may additionally decide per provider attempt whether its synchronous
|
|
98
|
+
`attributions(context)` hook returns no, one, or many opaque tags
|
|
99
|
+
({§plugin-attribution}).
|
|
59
100
|
|
|
60
|
-
|
|
101
|
+
| Policy | Result |
|
|
102
|
+
| ----------------------------------- | --------------------------------------------- |
|
|
103
|
+
| `PLURNK_EXECS_<TAG>=0` or `false` | Tag is not registered. |
|
|
104
|
+
| `PLURNK_EXECS_ONLY=<list>` | Only named tags remain; empty registers none. |
|
|
105
|
+
| `Policy.enabledAcross(tag, layers)` | Every layer must admit the tag. |
|
|
61
106
|
|
|
62
|
-
|
|
63
|
-
-
|
|
64
|
-
- **Runtime policy (enable/disable cascade).** `discover()` applies the operator kill-switch uniformly to every tag (SPEC §3.3): `PLURNK_EXECS_<TAG>=0` kills one tag, `PLURNK_EXECS_ONLY=a,b,c` is an allowlist (all else off). Disabled tags are **not** registered — returned in `Discovery.disabled`. It's purely subtractive, so it **cascades**: the consumer feeds a client-declared policy (same `PLURNK_EXECS_*` format) through `Policy.enabledAcross(tag, [serviceEnv, clientLayer])` and the client can only narrow — never re-enable what the service disabled. `disable all but search` → `PLURNK_EXECS_ONLY=search`.
|
|
107
|
+
Policy is subtractive; a downstream layer cannot restore a removed tag. See
|
|
108
|
+
{§executor-discovery}, {§executor-trust}, and {§executor-policy}.
|
|
65
109
|
|
|
66
110
|
## Exports
|
|
67
111
|
|
|
68
|
-
- `BaseExecutor
|
|
69
|
-
- `
|
|
70
|
-
- `
|
|
71
|
-
- `
|
|
72
|
-
-
|
|
73
|
-
- `
|
|
74
|
-
- `SpawnArgs` — the `SubprocessExecutor.spawnArgs()` return shape for
|
|
75
|
-
runtime-specific subclasses.
|
|
112
|
+
- `BaseExecutor`, `SubprocessExecutor`, and `SpawnArgs`.
|
|
113
|
+
- `discover`, `Policy`, `RuntimeTag`, and runtime discovery types.
|
|
114
|
+
- `Advertise`, a deprecated frozen 1.x compatibility helper with no current service path.
|
|
115
|
+
- `ErrorDetail` and `PLURNK_EXECS_ERROR_DETAIL_LIMIT`.
|
|
116
|
+
- Executor arguments, channel, availability, and effect types.
|
|
117
|
+
- `Results`, result types, and runtime-neutral Notice types.
|
|
76
118
|
|
|
77
119
|
## Tests
|
|
78
120
|
|