@plurnk/plurnk-execs 0.1.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/LICENSE +21 -0
- package/README.md +19 -0
- package/SPEC.md +77 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime.d.ts +5 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +25 -0
- package/dist/runtime.js.map +1 -0
- package/dist/types.d.ts +22 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PossumTech Laboratories
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# plurnk-execs
|
|
2
|
+
|
|
3
|
+
Framework + contract for `@plurnk/plurnk-execs-*` runtime executor packages. Consumed by [plurnk-service](https://github.com/plurnk/plurnk-service)'s `exec` scheme for EXEC op dispatch.
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
- [`SPEC.md`](./SPEC.md) — author-facing contract.
|
|
8
|
+
- Constellation: [plurnk-grammar](https://github.com/plurnk/plurnk-grammar) (EXEC AST), [plurnk-providers](https://github.com/plurnk/plurnk-providers), [plurnk-schemes](https://github.com/plurnk/plurnk-schemes), [plurnk-mimetypes](https://github.com/plurnk/plurnk-mimetypes).
|
|
9
|
+
|
|
10
|
+
## Exports
|
|
11
|
+
|
|
12
|
+
- `SpawnArgs`, `RuntimeResolver` — types.
|
|
13
|
+
- `KNOWN_RUNTIMES` — read-only set of v0 hardcoded runtime tags.
|
|
14
|
+
- `isKnownRuntime(runtime)` — predicate.
|
|
15
|
+
- `resolveRuntime(runtime, command)` — runtime tag + command → `SpawnArgs` for `node:child_process.spawn`.
|
|
16
|
+
|
|
17
|
+
## Tests
|
|
18
|
+
|
|
19
|
+
`test:lint`, `test:unit`.
|
package/SPEC.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# plurnk-execs — Specification
|
|
2
|
+
|
|
3
|
+
Contract for `@plurnk/plurnk-execs-*` sibling packages — runtime executors that plurnk-service's `exec://` scheme dispatches to. Audience: implementer of a runtime executor. Consumer: [plurnk-service](https://github.com/plurnk/plurnk-service) (SPEC.md §6.8, §10).
|
|
4
|
+
|
|
5
|
+
## §1 Role
|
|
6
|
+
|
|
7
|
+
A runtime executor handles one or more EXEC `runtime` slot values. Today plurnk-service's `Exec` scheme hardcodes the runtime → spawn-args mapping for shell / node / python; this repo exports the same logic as `resolveRuntime`. The forward-spec is plugin discovery (one runtime per sibling); v0 ships the hardcoded path.
|
|
8
|
+
|
|
9
|
+
## §2 v0 surface
|
|
10
|
+
|
|
11
|
+
`resolveRuntime(runtime: string, command: string) → SpawnArgs`:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
interface SpawnArgs {
|
|
15
|
+
cmd: string;
|
|
16
|
+
args: string[];
|
|
17
|
+
useShell: boolean;
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Maps:
|
|
22
|
+
|
|
23
|
+
| Runtime | Spawn |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `""` / `"sh"` / `"bash"` | `{ cmd: command, args: [], useShell: true }` |
|
|
26
|
+
| `"node"` | `{ cmd: "node", args: ["-e", command], useShell: false }` |
|
|
27
|
+
| `"python"` / `"python3"` | `{ cmd: "python3", args: ["-c", command], useShell: false }` |
|
|
28
|
+
| any other | `{ cmd: runtime, args: ["-c", command], useShell: false }` (conservative fallback) |
|
|
29
|
+
|
|
30
|
+
`resolveRuntime` never throws. Consumers gate unknown runtimes with `isKnownRuntime(runtime)` and return 501 from the scheme before invoking.
|
|
31
|
+
|
|
32
|
+
`KNOWN_RUNTIMES` is the v0 hardcoded set; equivalent to the union of mapped runtimes above except the conservative fallback.
|
|
33
|
+
|
|
34
|
+
## §3 Forward-spec — plugin discovery
|
|
35
|
+
|
|
36
|
+
The full constellation pattern (mirroring `plurnk-mimetypes`):
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"name": "@plurnk/plurnk-execs-<runtime>",
|
|
41
|
+
"plurnk": {
|
|
42
|
+
"kind": "exec",
|
|
43
|
+
"runtimes": [
|
|
44
|
+
{ "name": "sh", "glyph": "🐚" },
|
|
45
|
+
{ "name": "bash", "glyph": "🐚" }
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Each sibling registers one or more runtime tags. Plurnk-service scans `node_modules/@plurnk/*` at boot, finds `plurnk.kind === "exec"` packages, registers their handlers. Collision on runtime name: fail-hard.
|
|
52
|
+
|
|
53
|
+
Each runtime exports a `BaseExecutor` subclass (or equivalent) with `run(args) → Promise<ExecResult>`. Args shape, result shape, AbortSignal handling — all settle as the first sub-siblings ship (`plurnk-execs-sh` would be canonical).
|
|
54
|
+
|
|
55
|
+
Sub-siblings expected: `plurnk-execs-sh` (default subprocess), `plurnk-execs-node`, `plurnk-execs-python`, `plurnk-execs-search` (web search).
|
|
56
|
+
|
|
57
|
+
## §4 Consumer surface (plurnk-service today)
|
|
58
|
+
|
|
59
|
+
The `exec` scheme in plurnk-service:
|
|
60
|
+
|
|
61
|
+
1. Calls `isKnownRuntime(runtime)` — returns 501 if false.
|
|
62
|
+
2. Calls `resolveRuntime(runtime, command)` to get `SpawnArgs`.
|
|
63
|
+
3. Passes args to `node:child_process.spawn` and manages the subprocess lifecycle (channels, AbortController, subscription registry, wake-on-completion).
|
|
64
|
+
|
|
65
|
+
Steps 1–2 are this repo's surface. Step 3 stays in the `exec` scheme. The plug-in discovery future (§3) will absorb step 3's invocation into the executor interface, but for v0 the scheme owns the spawn/streaming machinery and consumes this repo only for the runtime-tag translation.
|
|
66
|
+
|
|
67
|
+
## §5 Forbidden (for future siblings)
|
|
68
|
+
|
|
69
|
+
| ❌ |
|
|
70
|
+
|---|
|
|
71
|
+
| Database access |
|
|
72
|
+
| Imports from `@plurnk/plurnk-service/*` |
|
|
73
|
+
| Mutating arguments |
|
|
74
|
+
| Holding state across `run` calls beyond config |
|
|
75
|
+
| Reading runtime output via `console.*` |
|
|
76
|
+
| Ignoring cancellation signals |
|
|
77
|
+
| Spawning processes outside the runtime's domain (e.g. an HTTP runtime spawning subprocesses) |
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SpawnArgs } from "./types.ts";
|
|
2
|
+
export declare const KNOWN_RUNTIMES: ReadonlySet<string>;
|
|
3
|
+
export declare const isKnownRuntime: (runtime: string) => boolean;
|
|
4
|
+
export declare const resolveRuntime: (runtime: string, command: string) => SpawnArgs;
|
|
5
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAI5C,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAE7C,CAAC;AAEH,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,OAAsC,CAAC;AAExF,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,EAAE,SAAS,MAAM,KAAG,SAcjE,CAAC"}
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Runtime tag → spawn-args dispatch. Hardcoded v0 multiplexer; plugin
|
|
2
|
+
// discovery (one runtime per `@plurnk/plurnk-execs-*` sibling) is the
|
|
3
|
+
// forward-spec path documented in SPEC.md.
|
|
4
|
+
// Runtimes plurnk-service's `Exec` scheme accepts at v0. Unknown runtimes
|
|
5
|
+
// must return 501 from the scheme; `resolveRuntime` itself never throws.
|
|
6
|
+
export const KNOWN_RUNTIMES = new Set([
|
|
7
|
+
"", "sh", "bash", "node", "python", "python3",
|
|
8
|
+
]);
|
|
9
|
+
export const isKnownRuntime = (runtime) => KNOWN_RUNTIMES.has(runtime);
|
|
10
|
+
export const resolveRuntime = (runtime, command) => {
|
|
11
|
+
if (runtime === "" || runtime === "sh" || runtime === "bash") {
|
|
12
|
+
return { cmd: command, args: [], useShell: true };
|
|
13
|
+
}
|
|
14
|
+
if (runtime === "node") {
|
|
15
|
+
return { cmd: "node", args: ["-e", command], useShell: false };
|
|
16
|
+
}
|
|
17
|
+
if (runtime === "python" || runtime === "python3") {
|
|
18
|
+
return { cmd: "python3", args: ["-c", command], useShell: false };
|
|
19
|
+
}
|
|
20
|
+
// Unknown runtime: conservative `<runtime> -c <command>` fallback.
|
|
21
|
+
// Schemes should gate this off with `isKnownRuntime` and return 501,
|
|
22
|
+
// but the resolver itself stays total.
|
|
23
|
+
return { cmd: runtime, args: ["-c", command], useShell: false };
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,sEAAsE;AACtE,2CAA2C;AAI3C,0EAA0E;AAC1E,yEAAyE;AACzE,MAAM,CAAC,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IACvD,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS;CAChD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAe,EAAW,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,OAAe,EAAa,EAAE;IAC1E,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QAC3D,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACtD,CAAC;IACD,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACrB,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACnE,CAAC;IACD,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAChD,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACtE,CAAC;IACD,mEAAmE;IACnE,qEAAqE;IACrE,uCAAuC;IACvC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACpE,CAAC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface SpawnArgs {
|
|
2
|
+
/** Command to invoke (e.g. "node", "python3", or — when useShell — the raw command). */
|
|
3
|
+
cmd: string;
|
|
4
|
+
/** Args passed to the command. */
|
|
5
|
+
args: string[];
|
|
6
|
+
/** When true, the command is interpreted as a shell line (cmd is the whole line, args ignored). */
|
|
7
|
+
useShell: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Translate a runtime tag + command string into spawn args for `node:child_process.spawn`.
|
|
11
|
+
*
|
|
12
|
+
* Runtimes:
|
|
13
|
+
* - `""` / `"sh"` / `"bash"` → shell-mode invocation of the command
|
|
14
|
+
* - `"node"` → `node -e <command>`
|
|
15
|
+
* - `"python"` / `"python3"` → `python3 -c <command>`
|
|
16
|
+
* - any other (unknown) runtime tag → conservative `<runtime> -c <command>` fallback
|
|
17
|
+
*
|
|
18
|
+
* Consumers check `isKnownRuntime(runtime)` before calling to enforce a 501 boundary
|
|
19
|
+
* on unconfigured runtimes; this function never throws.
|
|
20
|
+
*/
|
|
21
|
+
export type RuntimeResolver = (runtime: string, command: string) => SpawnArgs;
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAQA,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;CACrB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Runtime executor contract. Each `@plurnk/plurnk-execs-*` sibling declares
|
|
2
|
+
// one or more runtime tags (`sh`, `bash`, `python`, `search`, etc.) and
|
|
3
|
+
// provides the dispatch logic for those tags.
|
|
4
|
+
//
|
|
5
|
+
// v0 surface: runtime tag → spawn-args translator (the only piece
|
|
6
|
+
// plurnk-service's exec scheme needs migrated out of its own codebase).
|
|
7
|
+
// Plugin discovery / framework registry is forward-spec — see SPEC.md.
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wEAAwE;AACxE,8CAA8C;AAC9C,EAAE;AACF,kEAAkE;AAClE,wEAAwE;AACxE,uEAAuE"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@plurnk/plurnk-execs",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Framework + contract for the @plurnk/plurnk-execs-* runtime executor family.",
|
|
5
|
+
"keywords": ["plurnk", "exec", "runtime", "executor"],
|
|
6
|
+
"homepage": "https://github.com/plurnk/plurnk-execs#readme",
|
|
7
|
+
"bugs": {
|
|
8
|
+
"url": "https://github.com/plurnk/plurnk-execs/issues"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/plurnk/plurnk-execs.git"
|
|
13
|
+
},
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=25"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"author": "@wikitopian",
|
|
19
|
+
"type": "module",
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"default": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./package.json": "./package.json"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist/**/*",
|
|
32
|
+
"README.md",
|
|
33
|
+
"SPEC.md"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"test:lint": "tsc --noEmit",
|
|
37
|
+
"test:unit": "node --test src/**/*.test.ts",
|
|
38
|
+
"test": "npm run test:lint && npm run test:unit",
|
|
39
|
+
"build:dist": "tsc -p tsconfig.build.json",
|
|
40
|
+
"build": "npm run build:dist",
|
|
41
|
+
"prepare": "npm run build"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^25.8.0",
|
|
45
|
+
"typescript": "^6.0.3"
|
|
46
|
+
}
|
|
47
|
+
}
|