@sublang/slc 0.4.0 → 0.6.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/README.md +100 -131
- package/dist/app.d.ts +20 -20
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +37 -30
- package/dist/app.js.map +1 -1
- package/dist/artifacts.d.ts +6 -6
- package/dist/artifacts.d.ts.map +1 -1
- package/dist/artifacts.js +9 -9
- package/dist/artifacts.js.map +1 -1
- package/dist/cli.js +3 -3
- package/dist/cligent-agent.d.ts +1 -1
- package/dist/cligent-agent.js +5 -5
- package/dist/compiled-executor.d.ts +14 -6
- package/dist/compiled-executor.d.ts.map +1 -1
- package/dist/compiled-executor.js +133 -31
- package/dist/compiled-executor.js.map +1 -1
- package/dist/config-file.d.ts +10 -6
- package/dist/config-file.d.ts.map +1 -1
- package/dist/config-file.js +23 -10
- package/dist/config-file.js.map +1 -1
- package/dist/config.d.ts +22 -18
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +90 -27
- package/dist/config.js.map +1 -1
- package/dist/emitted-imports.d.ts +14 -0
- package/dist/emitted-imports.d.ts.map +1 -1
- package/dist/emitted-imports.js +63 -7
- package/dist/emitted-imports.js.map +1 -1
- package/dist/entry-module.d.ts +5 -3
- package/dist/entry-module.d.ts.map +1 -1
- package/dist/entry-module.js +41 -13
- package/dist/entry-module.js.map +1 -1
- package/dist/execution.d.ts +10 -10
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +13 -13
- package/dist/execution.js.map +1 -1
- package/dist/hash.js +2 -2
- package/dist/host-capabilities.d.ts +115 -0
- package/dist/host-capabilities.d.ts.map +1 -0
- package/dist/host-capabilities.js +507 -0
- package/dist/host-capabilities.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interpreter.d.ts +2 -2
- package/dist/interpreter.d.ts.map +1 -1
- package/dist/interpreter.js +7 -7
- package/dist/invocation.d.ts +6 -6
- package/dist/invocation.d.ts.map +1 -1
- package/dist/invocation.js +1 -1
- package/dist/link.d.ts +4 -4
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +11 -11
- package/dist/link.js.map +1 -1
- package/dist/phase-runner.d.ts +4 -4
- package/dist/phase-runner.js +9 -9
- package/dist/phase.d.ts +4 -4
- package/dist/phase.d.ts.map +1 -1
- package/dist/phase.js +7 -7
- package/dist/phase.js.map +1 -1
- package/dist/pin-closure.d.ts +35 -7
- package/dist/pin-closure.d.ts.map +1 -1
- package/dist/pin-closure.js +135 -21
- package/dist/pin-closure.js.map +1 -1
- package/dist/pin-currency.d.ts +9 -4
- package/dist/pin-currency.d.ts.map +1 -1
- package/dist/pin-currency.js +57 -20
- package/dist/pin-currency.js.map +1 -1
- package/dist/pin-generate.d.ts +7 -7
- package/dist/pin-generate.d.ts.map +1 -1
- package/dist/pin-generate.js +14 -8
- package/dist/pin-generate.js.map +1 -1
- package/dist/pin-inputs.d.ts +41 -0
- package/dist/pin-inputs.d.ts.map +1 -0
- package/dist/pin-inputs.js +179 -0
- package/dist/pin-inputs.js.map +1 -0
- package/dist/pin-paths.d.ts +1 -1
- package/dist/pin-paths.js +4 -4
- package/dist/pin-paths.js.map +1 -1
- package/dist/pins.d.ts +4 -4
- package/dist/pins.d.ts.map +1 -1
- package/dist/pins.js +5 -5
- package/dist/pins.js.map +1 -1
- package/dist/pipeline.d.ts +5 -5
- package/dist/pipeline.js +10 -10
- package/dist/playbook-contract.d.ts +53 -5
- package/dist/playbook-contract.d.ts.map +1 -1
- package/dist/playbook-contract.js +70 -21
- package/dist/playbook-contract.js.map +1 -1
- package/dist/playbook-ports.d.ts +9 -9
- package/dist/playbook-ports.d.ts.map +1 -1
- package/dist/playbook-ports.js +6 -4
- package/dist/playbook-ports.js.map +1 -1
- package/dist/progress.d.ts +8 -9
- package/dist/progress.d.ts.map +1 -1
- package/dist/progress.js +3 -3
- package/dist/progress.js.map +1 -1
- package/dist/resolver.d.ts +9 -9
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +12 -12
- package/dist/resolver.js.map +1 -1
- package/dist/reviewing-agent.d.ts +18 -0
- package/dist/reviewing-agent.d.ts.map +1 -0
- package/dist/reviewing-agent.js +295 -0
- package/dist/reviewing-agent.js.map +1 -0
- package/dist/runner.d.ts +1 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +195 -80
- package/dist/runner.js.map +1 -1
- package/dist/slc.config.template.yaml +6 -2
- package/dist/verify-coverage.d.ts +4 -3
- package/dist/verify-coverage.d.ts.map +1 -1
- package/dist/verify-coverage.js +509 -71
- package/dist/verify-coverage.js.map +1 -1
- package/dist/verify.d.ts +111 -15
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +656 -59
- package/dist/verify.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -19,17 +19,18 @@ through it. Why compile prose instead of prompting with it:
|
|
|
19
19
|
stop — the control flow becomes an inspectable
|
|
20
20
|
[XState](https://xstate.js.org) machine, not prompt improvisation.
|
|
21
21
|
LLM judgment is confined to the work *inside* each state.
|
|
22
|
-
- **Auditable at every stage.**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
binding its output to the source spec.
|
|
22
|
+
- **Auditable at every stage.** Every intermediate is a file you can
|
|
23
|
+
read and edit: the normalized text, one testable "shall" item per
|
|
24
|
+
behavior, the state machine itself. The compiler also emits tests
|
|
25
|
+
binding its output back to the spec.
|
|
27
26
|
- **Cheaper and safer by optimization.** Steps that need no judgment are
|
|
28
27
|
rewritten at compile time into plain shell commands — no LLM call, no
|
|
29
|
-
hallucination
|
|
28
|
+
hallucination.
|
|
30
29
|
- **Your agents, per role.** Compilation and execution run through the
|
|
31
30
|
agent CLIs you already use — Claude Code, Codex, Gemini, OpenCode —
|
|
32
|
-
selectable per role
|
|
31
|
+
selectable per role, with an optional
|
|
32
|
+
[second agent reviewing](#reviewed-compilation-two-agents) every
|
|
33
|
+
compile step.
|
|
33
34
|
|
|
34
35
|
The flagship pipeline is `playbook` (the name of both the pipeline and
|
|
35
36
|
the sibling [playbook](https://github.com/sublang-ai/playbook) project
|
|
@@ -41,9 +42,9 @@ a linked module the `playbook` CLI runs.
|
|
|
41
42
|
The [demo](demo/README.md) compiles a one-paragraph description into a
|
|
42
43
|
two-agent code-review loop, then lets it loose on a buggy C file: the
|
|
43
44
|
coder and reviewer commit, review, and debate inside a real Git
|
|
44
|
-
repository until the review comes back clean. Precompiled
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
repository until the review comes back clean. Precompiled artifacts are
|
|
46
|
+
included, so you can watch a run — or read every compile stage —
|
|
47
|
+
without waiting on a compile.
|
|
47
48
|
|
|
48
49
|
## Install
|
|
49
50
|
|
|
@@ -53,60 +54,42 @@ npm install -g @anthropic-ai/claude-agent-sdk @openai/codex-sdk
|
|
|
53
54
|
slc --version
|
|
54
55
|
```
|
|
55
56
|
|
|
56
|
-
The second line supplies the agent SDKs for the default Claude and Codex
|
|
57
|
-
lineup. Playbook 4 installs none itself — which versions work is
|
|
58
|
-
`@sublang/cligent`'s to enforce at load — so name the SDKs your own
|
|
59
|
-
configuration needs. If one is missing, the compile stops before any
|
|
60
|
-
agent call and names the package to install; if one is too old, it
|
|
61
|
-
names the installed and required versions along with the exact version
|
|
62
|
-
to install.
|
|
63
|
-
|
|
64
|
-
Compiled artifacts import the Playbook engine from their own directory;
|
|
65
|
-
when that import does not resolve, `playbook run` (3.1+) links its own
|
|
66
|
-
engine beside the artifact and says so (`--no-provision` opts out).
|
|
67
|
-
Working inside an npm project instead? Install the same set there — the
|
|
68
|
-
compiler, the engine, and the SDKs your lineup uses — and prefix the
|
|
69
|
-
commands with `npx`. A project's own install is always authoritative,
|
|
70
|
-
and a globally installed SDK is invisible to a project's nested
|
|
71
|
-
`@sublang/cligent`, so the SDKs belong in the same tree
|
|
72
|
-
([RELEASE-11](specs/dev/release.md#release-11) has the full rules).
|
|
73
|
-
|
|
74
57
|
Requirements:
|
|
75
58
|
|
|
76
|
-
- A POSIX platform — macOS or Linux; on Windows, use WSL (or Git
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
- Node.js >= 23.6 (compiled phase artifacts are imported as native
|
|
80
|
-
TypeScript at runtime).
|
|
59
|
+
- A POSIX platform — macOS or Linux; on Windows, use WSL (or Git Bash).
|
|
60
|
+
Compiled script steps execute through `sh`.
|
|
61
|
+
- Node.js >= 23.6 (compiled artifacts are imported as native TypeScript).
|
|
81
62
|
- One supported coding-agent CLI, installed and authenticated:
|
|
82
63
|
[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview),
|
|
83
64
|
[Codex CLI](https://github.com/openai/codex),
|
|
84
65
|
[Gemini CLI](https://github.com/google-gemini/gemini-cli), or
|
|
85
66
|
[OpenCode](https://opencode.ai).
|
|
86
67
|
|
|
68
|
+
The second install line supplies the agent SDKs for the default Claude
|
|
69
|
+
and Codex lineup; name the SDKs your own lineup needs instead. A missing
|
|
70
|
+
or too-old SDK stops the compile before any agent call and names the
|
|
71
|
+
exact package and version to install.
|
|
72
|
+
|
|
73
|
+
Compiled artifacts import the Playbook engine from their own directory;
|
|
74
|
+
when that import does not resolve, `playbook run` (3.1+) links its own
|
|
75
|
+
engine beside the artifact and says so (`--no-provision` opts out).
|
|
76
|
+
Working inside an npm project? Install the same set there and prefix the
|
|
77
|
+
commands with `npx`: a project-local install is authoritative wherever it
|
|
78
|
+
resolves, a project manifest declaring `@sublang/playbook` must install
|
|
79
|
+
it itself, and a global SDK is invisible to a project's nested
|
|
80
|
+
`@sublang/cligent`
|
|
81
|
+
([[release-11](specs/packages/release.md#release-11)] has the full rules).
|
|
82
|
+
|
|
87
83
|
## Quick start
|
|
88
84
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
85
|
+
Write a prose workflow as a `.md` or `.txt` file —
|
|
86
|
+
[`demo/workflow.txt`](demo/workflow.txt) is a complete one-paragraph
|
|
87
|
+
example — and compile it from any directory:
|
|
92
88
|
|
|
93
89
|
```bash
|
|
94
90
|
slc playbook my-workflow.md
|
|
95
91
|
```
|
|
96
92
|
|
|
97
|
-
`slc` finds the `playbook` pipeline inside its own `@sublang/playbook`
|
|
98
|
-
dependency, so it compiles in any directory — no clone, no project
|
|
99
|
-
setup. Compilation drives your configured coding agent — the first run
|
|
100
|
-
seeds `~/.config/slc/config.yaml` with `agent: claude-code`; set
|
|
101
|
-
`SLC_AGENT` (or edit that file) to use another agent CLI. Expect it to
|
|
102
|
-
take a while: duration is agent- and workload-dependent, and measured
|
|
103
|
-
compiles of a five-line workflow have run from tens of minutes to more
|
|
104
|
-
than two hours, with the first intermediate typically landing within
|
|
105
|
-
about five minutes. Plain-text input (`.txt`) works too; it is
|
|
106
|
-
normalized first. The pipeline's optimization pass, which rewrites
|
|
107
|
-
judgment-free steps into plain script, runs by default
|
|
108
|
-
(`--no-optimize` skips it).
|
|
109
|
-
|
|
110
93
|
Artifacts land in your working directory: `my-workflow.playbook/` holds
|
|
111
94
|
the intermediates — `my-workflow.gears.md`, the XState machine
|
|
112
95
|
`my-workflow.fsm.ts`, the linked runtime module, and its verification
|
|
@@ -116,105 +99,91 @@ tests — and `my-workflow.ts` is the runnable entry. Run it:
|
|
|
116
99
|
playbook run ./my-workflow.ts "<your task>"
|
|
117
100
|
```
|
|
118
101
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
102
|
+
Compilation drives your configured coding agent, so **expect it to take
|
|
103
|
+
a while**: measured compiles of a five-line workflow have run from tens
|
|
104
|
+
of minutes to more than two hours, with the first intermediate typically
|
|
105
|
+
landing within about five minutes. Meanwhile `slc` reports each phase,
|
|
106
|
+
each artifact with its elapsed time, and a heartbeat at least every 30
|
|
107
|
+
seconds on stderr; an agent call that goes silent for `stallTimeout`
|
|
108
|
+
seconds fails that phase instead of hanging. Success prints the artifact
|
|
109
|
+
paths and exits 0; a failure prints diagnostics naming the failing phase
|
|
110
|
+
and exits non-zero.
|
|
111
|
+
|
|
112
|
+
Intermediates are first-class: edit one, re-run a single phase
|
|
113
|
+
(`slc playbook.gears2fsm …`), and it lands in the same place.
|
|
114
|
+
`slc --help` shows all invocation forms and flags, including
|
|
115
|
+
`--no-optimize` to skip the optimization pass.
|
|
122
116
|
|
|
123
117
|
### Incremental recompiles
|
|
124
118
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
-
|
|
142
|
-
`--rebuild` is given.
|
|
143
|
-
|
|
144
|
-
Update is only a hint to the usual executor. The phase definition remains the
|
|
145
|
-
sole authority, needs no update section, and uses the same acceptance rules as
|
|
146
|
-
a fresh compile. A run that only reuses reports `up to date` and records
|
|
147
|
-
nothing new. Before the first executor in an eligible run may write, `slc`
|
|
148
|
-
removes the active marker; only a wholly successful run, including required
|
|
149
|
-
deterministic post-processing, publishes a new marker. Once the marker is
|
|
150
|
-
removed, a failed or interrupted run therefore leaves the next run to compile
|
|
151
|
-
ordinarily. `--rebuild` forces every phase through Ordinary mode and records a
|
|
152
|
-
fresh successful build while retaining older numbered snapshots.
|
|
153
|
-
|
|
154
|
-
History selection and publication do not apply to `-o`, the reserved `slc`
|
|
155
|
-
meta-pipeline, single-phase or standalone-pass runs, or direct-link runs. If one
|
|
156
|
-
of those excluded forms is about to overwrite an artifact named by a usable
|
|
157
|
-
active build, `slc` clears that marker first so it cannot describe the new
|
|
158
|
-
bytes.
|
|
159
|
-
|
|
160
|
-
`.slc/` sits inside the artifact bundle and holds verbatim copies of your
|
|
161
|
-
source and every accepted phase output, so treat it as no less private than
|
|
162
|
-
the source, and add `.slc/` to your `.gitignore` if you commit the bundle.
|
|
163
|
-
Deleting it is always safe — the next run simply compiles ordinarily — and
|
|
164
|
-
old numbered builds under `.slc/builds/` can be pruned at any time. An upgrade
|
|
165
|
-
that changes a recorded definition or input invalidates only the affected
|
|
166
|
-
steps: an eligible compile step can use Update while link steps run ordinarily.
|
|
167
|
-
Pass `--rebuild` after an upgrade when you want every phase to compile from
|
|
168
|
-
scratch instead.
|
|
169
|
-
|
|
170
|
-
While a compile runs, `slc` reports progress on stderr: each phase as it
|
|
171
|
-
starts, each artifact as it lands with the elapsed time, the compiled
|
|
172
|
-
runtime's own state transitions, and a heartbeat so the terminal is
|
|
173
|
-
never silent for more than 30 seconds. An agent call that goes quiet for
|
|
174
|
-
`stallTimeout` seconds (default 600, `0` disables) is aborted and
|
|
175
|
-
reported as a failed phase rather than hanging indefinitely.
|
|
176
|
-
|
|
177
|
-
Success prints the written artifact paths to stdout and exits 0 — or
|
|
178
|
-
just `up to date` when incremental selection recompiled nothing, in which
|
|
179
|
-
case the paths the previous run reported are still current; a failure
|
|
180
|
-
prints diagnostics to stderr — naming the failing phase when one is at
|
|
181
|
-
fault — and exits non-zero.
|
|
119
|
+
A successful full compile is snapshotted under `<artifact-dir>/.slc/`,
|
|
120
|
+
so a re-run only redoes what changed. Per phase, `slc` picks:
|
|
121
|
+
|
|
122
|
+
- **Reuse** — inputs are byte-identical: no agent call, and the artifact
|
|
123
|
+
on disk is left exactly as it is, manual refinements included.
|
|
124
|
+
- **Update** — inputs changed: the phase runs ordinarily and also
|
|
125
|
+
receives its prior input and a diff, as a hint to update the artifact
|
|
126
|
+
rather than rewrite it from scratch.
|
|
127
|
+
- **Ordinary** — no usable record, a changed link phase, or `--rebuild`.
|
|
128
|
+
|
|
129
|
+
A run that reuses everything prints `up to date` instead of paths.
|
|
130
|
+
History is success-only, so an interrupted or failed run simply leaves
|
|
131
|
+
the next one to compile ordinarily. `.slc/` holds verbatim copies of
|
|
132
|
+
your source and outputs — treat it as no less private, gitignore it if
|
|
133
|
+
you commit the bundle, and delete it freely. Excluded invocation forms
|
|
134
|
+
and the full rules are in the
|
|
135
|
+
[incremental spec](specs/packages/incremental-compilation.md).
|
|
182
136
|
|
|
183
137
|
## Configuration
|
|
184
138
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
and `pipelinePath` to the working directory.
|
|
139
|
+
The first run seeds `~/.config/slc/config.yaml` with
|
|
140
|
+
`agent: claude-code`, so a fresh machine needs no setup. A
|
|
141
|
+
`slc.config.yaml` in the working directory wins over the user config,
|
|
142
|
+
and `SLC_AGENT`, `SLC_MODEL`, and the other `SLC_*` variables override
|
|
143
|
+
either, per key.
|
|
191
144
|
|
|
192
145
|
```yaml
|
|
193
146
|
# slc.config.yaml
|
|
194
147
|
agent: claude-code # claude-code | codex | gemini | opencode
|
|
195
148
|
model: claude-opus-4-8 # optional; omit to use the agent CLI's default
|
|
149
|
+
effort: high # optional adapter-scoped reasoning effort
|
|
150
|
+
reviewerAgent: codex # optional; enables reviewed compilation
|
|
151
|
+
reviewerModel: gpt-5.3-codex # optional reviewer model
|
|
152
|
+
reviewerEffort: xhigh # optional reviewer reasoning effort
|
|
196
153
|
stallTimeout: 600 # seconds of agent silence before a stalled call fails
|
|
197
154
|
pipelinePath: # search roots for <pipeline> references; defaults to the cwd
|
|
198
155
|
- ./pipelines
|
|
199
156
|
```
|
|
200
157
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
158
|
+
Discovery order, `--config`, and validation rules live in the
|
|
159
|
+
[CLI spec](specs/packages/cli.md); `slc --help` prints the summary.
|
|
160
|
+
|
|
161
|
+
### Reviewed compilation (two agents)
|
|
162
|
+
|
|
163
|
+
Set `reviewerAgent` to compile with two independent agents. Your `agent`
|
|
164
|
+
selection is the Coder that writes each artifact; the Reviewer then
|
|
165
|
+
inspects that work read-only and reports only material correctness or
|
|
166
|
+
spec defects, and the Coder answers every finding with evidence and a
|
|
167
|
+
minimal fix. Up to three review rounds — if the third still reports
|
|
168
|
+
findings, the phase fails closed and names them rather than shipping a
|
|
169
|
+
questionable artifact.
|
|
170
|
+
|
|
171
|
+
It costs at least one extra agent call per transformation that runs.
|
|
172
|
+
Reuse performs no transformation and so makes no calls; Update,
|
|
173
|
+
Ordinary, and `--rebuild` use the loop automatically
|
|
174
|
+
([DR-022](specs/decisions/022-two-agent-reviewed-compilation.md)).
|
|
206
175
|
|
|
207
176
|
## How pipelines work
|
|
208
177
|
|
|
209
178
|
A pipeline is a directory of phase definitions named
|
|
210
179
|
`<source-format>2<target-format>.md`, each declaring its formats in a
|
|
211
|
-
`## Formats` table, plus an optional `link.md`
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
180
|
+
`## Formats` table, plus an optional `link.md` for the terminal link
|
|
181
|
+
phase. `slc` infers phase order by chaining formats — no manifest — and
|
|
182
|
+
refuses incomplete, branching, or cyclic chains. Adding a phase means
|
|
183
|
+
writing a definition, never changing the compiler: `slc` itself performs
|
|
184
|
+
only the generic mechanics of chaining, validation, and artifact
|
|
185
|
+
placement. The bundled `playbook` pipeline chains `text2gears` and
|
|
186
|
+
`gears2fsm`, with `link` emitting the runnable runtime.
|
|
218
187
|
|
|
219
188
|
Every phase runs through a coding agent, one of two ways:
|
|
220
189
|
|
|
@@ -222,11 +191,11 @@ Every phase runs through a coding agent, one of two ways:
|
|
|
222
191
|
performs it. This is how an npm-installed `slc` runs the `playbook`
|
|
223
192
|
pipeline, using the definitions shipped inside `@sublang/playbook`.
|
|
224
193
|
- **Compiled** — the phase's own compiled playbook artifact drives the
|
|
225
|
-
agent through audited state-machine steps. This repository
|
|
226
|
-
|
|
227
|
-
|
|
194
|
+
agent through audited state-machine steps. This repository runs its
|
|
195
|
+
bundled phases this way: `slc` is self-hosting, its phase definitions
|
|
196
|
+
compiled, reviewed, and sha256-pinned under
|
|
228
197
|
[`pipelines/playbook/`](pipelines/playbook), failing closed on drift
|
|
229
|
-
([self-hosting spec](specs/
|
|
198
|
+
([self-hosting spec](specs/packages/self-hosting.md)).
|
|
230
199
|
|
|
231
200
|
Specs are the source of truth — start at the
|
|
232
201
|
[spec map](specs/map.md).
|
package/dist/app.d.ts
CHANGED
|
@@ -11,11 +11,11 @@ export type DepsBuilder = (io: {
|
|
|
11
11
|
env: Record<string, string | undefined>;
|
|
12
12
|
cwd: string;
|
|
13
13
|
signal: AbortSignal;
|
|
14
|
-
/** Explicit `--config <path>`, when given (
|
|
14
|
+
/** Explicit `--config <path>`, when given (cli-20). */
|
|
15
15
|
configPath?: string;
|
|
16
|
-
/** Sink for host notes such as first-run config seeding (DR-015,
|
|
16
|
+
/** Sink for host notes such as first-run config seeding (DR-015, cli-30). */
|
|
17
17
|
note?: (text: string) => void;
|
|
18
|
-
/** The run's progress sink, rendered to stderr by the bin (DR-019,
|
|
18
|
+
/** The run's progress sink, rendered to stderr by the bin (DR-019, cli-35). */
|
|
19
19
|
progress?: ProgressSink;
|
|
20
20
|
}) => SlcDeps | Promise<SlcDeps>;
|
|
21
21
|
/** Injectable IO and configuration for {@link run}; all fields default to the process. */
|
|
@@ -24,9 +24,9 @@ export interface RunOptions {
|
|
|
24
24
|
cwd?: string;
|
|
25
25
|
stdout?: (text: string) => void;
|
|
26
26
|
stderr?: (text: string) => void;
|
|
27
|
-
/** Cancellation signal passed into `runSlc` (
|
|
27
|
+
/** Cancellation signal passed into `runSlc` (cli-10). */
|
|
28
28
|
signal?: AbortSignal;
|
|
29
|
-
/** Overrides production dependency construction (
|
|
29
|
+
/** Overrides production dependency construction (cli-6, cli-7). */
|
|
30
30
|
buildDeps?: DepsBuilder;
|
|
31
31
|
}
|
|
32
32
|
/** The executor factory {@link buildSlcDeps} uses; injected in tests. */
|
|
@@ -35,19 +35,19 @@ export type ExecutorFactory = typeof createConfiguredExecutor;
|
|
|
35
35
|
export type CompiledFactoryBuilder = typeof createConfiguredCompiledFactory;
|
|
36
36
|
/**
|
|
37
37
|
* Builds the production {@link SlcDeps}: a pipeline resolver over the resolved
|
|
38
|
-
* search roots (
|
|
39
|
-
* meta-pipeline definitions `@sublang/playbook` provides (
|
|
40
|
-
* interpreted executor for the resolved agent/model (
|
|
41
|
-
* compiled-execution factory a current pinned phase selects (
|
|
42
|
-
* Configuration is loaded from the config file (DR-006,
|
|
38
|
+
* search roots (cli-6) — with the reserved `slc` reference routed to the
|
|
39
|
+
* meta-pipeline definitions `@sublang/playbook` provides (self-hosting-2) — an
|
|
40
|
+
* interpreted executor for the resolved agent/model (cli-7), and the
|
|
41
|
+
* compiled-execution factory a current pinned phase selects (cli-8, phase-execution-27).
|
|
42
|
+
* Configuration is loaded from the config file (DR-006, cli-20) and
|
|
43
43
|
* then overridden per key by a non-blank environment variable, so existing
|
|
44
44
|
* env-only runs are unchanged and the file fills any key the environment leaves
|
|
45
45
|
* unset.
|
|
46
46
|
*
|
|
47
47
|
* @throws {import('./config-file.js').ConfigFileError} when an explicit
|
|
48
|
-
* `--config` path is absent or the file is malformed or invalid (
|
|
48
|
+
* `--config` path is absent or the file is malformed or invalid (cli-21).
|
|
49
49
|
* @throws {import('./config.js').ConfigError} when neither source supplies an
|
|
50
|
-
* agent, or the resolved agent is unsupported (
|
|
50
|
+
* agent, or the resolved agent is unsupported (cli-12).
|
|
51
51
|
*/
|
|
52
52
|
export declare function buildSlcDeps({ env, cwd, signal, configPath, note, progress }: Parameters<DepsBuilder>[0], createExecutor?: ExecutorFactory, createCompiled?: CompiledFactoryBuilder): Promise<SlcDeps>;
|
|
53
53
|
/** The cligent-invocation selection after merging environment over file (DR-006). */
|
|
@@ -55,34 +55,34 @@ export interface RunConfig {
|
|
|
55
55
|
selection: AgentSelection;
|
|
56
56
|
/** Search-root source: an `SLC_PIPELINE_PATH` string, the file's sequence, or undefined. */
|
|
57
57
|
pipelinePath: string | string[] | undefined;
|
|
58
|
-
/** Agent-stall watchdog window in milliseconds; `0` disables (DR-019,
|
|
58
|
+
/** Agent-stall watchdog window in milliseconds; `0` disables (DR-019, cli-34). */
|
|
59
59
|
stallTimeoutMs: number;
|
|
60
60
|
}
|
|
61
|
-
/** Default agent-stall watchdog window in seconds (DR-019,
|
|
61
|
+
/** Default agent-stall watchdog window in seconds (DR-019, cli-34). */
|
|
62
62
|
export declare const DEFAULT_STALL_TIMEOUT_SECONDS = 600;
|
|
63
63
|
/**
|
|
64
|
-
* Merges the environment over config-file values per key (DR-006,
|
|
64
|
+
* Merges the environment over config-file values per key (DR-006, cli-20): for
|
|
65
65
|
* each key a non-blank environment variable wins, otherwise the file value,
|
|
66
66
|
* otherwise the built-in default. The agent and model go through
|
|
67
67
|
* {@link resolveAgentSelection} so the supported-agent check stays single-sourced
|
|
68
|
-
* (
|
|
68
|
+
* (cli-7, cli-12); the stall timeout defaults to
|
|
69
69
|
* {@link DEFAULT_STALL_TIMEOUT_SECONDS} with `0` disabling the watchdog
|
|
70
|
-
* (DR-019,
|
|
70
|
+
* (DR-019, cli-34).
|
|
71
71
|
*
|
|
72
72
|
* @throws {Error} when `SLC_STALL_TIMEOUT` is not a non-negative number.
|
|
73
73
|
*/
|
|
74
74
|
export declare function resolveRunConfig(env: Record<string, string | undefined>, file: FileConfig): RunConfig;
|
|
75
|
-
/** Usage text naming the documented invocation forms and configuration (
|
|
75
|
+
/** Usage text naming the documented invocation forms and configuration (cli-2). */
|
|
76
76
|
export declare function usageText(): string;
|
|
77
77
|
/**
|
|
78
|
-
* Runs the `slc` command line and returns a process exit code (
|
|
78
|
+
* Runs the `slc` command line and returns a process exit code (`cli` package).
|
|
79
79
|
* Never rejects: configuration refusals and run failures are reported and
|
|
80
80
|
* mapped to a non-zero code.
|
|
81
81
|
*/
|
|
82
82
|
export declare function run(argv: readonly string[], options?: RunOptions): Promise<number>;
|
|
83
83
|
/**
|
|
84
84
|
* Wires `SIGINT`/`SIGTERM` on `emitter` to abort a fresh controller, returning
|
|
85
|
-
* its cancellation signal and a disposer that removes the listeners (
|
|
85
|
+
* its cancellation signal and a disposer that removes the listeners (cli-10).
|
|
86
86
|
* The `cli.ts` shim passes `process`; tests pass a fake emitter so the
|
|
87
87
|
* interrupt-to-abort wiring is exercised without real signals.
|
|
88
88
|
*/
|
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAoBA,OAAO,EACL,+BAA+B,EAC/B,wBAAwB,EAExB,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAA0B,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAM1E,OAAO,EAAU,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAUnD,wBAAwB;AACxB,eAAO,MAAM,IAAI,QAAQ,CAAC;AAE1B,sCAAsC;AACtC,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,4EAA4E;AAC5E,MAAM,MAAM,WAAW,GAAG,CAAC,EAAE,EAAE;IAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,WAAW,CAAC;IACpB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEjC,0FAA0F;AAC1F,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,yDAAyD;IACzD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,mEAAmE;IACnE,SAAS,CAAC,EAAE,WAAW,CAAC;CACzB;AAED,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG,OAAO,wBAAwB,CAAC;AAE9D,2FAA2F;AAC3F,MAAM,MAAM,sBAAsB,GAAG,OAAO,+BAA+B,CAAC;AAE5E;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,YAAY,CAChC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAK5E,cAAc,GAAE,eAA0C,EAC1D,cAAc,GAAE,sBAAwD,GACvE,OAAO,CAAC,OAAO,CAAC,CAmClB;AAED,qFAAqF;AACrF,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,cAAc,CAAC;IAC1B,4FAA4F;IAC5F,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IAC5C,kFAAkF;IAClF,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,uEAAuE;AACvE,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,IAAI,EAAE,UAAU,GACf,SAAS,
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
package/dist/app.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
|
|
3
3
|
/**
|
|
4
|
-
* The `slc` bin orchestrator (
|
|
4
|
+
* The `slc` bin orchestrator (`cli` package).
|
|
5
5
|
*
|
|
6
6
|
* `run` is the testable command-line entry: it short-circuits `--version` and
|
|
7
|
-
* `--help` before touching any pipeline or agent (
|
|
8
|
-
* the run dependencies from environment configuration (
|
|
9
|
-
* invokes the injectable `runSlc` core under a cancellation signal (
|
|
7
|
+
* `--help` before touching any pipeline or agent (cli-1, cli-2, cli-9), builds
|
|
8
|
+
* the run dependencies from environment configuration (cli-6, cli-7, cli-12),
|
|
9
|
+
* invokes the injectable `runSlc` core under a cancellation signal (cli-10), and
|
|
10
10
|
* maps the result onto process streams and an exit code — produced artifact
|
|
11
|
-
* paths to stdout on success, the failure report to stderr otherwise (
|
|
12
|
-
*
|
|
11
|
+
* paths to stdout on success, the failure report to stderr otherwise (cli-3,
|
|
12
|
+
* cli-4, cli-11). Every IO seam is injectable so the bin is integration-testable
|
|
13
13
|
* without a real agent; the `cli.ts` shim supplies the process-backed defaults
|
|
14
|
-
* and signal wiring. See specs/
|
|
14
|
+
* and signal wiring. See specs/packages/cli.md.
|
|
15
15
|
*/
|
|
16
16
|
import { createRequire } from 'node:module';
|
|
17
17
|
import { messageOf } from './errors.js';
|
|
@@ -33,19 +33,19 @@ export function version() {
|
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Builds the production {@link SlcDeps}: a pipeline resolver over the resolved
|
|
36
|
-
* search roots (
|
|
37
|
-
* meta-pipeline definitions `@sublang/playbook` provides (
|
|
38
|
-
* interpreted executor for the resolved agent/model (
|
|
39
|
-
* compiled-execution factory a current pinned phase selects (
|
|
40
|
-
* Configuration is loaded from the config file (DR-006,
|
|
36
|
+
* search roots (cli-6) — with the reserved `slc` reference routed to the
|
|
37
|
+
* meta-pipeline definitions `@sublang/playbook` provides (self-hosting-2) — an
|
|
38
|
+
* interpreted executor for the resolved agent/model (cli-7), and the
|
|
39
|
+
* compiled-execution factory a current pinned phase selects (cli-8, phase-execution-27).
|
|
40
|
+
* Configuration is loaded from the config file (DR-006, cli-20) and
|
|
41
41
|
* then overridden per key by a non-blank environment variable, so existing
|
|
42
42
|
* env-only runs are unchanged and the file fills any key the environment leaves
|
|
43
43
|
* unset.
|
|
44
44
|
*
|
|
45
45
|
* @throws {import('./config-file.js').ConfigFileError} when an explicit
|
|
46
|
-
* `--config` path is absent or the file is malformed or invalid (
|
|
46
|
+
* `--config` path is absent or the file is malformed or invalid (cli-21).
|
|
47
47
|
* @throws {import('./config.js').ConfigError} when neither source supplies an
|
|
48
|
-
* agent, or the resolved agent is unsupported (
|
|
48
|
+
* agent, or the resolved agent is unsupported (cli-12).
|
|
49
49
|
*/
|
|
50
50
|
export async function buildSlcDeps({ env, cwd, signal, configPath, note, progress },
|
|
51
51
|
// Injectable so a test can capture the executor options — notably the
|
|
@@ -65,7 +65,7 @@ createExecutor = createConfiguredExecutor, createCompiled = createConfiguredComp
|
|
|
65
65
|
// Auto-accept the agents' file operations so a non-interactive `slc` run can
|
|
66
66
|
// write its target artifact; the DR-003 generic checks still guard the
|
|
67
67
|
// protected inputs (DR-004). The stall watchdog rides every constructed
|
|
68
|
-
// transport (DR-019,
|
|
68
|
+
// transport (DR-019, cli-35).
|
|
69
69
|
const agentOpts = {
|
|
70
70
|
cwd,
|
|
71
71
|
permissions: { mode: 'auto' },
|
|
@@ -73,7 +73,7 @@ createExecutor = createConfiguredExecutor, createCompiled = createConfiguredComp
|
|
|
73
73
|
};
|
|
74
74
|
const executor = createExecutor(selection, agentOpts);
|
|
75
75
|
// Compiled-runtime status streams to the same reporter as phase progress
|
|
76
|
-
// (
|
|
76
|
+
// (phase-execution-25, cli-32).
|
|
77
77
|
const compiled = createCompiled(selection, {
|
|
78
78
|
...agentOpts,
|
|
79
79
|
onStatus: progress === undefined
|
|
@@ -82,16 +82,16 @@ createExecutor = createConfiguredExecutor, createCompiled = createConfiguredComp
|
|
|
82
82
|
});
|
|
83
83
|
return { resolver, executor, compiled, cwd, signal, progress };
|
|
84
84
|
}
|
|
85
|
-
/** Default agent-stall watchdog window in seconds (DR-019,
|
|
85
|
+
/** Default agent-stall watchdog window in seconds (DR-019, cli-34). */
|
|
86
86
|
export const DEFAULT_STALL_TIMEOUT_SECONDS = 600;
|
|
87
87
|
/**
|
|
88
|
-
* Merges the environment over config-file values per key (DR-006,
|
|
88
|
+
* Merges the environment over config-file values per key (DR-006, cli-20): for
|
|
89
89
|
* each key a non-blank environment variable wins, otherwise the file value,
|
|
90
90
|
* otherwise the built-in default. The agent and model go through
|
|
91
91
|
* {@link resolveAgentSelection} so the supported-agent check stays single-sourced
|
|
92
|
-
* (
|
|
92
|
+
* (cli-7, cli-12); the stall timeout defaults to
|
|
93
93
|
* {@link DEFAULT_STALL_TIMEOUT_SECONDS} with `0` disabling the watchdog
|
|
94
|
-
* (DR-019,
|
|
94
|
+
* (DR-019, cli-34).
|
|
95
95
|
*
|
|
96
96
|
* @throws {Error} when `SLC_STALL_TIMEOUT` is not a non-negative number.
|
|
97
97
|
*/
|
|
@@ -100,6 +100,9 @@ export function resolveRunConfig(env, file) {
|
|
|
100
100
|
SLC_AGENT: nonBlank(env.SLC_AGENT) ?? file.agent,
|
|
101
101
|
SLC_MODEL: nonBlank(env.SLC_MODEL) ?? file.model,
|
|
102
102
|
SLC_EFFORT: nonBlank(env.SLC_EFFORT) ?? file.effort,
|
|
103
|
+
SLC_REVIEWER_AGENT: nonBlank(env.SLC_REVIEWER_AGENT) ?? file.reviewerAgent,
|
|
104
|
+
SLC_REVIEWER_MODEL: nonBlank(env.SLC_REVIEWER_MODEL) ?? file.reviewerModel,
|
|
105
|
+
SLC_REVIEWER_EFFORT: nonBlank(env.SLC_REVIEWER_EFFORT) ?? file.reviewerEffort,
|
|
103
106
|
});
|
|
104
107
|
const pipelinePath = nonBlank(env.SLC_PIPELINE_PATH) ?? file.pipelinePath;
|
|
105
108
|
const stallSeconds = parseStallTimeout(nonBlank(env.SLC_STALL_TIMEOUT)) ??
|
|
@@ -125,7 +128,7 @@ function parseStallTimeout(value) {
|
|
|
125
128
|
function nonBlank(value) {
|
|
126
129
|
return value !== undefined && value.trim() !== '' ? value : undefined;
|
|
127
130
|
}
|
|
128
|
-
/** Usage text naming the documented invocation forms and configuration (
|
|
131
|
+
/** Usage text naming the documented invocation forms and configuration (cli-2). */
|
|
129
132
|
export function usageText() {
|
|
130
133
|
return [
|
|
131
134
|
'Usage:',
|
|
@@ -155,11 +158,15 @@ export function usageText() {
|
|
|
155
158
|
' environment variable below:',
|
|
156
159
|
' ./slc.config.yaml',
|
|
157
160
|
' ${XDG_CONFIG_HOME:-~/.config}/slc/config.yaml',
|
|
158
|
-
' Keys: agent, model, effort,
|
|
161
|
+
' Keys: agent, model, effort, reviewerAgent, reviewerModel,',
|
|
162
|
+
' reviewerEffort, pipelinePath, stallTimeout.',
|
|
159
163
|
'',
|
|
160
164
|
' SLC_AGENT agent CLI: claude-code | codex | gemini | opencode',
|
|
161
165
|
' SLC_MODEL optional model for the agent CLI',
|
|
162
166
|
' SLC_EFFORT optional adapter-scoped reasoning effort (e.g. xhigh)',
|
|
167
|
+
' SLC_REVIEWER_AGENT optional independent reviewer; enables reviewed compilation',
|
|
168
|
+
' SLC_REVIEWER_MODEL optional model for the reviewer agent CLI',
|
|
169
|
+
' SLC_REVIEWER_EFFORT optional adapter-scoped reviewer reasoning effort',
|
|
163
170
|
' SLC_PIPELINE_PATH search roots for <pipeline> references (default: cwd)',
|
|
164
171
|
' SLC_STALL_TIMEOUT seconds of agent inactivity before a stalled call',
|
|
165
172
|
' fails the run (default: 600; 0 disables)',
|
|
@@ -168,7 +175,7 @@ export function usageText() {
|
|
|
168
175
|
}
|
|
169
176
|
/**
|
|
170
177
|
* Splits `--config <path>` out of argv, returning the path and the remaining
|
|
171
|
-
* arguments for `runSlc` (
|
|
178
|
+
* arguments for `runSlc` (cli-20). `--config` is a bin-level flag, so it is
|
|
172
179
|
* removed before the grammar parser, which rejects unknown options.
|
|
173
180
|
*
|
|
174
181
|
* @throws {Error} when `--config` is given without a following value.
|
|
@@ -191,14 +198,14 @@ function extractConfigFlag(argv) {
|
|
|
191
198
|
return { configPath, rest };
|
|
192
199
|
}
|
|
193
200
|
/**
|
|
194
|
-
* Runs the `slc` command line and returns a process exit code (
|
|
201
|
+
* Runs the `slc` command line and returns a process exit code (`cli` package).
|
|
195
202
|
* Never rejects: configuration refusals and run failures are reported and
|
|
196
203
|
* mapped to a non-zero code.
|
|
197
204
|
*/
|
|
198
205
|
export async function run(argv, options = {}) {
|
|
199
206
|
const stdout = options.stdout ?? ((text) => void process.stdout.write(text));
|
|
200
207
|
const stderr = options.stderr ?? ((text) => void process.stderr.write(text));
|
|
201
|
-
// Conveniences short-circuit before any pipeline or agent work (
|
|
208
|
+
// Conveniences short-circuit before any pipeline or agent work (cli-1, cli-2, cli-9).
|
|
202
209
|
if (hasFlag(argv, '--version', '-v')) {
|
|
203
210
|
stdout(`${name} ${version()}\n`);
|
|
204
211
|
return 0;
|
|
@@ -211,13 +218,13 @@ export async function run(argv, options = {}) {
|
|
|
211
218
|
const cwd = options.cwd ?? process.cwd();
|
|
212
219
|
const signal = options.signal ?? new AbortController().signal;
|
|
213
220
|
// In-run progress renders on stderr as it happens, with the silence-bounded
|
|
214
|
-
// heartbeat (DR-019,
|
|
221
|
+
// heartbeat (DR-019, cli-32, cli-33, cli-35).
|
|
215
222
|
const reporter = createProgressReporter(stderr);
|
|
216
223
|
let deps;
|
|
217
224
|
let rest;
|
|
218
225
|
try {
|
|
219
226
|
// `--config <path>` is a bin-level flag: strip it before runSlc, whose
|
|
220
|
-
// grammar (parseInvocation) rejects unknown options (
|
|
227
|
+
// grammar (parseInvocation) rejects unknown options (cli-20).
|
|
221
228
|
const extracted = extractConfigFlag(argv);
|
|
222
229
|
rest = extracted.rest;
|
|
223
230
|
deps = await (options.buildDeps ?? buildSlcDeps)({
|
|
@@ -231,7 +238,7 @@ export async function run(argv, options = {}) {
|
|
|
231
238
|
}
|
|
232
239
|
catch (error) {
|
|
233
240
|
// Configuration refusals — a bad `--config`, an invalid config file
|
|
234
|
-
// (
|
|
241
|
+
// (cli-21), or an unset/unsupported agent (cli-12) — fail the run.
|
|
235
242
|
reporter.dispose();
|
|
236
243
|
stderr(`${name}: ${messageOf(error)}\n`);
|
|
237
244
|
return 1;
|
|
@@ -248,7 +255,7 @@ export async function run(argv, options = {}) {
|
|
|
248
255
|
stdout('up to date\n');
|
|
249
256
|
else if (result.outputs.length > 0)
|
|
250
257
|
stdout(`${result.outputs.join('\n')}\n`);
|
|
251
|
-
// Surface
|
|
258
|
+
// Surface benign ambiguity resolved during the run without polluting paths.
|
|
252
259
|
if (result.diagnostics.length > 0)
|
|
253
260
|
stderr(`${result.diagnostics.join('\n')}\n`);
|
|
254
261
|
return 0;
|
|
@@ -259,7 +266,7 @@ export async function run(argv, options = {}) {
|
|
|
259
266
|
}
|
|
260
267
|
/**
|
|
261
268
|
* Wires `SIGINT`/`SIGTERM` on `emitter` to abort a fresh controller, returning
|
|
262
|
-
* its cancellation signal and a disposer that removes the listeners (
|
|
269
|
+
* its cancellation signal and a disposer that removes the listeners (cli-10).
|
|
263
270
|
* The `cli.ts` shim passes `process`; tests pass a fake emitter so the
|
|
264
271
|
* interrupt-to-abort wiring is exercised without real signals.
|
|
265
272
|
*/
|