@plurnk/plurnk-execs 1.16.5 → 1.18.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 +19 -11
- package/README.md +34 -8
- package/SPEC.md +152 -61
- package/dist/BaseExecutor.d.ts +3 -1
- package/dist/BaseExecutor.d.ts.map +1 -1
- package/dist/BaseExecutor.js +8 -0
- package/dist/BaseExecutor.js.map +1 -1
- package/dist/DocFile.d.ts +5 -0
- package/dist/DocFile.d.ts.map +1 -0
- package/dist/DocFile.js +28 -0
- package/dist/DocFile.js.map +1 -0
- package/dist/InvocationMetadata.d.ts +22 -0
- package/dist/InvocationMetadata.d.ts.map +1 -0
- package/dist/InvocationMetadata.js +63 -0
- package/dist/InvocationMetadata.js.map +1 -0
- package/dist/RuntimeInvocation.d.ts.map +1 -1
- package/dist/RuntimeInvocation.js +19 -14
- package/dist/RuntimeInvocation.js.map +1 -1
- package/dist/RuntimeSummary.d.ts +0 -3
- package/dist/RuntimeSummary.d.ts.map +1 -1
- package/dist/RuntimeSummary.js +7 -13
- package/dist/RuntimeSummary.js.map +1 -1
- package/dist/RuntimeTag.d.ts.map +1 -1
- package/dist/RuntimeTag.js +8 -1
- package/dist/RuntimeTag.js.map +1 -1
- package/dist/SubprocessExecutor.d.ts +3 -2
- package/dist/SubprocessExecutor.d.ts.map +1 -1
- package/dist/SubprocessExecutor.js +30 -4
- package/dist/SubprocessExecutor.js.map +1 -1
- package/dist/SubprocessInput.d.ts +10 -0
- package/dist/SubprocessInput.d.ts.map +1 -0
- package/dist/SubprocessInput.js +86 -0
- package/dist/SubprocessInput.js.map +1 -0
- package/dist/discover.d.ts.map +1 -1
- package/dist/discover.js +2 -19
- package/dist/discover.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +4 -8
- package/dist/runtime.js.map +1 -1
- package/dist/types.d.ts +22 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -4
- package/dist/advertise.d.ts +0 -13
- package/dist/advertise.d.ts.map +0 -1
- package/dist/advertise.js +0 -12
- package/dist/advertise.js.map +0 -1
package/.env.defaults
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
# is no force-enable verb. Unset ⇒ every discovered runtime is registered. This
|
|
4
|
-
# package sets no operative default; the comments below ARE the operator docs.
|
|
1
|
+
# @plurnk/plurnk-execs — installed runtime admission.
|
|
2
|
+
# These filters only remove registered runtimes; they cannot install or force-enable tools.
|
|
5
3
|
|
|
6
|
-
#
|
|
4
|
+
# Comma-separated allowlist; unset = all discovered runtimes.
|
|
7
5
|
# PLURNK_EXECS_ONLY=sh,jq
|
|
8
|
-
|
|
9
|
-
# Per-tag kill-switch (case-insensitive): set any registered tag to 0 to drop it.
|
|
10
|
-
# Absent ⇒ the runtime stays enabled. e.g.:
|
|
6
|
+
# Per-runtime switch, case-insensitive: 0 = disabled; absent = enabled.
|
|
11
7
|
# PLURNK_EXECS_PYTHON3=0
|
|
12
8
|
# PLURNK_EXECS_BC=0
|
|
13
|
-
|
|
14
|
-
# Maximum
|
|
15
|
-
# operation's model-facing Problem detail. Empty/unset leaves them unbounded.
|
|
9
|
+
# PLURNK_EXECS_QUESTION=0
|
|
10
|
+
# Maximum diagnostic characters in model-facing errors; empty/unset = unbounded.
|
|
16
11
|
PLURNK_EXECS_ERROR_DETAIL_LIMIT=512
|
|
12
|
+
|
|
13
|
+
# Subprocess-common floors ({§operator-config-env-defaults}, {§exec-env-scoped}). The
|
|
14
|
+
# executor framework owns these because every subprocess runtime wants them and one owner
|
|
15
|
+
# per key is enforced at boot — each executor redeclaring them would crash the daemon.
|
|
16
|
+
# They are set-if-unset, so an operator who exports PAGER=less keeps theirs.
|
|
17
|
+
# A pager that waits for a keypress hangs a spawn that has no terminal.
|
|
18
|
+
PAGER=cat
|
|
19
|
+
# git consults its own pager variable first, so both are set.
|
|
20
|
+
GIT_PAGER=cat
|
|
21
|
+
# Colour escapes and progress spinners are noise in a captured channel.
|
|
22
|
+
NO_COLOR=1
|
|
23
|
+
# Non-interactive by construction: tools that branch on CI take the unattended path.
|
|
24
|
+
CI=1
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# plurnk-execs
|
|
2
2
|
|
|
3
3
|
Lean framework and contract for `@plurnk/plurnk-execs-*` runtime packages. Core
|
|
4
|
-
uses it to discover
|
|
4
|
+
uses it to discover runtime tags, admit calls, and stream each runtime's output
|
|
5
5
|
under its own tag-addressed scheme. The default service manifest, not this
|
|
6
6
|
framework, owns the standard installed leaf set ({§bundled-set}).
|
|
7
7
|
|
|
@@ -18,7 +18,7 @@ framework or service.
|
|
|
18
18
|
## Documentation
|
|
19
19
|
|
|
20
20
|
- [`SPEC.md`](./SPEC.md) — authoritative executor author and consumer contract.
|
|
21
|
-
- [plurnk-contracts](https://github.com/plurnk/plurnk-service/tree/main/plurnk-contracts) —
|
|
21
|
+
- [plurnk-contracts](https://github.com/plurnk/plurnk-service/tree/main/plurnk-contracts) — the execution AST and shared runtime-neutral contracts.
|
|
22
22
|
- [plurnk-schemes](https://github.com/plurnk/plurnk-service/tree/main/plurnk-schemes) — universal operation results and derived output-scheme contract.
|
|
23
23
|
|
|
24
24
|
## Write an executor
|
|
@@ -51,10 +51,15 @@ One package may claim several tags; the consumer instantiates and probes each
|
|
|
51
51
|
tag independently. A name uses lowercase URI-scheme syntax
|
|
52
52
|
`[a-z][a-z0-9+.-]*`; `only` is reserved by runtime policy. `summary` is the
|
|
53
53
|
one-line capability description. `invocation` defines the body and optional
|
|
54
|
-
target buckets
|
|
55
|
-
generated `worker
|
|
54
|
+
target buckets used for dispatch enforcement and a canonical example for its
|
|
55
|
+
generated `worker:///_plurnk/plurnk/<tag>.md` document. A `docs/<tag>.md` file supplies
|
|
56
56
|
supplemental detail. See {§executor-runtime-declaration}.
|
|
57
57
|
|
|
58
|
+
For JSON inputs, supply `invocation.inputSchema` instead of an authored example
|
|
59
|
+
or signature. The shared renderer lists required top-level fields and links to
|
|
60
|
+
the complete raw schema and description; nested and optional inputs stay in
|
|
61
|
+
that on-demand document ({§executor-input-schema-preview}).
|
|
62
|
+
|
|
58
63
|
### Implement the executor
|
|
59
64
|
|
|
60
65
|
| Runtime shape | Base class | Author-owned hooks |
|
|
@@ -75,7 +80,7 @@ acceptance is not a same-turn result. See {§executor-effect}.
|
|
|
75
80
|
|
|
76
81
|
### Understand the target
|
|
77
82
|
|
|
78
|
-
The
|
|
83
|
+
The execution's `(target)` slot is runtime-specific:
|
|
79
84
|
|
|
80
85
|
| Runtime family | Typical mapping |
|
|
81
86
|
| -------------- | ----------------------------------------------------------------- |
|
|
@@ -85,11 +90,33 @@ The EXEC `(target)` slot is runtime-specific:
|
|
|
85
90
|
The consumer supplies both `cwd` and a resolved `target`; the leaf maps them
|
|
86
91
|
to its tool rather than reconstructing filesystem or scheme policy.
|
|
87
92
|
|
|
93
|
+
### Own invocation metadata
|
|
94
|
+
|
|
95
|
+
`prepare(input)` validates the tool's raw header metadata before admission and
|
|
96
|
+
returns the effective cwd. `run(args)` receives that cwd and the original
|
|
97
|
+
metadata, separately from the unchanged body. Source acquisition never inherits
|
|
98
|
+
execution metadata. `BaseExecutor` supplies `[{"cwd": "..."}]`; `SubprocessExecutor` adds
|
|
99
|
+
literal script arguments with `[{"args": ["arg",...]}]`. Override preparation for
|
|
100
|
+
tool-specific options. See {§executor-metadata}.
|
|
101
|
+
|
|
102
|
+
### Receive live input
|
|
103
|
+
|
|
104
|
+
In-process executors may call `args.registerInput?.(async ({ body, metadata,
|
|
105
|
+
signal }) => result)` once during `run()`. Keep the receiver local to that
|
|
106
|
+
invocation, honor cancellation, and return a standard `SchemeResult` for each
|
|
107
|
+
delivery. The consumer routes SEND to the existing execution address and owns
|
|
108
|
+
ordering, deadlines, permissions, and proposals. This does not expose Worker
|
|
109
|
+
identity or grant access to stored output.
|
|
110
|
+
|
|
111
|
+
`SubprocessExecutor` supplies this receiver when launched with `[{"stdin": "open"}]`.
|
|
112
|
+
SEND writes exact UTF-8 input; `[{"eof": true}]` ends stdin. No option means ordinary
|
|
113
|
+
batch EOF. See [the live-input contract](SPEC.md#executor-live-input-invocation-local-input).
|
|
114
|
+
|
|
88
115
|
### Address output
|
|
89
116
|
|
|
90
117
|
The runtime tag is also the output scheme. A subprocess result is therefore
|
|
91
|
-
read at an address such as `sh:///
|
|
92
|
-
be `sqlite:///
|
|
118
|
+
read at an address such as `sh:///ab3d5678#stdout`, while a structured result may
|
|
119
|
+
be `sqlite:///f2c49a10#results`. `exec://` is not an output address. Executors only
|
|
93
120
|
produce channels; the consumer owns storage and every later READ/FIND. See
|
|
94
121
|
{§executor-output-address}.
|
|
95
122
|
|
|
@@ -116,7 +143,6 @@ Policy is subtractive; a downstream layer cannot restore a removed tag. See
|
|
|
116
143
|
|
|
117
144
|
- `BaseExecutor`, `SubprocessExecutor`, and `SpawnArgs`.
|
|
118
145
|
- `discover`, `Policy`, `RuntimeTag`, and runtime discovery types.
|
|
119
|
-
- `Advertise`, a deprecated frozen 1.x compatibility helper with no current service path.
|
|
120
146
|
- `ErrorDetail` and `PLURNK_EXECS_ERROR_DETAIL_LIMIT`.
|
|
121
147
|
- Executor arguments, channel, availability, and effect types.
|
|
122
148
|
- `Results`, result types, and runtime-neutral Notice types.
|
package/SPEC.md
CHANGED
|
@@ -6,7 +6,7 @@ the framework; executor leaves implement it.
|
|
|
6
6
|
## §executor-role Role and ownership
|
|
7
7
|
|
|
8
8
|
An executor owns one declared runtime-specific invocation shape, its mapping
|
|
9
|
-
from that
|
|
9
|
+
from that fence body and realized target to work, declared output channels,
|
|
10
10
|
environment availability, and effect classification. The consumer owns
|
|
11
11
|
dispatch, invocation-shape enforcement and target realization, proposal policy,
|
|
12
12
|
storage, subscriptions, deadlines, polling, cancellation delivery, packet
|
|
@@ -17,7 +17,7 @@ flowchart LR
|
|
|
17
17
|
Manifest["package runtime declarations"] --> Discover["framework discovery"]
|
|
18
18
|
Discover --> Registry["runtime-tag registry"]
|
|
19
19
|
Registry --> Probe["consumer instantiates and probes each tag"]
|
|
20
|
-
Request["
|
|
20
|
+
Request["fence with runtime tag"] --> Effect["executor effect fact"]
|
|
21
21
|
Effect --> Admission["consumer proposal policy"]
|
|
22
22
|
Admission --> Stream["consumer creates tag-addressed stream"]
|
|
23
23
|
Stream --> Run["executor run with consumer sinks"]
|
|
@@ -39,6 +39,7 @@ abstract class BaseExecutor {
|
|
|
39
39
|
|
|
40
40
|
abstract get channels(): Readonly<Record<string, ChannelDecl>>;
|
|
41
41
|
get defaultChannel(): string;
|
|
42
|
+
prepare(input: ExecInput): Promise<ExecPreparation>;
|
|
42
43
|
abstract run(args: ExecArgs): Promise<ExecResult>;
|
|
43
44
|
probe(signal?: AbortSignal): Promise<RuntimeAvailability>;
|
|
44
45
|
effect(target: string | null): Effect;
|
|
@@ -55,8 +56,10 @@ interface ExecArgs {
|
|
|
55
56
|
body: string;
|
|
56
57
|
cwd: string | null;
|
|
57
58
|
target: string | null;
|
|
59
|
+
metadata: readonly string[] | null;
|
|
58
60
|
env?: NodeJS.ProcessEnv;
|
|
59
61
|
signal: AbortSignal;
|
|
62
|
+
registerInput?(receiver: ExecInputReceiver): void;
|
|
60
63
|
write(channel: string, chunk: string, mimetype?: string): void;
|
|
61
64
|
setState(channel: string, state: ChannelState): void;
|
|
62
65
|
emit(notice: Notice): void;
|
|
@@ -71,11 +74,12 @@ interface ExecArgs {
|
|
|
71
74
|
`ExecArgs` deliberately carries **no Worker identity**: an executor is a
|
|
72
75
|
worker-agnostic capability, and `run` may assume nothing about which Worker,
|
|
73
76
|
Loop, or workspace invoked it beyond the arguments given. A runtime whose
|
|
74
|
-
behavior depends on a
|
|
75
|
-
manager — is published per
|
|
76
|
-
identity at publication ({§functionality-model-projection}
|
|
77
|
-
|
|
78
|
-
identity
|
|
77
|
+
behavior depends on a workspace — an attached MCP server or Functionality
|
|
78
|
+
manager — is published per workspace by its module, closing over that
|
|
79
|
+
identity at publication ({§functionality-model-projection}). Consumers must not smuggle
|
|
80
|
+
identity through `env` or `body` conventions; a consumer that owns both a
|
|
81
|
+
runtime and the execution identity binds the two to each other outside these
|
|
82
|
+
arguments, at the operation.
|
|
79
83
|
|
|
80
84
|
interface RuntimeAvailability {
|
|
81
85
|
available: boolean;
|
|
@@ -90,7 +94,7 @@ The framework constructs one executor per matched runtime tag with
|
|
|
90
94
|
`this.runtime`; it must not retain per-run state on the executor instance. The
|
|
91
95
|
derived addressable runtime scheme retains `glyph` for client discovery
|
|
92
96
|
({§manifest-client-display}); runtime aliases remain excluded from scheme
|
|
93
|
-
model-teaching because the
|
|
97
|
+
model-teaching because the execution invocation directory owns that hot-path
|
|
94
98
|
surface.
|
|
95
99
|
|
|
96
100
|
### §executor-sinks Inputs and sinks
|
|
@@ -98,11 +102,13 @@ surface.
|
|
|
98
102
|
| Field | Contract |
|
|
99
103
|
| ---------- | ------------------------------------------------------------------------------------------------------- |
|
|
100
104
|
| `runtime` | The matched tag. |
|
|
101
|
-
| `body` | The authored
|
|
105
|
+
| `body` | The authored fence body, interpreted according to the runtime's invocation declaration. |
|
|
102
106
|
| `cwd` | Consumer-selected project working directory, or `null` for a runtime that has none. |
|
|
103
|
-
| `target` | Consumer-realized optional
|
|
107
|
+
| `target` | Consumer-realized optional execution target. Its representation and role come from the invocation declaration. |
|
|
108
|
+
| `metadata` | Exact ordered header blocks owned by the invoked executor, retained separately from the body and target. |
|
|
104
109
|
| `env` | Exact child environment when supplied. A subprocess must use it instead of reconstructing host policy. |
|
|
105
110
|
| `signal` | Consumer cancellation. Every executor must honor it at each cancellable boundary. |
|
|
111
|
+
| `registerInput` | Optionally register one live input receiver for this invocation under {§executor-live-input}. |
|
|
106
112
|
| `write` | Append to a declared channel. An optional mimetype replaces that channel's per-call output type. |
|
|
107
113
|
| `setState` | Move a declared channel from `active` to terminal `closed` or `errored`. |
|
|
108
114
|
| `emit` | Publish a transient, nonterminal Notice. |
|
|
@@ -113,6 +119,61 @@ The executor receives callbacks, never a database, subscription registry,
|
|
|
113
119
|
packet builder, or wake mechanism. Related lifecycle behavior remains on the
|
|
114
120
|
consumer side of {§executor-role}.
|
|
115
121
|
|
|
122
|
+
### §executor-metadata Invocation metadata ownership
|
|
123
|
+
|
|
124
|
+
The invoked executor owns its `[metadata]` for every target kind. The source
|
|
125
|
+
scheme supplies the program or data; it does not inherit the invoking tool's
|
|
126
|
+
options. An internal source READ therefore carries no execution metadata. An
|
|
127
|
+
authored READ retains its own source-scheme metadata contract.
|
|
128
|
+
|
|
129
|
+
| Stage | Contract |
|
|
130
|
+
| ----- | -------- |
|
|
131
|
+
| Preparation | Optional `prepare(input)` receives `runtime`, `body`, logical `target`, default `cwd`, and ordered raw `metadata`, before effect admission or source acquisition. It validates options without executing the program and returns `200` with a concrete `cwd` or `null`, or one universal failure. No hook means no metadata support. |
|
|
132
|
+
| Framework default | `BaseExecutor.prepare` accepts `[{"cwd": "<directory>"}]`. Relative directories resolve against the supplied default cwd; an absent override preserves it. Unknown fields, duplicates, malformed values, and nonexistent directories are refused. Tools can override preparation to own different metadata. |
|
|
133
|
+
| Subprocess options | `SubprocessExecutor` additionally accepts `[{"stdin": "open"}]` ({§executor-stdin}) and `[{"args": ["arg",...]}]`. The JSON array contains strings without NUL, preserves order and empty/whitespace-containing arguments, and appends directly to the spawn argument vector without shell parsing. Inline programs retain their interpreter's usual argument conventions. |
|
|
134
|
+
| Execution | `run()` receives the prepared cwd, realized target, unchanged body, and original metadata. The subprocess family uses the same option parser to obtain argv; cwd is already prepared and is not resolved a second time. |
|
|
135
|
+
| Evidence | Raw metadata follows the existing transient proposal handoff, never added to proposal attrs or emitted as receipt metadata. Expected preparation failures retain the tool's Problem; malformed preparation results are internal contract failures. |
|
|
136
|
+
|
|
137
|
+
Metadata does not turn inline programs or script stdin into JSON envelopes.
|
|
138
|
+
Executable references document advanced options on demand; no language-level
|
|
139
|
+
option names or hot-path teaching are required.
|
|
140
|
+
|
|
141
|
+
### §executor-live-input Invocation-local input
|
|
142
|
+
|
|
143
|
+
`ExecArgs.registerInput?(receiver)` binds one receiver to the current invocation.
|
|
144
|
+
The receiver accepts `{ body: string, metadata: readonly string[] | null,
|
|
145
|
+
signal: AbortSignal }` and resolves a universal `SchemeResult`. The body is exact
|
|
146
|
+
authored text; metadata belongs to the receiver. Registration is once per run,
|
|
147
|
+
never executor-instance state. An absent callback means the consumer cannot
|
|
148
|
+
deliver live input. A receiver must honor cancellation at each delivery boundary.
|
|
149
|
+
|
|
150
|
+
| Responsibility | Owner |
|
|
151
|
+
| --- | --- |
|
|
152
|
+
| Address, workspace admission, capability checks, proposals | Consumer, using the existing execution identity and effect. |
|
|
153
|
+
| Delivery ordering, bounded backpressure, lifetime | Consumer; serialize accepted deliveries, never replay an ambiguous write, retire on execution settlement/cancellation. |
|
|
154
|
+
| Input meaning, framing, EOF, delivery result | Receiver; acceptance does not imply consumption, command success, or execution completion. |
|
|
155
|
+
| Output, progress, completion | Existing `write`, `setState`, and `run` result; input introduces no second output or wake path. |
|
|
156
|
+
|
|
157
|
+
#### §executor-stdin Subprocess input
|
|
158
|
+
|
|
159
|
+
`SubprocessExecutor` accepts `[{"stdin": "open"}]` at invocation. The initial recipe
|
|
160
|
+
input precedes SEND bodies and stdin remains open; without this option, existing
|
|
161
|
+
batch input and EOF behavior is unchanged. The same input adapter serves `jq`.
|
|
162
|
+
|
|
163
|
+
| SEND input | Effect |
|
|
164
|
+
| --- | --- |
|
|
165
|
+
| Body, no metadata | Write its exact UTF-8 bytes, including authored newlines; no implicit newline. Empty input is a no-op, not EOF. |
|
|
166
|
+
| `[{"eof": true}]` with optional body | Write the body, then close stdin. Later SENDs return `410 input-closed`, including repeated EOF. |
|
|
167
|
+
| Other or duplicate metadata | `400`, before writing. |
|
|
168
|
+
| Pipe failure | Factual delivery failure with the native error code; no automatic retry. |
|
|
169
|
+
| Delivery cancellation | Stop the pending write and close stdin. The process retains its ordinary lifecycle. |
|
|
170
|
+
|
|
171
|
+
A successful receipt reports `bytesAccepted` and `inputClosed`, with those facts
|
|
172
|
+
in the ordinary model-visible `detail`. It acknowledges the writable pipe, not
|
|
173
|
+
application processing. Subprocess leaves inherit this
|
|
174
|
+
contract; logical executors need not offer a receiver. In particular, SQLite,
|
|
175
|
+
client-interaction tools, and MCP transports do not gain stdin through this API.
|
|
176
|
+
|
|
116
177
|
### §executor-channels Channels
|
|
117
178
|
|
|
118
179
|
The executor declares every channel it may write. The consumer seeds a stream
|
|
@@ -135,8 +196,10 @@ reformatting arbitrary source JSON read from an entry.
|
|
|
135
196
|
subprocess `exitCode`. A result with `status >= 400` carries exactly one RFC
|
|
136
197
|
9457 Problem whose status agrees with the result. Expected runtime failures
|
|
137
198
|
resolve as failure results and leave affected channels `errored`; they do not
|
|
138
|
-
throw.
|
|
139
|
-
|
|
199
|
+
throw. Rejection by an aborted execution's signal reason or an `AbortError`
|
|
200
|
+
is cancellation, not an executor defect; the consumer preserves its distinct
|
|
201
|
+
cancellation/deadline result. Other throws and invalid results become durable
|
|
202
|
+
contract failures before the consumer closes the stream.
|
|
140
203
|
|
|
141
204
|
A nonzero subprocess exit directs the caller only to inspect both stdout and
|
|
142
205
|
stderr because either may contain the useful diagnostic; it does not presume
|
|
@@ -173,7 +236,7 @@ reclassifies the materialized path.
|
|
|
173
236
|
| `pure` | Has no externally observable side effect. | Automatically accepted. |
|
|
174
237
|
|
|
175
238
|
The classification controls admission policy and may be reused as operational
|
|
176
|
-
metadata; it never changes within the invocation. After acceptance, every
|
|
239
|
+
metadata; it never changes within the invocation. After acceptance, every execution
|
|
177
240
|
uses the same background stream path: output is not returned in the dispatching
|
|
178
241
|
turn. Core owns that composed behavior in {§exec-host-proposes},
|
|
179
242
|
{§exec-readpure-ungated}, and {§exec-stream}.
|
|
@@ -195,34 +258,49 @@ unavailable is a fail-hard boot error.
|
|
|
195
258
|
|
|
196
259
|
## §executor-output-address Tag-addressed output
|
|
197
260
|
|
|
198
|
-
`exec` is the consumer's internal
|
|
261
|
+
`exec` is the consumer's internal execution dispatcher; it is not a model-facing
|
|
199
262
|
output namespace. Every available runtime receives one derived read-only
|
|
200
263
|
scheme face from its tag, channels, and default channel. The executor authors
|
|
201
264
|
no second scheme manifest.
|
|
202
265
|
|
|
203
266
|
| Output | Model-facing address |
|
|
204
267
|
| ------------------------- | ------------------------------------------------------------------ |
|
|
205
|
-
|
|
|
206
|
-
| Fragmentless read | `<tag>:///<
|
|
207
|
-
| Example subprocess stdout | `sh:///
|
|
208
|
-
| Example structured result | `sqlite:///
|
|
268
|
+
| Workspace execution stream | `<tag>:///<id>#<channel>` |
|
|
269
|
+
| Fragmentless read | `<tag>:///<id>` → the declared default channel |
|
|
270
|
+
| Example subprocess stdout | `sh:///ab3d5678#stdout` |
|
|
271
|
+
| Example structured result | `sqlite:///c2d45678#results` |
|
|
209
272
|
|
|
210
273
|
The executor only produces through `write` and `setState`. The consumer stores
|
|
211
274
|
the entry and serves every later READ/FIND through uniform entry machinery.
|
|
212
275
|
An executor does not implement a private read face, orientation receipt,
|
|
213
|
-
slicer, or index.
|
|
214
|
-
belong to core's {§
|
|
276
|
+
slicer, or index. Workspace-stable resource addresses and packet projection
|
|
277
|
+
belong to core's {§execution-output-identity} and {§exec-stream} contracts.
|
|
278
|
+
Address resolution binds the workspace without requiring an exact stored row:
|
|
279
|
+
FIND patterns and descendant resource paths participate in ordinary discovery;
|
|
280
|
+
an exact READ reports its own missing resource ({§entry-address-resolution}).
|
|
281
|
+
|
|
282
|
+
`publishedChannel` selects one declared channel for automatic stream observations;
|
|
283
|
+
absent/null selects all channels. Non-published channels remain READ-addressable.
|
|
284
|
+
This is the ordinary subscription publication selection, not another delivery path.
|
|
215
285
|
|
|
216
286
|
### §executor-entry-sink Optional materialization
|
|
217
287
|
|
|
218
|
-
`entry(path, content, {
|
|
219
|
-
executor access to storage.
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
288
|
+
`entry(path, content, { mimetype?, name? })` is a consumer-implemented sink, not
|
|
289
|
+
executor access to storage. It returns the canonical address of an ordinary
|
|
290
|
+
resource; publication alone does not attach media or wake a Worker.
|
|
291
|
+
|
|
292
|
+
| Input | Meaning |
|
|
293
|
+
| --- | --- |
|
|
294
|
+
| Absolute resource URL | Materialize or update that resource through its scheme owner. |
|
|
295
|
+
| `path: null` | Publish beneath this invocation's output address, in `resources/`. Preserve `name` as one URI-encoded component; otherwise allocate an eight-character hexadecimal identifier. Duplicate names receive a hash suffix, never overwrite another publication. The returned address is workspace-stable and carries no Worker selector. |
|
|
296
|
+
| String content + mimetype | Supplied text; preserve its source layout. |
|
|
297
|
+
| `Uint8Array` content + mimetype | Supplied bytes, retained as bytes, not a JSON/base64 body. |
|
|
298
|
+
| `content: null` | Consumer-sourced acquisition from an absolute HTTP(S) URL. |
|
|
299
|
+
|
|
300
|
+
Core owns names, storage, publication evidence, and byte acquisition. Executors
|
|
301
|
+
publish returned addresses in their result. Rejection means materialization
|
|
302
|
+
failed, not that the upstream operation had no effect. An absent sink cannot
|
|
303
|
+
be reported as successful resource publication.
|
|
226
304
|
|
|
227
305
|
## §executor-discovery Discovery and registration
|
|
228
306
|
|
|
@@ -284,7 +362,7 @@ at boot; changing package membership or configuration requires a restart.
|
|
|
284
362
|
| ------------- | -------------------------------------------------------------------------------------------------- |
|
|
285
363
|
| `name` | Canonical runtime tag and derived output-scheme name, admitted below. |
|
|
286
364
|
| `glyph` | Optional presentation glyph. |
|
|
287
|
-
| `summary` | Required one-line description, or `{ from: "tools" }` for an exact family inventory.
|
|
365
|
+
| `summary` | Required one-line description, or `{ from: "tools", description?: string }` for an exact family inventory with an optional one-line purpose. |
|
|
288
366
|
| `invocation` | Required body and target contract, validated and normalized below. |
|
|
289
367
|
| `details` | Optional supplemental Markdown. `docs/<tag>.md` wins over the inline manifest field. |
|
|
290
368
|
| `attribution` | Published per-tag projection of the validated package declaration ({§plugin-attribution}). |
|
|
@@ -294,7 +372,11 @@ The framework validates and carries the summary source, invocation, and suppleme
|
|
|
294
372
|
details as separate facts. A `{ from: "tools" }` summary is valid only for a
|
|
295
373
|
runtime implementing {§executor-tool-registry}; the consumer resolves it from
|
|
296
374
|
the exact effective tool set, after capability attenuation, so a denied tool
|
|
297
|
-
cannot survive in the family orientation line. The
|
|
375
|
+
cannot survive in the family orientation line. The inventory renders as
|
|
376
|
+
one compact executable fence naming `runtime (target|...)`, with the optional
|
|
377
|
+
purpose as a trailing aside and body line breaks represented by literal `\n`;
|
|
378
|
+
an authored string remains a description, without expanding its tool inventory.
|
|
379
|
+
The consumer deterministically renders the
|
|
298
380
|
model-facing tool document from either the static invocation or the executor's exact
|
|
299
381
|
{§executor-tool-registry}; authors never duplicate Summary or Invocation in
|
|
300
382
|
prose. A
|
|
@@ -320,20 +402,21 @@ details; the generated tool document owns the one model-facing H1.
|
|
|
320
402
|
| `target.kind` | One of the structural realization modes below. |
|
|
321
403
|
| `exclusive` | Optional `true`: body and target are alternative inputs and supplying both is refused. |
|
|
322
404
|
| `example` | Concise executable witness with a one-line `body`, `target`, or both as the declared shape permits. |
|
|
323
|
-
| `signature` |
|
|
405
|
+
| `signature` | Authored one-line structural body signature when no JSON Schema defines the input. |
|
|
406
|
+
| `inputSchema` | Original JSON Schema object for the input; the common document renderer derives its preview. |
|
|
324
407
|
|
|
325
408
|
| Target kind | Consumer realization |
|
|
326
409
|
| ----------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
327
410
|
| `literal` | Preserve the complete authored target string. It is an executor identifier, never a scheme read or filesystem classification. |
|
|
328
411
|
| `path` | Accept only a local or `file://` path and pass that path directly. |
|
|
329
|
-
| `resource` | Pass a local/file path directly
|
|
412
|
+
| `resource` | Pass a local/file path directly. After acceptance, resolve a non-file data-scheme address through one exact READ; use its owner-supplied native file or a standalone temporary representation ({§exec-source-temporary}). |
|
|
330
413
|
| `script` | As `resource`, and the local path must be an existing file: a directory or an absent path is refused before anything spawns ({§exec-executor-slot}). |
|
|
331
414
|
|
|
332
|
-
Every
|
|
415
|
+
Every execution must supply at least a body or target even when neither field is
|
|
333
416
|
independently required. A target's meaning never changes because the body is
|
|
334
|
-
empty or non-empty. `exclusive` requires a target declaration. Exactly one of `example
|
|
335
|
-
`signature` is present. An example must satisfy the same required, refused,
|
|
336
|
-
and exclusive buckets and parse as exactly one
|
|
417
|
+
empty or non-empty. `exclusive` requires a target declaration. Exactly one of `example`,
|
|
418
|
+
`signature`, or `inputSchema` is present. An example must satisfy the same required, refused,
|
|
419
|
+
and exclusive buckets and parse as exactly one executor fence for the runtime. A
|
|
337
420
|
signature is presentation, not an executable example; dispatch still enforces
|
|
338
421
|
the invocation's body and target declarations. An invocation declaration
|
|
339
422
|
with a missing field, unknown field, invalid combination, multiline role, or
|
|
@@ -377,25 +460,38 @@ I/O boundary rather than making packet assembly perform network discovery.
|
|
|
377
460
|
§executor-tool-document **Tool documents are the model-facing executor
|
|
378
461
|
directory.** A general runtime's document carries exact H2 `Summary` and
|
|
379
462
|
`Invocation` sections plus its executable witness. Its Summary is that compact
|
|
380
|
-
invocation witness in
|
|
381
|
-
operation
|
|
382
|
-
one-line body.
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
tool
|
|
387
|
-
|
|
463
|
+
invocation witness in plain text, with the authored description as an
|
|
464
|
+
operation aside on its invocation line and a literal `\n` before a
|
|
465
|
+
one-line body. The bundled subprocess interpreters declare concrete inline-program
|
|
466
|
+
examples; their catalog summaries include the program body without a script target.
|
|
467
|
+
An exact registry instead renders one compact family document whose Summary is
|
|
468
|
+
authored or derived from its effective tools. Its H2 `Tools` contains one
|
|
469
|
+
executable fence per tool, naming the runtime and exact target, with its aside
|
|
470
|
+
and input preview. A schema-backed invocation
|
|
471
|
+
links from its aside to a child document containing the full description and
|
|
472
|
+
original input JSON Schema. Non-schema invocations retain their authored witness
|
|
473
|
+
and supplemental details.
|
|
388
474
|
Supplemental `details` follows framework-owned sections and cannot own identity,
|
|
389
475
|
invocation, or admission. The consumer chooses resource addresses, materializes
|
|
390
476
|
the documents, and exposes each Summary through ordinary FIND metadata. No
|
|
391
477
|
executor table or executor-specific discovery protocol exists.
|
|
392
478
|
|
|
479
|
+
§executor-input-schema-preview Schema-backed previews list only explicitly
|
|
480
|
+
required top-level fields, with quoted names and declared broad JSON types.
|
|
481
|
+
Nested objects and arrays stay opaque; an undeclared type is `unknown`. Optional
|
|
482
|
+
fields, references, constraints, and conditional branches are not interpreted.
|
|
483
|
+
The preview is not a complete signature or validation promise. Its schema link
|
|
484
|
+
provides the complete original schema, including descriptions, definitions,
|
|
485
|
+
references, and constraints; repository-owned referenced schemas are included
|
|
486
|
+
unchanged alongside it. Documentation performs no network reference resolution.
|
|
487
|
+
Output schemas are not input teaching.
|
|
488
|
+
|
|
393
489
|
Runtime-name admission is one identity contract:
|
|
394
490
|
|
|
395
491
|
| Constraint | Contract |
|
|
396
492
|
| ----------- | ------------------------------------------------------------------------------------------------------------- |
|
|
397
|
-
| Syntax | `[a-z][a-z0-9+.-]*`: canonical lowercase RFC-scheme syntax that is also an admitted
|
|
398
|
-
| Identity | The exact name is the
|
|
493
|
+
| Syntax | `[a-z][a-z0-9+.-]*`: canonical lowercase RFC-scheme syntax that is also an admitted execution identifier. |
|
|
494
|
+
| Identity | The exact name is the fence name, registry key, tool-family identity, and output URI-scheme name. |
|
|
399
495
|
| Reservation | `only` is unavailable because `PLURNK_EXECS_ONLY` owns that case-insensitive configuration key. |
|
|
400
496
|
|
|
401
497
|
Installed static declarations, trusted dynamic-hook declarations, and
|
|
@@ -429,7 +525,8 @@ swallowed.
|
|
|
429
525
|
|
|
430
526
|
### §executor-policy Subtractive runtime policy
|
|
431
527
|
|
|
432
|
-
|
|
528
|
+
Registration applies the daemon's policy to every tag, whether discovered from
|
|
529
|
+
a package or supplied by a daemon module, including workspace-scoped runtimes. The exported
|
|
433
530
|
`Policy` parser can apply the same grammar to additional consumer-owned layers.
|
|
434
531
|
|
|
435
532
|
| Variable | Enforced effect |
|
|
@@ -440,18 +537,11 @@ Discovery applies the daemon's registration policy to every tag. The exported
|
|
|
440
537
|
| `Policy.enabledAcross(tag, [a, b, ...])` | Keep the tag only when every supplied layer enables it. |
|
|
441
538
|
|
|
442
539
|
Policy is purely subtractive: no layer can re-enable a tag removed by another.
|
|
443
|
-
|
|
444
|
-
|
|
540
|
+
Disabled tags publish neither an executor nor its scheme or tool documents;
|
|
541
|
+
package discovery also returns them in `Discovery.disabled`.
|
|
542
|
+
Workspace and loop admission remain consumer concerns;
|
|
445
543
|
the framework does not define a second Active/Available state machine.
|
|
446
544
|
|
|
447
|
-
### §executor-advertise-compat Frozen `Advertise` compatibility
|
|
448
|
-
|
|
449
|
-
| Surface | 1.x contract |
|
|
450
|
-
|--------------------------------------|-------------------------------------------------------------------------------------------------------------|
|
|
451
|
-
| `Advertise.contribute(registry, fn)` | Filters the supplied registry; returns `NO_EXECS_NOTICE` only when the filtered result is empty. |
|
|
452
|
-
| Architectural ownership | None. It does not discover, probe, admit, dispatch, or render; the composed service never calls it. |
|
|
453
|
-
| Evolution | Frozen. New consumers compose discovery and `Policy` with their own presentation. Removal is SemVer-major. |
|
|
454
|
-
|
|
455
545
|
## §executor-default-inventory Current installed set
|
|
456
546
|
|
|
457
547
|
The default `@plurnk/plurnk-service` composition installs the following
|
|
@@ -490,9 +580,10 @@ interface SpawnArgs {
|
|
|
490
580
|
| `python3` | `python3 -c <body>`. |
|
|
491
581
|
| Other default-base runtime | `<runtime> -c <body>`; specialized leaves override this fallback. |
|
|
492
582
|
|
|
493
|
-
With a target, the target is the program and the body is its stdin.
|
|
583
|
+
With a target, the target is the program and the body is its stdin. Each leaf
|
|
584
|
+
uses its interpreter's file form (`awk -f <target>`, for example). The working
|
|
494
585
|
directory is the consumer's `cwd` — the project root, or the directory a
|
|
495
|
-
`{cwd
|
|
586
|
+
`[{"cwd": "<directory>"}]` block on the heading names ({§exec-executor-slot}); a
|
|
496
587
|
directory is never a target. Data runtimes define their own declared target
|
|
497
588
|
kind and role.
|
|
498
589
|
|
|
@@ -504,7 +595,7 @@ violations for the consumer to contain.
|
|
|
504
595
|
|
|
505
596
|
### §executor-cancellation Cancellation and consumer timing
|
|
506
597
|
|
|
507
|
-
Executors know only the supplied `AbortSignal`. Core owns
|
|
598
|
+
Executors know only the supplied `AbortSignal`. Core owns execution timeout and poll
|
|
508
599
|
syntax, timers, wakes, and loop lifetime in {§exec-timeout} and {§exec-poll}.
|
|
509
600
|
Subprocess cancellation signals the process group: a caller-supplied kill code
|
|
510
601
|
is delivered once; ordinary cancellation uses SIGHUP; loop-end housekeeping
|
|
@@ -516,7 +607,7 @@ The consumer:
|
|
|
516
607
|
|
|
517
608
|
1. discovers declared tags, instantiates and probes each tag, and caches the verdict;
|
|
518
609
|
2. registers a derived output scheme for every admitted, available tag;
|
|
519
|
-
3. resolves
|
|
610
|
+
3. resolves the fence name to exactly one tag and obtains its effect fact;
|
|
520
611
|
4. applies proposal policy, creates the stream entry, and supplies sinks plus cancellation;
|
|
521
612
|
5. validates the terminal result and closes every declared channel and subscription coherently; and
|
|
522
613
|
6. projects stream observations and later reads without calling back into the executor.
|
package/dist/BaseExecutor.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SchemeHandler, SchemeManifest } from "@plurnk/plurnk-schemes";
|
|
2
|
-
import type { ChannelDecl, Effect, ExecArgs, ExecResult, ExecutorMetadata, RuntimeAvailability } from "./types.ts";
|
|
2
|
+
import type { ChannelDecl, Effect, ExecArgs, ExecInput, ExecPreparation, ExecResult, ExecutorMetadata, RuntimeAvailability } from "./types.ts";
|
|
3
3
|
export default abstract class BaseExecutor implements SchemeHandler {
|
|
4
4
|
readonly runtime: string;
|
|
5
5
|
readonly glyph: string;
|
|
@@ -7,7 +7,9 @@ export default abstract class BaseExecutor implements SchemeHandler {
|
|
|
7
7
|
get manifest(): SchemeManifest;
|
|
8
8
|
get traits(): ReadonlyArray<string> | undefined;
|
|
9
9
|
get defaultChannel(): string;
|
|
10
|
+
get publishedChannel(): string | null;
|
|
10
11
|
abstract get channels(): Readonly<Record<string, ChannelDecl>>;
|
|
12
|
+
prepare(input: ExecInput): Promise<ExecPreparation>;
|
|
11
13
|
abstract run(args: ExecArgs): Promise<ExecResult>;
|
|
12
14
|
probe(_signal?: AbortSignal): Promise<RuntimeAvailability>;
|
|
13
15
|
effect(_target: string | null): Effect;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseExecutor.d.ts","sourceRoot":"","sources":["../src/BaseExecutor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,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":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAY/I,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,YAAa,YAAW,aAAa;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,gBAAgB,EAG/C;IAaD,IAAI,QAAQ,IAAI,cAAc,CAU7B;IAGD,IAAI,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAE9C;IAID,IAAI,cAAc,IAAI,MAAM,CAE3B;IAGD,IAAI,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEpC;IAOD,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAE/D,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC,CAElD;IAOD,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAmB5C,KAAK,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAE/D;IAQD,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAErC;CACJ"}
|
package/dist/BaseExecutor.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { OutputScheme } from "@plurnk/plurnk-schemes";
|
|
2
|
+
import InvocationMetadata from "./InvocationMetadata.js";
|
|
2
3
|
// Base class for runtime executors (parallel to plurnk-mimetypes' BaseHandler).
|
|
3
4
|
// A `@plurnk/plurnk-execs-*` sibling subclasses this and implements `run()`.
|
|
4
5
|
// The framework instantiates one executor per matched runtime tag, injecting
|
|
@@ -44,6 +45,13 @@ export default class BaseExecutor {
|
|
|
44
45
|
get defaultChannel() {
|
|
45
46
|
return Object.keys(this.channels)[0] ?? "";
|
|
46
47
|
}
|
|
48
|
+
// Select the existing stream-publication contract; null publishes every channel.
|
|
49
|
+
get publishedChannel() {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
prepare(input) {
|
|
53
|
+
return InvocationMetadata.prepare(input);
|
|
54
|
+
}
|
|
47
55
|
// Whether this runtime's execution environment is usable in the current
|
|
48
56
|
// deployment. Default: available (pure / in-process runtimes — e.g. node,
|
|
49
57
|
// sqlite, where the daemon itself satisfies the dependency). Subclasses
|
package/dist/BaseExecutor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseExecutor.js","sourceRoot":"","sources":["../src/BaseExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"BaseExecutor.js","sourceRoot":"","sources":["../src/BaseExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGtD,OAAO,kBAAkB,MAAM,yBAAyB,CAAC;AAEzD,gFAAgF;AAChF,6EAA6E;AAC7E,6EAA6E;AAC7E,yEAAyE;AACzE,EAAE;AACF,2EAA2E;AAC3E,6EAA6E;AAC7E,2EAA2E;AAC3E,4DAA4D;AAC5D,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;IAED,kEAAkE;IAClE,gCAAgC;IAChC,8EAA8E;IAC9E,8EAA8E;IAC9E,6EAA6E;IAC7E,yDAAyD;IACzD,2EAA2E;IAC3E,0EAA0E;IAC1E,6EAA6E;IAC7E,2EAA2E;IAC3E,8EAA8E;IAC9E,IAAI,QAAQ;QACR,OAAO,YAAY,CAAC,mBAAmB,CAAC;YACpC,IAAI,EAAE,IAAI,CAAC,OAAO;YAClB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,MAAM,CAAC,WAAW,CACxB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAC7E;YACD,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM;SACtB,CAAC,CAAC;IACP,CAAC;IAED,+DAA+D;IAC/D,IAAI,MAAM;QACN,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,yEAAyE;IACzE,oEAAoE;IACpE,IAAI,cAAc;QACd,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,CAAC;IAED,iFAAiF;IACjF,IAAI,gBAAgB;QAChB,OAAO,IAAI,CAAC;IAChB,CAAC;IASD,OAAO,CAAC,KAAgB;QACpB,OAAO,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IASD,wEAAwE;IACxE,0EAA0E;IAC1E,wEAAwE;IACxE,iEAAiE;IACjE,EAAE;IACF,8EAA8E;IAC9E,yEAAyE;IACzE,2EAA2E;IAC3E,yEAAyE;IACzE,4DAA4D;IAC5D,EAAE;IACF,sEAAsE;IACtE,4EAA4E;IAC5E,yEAAyE;IACzE,kEAAkE;IAClE,6EAA6E;IAC7E,iBAAiB;IACjB,KAAK,CAAC,KAAK,CAAC,OAAqB;QAC7B,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC/B,CAAC;IAED,4EAA4E;IAC5E,6EAA6E;IAC7E,8EAA8E;IAC9E,yEAAyE;IACzE,wEAAwE;IACxE,gEAAgE;IAChE,MAAM,CAAC,OAAsB;QACzB,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocFile.d.ts","sourceRoot":"","sources":["../src/DocFile.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,OAAO,OAAO,OAAO;IAExB,OAAa,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMlE;IAED,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAM/C;CACJ"}
|
package/dist/DocFile.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
// A package's `docs/<tag>.md` — the authored teaching carried beneath a generated tool
|
|
4
|
+
// document's header ({§executor-discovery}). Runtimes and Functionality families share this
|
|
5
|
+
// one rule: the file stays a valid standalone document whose exact authoring title `# <tag>`
|
|
6
|
+
// is removed, because the generated document owns the one model-facing H1.
|
|
7
|
+
export default class DocFile {
|
|
8
|
+
// The tag's supplemental detail file, or null when the package ships none.
|
|
9
|
+
static async read(dir, tag) {
|
|
10
|
+
try {
|
|
11
|
+
return DocFile.body(await fs.readFile(path.join(dir, "docs", `${tag}.md`), "utf-8"), tag);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
static body(source, tag) {
|
|
18
|
+
const title = `# ${tag}`;
|
|
19
|
+
if (source === title || source === `${title}\n`)
|
|
20
|
+
return "";
|
|
21
|
+
if (source.startsWith(`${title}\r\n`))
|
|
22
|
+
return source.slice(title.length + 2).replace(/^\r?\n/u, "");
|
|
23
|
+
if (source.startsWith(`${title}\n`))
|
|
24
|
+
return source.slice(title.length + 1).replace(/^\r?\n/u, "");
|
|
25
|
+
return source;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=DocFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocFile.js","sourceRoot":"","sources":["../src/DocFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,uFAAuF;AACvF,4FAA4F;AAC5F,6FAA6F;AAC7F,2EAA2E;AAC3E,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,2EAA2E;IAC3E,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,GAAW;QACtC,IAAI,CAAC;YACD,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9F,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,MAAc,EAAE,GAAW;QACnC,MAAM,KAAK,GAAG,KAAK,GAAG,EAAE,CAAC;QACzB,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,GAAG,KAAK,IAAI;YAAE,OAAO,EAAE,CAAC;QAC3D,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,KAAK,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACpG,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,KAAK,IAAI,CAAC;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAClG,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ"}
|