@orkestrel/scaffold 0.0.64 → 0.0.66
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 +11 -1
- package/dist/host/agents/skills/enterprise-bootstrap/SKILL.md +202 -175
- package/dist/host/agents/skills/enterprise-bootstrap/references/bootstrap-reference.md +347 -94
- package/dist/host/agents/skills/enterprise-bootstrap/references/color-modes.md +356 -0
- package/dist/host/agents/skills/enterprise-bootstrap/references/components.md +100 -45
- package/dist/host/agents/skills/enterprise-bootstrap/references/frontend-design.md +295 -101
- package/dist/host/agents/skills/enterprise-bootstrap/references/inputs.md +60 -41
- package/dist/host/agents/skills/enterprise-bootstrap/references/inspection.md +255 -132
- package/dist/host/agents/skills/enterprise-bootstrap/references/responsive-layout.md +237 -0
- package/dist/host/agents/skills/enterprise-bootstrap/references/utilities.md +111 -17
- package/dist/host/claude/agents/orkestrel.md +24 -24
- package/dist/host/claude/rules/workspace.md +2 -2
- package/dist/host/claude/settings.json +1 -1
- package/dist/host/claude/skills/enterprise-bootstrap/SKILL.md +11 -10
- package/dist/host/guides/scaffold.md +63 -22
- package/dist/host/manifest.json +26 -14
- package/dist/host/scripts/ollama.sh +322 -13
- package/dist/src/core/index.cjs +34 -13
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +31 -9
- package/dist/src/core/index.d.ts +31 -9
- package/dist/src/core/index.js +33 -14
- package/dist/src/core/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -1,20 +1,329 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# caller-controlled endpoint is contacted or copied into model context.
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
MAX_SECONDS=590
|
|
5
|
+
CLEANUP_SECONDS=5
|
|
6
|
+
OPERATION_SECONDS=$((MAX_SECONDS - CLEANUP_SECONDS - 1))
|
|
7
|
+
STARTED_SECONDS=$SECONDS
|
|
8
|
+
STARTUP_SECONDS=60
|
|
9
|
+
INSTALLER_URL='https://ollama.com/install.sh'
|
|
10
|
+
|
|
11
|
+
launched_pid=
|
|
12
|
+
installer_path=
|
|
13
|
+
|
|
14
|
+
fail() {
|
|
15
|
+
printf 'ollama.sh: %s\n' "$1" >&2
|
|
16
|
+
exit 1
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
remaining_seconds() {
|
|
20
|
+
local remaining=$((OPERATION_SECONDS - (SECONDS - STARTED_SECONDS)))
|
|
21
|
+
if ((remaining < 1)); then
|
|
22
|
+
printf '0\n'
|
|
23
|
+
else
|
|
24
|
+
printf '%s\n' "$remaining"
|
|
25
|
+
fi
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
terminate_group() {
|
|
29
|
+
local pid=$1
|
|
30
|
+
local deadline=$((SECONDS + CLEANUP_SECONDS))
|
|
31
|
+
kill -TERM -- "-$pid" >/dev/null 2>&1 || true
|
|
32
|
+
while kill -0 -- "-$pid" >/dev/null 2>&1; do
|
|
33
|
+
if ((SECONDS >= deadline)); then
|
|
34
|
+
kill -KILL -- "-$pid" >/dev/null 2>&1 || true
|
|
35
|
+
break
|
|
36
|
+
fi
|
|
37
|
+
sleep 1
|
|
38
|
+
done
|
|
39
|
+
wait "$pid" >/dev/null 2>&1 || true
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
cleanup() {
|
|
43
|
+
local status=$1
|
|
44
|
+
if [[ -n "$installer_path" && -f "$installer_path" ]]; then
|
|
45
|
+
rm -f -- "$installer_path"
|
|
46
|
+
fi
|
|
47
|
+
if ((status != 0)) && [[ -n "$launched_pid" ]]; then
|
|
48
|
+
terminate_group "$launched_pid"
|
|
49
|
+
fi
|
|
50
|
+
exit "$status"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
normalize_host() {
|
|
54
|
+
OLLAMA_INPUT="$1" "$node_path" -e '
|
|
55
|
+
const { isIP } = require("node:net")
|
|
56
|
+
const raw = process.env.OLLAMA_INPUT
|
|
57
|
+
if (raw === undefined || raw.length === 0) process.exit(1)
|
|
58
|
+
let url
|
|
59
|
+
try {
|
|
60
|
+
url = new URL(/^https?:\/\//iu.test(raw) ? raw : `http://${raw}`)
|
|
61
|
+
} catch {
|
|
62
|
+
process.exit(1)
|
|
63
|
+
}
|
|
64
|
+
if (
|
|
65
|
+
(url.protocol !== "http:" && url.protocol !== "https:") ||
|
|
66
|
+
url.username !== "" ||
|
|
67
|
+
url.password !== "" ||
|
|
68
|
+
url.pathname !== "/" ||
|
|
69
|
+
url.search !== "" ||
|
|
70
|
+
url.hash !== "" ||
|
|
71
|
+
url.hostname === ""
|
|
72
|
+
) process.exit(1)
|
|
73
|
+
const hostname =
|
|
74
|
+
url.hostname.startsWith("[") && url.hostname.endsWith("]")
|
|
75
|
+
? url.hostname.slice(1, -1)
|
|
76
|
+
: url.hostname
|
|
77
|
+
const family = isIP(hostname)
|
|
78
|
+
const loopback =
|
|
79
|
+
hostname === "localhost" ||
|
|
80
|
+
(family === 4 && hostname.split(".")[0] === "127") ||
|
|
81
|
+
(family === 6 && hostname === "::1")
|
|
82
|
+
process.stdout.write(`${url.origin}\n${loopback ? "true" : "false"}`)
|
|
83
|
+
'
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
build_payload() {
|
|
87
|
+
OLLAMA_MODEL_VALUE="$model" "$node_path" -e '
|
|
88
|
+
const model = process.env.OLLAMA_MODEL_VALUE
|
|
89
|
+
if (model === undefined || model.length === 0) process.exit(1)
|
|
90
|
+
let body
|
|
91
|
+
switch (process.argv[1]) {
|
|
92
|
+
case "show":
|
|
93
|
+
body = { model }
|
|
94
|
+
break
|
|
95
|
+
case "pull":
|
|
96
|
+
body = { model, stream: false }
|
|
97
|
+
break
|
|
98
|
+
case "chat":
|
|
99
|
+
body = {
|
|
100
|
+
model,
|
|
101
|
+
messages: [{ role: "user", content: "hi" }],
|
|
102
|
+
stream: false,
|
|
103
|
+
think: false,
|
|
104
|
+
keep_alive: "30m",
|
|
105
|
+
options: { num_predict: 1 },
|
|
106
|
+
}
|
|
107
|
+
break
|
|
108
|
+
default:
|
|
109
|
+
process.exit(1)
|
|
110
|
+
}
|
|
111
|
+
process.stdout.write(JSON.stringify(body))
|
|
112
|
+
' "$1"
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
validate_response() {
|
|
116
|
+
"$node_path" -e '
|
|
117
|
+
const { readFileSync } = require("node:fs")
|
|
118
|
+
let body
|
|
119
|
+
try {
|
|
120
|
+
body = JSON.parse(readFileSync(0, "utf8"))
|
|
121
|
+
} catch {
|
|
122
|
+
process.exit(1)
|
|
123
|
+
}
|
|
124
|
+
if (body === null || typeof body !== "object" || Array.isArray(body)) process.exit(1)
|
|
125
|
+
if (process.argv[1] === "pull") process.exit(body.status === "success" ? 0 : 1)
|
|
126
|
+
if (process.argv[1] === "chat") process.exit(body.done === true ? 0 : 1)
|
|
127
|
+
process.exit(1)
|
|
128
|
+
' "$1"
|
|
129
|
+
}
|
|
8
130
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
131
|
+
probe_version() {
|
|
132
|
+
local allowance=$1
|
|
133
|
+
local status
|
|
134
|
+
if ! status=$(curl --silent --max-time "$allowance" --output /dev/null \
|
|
135
|
+
--write-out '%{http_code}' "$normalized_host/api/version" 2>/dev/null); then
|
|
136
|
+
return 1
|
|
137
|
+
fi
|
|
138
|
+
[[ "$status" =~ ^2[0-9][0-9]$ ]]
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
trap 'cleanup $?' EXIT
|
|
142
|
+
|
|
143
|
+
if ! command -v node >/dev/null 2>&1; then
|
|
144
|
+
printf 'ollama.sh: node is required for URL and JSON handling\n' >&2
|
|
145
|
+
exit 127
|
|
12
146
|
fi
|
|
147
|
+
if ! command -v curl >/dev/null 2>&1; then
|
|
148
|
+
printf 'ollama.sh: curl is required for Ollama setup\n' >&2
|
|
149
|
+
exit 127
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
node_path=$(command -v node)
|
|
153
|
+
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
|
|
154
|
+
project_root=$(cd -- "$script_dir/.." && pwd -P)
|
|
155
|
+
tmp_dir="$project_root/tmp"
|
|
156
|
+
mkdir -p -- "$tmp_dir"
|
|
13
157
|
|
|
14
|
-
if
|
|
15
|
-
|
|
158
|
+
if [[ ${OLLAMA_HOST+x} == x ]]; then
|
|
159
|
+
host_input=$OLLAMA_HOST
|
|
16
160
|
else
|
|
17
|
-
|
|
161
|
+
host_input='http://127.0.0.1:11434'
|
|
162
|
+
fi
|
|
163
|
+
if [[ ${OLLAMA_MODEL+x} == x ]]; then
|
|
164
|
+
model=$OLLAMA_MODEL
|
|
165
|
+
else
|
|
166
|
+
model='qwen3.5:2b-q4_K_M'
|
|
167
|
+
fi
|
|
168
|
+
if [[ -z "$model" ]]; then
|
|
169
|
+
fail 'OLLAMA_MODEL must not be empty'
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
if ! host_data=$(normalize_host "$host_input"); then
|
|
173
|
+
fail 'OLLAMA_HOST must be an HTTP origin without credentials, path, query, or fragment'
|
|
174
|
+
fi
|
|
175
|
+
if [[ "$host_data" != *$'\n'* ]]; then
|
|
176
|
+
fail 'OLLAMA_HOST normalization returned no endpoint classification'
|
|
177
|
+
fi
|
|
178
|
+
normalized_host=${host_data%%$'\n'*}
|
|
179
|
+
loopback=${host_data#*$'\n'}
|
|
180
|
+
|
|
181
|
+
ready=false
|
|
182
|
+
if probe_version 2; then
|
|
183
|
+
ready=true
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
if [[ "$ready" != true ]]; then
|
|
187
|
+
if [[ "$loopback" != true || "$normalized_host" != http://* ]]; then
|
|
188
|
+
fail 'the configured endpoint is unreachable; local startup is limited to HTTP loopback'
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
if ! command -v ollama >/dev/null 2>&1; then
|
|
192
|
+
if [[ ${CLAUDE_CODE_REMOTE:-} != true && ${CI:-} != true ]]; then
|
|
193
|
+
printf 'ollama.sh: ollama is required to start an unreachable loopback endpoint\n' >&2
|
|
194
|
+
exit 127
|
|
195
|
+
fi
|
|
196
|
+
if [[ $(uname -s) != Linux ]]; then
|
|
197
|
+
fail 'automatic Ollama installation is supported only on Linux'
|
|
198
|
+
fi
|
|
199
|
+
if ! command -v timeout >/dev/null 2>&1; then
|
|
200
|
+
printf 'ollama.sh: timeout is required to bound automatic installation\n' >&2
|
|
201
|
+
exit 127
|
|
202
|
+
fi
|
|
203
|
+
if ! command -v mktemp >/dev/null 2>&1; then
|
|
204
|
+
printf 'ollama.sh: mktemp is required for automatic installation\n' >&2
|
|
205
|
+
exit 127
|
|
206
|
+
fi
|
|
207
|
+
installer_path=$(mktemp "$tmp_dir/ollama-install.XXXXXX.sh")
|
|
208
|
+
remaining=$(remaining_seconds)
|
|
209
|
+
if ((remaining == 0)); then
|
|
210
|
+
fail 'the setup deadline expired before installation'
|
|
211
|
+
fi
|
|
212
|
+
if ! curl --fail --silent --show-error --location \
|
|
213
|
+
--proto '=https' --proto-redir '=https' --max-time "$remaining" \
|
|
214
|
+
--output "$installer_path" "$INSTALLER_URL"; then
|
|
215
|
+
fail 'the official Ollama installer download failed'
|
|
216
|
+
fi
|
|
217
|
+
if [[ ! -s "$installer_path" ]]; then
|
|
218
|
+
fail 'the official Ollama installer download was empty'
|
|
219
|
+
fi
|
|
220
|
+
remaining=$(remaining_seconds)
|
|
221
|
+
if ((remaining == 0)); then
|
|
222
|
+
fail 'the setup deadline expired before installation'
|
|
223
|
+
fi
|
|
224
|
+
if ! timeout --signal=TERM --kill-after=5s "${remaining}s" sh "$installer_path"; then
|
|
225
|
+
fail 'the official Ollama installer did not complete within the setup deadline'
|
|
226
|
+
fi
|
|
227
|
+
ollama_path=$(command -v ollama || true)
|
|
228
|
+
if [[ -z "$ollama_path" || ! -f "$ollama_path" || ! -x "$ollama_path" ]]; then
|
|
229
|
+
fail 'the official Ollama installer completed without an executable in PATH'
|
|
230
|
+
fi
|
|
231
|
+
remaining=$(remaining_seconds)
|
|
232
|
+
if ((remaining == 0)); then
|
|
233
|
+
fail 'the setup deadline expired after installation'
|
|
234
|
+
fi
|
|
235
|
+
probe_allowance=2
|
|
236
|
+
if ((remaining < probe_allowance)); then probe_allowance=$remaining; fi
|
|
237
|
+
if probe_version "$probe_allowance"; then
|
|
238
|
+
ready=true
|
|
239
|
+
fi
|
|
240
|
+
fi
|
|
241
|
+
|
|
242
|
+
if [[ "$ready" != true ]]; then
|
|
243
|
+
host_kernel=$(uname -s)
|
|
244
|
+
if [[ "$host_kernel" == MINGW* || "$host_kernel" == MSYS* || "$host_kernel" == CYGWIN* ]]; then
|
|
245
|
+
fail 'starting Ollama from Git Bash is unsupported because failure cleanup cannot terminate its Windows process tree safely'
|
|
246
|
+
fi
|
|
247
|
+
if ! command -v setsid >/dev/null 2>&1; then
|
|
248
|
+
fail 'setsid is required to own an Ollama daemon process group for failure cleanup'
|
|
249
|
+
fi
|
|
250
|
+
ollama_path=$(command -v ollama)
|
|
251
|
+
log_path="$tmp_dir/ollama-service.log"
|
|
252
|
+
OLLAMA_HOST="$normalized_host" setsid "$ollama_path" serve </dev/null >>"$log_path" 2>&1 &
|
|
253
|
+
launched_pid=$!
|
|
254
|
+
startup_started=$SECONDS
|
|
255
|
+
while true; do
|
|
256
|
+
remaining=$(remaining_seconds)
|
|
257
|
+
startup_remaining=$((STARTUP_SECONDS - (SECONDS - startup_started)))
|
|
258
|
+
if ((remaining == 0 || startup_remaining <= 0)); then
|
|
259
|
+
fail 'Ollama did not become ready within the startup deadline; see tmp/ollama-service.log'
|
|
260
|
+
fi
|
|
261
|
+
probe_allowance=2
|
|
262
|
+
if ((remaining < probe_allowance)); then probe_allowance=$remaining; fi
|
|
263
|
+
if ((startup_remaining < probe_allowance)); then probe_allowance=$startup_remaining; fi
|
|
264
|
+
if probe_version "$probe_allowance"; then
|
|
265
|
+
ready=true
|
|
266
|
+
break
|
|
267
|
+
fi
|
|
268
|
+
sleep 1
|
|
269
|
+
done
|
|
270
|
+
fi
|
|
271
|
+
fi
|
|
272
|
+
|
|
273
|
+
show_payload=$(build_payload show) || fail 'failed to serialize the model request'
|
|
274
|
+
remaining=$(remaining_seconds)
|
|
275
|
+
if ((remaining == 0)); then fail 'the setup deadline expired before model inspection'; fi
|
|
276
|
+
if ! show_status=$(curl --silent --show-error --max-time "$remaining" \
|
|
277
|
+
--output /dev/null --write-out '%{http_code}' \
|
|
278
|
+
--header 'Content-Type: application/json' --data-binary "$show_payload" \
|
|
279
|
+
"$normalized_host/api/show"); then
|
|
280
|
+
fail 'the model inspection request failed'
|
|
281
|
+
fi
|
|
282
|
+
|
|
283
|
+
if [[ "$show_status" == 404 ]]; then
|
|
284
|
+
pull_payload=$(build_payload pull) || fail 'failed to serialize the pull request'
|
|
285
|
+
remaining=$(remaining_seconds)
|
|
286
|
+
if ((remaining == 0)); then fail 'the setup deadline expired before model pull'; fi
|
|
287
|
+
if ! pull_wire=$(curl --silent --show-error --max-time "$remaining" \
|
|
288
|
+
--write-out $'\n%{http_code}' \
|
|
289
|
+
--header 'Content-Type: application/json' --data-binary "$pull_payload" \
|
|
290
|
+
"$normalized_host/api/pull"); then
|
|
291
|
+
fail 'the model pull request failed'
|
|
292
|
+
fi
|
|
293
|
+
if [[ "$pull_wire" != *$'\n'* ]]; then
|
|
294
|
+
fail 'the model pull response carried no HTTP status'
|
|
295
|
+
fi
|
|
296
|
+
pull_status=${pull_wire##*$'\n'}
|
|
297
|
+
pull_response=${pull_wire%$'\n'*}
|
|
298
|
+
if [[ ! "$pull_status" =~ ^2[0-9][0-9]$ ]]; then
|
|
299
|
+
fail 'the model pull request returned an unsuccessful HTTP status'
|
|
300
|
+
fi
|
|
301
|
+
if ! printf '%s' "$pull_response" | validate_response pull; then
|
|
302
|
+
fail 'the model pull response did not report completion'
|
|
303
|
+
fi
|
|
304
|
+
elif [[ ! "$show_status" =~ ^2[0-9][0-9]$ ]]; then
|
|
305
|
+
fail 'the model inspection request failed without reporting absence'
|
|
306
|
+
fi
|
|
307
|
+
|
|
308
|
+
chat_payload=$(build_payload chat) || fail 'failed to serialize the warm request'
|
|
309
|
+
remaining=$(remaining_seconds)
|
|
310
|
+
if ((remaining == 0)); then fail 'the setup deadline expired before model warmup'; fi
|
|
311
|
+
if ! chat_wire=$(curl --silent --show-error --max-time "$remaining" \
|
|
312
|
+
--write-out $'\n%{http_code}' \
|
|
313
|
+
--header 'Content-Type: application/json' --data-binary "$chat_payload" \
|
|
314
|
+
"$normalized_host/api/chat"); then
|
|
315
|
+
fail 'the model warm request failed'
|
|
316
|
+
fi
|
|
317
|
+
if [[ "$chat_wire" != *$'\n'* ]]; then
|
|
318
|
+
fail 'the model warm response carried no HTTP status'
|
|
319
|
+
fi
|
|
320
|
+
chat_status=${chat_wire##*$'\n'}
|
|
321
|
+
chat_response=${chat_wire%$'\n'*}
|
|
322
|
+
if [[ ! "$chat_status" =~ ^2[0-9][0-9]$ ]]; then
|
|
323
|
+
fail 'the model warm request returned an unsuccessful HTTP status'
|
|
324
|
+
fi
|
|
325
|
+
if ! printf '%s' "$chat_response" | validate_response chat; then
|
|
326
|
+
fail 'the model warm response did not report completion'
|
|
18
327
|
fi
|
|
19
328
|
|
|
20
|
-
|
|
329
|
+
printf 'ollama.sh: Ollama is ready\n'
|
package/dist/src/core/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@ let _orkestrel_template = require("@orkestrel/template");
|
|
|
4
4
|
let _orkestrel_emitter = require("@orkestrel/emitter");
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "@orkestrel/scaffold",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.66",
|
|
8
8
|
description: "Scaffold workspaces with commands: new, audit, repair, catalog, and overwrite.",
|
|
9
9
|
keywords: [
|
|
10
10
|
"audit",
|
|
@@ -94,14 +94,14 @@ var package_default = {
|
|
|
94
94
|
"@orkestrel/contract": "^0.0.17",
|
|
95
95
|
"@orkestrel/emitter": "^0.0.10",
|
|
96
96
|
"@orkestrel/markdown": "^0.0.14",
|
|
97
|
-
"@orkestrel/process": "^0.0.
|
|
97
|
+
"@orkestrel/process": "^0.0.12",
|
|
98
98
|
"@orkestrel/template": "^0.0.7"
|
|
99
99
|
},
|
|
100
100
|
devDependencies: {
|
|
101
101
|
"@microsoft/api-extractor": "^7.59.0",
|
|
102
|
-
"@orkestrel/guide": "^0.0.
|
|
102
|
+
"@orkestrel/guide": "^0.0.18",
|
|
103
103
|
"@orkestrel/html": "^0.0.9",
|
|
104
|
-
"@orkestrel/probe": "^0.0.
|
|
104
|
+
"@orkestrel/probe": "^0.0.13",
|
|
105
105
|
"@orkestrel/test": "^0.0.14",
|
|
106
106
|
"@types/node": "^26.5.0",
|
|
107
107
|
"@vitest/browser-playwright": "^4.1.11",
|
|
@@ -112,7 +112,7 @@ var package_default = {
|
|
|
112
112
|
"vite": "^8.2.2",
|
|
113
113
|
"vitest": "^4.1.11"
|
|
114
114
|
},
|
|
115
|
-
engines: { "node": ">=22.
|
|
115
|
+
engines: { "node": ">=22.18.0" }
|
|
116
116
|
};
|
|
117
117
|
//#endregion
|
|
118
118
|
//#region src/core/constants.ts
|
|
@@ -384,7 +384,7 @@ var CATALOG_OPENING_MARKER = "<!-- orkestrel:catalog -->";
|
|
|
384
384
|
* refused rather than rewritten.
|
|
385
385
|
*/
|
|
386
386
|
var CATALOG_CLOSING_MARKER = "<!-- /orkestrel:catalog -->";
|
|
387
|
-
/** Names the
|
|
387
|
+
/** Names the inventory skeleton a workspace with declared service vendors is given once. */
|
|
388
388
|
var SERVICE_SCRIPT_PATH = "scripts/service.sh";
|
|
389
389
|
/** Names the shared Vitest global-setup module whose presence makes a workspace `global`. */
|
|
390
390
|
var GLOBAL_SETUP_PATH = "tests/setupGlobal.ts";
|
|
@@ -527,11 +527,29 @@ var MAX_MANIFEST_BYTES = 1048576;
|
|
|
527
527
|
/** Caps the bytes retained across one whole plan or audit. */
|
|
528
528
|
var MAX_TOTAL_ARTIFACT_BYTES = 104857600;
|
|
529
529
|
/** Names the oldest Node version the generated toolchain supports. */
|
|
530
|
-
var MINIMUM_NODE_VERSION = "22.
|
|
530
|
+
var MINIMUM_NODE_VERSION = "22.18.0";
|
|
531
|
+
/** Names the oldest npm version the generated toolchain supports. */
|
|
532
|
+
var MINIMUM_NPM_VERSION = "11.6.0";
|
|
531
533
|
/** Names the version a workspace starts at. */
|
|
532
534
|
var DEFAULT_VERSION = "0.0.1";
|
|
533
535
|
/** Names the `engines.node` range a workspace starts with. */
|
|
534
536
|
var DEFAULT_ENGINES = `>=${MINIMUM_NODE_VERSION}`;
|
|
537
|
+
/**
|
|
538
|
+
* Holds the `devEngines` record every generated manifest carries.
|
|
539
|
+
*
|
|
540
|
+
* @remarks
|
|
541
|
+
* Every generated manifest names npm at the {@link MINIMUM_NPM_VERSION} floor with the `onFail`
|
|
542
|
+
* key set to the `error` value, and no blueprint field varies that record. An npm at 10.9.0 or
|
|
543
|
+
* later reads the `devEngines` record. Such an npm earlier than the floor refuses an install in a
|
|
544
|
+
* generated workspace rather than resolving its dependency graph.
|
|
545
|
+
* The neighbouring `DEFAULT_ENGINES` constant is the Node range, and a blueprint's `engines`
|
|
546
|
+
* field does replace that one.
|
|
547
|
+
*/
|
|
548
|
+
var WORKSPACE_DEV_ENGINES = Object.freeze({ packageManager: Object.freeze({
|
|
549
|
+
name: "npm",
|
|
550
|
+
version: `>=${MINIMUM_NPM_VERSION}`,
|
|
551
|
+
onFail: "error"
|
|
552
|
+
}) });
|
|
535
553
|
/** Holds the tooling versions scaffold and every generated workspace share. */
|
|
536
554
|
var BASE_DEV_DEPENDENCIES = Object.freeze({
|
|
537
555
|
"@orkestrel/guide": package_default.devDependencies["@orkestrel/guide"],
|
|
@@ -936,9 +954,9 @@ export const conformance = (): UserConfig => ({
|
|
|
936
954
|
},
|
|
937
955
|
})
|
|
938
956
|
`,
|
|
939
|
-
service: `// The live external services this
|
|
940
|
-
// \`
|
|
941
|
-
//
|
|
957
|
+
service: `// The caller prepares the live external services before this project.
|
|
958
|
+
// \`tests/setupService.ts\` verifies readiness, and the project stays out of \`npm test\`
|
|
959
|
+
// because a real service answers it.
|
|
942
960
|
export const service = (): UserConfig => ({
|
|
943
961
|
resolve,
|
|
944
962
|
test: {
|
|
@@ -4287,9 +4305,9 @@ function matchesRange(range, latest) {
|
|
|
4287
4305
|
* ```ts
|
|
4288
4306
|
* import { matchesEngines } from '@orkestrel/scaffold'
|
|
4289
4307
|
*
|
|
4290
|
-
* matchesEngines('>=22.
|
|
4308
|
+
* matchesEngines('>=22.18.0') // true
|
|
4291
4309
|
* matchesEngines('>=20.0.0') // false
|
|
4292
|
-
* matchesEngines('22.
|
|
4310
|
+
* matchesEngines('22.18.0') // false
|
|
4293
4311
|
* ```
|
|
4294
4312
|
*/
|
|
4295
4313
|
function matchesEngines(engines) {
|
|
@@ -4838,6 +4856,7 @@ function blueprintToManifest(blueprint) {
|
|
|
4838
4856
|
devDependencies: blueprintToDevDependencies(blueprint),
|
|
4839
4857
|
...Object.keys(peerDependencies).length > 0 ? { peerDependencies } : {},
|
|
4840
4858
|
...Object.keys(peerDependenciesMeta).length > 0 ? { peerDependenciesMeta } : {},
|
|
4859
|
+
devEngines: WORKSPACE_DEV_ENGINES,
|
|
4841
4860
|
engines: { node: blueprint.engines }
|
|
4842
4861
|
};
|
|
4843
4862
|
return `${JSON.stringify(manifest, void 0, " ")}\n`;
|
|
@@ -6581,7 +6600,7 @@ function overridesToQuestions(overrides, artifacts) {
|
|
|
6581
6600
|
* })
|
|
6582
6601
|
*
|
|
6583
6602
|
* blueprint.version // '0.0.1'
|
|
6584
|
-
* blueprint.engines // '>=22.
|
|
6603
|
+
* blueprint.engines // '>=22.18.0'
|
|
6585
6604
|
* ```
|
|
6586
6605
|
*/
|
|
6587
6606
|
function createBlueprint(name, input) {
|
|
@@ -6964,6 +6983,7 @@ exports.MAX_SCRIPT_LENGTH = MAX_SCRIPT_LENGTH;
|
|
|
6964
6983
|
exports.MAX_TOTAL_ARTIFACT_BYTES = MAX_TOTAL_ARTIFACT_BYTES;
|
|
6965
6984
|
exports.MAX_TOTAL_REGISTRY_BYTES = MAX_TOTAL_REGISTRY_BYTES;
|
|
6966
6985
|
exports.MINIMUM_NODE_VERSION = MINIMUM_NODE_VERSION;
|
|
6986
|
+
exports.MINIMUM_NPM_VERSION = MINIMUM_NPM_VERSION;
|
|
6967
6987
|
exports.NAME_PATTERN = NAME_PATTERN;
|
|
6968
6988
|
exports.ORCHESTRATION_PATH_NAMES = ORCHESTRATION_PATH_NAMES;
|
|
6969
6989
|
exports.ORCHESTRATION_PATH_PREFIXES = ORCHESTRATION_PATH_PREFIXES;
|
|
@@ -6980,6 +7000,7 @@ exports.SRC_MATRIX = SRC_MATRIX;
|
|
|
6980
7000
|
exports.ScaffoldError = ScaffoldError;
|
|
6981
7001
|
exports.TAB_WIDTH = TAB_WIDTH;
|
|
6982
7002
|
exports.VERSION_PATTERN = VERSION_PATTERN;
|
|
7003
|
+
exports.WORKSPACE_DEV_ENGINES = WORKSPACE_DEV_ENGINES;
|
|
6983
7004
|
exports.WORKSPACE_OWNED_PATHS = WORKSPACE_OWNED_PATHS;
|
|
6984
7005
|
exports.applyOverrides = applyOverrides;
|
|
6985
7006
|
exports.artifactToFinding = artifactToFinding;
|