@silvermoon-work/task-builder-cli 0.1.0-canary-261109-3 → 0.1.0-canary-261111-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 +167 -121
- package/dist/bin.js +5 -3
- package/dist/bin.js.map +1 -1
- package/dist/delivery.d.ts +28 -0
- package/dist/delivery.d.ts.map +1 -0
- package/dist/delivery.js +146 -0
- package/dist/delivery.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +265 -136
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +30 -6
- package/dist/node.js.map +1 -1
- package/dist/project.d.ts +1 -4
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +19 -15
- package/dist/project.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,150 +1,196 @@
|
|
|
1
1
|
# @silvermoon-work/task-builder-cli
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
help, version, output rendering, host paths, file writes and executable signals.
|
|
7
|
-
It does not implement bundling or CAR encoding itself.
|
|
8
|
-
|
|
9
|
-
The preceding release was `0.1.0-canary-261109-1`, depending on
|
|
10
|
-
`task-builder@0.1.0-canary-261109-2`. CLI version `0.1.0-canary-261109-3`
|
|
11
|
-
requires core `0.1.0-canary-261109-3` and generates the migrated SDK template.
|
|
12
|
-
The older core package's binary is not
|
|
13
|
-
this Commander CLI. See the
|
|
14
|
-
[published-package verification guide](../../docs/end-to-end-verification.md).
|
|
3
|
+
Task production CLI and reusable command runner. Node >=22.13 is required.
|
|
4
|
+
This document describes the redesigned source interface; registry acceptance
|
|
5
|
+
requires separately publishing compatible Builder and CLI packages.
|
|
15
6
|
|
|
16
7
|
## Commands
|
|
17
8
|
|
|
18
9
|
```text
|
|
19
|
-
task-builder init <
|
|
20
|
-
task-builder build
|
|
21
|
-
task-builder car <
|
|
22
|
-
task-builder check <bundle.car> [--expected-cid <cid>]
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
The original `task-builder <task.build.yaml> [build options]` shorthand is
|
|
26
|
-
Commander's default build command, not a second hand-written parser.
|
|
27
|
-
|
|
28
|
-
```text
|
|
10
|
+
task-builder init <directory> [--package-name <name>] [--task-name <name>]
|
|
11
|
+
task-builder build [build-file] [--out-dir <directory>] [--no-car]
|
|
12
|
+
task-builder car <task-file> [--output <file>]
|
|
29
13
|
task-builder --help
|
|
30
14
|
task-builder build --help
|
|
31
|
-
task-builder help car
|
|
32
15
|
task-builder --version
|
|
33
|
-
task-builder check bundle.car --format text
|
|
34
|
-
task-builder --format json check bundle.car
|
|
35
16
|
```
|
|
36
17
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
`--
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
`{ error: { code, message } }`. Exit codes are 0 for success/help/version,
|
|
54
|
-
2 for Commander usage errors, 1 for operation errors, 130 for SIGINT and
|
|
55
|
-
143 for SIGTERM. There is no automatic install, overwrite, upload, pin or publish.
|
|
18
|
+
Only these three commands exist. No arguments prints help, without building.
|
|
19
|
+
There is no `help` command, implicit build, `check`, `--root`, `--format`,
|
|
20
|
+
`--trusted-contract`, dependency-version selection, CID sidecar, or business
|
|
21
|
+
field override. Unknown, extra and duplicate options/arguments fail.
|
|
22
|
+
No command prompts, reads stdin, installs dependencies, uploads or publishes.
|
|
23
|
+
TTY and redirected invocations have the same behavior.
|
|
24
|
+
|
|
25
|
+
Successful business commands write one newline-terminated
|
|
26
|
+
`{ "ok": true, "data": ... }` object to stdout. Failures write one
|
|
27
|
+
`{ "ok": false, "error": { "code": "...", "message": "..." } }` object to stdout;
|
|
28
|
+
`error` has exactly those two nonempty fields. Verified partial delivery can
|
|
29
|
+
also appear as `data` in that same failure object.
|
|
30
|
+
Stderr is reserved for CLI diagnostics and is empty by default. Help and root
|
|
31
|
+
version are text on stdout. Exit status is 0 for success/help/version, 1 for
|
|
32
|
+
ordinary failures. Confirmed cancellation and cleanup use 130 (SIGINT) or 143
|
|
33
|
+
(SIGTERM); an uncertain delivery or cleanup always uses 1.
|
|
56
34
|
|
|
57
35
|
## Init composition
|
|
58
36
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
The
|
|
63
|
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
not the
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
37
|
+
The target must not exist and its parent must exist. Package name defaults to
|
|
38
|
+
the target directory basename; invalid names require `--package-name` rather
|
|
39
|
+
than silent sanitization. Task name defaults to the package's unscoped name.
|
|
40
|
+
The editable template includes:
|
|
41
|
+
|
|
42
|
+
- `package.json`, `.gitignore`, `pnpm-workspace.yaml`;
|
|
43
|
+
- `task.build.yaml`, explicit `src/main.ts` and `src/helper.ts`;
|
|
44
|
+
- a TypeBox `src/contract.ts` with a shared Schema and `assets/greeting.txt`;
|
|
45
|
+
- Node minimum 22.13.0, `assets/**` → `resources/`, no binary rules;
|
|
46
|
+
- build, standalone CAR and explicit `clean` scripts; no dependency installation.
|
|
47
|
+
|
|
48
|
+
The contract exports `Input` and `Result` via `Static<typeof ...>`; the Worker
|
|
49
|
+
imports those types with `import type` rather than repeating the data shapes.
|
|
50
|
+
The shared nonempty text reference retains its string type, and the runtime
|
|
51
|
+
Schemas still reject extra properties and enforce integer byte/chunk counts
|
|
52
|
+
with minima 0/1. Messages remain disabled. The generated package explicitly
|
|
53
|
+
depends on `@sinclair/typebox@0.34.52`, not Builder's transitive dependencies.
|
|
54
|
+
Build evaluates this TS contract as trusted code; esbuild transpiles but does
|
|
55
|
+
not typecheck it. JSON contracts remain supported when selected in the build
|
|
56
|
+
description.
|
|
57
|
+
|
|
58
|
+
Init fixes `outDirectory` to `dist/<derived-name>` using the final package name,
|
|
59
|
+
not the Task name: `echo-task` → `dist/echo-task`, `@acme/echo-task` →
|
|
60
|
+
`dist/acme-echo-task`. Only the leading `@` is removed and the scope separator
|
|
61
|
+
`/` becomes `-`. Invalid npm names and unsafe derived paths (such as Windows
|
|
62
|
+
device names or trailing dots) are rejected, never silently sanitized.
|
|
63
|
+
Later package-name changes do not rewrite the build description or scripts.
|
|
64
|
+
|
|
65
|
+
`pnpm build` writes that module and its sibling `dist/<derived-name>.car`.
|
|
66
|
+
`pnpm car` reads `dist/<derived-name>/task.yaml` and targets the same CAR,
|
|
67
|
+
refusing to overwrite an existing archive, including one produced by build.
|
|
68
|
+
Use `pnpm build --no-car` before `pnpm car` when no archive already exists.
|
|
69
|
+
`pnpm clean` runs `rimraf dist`, deleting all modules and CARs under `dist`;
|
|
70
|
+
rimraf 6.1.4 is a generated devDependency compatible with Node >=22.13.0.
|
|
71
|
+
Build never runs clean automatically: validation still precedes delivery,
|
|
72
|
+
and stale unselected files remain until explicitly cleaned.
|
|
73
|
+
|
|
74
|
+
CLI and Builder dependency versions come from their actual installed metadata;
|
|
75
|
+
the SDK version comes from that Builder release's template. They need not
|
|
76
|
+
match. No remote tag lookup or version override is performed.
|
|
77
|
+
The pnpm template allows only esbuild's postinstall (`allowBuilds.esbuild: true`);
|
|
78
|
+
no other dependency build scripts are approved. Do not omit optional dependencies.
|
|
79
|
+
|
|
80
|
+
## Build and delivery
|
|
81
|
+
|
|
82
|
+
`build-file` defaults to `task.build.yaml`. Source, contract, Task identity,
|
|
83
|
+
runtime and resource rules come only from that file, which is not rewritten.
|
|
84
|
+
Output precedence is `--out-dir` > `outDirectory` > description-directory `dist`.
|
|
85
|
+
CLI paths are relative to cwd; description paths are relative to the description.
|
|
86
|
+
Within pnpm workspaces, the existing workspace tree supplies installed
|
|
87
|
+
dependencies; imports never fall back to the CLI's dependencies.
|
|
88
|
+
|
|
89
|
+
The default CAR is the module directory's sibling `<directory-basename>.car`.
|
|
90
|
+
Both the module and CAR remain after success. `--no-car` does not update or
|
|
91
|
+
delete an older CAR: `data.car: null` describes this invocation only.
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"ok": true,
|
|
96
|
+
"data": {
|
|
97
|
+
"module": {
|
|
98
|
+
"directory": "<absolute module directory>",
|
|
99
|
+
"declaration": "<absolute task.yaml>",
|
|
100
|
+
"files": ["task.yaml", "worker.cjs", "schemas/input.json", "schemas/result.json", "schemas/message.json"]
|
|
101
|
+
},
|
|
102
|
+
"cid": "<verified module CID>",
|
|
103
|
+
"car": { "path": "<absolute CAR>" }
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
93
107
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
Files list exactly the current declaration's selection, including any selected
|
|
109
|
+
resources/shared Schemas, using protocol `/` paths. Other paths are host
|
|
110
|
+
absolute paths. Old unselected files stay on disk but are excluded from
|
|
111
|
+
validation and CAR. No output directory is recursively cleared.
|
|
112
|
+
|
|
113
|
+
All generated bytes are staged and validated before replacing any outputs.
|
|
114
|
+
Each file replacement uses complete sibling bytes rather than truncating the
|
|
115
|
+
old file. Delivered module bytes and CAR bytes are validated again.
|
|
116
|
+
A failure during module updates can leave some replaced files and reports
|
|
117
|
+
`DELIVERY_UNCERTAIN`, not a claimed rollback or a trusted module. A valid new
|
|
118
|
+
module survives CAR failure, reported with its module/CID, `car: null` and an
|
|
119
|
+
explanation that any unreplaced old CAR is not a new delivery.
|
|
120
|
+
Staging belongs only to the invocation and is released on completion/failure.
|
|
121
|
+
Input/output overlap, observable destination races and linked output paths are
|
|
122
|
+
rejected. Filesystem checks are not an OS sandbox against a malicious author.
|
|
123
|
+
|
|
124
|
+
JS/TS contracts execute automatically as trusted Node code, in a short-lived
|
|
125
|
+
process with captured standard streams and a 30-second internal evaluation
|
|
126
|
+
budget. Console calls and direct stdout/stderr writes, including caught or
|
|
127
|
+
deferred attempts and evaluating dependencies, fail with
|
|
128
|
+
`CONTRACT_OUTPUT_FORBIDDEN`; output is never forwarded or silently accepted.
|
|
129
|
+
JSON contracts do not execute. This is **not a security sandbox**; other host
|
|
130
|
+
side effects remain possible. Task runtime logging is unaffected.
|
|
131
|
+
|
|
132
|
+
## Standalone CAR
|
|
133
|
+
|
|
134
|
+
`car` accepts an existing `task.yaml` file, never a directory. Only its declared
|
|
135
|
+
files are read and validated; unselected notes, stale files and archives are
|
|
136
|
+
not read. It never reads the build description, compiles, runs contracts or
|
|
137
|
+
installs packages. Links cannot escape the module tree, and reads detect
|
|
138
|
+
observable input changes.
|
|
139
|
+
The input module directory and all its ancestors must be canonical, without
|
|
140
|
+
symlinks or Windows junctions. Linked module/ancestor aliases are rejected
|
|
141
|
+
before choosing or writing an output, so they cannot disguise an internal CAR
|
|
142
|
+
destination as an external one.
|
|
143
|
+
|
|
144
|
+
The default destination uses the same sibling naming rule as build; `--output`
|
|
145
|
+
is cwd-relative and must be outside the input module. Existing destinations
|
|
146
|
+
are always refused, including during competing creation.
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"ok": true,
|
|
151
|
+
"data": {
|
|
152
|
+
"car": "<absolute CAR>",
|
|
153
|
+
"cid": "<verified CID>",
|
|
154
|
+
"declaration": "<absolute input task.yaml>",
|
|
155
|
+
"files": ["<complete declared selection>"]
|
|
156
|
+
}
|
|
157
|
+
}
|
|
103
158
|
```
|
|
104
159
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
owns process SIGINT/SIGTERM and their corresponding executable exit codes.
|
|
109
|
-
`createCliTaskProject(options)` can be used independently to decorate a template
|
|
110
|
-
without writing it to disk or installing packages.
|
|
160
|
+
Use the compiler-free `@silvermoon-work/task-builder/car` subpath for standalone
|
|
161
|
+
CAR inspection or the Engine CLI for actual consumption, not a removed
|
|
162
|
+
`task-builder check` command.
|
|
111
163
|
|
|
112
|
-
##
|
|
164
|
+
## Reusable runner and adapters
|
|
113
165
|
|
|
114
166
|
```ts
|
|
115
|
-
import {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const input = await directoryTree(projectDirectory);
|
|
123
|
-
const output = await buildTaskBundle(input, options);
|
|
124
|
-
await writeDirectory(output, newOutputDirectory);
|
|
167
|
+
import { runTaskBuilderCli } from "@silvermoon-work/task-builder-cli";
|
|
168
|
+
|
|
169
|
+
const exitCode = await runTaskBuilderCli(["build", "task.build.yaml"], {
|
|
170
|
+
cwd: projectDirectory,
|
|
171
|
+
signal,
|
|
172
|
+
stdout: { write: (text) => output.write(text) },
|
|
173
|
+
});
|
|
125
174
|
```
|
|
126
175
|
|
|
127
|
-
The
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
176
|
+
The runner does not exit the host, read stdin or install signal handlers.
|
|
177
|
+
Programmatic cancellation defaults to 130; executable signal ownership belongs
|
|
178
|
+
to `bin.js`. `createCliTaskProject({ name, taskName })` creates a template without
|
|
179
|
+
writing files. `./node` exports `directoryTree`, `writeDirectory` and
|
|
180
|
+
`writeStreamFile`: these lower-level writers retain exclusive-create semantics.
|
|
181
|
+
The CLI's build delivery layer implements replacement separately.
|
|
133
182
|
|
|
134
|
-
##
|
|
183
|
+
## Development and distribution
|
|
135
184
|
|
|
136
185
|
```text
|
|
137
186
|
pnpm --filter @silvermoon-work/task-builder-cli... build
|
|
138
|
-
|
|
139
|
-
node packages/task-builder-cli/dist/bin.js build packages/task-builder/examples/echo/task.build.yaml
|
|
140
|
-
pnpm --filter @silvermoon-work/task-builder-cli test
|
|
187
|
+
pnpm --filter @silvermoon-work/task-builder --filter @silvermoon-work/task-builder-cli test
|
|
141
188
|
pnpm check
|
|
142
189
|
```
|
|
143
190
|
|
|
144
|
-
|
|
145
|
-
CLI
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
the current init/CAR APIs.
|
|
191
|
+
Published packages contain precompiled `dist`, including the contract evaluation
|
|
192
|
+
process entrypoint. CLI bin is `dist/bin.js`; consumers do not compile the CLI.
|
|
193
|
+
Builder and CLI are separate releases. Required internal versions must already
|
|
194
|
+
exist in the configured registry; never auto-publish dependencies. The
|
|
195
|
+
[consumer guide](../../docs/end-to-end-verification.md) distinguishes local
|
|
196
|
+
development from an actual registry-installed Canary verification.
|
package/dist/bin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { runTaskBuilderCli } from "./index.js";
|
|
3
3
|
const controller = new AbortController();
|
|
4
|
-
let interrupted;
|
|
4
|
+
let interrupted = 130;
|
|
5
5
|
const interrupt = () => {
|
|
6
6
|
interrupted = 130;
|
|
7
7
|
controller.abort(new Error("Task builder interrupted by SIGINT."));
|
|
@@ -13,8 +13,10 @@ const terminate = () => {
|
|
|
13
13
|
process.once("SIGINT", interrupt);
|
|
14
14
|
process.once("SIGTERM", terminate);
|
|
15
15
|
try {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
process.exitCode = await runTaskBuilderCli(process.argv.slice(2), {
|
|
17
|
+
signal: controller.signal,
|
|
18
|
+
signalExitCode: () => interrupted,
|
|
19
|
+
});
|
|
18
20
|
}
|
|
19
21
|
finally {
|
|
20
22
|
process.removeListener("SIGINT", interrupt);
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;AACzC,IAAI,
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;AACzC,IAAI,WAAW,GAAc,GAAG,CAAC;AACjC,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,WAAW,GAAG,GAAG,CAAC;IAClB,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;AACrE,CAAC,CAAC;AACF,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,WAAW,GAAG,GAAG,CAAC;IAClB,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC;AACF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAClC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AACnC,IAAI,CAAC;IACH,OAAO,CAAC,QAAQ,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QAChE,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,cAAc,EAAE,GAAG,EAAE,CAAC,WAAW;KAClC,CAAC,CAAC;AACL,CAAC;QAAS,CAAC;IACT,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC5C,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type ReadonlyFileTree, type ReadOptions } from "@silvermoon-work/task-builder/tree";
|
|
2
|
+
export declare class CliError extends Error {
|
|
3
|
+
readonly code: string;
|
|
4
|
+
readonly data?: object | undefined;
|
|
5
|
+
constructor(code: string, message: string, data?: object | undefined);
|
|
6
|
+
}
|
|
7
|
+
export declare function inside(root: string, path: string): boolean;
|
|
8
|
+
export declare function defaultCar(directory: string): string;
|
|
9
|
+
export declare function info(path: string): Promise<import("fs").BigIntStats | undefined>;
|
|
10
|
+
/** Reject links in every existing component, including links inside output directories. */
|
|
11
|
+
export declare function safePath(path: string): Promise<void>;
|
|
12
|
+
export declare function selectedModule(directory: string, options?: ReadOptions): Promise<{
|
|
13
|
+
tree: ReadonlyFileTree;
|
|
14
|
+
files: string[];
|
|
15
|
+
}>;
|
|
16
|
+
export declare function verifyModule(directory: string, options?: ReadOptions): Promise<{
|
|
17
|
+
archive: import("@silvermoon-work/task-builder/car").EncodedTaskBundleCar;
|
|
18
|
+
tree: ReadonlyFileTree;
|
|
19
|
+
files: string[];
|
|
20
|
+
}>;
|
|
21
|
+
/** Complete and validate a sibling before atomic replacement; never truncate an old target. */
|
|
22
|
+
export declare function deliverFile(stream: ReadableStream<Uint8Array>, destination: string, options: ReadOptions & {
|
|
23
|
+
replace: boolean;
|
|
24
|
+
cid?: string;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
export declare function installModule(tree: ReadonlyFileTree, files: readonly string[], directory: string, options: ReadOptions): Promise<void>;
|
|
27
|
+
export declare function cleanup(directory: string): Promise<void>;
|
|
28
|
+
//# sourceMappingURL=delivery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../src/delivery.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,oCAAoC,CAAC;AAI5C,qBAAa,QAAS,SAAQ,KAAK;IAE/B,QAAQ,CAAC,IAAI,EAAE,MAAM;IAErB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;gBAFb,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACN,IAAI,CAAC,EAAE,MAAM,YAAA;CAIzB;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK1D;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQpD;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,iDAOtC;AAED,2FAA2F;AAC3F,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ1D;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;;;GAyBhF;AAED,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;;;;GAI9E;AAED,+FAA+F;AAC/F,wBAAsB,WAAW,CAC/B,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,WAAW,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACxD,OAAO,CAAC,IAAI,CAAC,CA0Df;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,gBAAgB,EACtB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,WAAW,iBAUrB;AAED,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS9D"}
|
package/dist/delivery.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { lstat, mkdir, realpath, rename, rm, unlink } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
4
|
+
import { encodeTaskBundleCar, readTaskBundleCar } from "@silvermoon-work/task-builder/car";
|
|
5
|
+
import { fileTree, readBytes, } from "@silvermoon-work/task-builder/tree";
|
|
6
|
+
import { parseTaskBundleYaml, validateTaskBundle } from "@silvermoon-work/task-protocol";
|
|
7
|
+
import { directoryTree, writeStreamFile } from "./node.js";
|
|
8
|
+
export class CliError extends Error {
|
|
9
|
+
code;
|
|
10
|
+
data;
|
|
11
|
+
constructor(code, message, data) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.data = data;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function inside(root, path) {
|
|
18
|
+
const distance = relative(root, path);
|
|
19
|
+
return (!distance || (distance !== ".." && !distance.startsWith(`..${sep}`) && !distance.includes(":")));
|
|
20
|
+
}
|
|
21
|
+
export function defaultCar(directory) {
|
|
22
|
+
const name = basename(directory);
|
|
23
|
+
if (!name || dirname(directory) === directory)
|
|
24
|
+
throw new CliError("INVALID_ARGUMENT", "Cannot derive a CAR name from the module directory; choose another directory or an explicit car --output.");
|
|
25
|
+
return join(dirname(directory), `${name}.car`);
|
|
26
|
+
}
|
|
27
|
+
export async function info(path) {
|
|
28
|
+
try {
|
|
29
|
+
return await lstat(path, { bigint: true });
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
33
|
+
return undefined;
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Reject links in every existing component, including links inside output directories. */
|
|
38
|
+
export async function safePath(path) {
|
|
39
|
+
const parent = dirname(path);
|
|
40
|
+
if (parent !== path)
|
|
41
|
+
await safePath(parent);
|
|
42
|
+
const value = await info(path);
|
|
43
|
+
if (value?.isSymbolicLink())
|
|
44
|
+
throw new CliError("UNSAFE_PATH", "Paths must not contain symbolic links.");
|
|
45
|
+
if (value && (await realpath(path)).toLowerCase() !== resolve(path).toLowerCase())
|
|
46
|
+
throw new CliError("UNSAFE_PATH", "Paths must be canonical.");
|
|
47
|
+
}
|
|
48
|
+
export async function selectedModule(directory, options = {}) {
|
|
49
|
+
const input = await directoryTree(directory);
|
|
50
|
+
const bytes = await readBytes(input, "task.yaml", 65_536, options);
|
|
51
|
+
const declaration = validateTaskBundle(parseTaskBundleYaml(bytes));
|
|
52
|
+
const files = [...declaration.include];
|
|
53
|
+
const tree = fileTree(new Map(files.map((file) => [
|
|
54
|
+
file,
|
|
55
|
+
async (readOptions) => {
|
|
56
|
+
try {
|
|
57
|
+
return await input.read(file, readOptions);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
61
|
+
throw new CliError("MODULE_FILE_MISSING", `Declared module file is missing: ${file}. No CAR was delivered.`);
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
])));
|
|
66
|
+
return { tree, files };
|
|
67
|
+
}
|
|
68
|
+
export async function verifyModule(directory, options = {}) {
|
|
69
|
+
const selected = await selectedModule(directory, options);
|
|
70
|
+
const archive = await encodeTaskBundleCar(selected.tree, options);
|
|
71
|
+
return { ...selected, archive };
|
|
72
|
+
}
|
|
73
|
+
/** Complete and validate a sibling before atomic replacement; never truncate an old target. */
|
|
74
|
+
export async function deliverFile(stream, destination, options) {
|
|
75
|
+
const temporary = join(dirname(destination), `.task-builder-${randomUUID()}`);
|
|
76
|
+
let owned = false;
|
|
77
|
+
let installed = false;
|
|
78
|
+
try {
|
|
79
|
+
await safePath(destination);
|
|
80
|
+
const previous = await info(destination);
|
|
81
|
+
if (previous && !options.replace)
|
|
82
|
+
throw new CliError("OUTPUT_EXISTS", "Output already exists; nothing was overwritten.");
|
|
83
|
+
if (previous && !previous.isFile())
|
|
84
|
+
throw new CliError("INVALID_ARGUMENT", "Output must be a regular file.");
|
|
85
|
+
await writeStreamFile(stream, temporary, options);
|
|
86
|
+
owned = true;
|
|
87
|
+
if (options.cid) {
|
|
88
|
+
const tree = await directoryTree(dirname(temporary));
|
|
89
|
+
const archive = await readTaskBundleCar(await tree.read(basename(temporary), options), {
|
|
90
|
+
...options,
|
|
91
|
+
expectedCid: options.cid,
|
|
92
|
+
});
|
|
93
|
+
await archive.close();
|
|
94
|
+
}
|
|
95
|
+
options.signal?.throwIfAborted();
|
|
96
|
+
await safePath(destination);
|
|
97
|
+
const current = await info(destination);
|
|
98
|
+
if (current?.ino !== previous?.ino ||
|
|
99
|
+
current?.dev !== previous?.dev ||
|
|
100
|
+
current?.mtimeNs !== previous?.mtimeNs)
|
|
101
|
+
throw new CliError("OUTPUT_CHANGED", "Output changed during delivery; it was not replaced.");
|
|
102
|
+
if (options.replace)
|
|
103
|
+
await rename(temporary, destination);
|
|
104
|
+
else {
|
|
105
|
+
// Exclusive creation remains mandatory even if another producer races this invocation.
|
|
106
|
+
const { link } = await import("node:fs/promises");
|
|
107
|
+
await link(temporary, destination);
|
|
108
|
+
installed = true;
|
|
109
|
+
await unlink(temporary);
|
|
110
|
+
}
|
|
111
|
+
owned = false;
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
await stream.cancel().catch(() => undefined);
|
|
115
|
+
if (owned) {
|
|
116
|
+
try {
|
|
117
|
+
await unlink(temporary);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
throw new CliError("DELIVERY_UNCERTAIN", "Delivery failed and temporary-file cleanup could not be confirmed.");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (installed)
|
|
124
|
+
throw new CliError("DELIVERY_UNCERTAIN", "CAR was installed but delivery cleanup reported an error; verify the destination before retrying.");
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export async function installModule(tree, files, directory, options) {
|
|
129
|
+
await safePath(directory);
|
|
130
|
+
await mkdir(directory, { recursive: true });
|
|
131
|
+
for (const file of files) {
|
|
132
|
+
const target = join(directory, ...file.split("/"));
|
|
133
|
+
await safePath(target);
|
|
134
|
+
await mkdir(dirname(target), { recursive: true });
|
|
135
|
+
await deliverFile(await tree.read(file, options), target, { ...options, replace: true });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
export async function cleanup(directory) {
|
|
139
|
+
try {
|
|
140
|
+
await rm(directory, { recursive: true, force: true });
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
throw new CliError("CLEANUP_UNCERTAIN", "Operation-owned staging cleanup could not be confirmed.");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=delivery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery.js","sourceRoot":"","sources":["../src/delivery.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ReadOptions } from "@silvermoon-work/task-builder/tree";
|
|
2
2
|
export { createCliTaskProject, type CliTaskProjectOptions } from "./project.js";
|
|
3
3
|
export interface CliWriter {
|
|
4
4
|
write(text: string): void | boolean;
|
|
@@ -7,7 +7,8 @@ export interface TaskBuilderCliOptions extends ReadOptions {
|
|
|
7
7
|
readonly cwd?: string;
|
|
8
8
|
readonly stdout?: CliWriter;
|
|
9
9
|
readonly stderr?: CliWriter;
|
|
10
|
+
readonly signalExitCode?: () => 130 | 143;
|
|
10
11
|
}
|
|
11
|
-
/**
|
|
12
|
+
/** One noninteractive invocation: one JSON result, no process exit or signal listeners. */
|
|
12
13
|
export declare function runTaskBuilderCli(argv: readonly string[], options?: TaskBuilderCliOptions): Promise<number>;
|
|
13
14
|
//# 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":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,oCAAoC,CAAC;AAexF,OAAO,EAAE,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAEhF,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC;CACrC;AACD,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,CAAC;CAC3C;AAkOD,2FAA2F;AAC3F,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CAgKjB"}
|