@claudinite/cli 0.0.0 → 1.61005.3

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.
@@ -0,0 +1,124 @@
1
+ The cn binaries include the following third-party Go modules, under these terms.
2
+
3
+ == github.com/BurntSushi/toml v1.6.0 ==
4
+
5
+ --- COPYING ---
6
+
7
+ The MIT License (MIT)
8
+
9
+ Copyright (c) 2013 TOML authors
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in
19
+ all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
+ THE SOFTWARE.
28
+
29
+ == github.com/dlclark/regexp2 v1.12.0 ==
30
+
31
+ --- LICENSE ---
32
+
33
+ The MIT License (MIT)
34
+
35
+ Copyright (c) Doug Clark
36
+
37
+ Permission is hereby granted, free of charge, to any person obtaining a copy
38
+ of this software and associated documentation files (the "Software"), to deal
39
+ in the Software without restriction, including without limitation the rights
40
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
41
+ copies of the Software, and to permit persons to whom the Software is
42
+ furnished to do so, subject to the following conditions:
43
+
44
+ The above copyright notice and this permission notice shall be included in all
45
+ copies or substantial portions of the Software.
46
+
47
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
50
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
53
+ SOFTWARE.
54
+
55
+ == go.yaml.in/yaml/v3 v3.0.5 ==
56
+
57
+ --- LICENSE ---
58
+
59
+
60
+ This project is covered by two different licenses: MIT and Apache.
61
+
62
+ #### MIT License ####
63
+
64
+ The following files were ported to Go from C files of libyaml, and thus
65
+ are still covered by their original MIT license, with the additional
66
+ copyright staring in 2011 when the project was ported over:
67
+
68
+ apic.go emitterc.go parserc.go readerc.go scannerc.go
69
+ writerc.go yamlh.go yamlprivateh.go
70
+
71
+ Copyright (c) 2006-2010 Kirill Simonov
72
+ Copyright (c) 2006-2011 Kirill Simonov
73
+
74
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
75
+ this software and associated documentation files (the "Software"), to deal in
76
+ the Software without restriction, including without limitation the rights to
77
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
78
+ of the Software, and to permit persons to whom the Software is furnished to do
79
+ so, subject to the following conditions:
80
+
81
+ The above copyright notice and this permission notice shall be included in all
82
+ copies or substantial portions of the Software.
83
+
84
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
85
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
86
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
87
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
88
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
89
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
90
+ SOFTWARE.
91
+
92
+ ### Apache License ###
93
+
94
+ All the remaining project files are covered by the Apache license:
95
+
96
+ Copyright (c) 2011-2019 Canonical Ltd
97
+
98
+ Licensed under the Apache License, Version 2.0 (the "License");
99
+ you may not use this file except in compliance with the License.
100
+ You may obtain a copy of the License at
101
+
102
+ http://www.apache.org/licenses/LICENSE-2.0
103
+
104
+ Unless required by applicable law or agreed to in writing, software
105
+ distributed under the License is distributed on an "AS IS" BASIS,
106
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
107
+ See the License for the specific language governing permissions and
108
+ limitations under the License.
109
+
110
+ --- NOTICE ---
111
+
112
+ Copyright 2011-2016 Canonical Ltd.
113
+
114
+ Licensed under the Apache License, Version 2.0 (the "License");
115
+ you may not use this file except in compliance with the License.
116
+ You may obtain a copy of the License at
117
+
118
+ http://www.apache.org/licenses/LICENSE-2.0
119
+
120
+ Unless required by applicable law or agreed to in writing, software
121
+ distributed under the License is distributed on an "AS IS" BASIS,
122
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123
+ See the License for the specific language governing permissions and
124
+ limitations under the License.
package/launch ADDED
@@ -0,0 +1,357 @@
1
+ #!/bin/sh
2
+ # Claudinite launcher. A member checks this file in as .claudinite/launch,
3
+ # unchanged; only the engine update replaces it.
4
+ #
5
+ # sh .claudinite/launch <cn arguments> fetch, verify and cache the pinned engine, then run it
6
+ # sh .claudinite/launch env install fetch, verify and cache only (environment pre-warm)
7
+ #
8
+ # It reads engine.version and engine.manifest from .claudinite/settings.yaml,
9
+ # .toml or .json, downloads that release's manifest.json and this platform's
10
+ # binary from the npm registry, checks the manifest against the pin and the
11
+ # binary against the manifest, caches the binary read-only, links
12
+ # .claudinite/bin/cn to it and execs it. Nothing is trusted that the pin
13
+ # does not cover; the registry's identity is immaterial to integrity.
14
+ #
15
+ # Only SessionStart and the Actions download step invoke it; every other hook
16
+ # runs .claudinite/bin/cn directly. Wired to Stop, its exit 2 on a refusal
17
+ # blocks the stop, and the next stop attempt hits it again, in a loop.
18
+ #
19
+ # Bootstrap: the @claudinite/cli packages carry this file as their bin, so
20
+ # `npx --yes @claudinite/cli init --packs ...` runs it from the package
21
+ # npx unpacked, through a symlink. Run with init and no settings file beside
22
+ # it, it takes the version and the binary's hash from the package's own
23
+ # manifest.json, fetches and checks the binary as above, caches it with the
24
+ # manifest and manifest.sig.json, and execs cn init, which verifies that
25
+ # signature before it writes anything. Windows is not covered: npm's shim
26
+ # for a sh script there is the desktop work.
27
+ #
28
+ # CLAUDINITE_REGISTRY overrides the registry and CLAUDINITE_MAX_DOWNLOAD_BYTES
29
+ # the download size cap; both exist for tests and the rehearsal.
30
+ set -u
31
+
32
+ registry=${CLAUDINITE_REGISTRY:-https://registry.npmjs.org}
33
+ max_bytes=${CLAUDINITE_MAX_DOWNLOAD_BYTES:-67108864}
34
+
35
+ if [ "${GITHUB_ACTIONS:-}" = true ]; then
36
+ context=actions
37
+ elif [ "${1:-}" = hook ] && [ "${2:-}" = session-start ]; then
38
+ context=session-start
39
+ elif [ "${1:-}" = hook ]; then
40
+ context=guard
41
+ else
42
+ context="command"
43
+ fi
44
+
45
+ tmp=
46
+ cleanup() {
47
+ if [ -n "$tmp" ]; then
48
+ chmod -R u+w "$tmp" 2>/dev/null
49
+ rm -rf "$tmp"
50
+ tmp=
51
+ fi
52
+ }
53
+ trap cleanup EXIT
54
+ trap 'cleanup; exit 1' HUP INT TERM
55
+
56
+ say() {
57
+ printf 'claudinite launch: %s\n' "$*" >&2
58
+ }
59
+
60
+ # A configuration or integrity failure: the engine never runs.
61
+ refuse() {
62
+ cleanup
63
+ say "$1"
64
+ case $context in
65
+ session-start)
66
+ printf 'Claudinite refused to run its engine: %s: stop and ask the person before continuing.\n' "$1"
67
+ exit 0 ;;
68
+ guard) exit 2 ;;
69
+ *) exit 1 ;;
70
+ esac
71
+ }
72
+
73
+ # The registry could not be reached; nothing verified is cached.
74
+ unreachable() {
75
+ cleanup
76
+ case $context in
77
+ session-start)
78
+ say "could not fetch $1"
79
+ printf 'Claudinite could not fetch its engine from %s: stop and ask the person before continuing.\n' "$1"
80
+ exit 0 ;;
81
+ guard)
82
+ say "could not fetch the engine from $1; continuing without it, and SessionStart will say so again"
83
+ exit 0 ;;
84
+ *)
85
+ say "could not fetch the engine from $1"
86
+ exit 1 ;;
87
+ esac
88
+ }
89
+
90
+ matches() {
91
+ printf '%s\n' "$1" | grep -Eqx "$2"
92
+ }
93
+
94
+ # Step 1: the pin, from exactly one settings file.
95
+
96
+ here=$(cd "$(dirname "$0")" && pwd) || refuse "cannot locate the .claudinite folder"
97
+ format=
98
+ count=0
99
+ for ext in yaml toml json; do
100
+ if [ -f "$here/settings.$ext" ]; then
101
+ format=$ext
102
+ count=$((count + 1))
103
+ fi
104
+ done
105
+
106
+ # The bootstrap reads the package npx unpacked: resolve the bin symlink.
107
+ bootstrap=
108
+ if [ "$count" -eq 0 ] && [ "${1:-}" = init ]; then
109
+ self=$0
110
+ while [ -L "$self" ]; do
111
+ link=$(readlink "$self") || break
112
+ case $link in
113
+ /*) self=$link ;;
114
+ *) self=$(dirname "$self")/$link ;;
115
+ esac
116
+ done
117
+ pkgdir=$(cd "$(dirname "$self")" && pwd) || refuse "cannot locate the package folder"
118
+ if [ -f "$pkgdir/manifest.json" ] && [ -f "$pkgdir/package.json" ]; then
119
+ bootstrap=1
120
+ fi
121
+ fi
122
+
123
+ if [ -n "$bootstrap" ]; then
124
+ settings=$pkgdir/manifest.json
125
+ [ -f "$pkgdir/manifest.sig.json" ] || refuse "$pkgdir holds no manifest.sig.json, and cn init never runs from an unsigned manifest"
126
+ else
127
+ [ "$count" -eq 1 ] || refuse "exactly one of .claudinite/settings.yaml, .claudinite/settings.toml or .claudinite/settings.json must exist, found $count"
128
+ settings=$here/settings.$format
129
+ fi
130
+
131
+ if [ "$format" = json ] && [ -z "$bootstrap" ]; then
132
+ engines=$(tr -d '\r\n' < "$settings" | grep -o '"engine"[[:blank:]]*:' | wc -l | tr -d ' ')
133
+ [ "$engines" -eq 1 ] || refuse "$settings must hold exactly one \"engine\" object, found $engines"
134
+ fi
135
+
136
+ # The lines of the engine block, one key per line. No parser: the values the
137
+ # launcher needs are plain quoted strings, read with a strict pattern.
138
+ engine_block() {
139
+ case $format in
140
+ yaml) awk '/^engine:[ \t]*$/ { inb = 1; next } inb && /^[^ \t]/ { inb = 0 } inb { print }' "$settings" ;;
141
+ toml) awk '/^\[engine\][ \t]*$/ { inb = 1; next } inb && /^[ \t]*\[/ { inb = 0 } inb { print }' "$settings" ;;
142
+ json) tr -d '\r\n' < "$settings" | sed -n 's/.*"engine"[[:blank:]]*:[[:blank:]]*{\([^{}]*\)}.*/\1/p' | tr ',' '\n' ;;
143
+ esac
144
+ }
145
+
146
+ # engine_value KEY: the key's quoted string, or empty when the key is absent.
147
+ # A key present twice, or not holding a plain quoted string, is refused.
148
+ engine_value() {
149
+ case $format in toml) sep='=' ;; *) sep=':' ;; esac
150
+ lines=$(engine_block | grep -E "^[[:blank:]]*\"?$1\"?[[:blank:]]*${sep}")
151
+ [ -z "$lines" ] && return 0
152
+ [ "$(printf '%s\n' "$lines" | wc -l | tr -d ' ')" -eq 1 ] || { echo "duplicate"; return 0; }
153
+ value=$(printf '%s\n' "$lines" | sed -n "s/^[[:blank:]]*\"\{0,1\}$1\"\{0,1\}[[:blank:]]*${sep}[[:blank:]]*\"\([^\"]*\)\"[[:blank:]]*\$/\1/p")
154
+ [ -n "$value" ] || value=malformed
155
+ printf '%s\n' "$value"
156
+ }
157
+
158
+ if [ -n "$bootstrap" ]; then
159
+ # The version and package as the package npx unpacked names them; the
160
+ # manifest's own hash stands in for the pin.
161
+ version=$(sed -n 's/^ *"version": *"\([0-9]*\.[0-9]*\.[0-9]*\)",\{0,1\}$/\1/p' "$pkgdir/manifest.json" | head -n 1)
162
+ package=$(sed -n 's/^ *"name": *"\(@claudinite\/cli[-a-z]*\)",\{0,1\}$/\1/p' "$pkgdir/package.json" | head -n 1)
163
+ matches "$version" '[0-9]+\.[0-9]+\.[0-9]+' || refuse "$pkgdir/manifest.json names no version"
164
+ matches "$package" '@claudinite/cli(-rc)?' \
165
+ || refuse "$pkgdir/package.json must name \"@claudinite/cli\" or \"@claudinite/cli-rc\""
166
+ else
167
+ version=$(engine_value version)
168
+ manifest_pin=$(engine_value manifest)
169
+ package=$(engine_value package)
170
+ [ -n "$package" ] || package=@claudinite/cli
171
+
172
+ matches "$version" '[0-9]+\.[0-9]+\.[0-9]+' \
173
+ || refuse "engine.version in $settings must be a quoted version like \"1.60928.1\""
174
+ matches "$manifest_pin" 'sha512-[A-Za-z0-9+/]{86}==' \
175
+ || refuse "engine.manifest in $settings must be a quoted sha512-... integrity string"
176
+ matches "$package" '@claudinite/cli(-rc)?' \
177
+ || refuse "engine.package in $settings must be \"@claudinite/cli\" or \"@claudinite/cli-rc\""
178
+ fi
179
+
180
+ case $(uname -s) in
181
+ Linux) os=linux ;;
182
+ Darwin) os=darwin ;;
183
+ MINGW*|MSYS*|CYGWIN*) os=windows ;;
184
+ *) refuse "unsupported operating system $(uname -s)" ;;
185
+ esac
186
+ case $(uname -m) in
187
+ x86_64|amd64) arch=x64 ;;
188
+ aarch64|arm64) arch=arm64 ;;
189
+ *) refuse "unsupported processor $(uname -m)" ;;
190
+ esac
191
+ bin=cn
192
+ bin_re=cn
193
+ if [ "$os" = windows ]; then
194
+ [ "$arch" = x64 ] || refuse "unsupported platform windows-$arch"
195
+ bin=cn.exe
196
+ bin_re='cn\.exe'
197
+ fi
198
+ platform=$os-$arch
199
+
200
+ if command -v sha256sum >/dev/null 2>&1; then
201
+ sha256() { sha256sum < "$1" | cut -d' ' -f1; }
202
+ sha512() { sha512sum < "$1" | cut -d' ' -f1; }
203
+ elif command -v shasum >/dev/null 2>&1; then
204
+ sha256() { shasum -a 256 < "$1" | cut -d' ' -f1; }
205
+ sha512() { shasum -a 512 < "$1" | cut -d' ' -f1; }
206
+ elif command -v openssl >/dev/null 2>&1; then
207
+ sha256() { openssl dgst -sha256 < "$1" | sed 's/.*= *//'; }
208
+ sha512() { openssl dgst -sha512 < "$1" | sed 's/.*= *//'; }
209
+ else
210
+ refuse "no SHA-256 tool found (sha256sum, shasum or openssl)"
211
+ fi
212
+ for tool in curl tar; do
213
+ command -v "$tool" >/dev/null 2>&1 || refuse "$tool is not installed; the launcher needs it to fetch the engine"
214
+ done
215
+
216
+ # The pin's SHA-512 as lowercase hex, to compare with the hash tools' output;
217
+ # the bootstrap's pin is the hash of the manifest npx unpacked.
218
+ if [ -n "$bootstrap" ]; then
219
+ pin_hex=$(sha512 "$pkgdir/manifest.json")
220
+ else
221
+ pin_hex=$(printf '%s\n' "${manifest_pin#sha512-}" | awk '
222
+ BEGIN {
223
+ a = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
224
+ for (i = 0; i < 64; i++) v[substr(a, i + 1, 1)] = i
225
+ h = "0123456789abcdef"
226
+ }
227
+ {
228
+ bits = 0; nb = 0; out = ""
229
+ for (i = 1; i <= length($0); i++) {
230
+ c = substr($0, i, 1)
231
+ if (c == "=") break
232
+ bits = bits * 64 + v[c]; nb += 6
233
+ if (nb >= 8) {
234
+ nb -= 8; p = 2 ^ nb
235
+ byte = int(bits / p); bits -= byte * p
236
+ out = out substr(h, int(byte / 16) + 1, 1) substr(h, byte % 16 + 1, 1)
237
+ }
238
+ }
239
+ print out
240
+ }')
241
+ fi
242
+
243
+ # This platform's SHA-256 from a manifest.json whose hash matched the pin.
244
+ manifest_entry() {
245
+ sed -n "s/^ *\"$platform\": {\"file\": \"$bin_re\", \"sha256\": \"\([0-9a-f]\{64\}\)\", \"size\": [0-9]*},\{0,1\}\$/\1/p" "$1"
246
+ }
247
+
248
+ # Step 2: the cache, re-hashed on every run.
249
+
250
+ if [ -z "${XDG_CACHE_HOME:-}" ] && [ -z "${HOME:-}" ]; then
251
+ refuse "HOME is not set, so there is no cache folder (set HOME or XDG_CACHE_HOME)"
252
+ fi
253
+ cache_root=${XDG_CACHE_HOME:-$HOME/.cache}/claudinite
254
+ vdir=$cache_root/$version
255
+
256
+ private_dir() {
257
+ if [ ! -d "$1" ]; then
258
+ (umask 077 && mkdir -p "$1") || refuse "cannot create the cache directory $1"
259
+ fi
260
+ [ -L "$1" ] && refuse "the cache directory $1 is a symbolic link"
261
+ [ "$os" = windows ] && return 0
262
+ # shellcheck disable=SC2012 # ls -ldn is the portable way to read mode and uid
263
+ set -- "$1" "$(ls -ldn "$1" | awk '{ print $1 " " $3 }')"
264
+ case $2 in
265
+ "drwx------ $(id -u)"|"drwx------. $(id -u)"|"drwx------+ $(id -u)"|"drwx------@ $(id -u)") ;;
266
+ *) refuse "the cache directory $1 must be mode 0700 and owned by you (found ${2% *})" ;;
267
+ esac
268
+ }
269
+ private_dir "$cache_root"
270
+ private_dir "$vdir"
271
+
272
+ cached_ok() {
273
+ [ -f "$vdir/manifest.json" ] && [ -f "$vdir/$bin" ] || return 1
274
+ [ "$(sha512 "$vdir/manifest.json")" = "$pin_hex" ] || return 1
275
+ want=$(manifest_entry "$vdir/manifest.json")
276
+ [ -n "$want" ] && [ "$(sha256 "$vdir/$bin")" = "$want" ]
277
+ }
278
+
279
+ if ! cached_ok; then
280
+ chmod u+w "$vdir/manifest.json" "$vdir/$bin" 2>/dev/null
281
+ rm -f "$vdir/manifest.json" "$vdir/$bin"
282
+
283
+ # Step 3: download by exact tarball URL, HTTPS only, with a size cap.
284
+
285
+ matches "$max_bytes" '[0-9]+' || refuse "CLAUDINITE_MAX_DOWNLOAD_BYTES must be a number"
286
+ # A whole transfer may take as long as the cap at about 220 kB/s, and never
287
+ # less than 30 s: the 64 MiB default allows about 300 s. --max-filesize
288
+ # bounds only the compressed size, so the wall clock is what stops a
289
+ # registry that stalls or trickles.
290
+ max_time=$((max_bytes / 220000))
291
+ [ "$max_time" -ge 30 ] || max_time=30
292
+ tmp=$(mktemp -d "$vdir/.download.XXXXXX") || refuse "cannot create a temporary folder in $vdir"
293
+
294
+ fetch() {
295
+ curl --proto =https --proto-redir =https --tlsv1.2 --fail --silent --show-error --location \
296
+ --connect-timeout 20 --max-time "$max_time" --max-filesize "$max_bytes" --output "$2" "$1" < /dev/null
297
+ status=$?
298
+ if [ "$status" -eq 63 ]; then
299
+ refuse "$1 is larger than the $max_bytes-byte download cap"
300
+ elif [ "$status" -ne 0 ]; then
301
+ unreachable "$1"
302
+ fi
303
+ size=$(wc -c < "$2" | tr -d ' ')
304
+ [ "$size" -le "$max_bytes" ] || refuse "$1 is larger than the $max_bytes-byte download cap"
305
+ }
306
+
307
+ name=${package#@claudinite/}
308
+ manifest_url=$registry/$package/-/$name-$version.tgz
309
+ binary_url=$registry/$package-$platform/-/$name-$platform-$version.tgz
310
+
311
+ fetch "$manifest_url" "$tmp/manifest.tgz"
312
+ tar -xzf "$tmp/manifest.tgz" -C "$tmp" package/manifest.json 2>/dev/null \
313
+ || refuse "$manifest_url holds no package/manifest.json"
314
+
315
+ # Step 4: the manifest against the pin, the binary against the manifest.
316
+
317
+ [ "$(sha512 "$tmp/package/manifest.json")" = "$pin_hex" ] \
318
+ || refuse "manifest.json of $package $version does not match the pin in $settings"
319
+ want=$(manifest_entry "$tmp/package/manifest.json")
320
+ [ -n "$want" ] || refuse "$package $version lists no binary for $platform"
321
+
322
+ mkdir "$tmp/platform" || refuse "cannot unpack into $tmp"
323
+ fetch "$binary_url" "$tmp/platform.tgz"
324
+ tar -xzf "$tmp/platform.tgz" -C "$tmp/platform" "package/bin/$bin" 2>/dev/null \
325
+ || refuse "$binary_url holds no package/bin/$bin"
326
+ [ "$(sha256 "$tmp/platform/package/bin/$bin")" = "$want" ] \
327
+ || refuse "the $platform binary of $package $version does not match its manifest entry"
328
+
329
+ if ! { chmod 0555 "$tmp/platform/package/bin/$bin" && chmod 0444 "$tmp/package/manifest.json" \
330
+ && mv -f "$tmp/platform/package/bin/$bin" "$vdir/$bin" \
331
+ && mv -f "$tmp/package/manifest.json" "$vdir/manifest.json"; }; then
332
+ refuse "cannot place the engine in $vdir"
333
+ fi
334
+ cleanup
335
+ fi
336
+
337
+ if [ "${1:-}" = env ] && [ "${2:-}" = install ] && [ "$#" -eq 2 ]; then
338
+ exit 0
339
+ fi
340
+
341
+ if [ -n "$bootstrap" ]; then
342
+ chmod u+w "$vdir/manifest.sig.json" 2>/dev/null
343
+ { cp "$pkgdir/manifest.sig.json" "$vdir/.manifest.sig.json.$$" && chmod 0444 "$vdir/.manifest.sig.json.$$" \
344
+ && mv -f "$vdir/.manifest.sig.json.$$" "$vdir/manifest.sig.json"; } || refuse "cannot place manifest.sig.json in $vdir"
345
+ exec "$vdir/$bin" "$@"
346
+ fi
347
+
348
+ # Step 5: link, unpack, run.
349
+
350
+ mkdir -p "$here/bin" || refuse "cannot create $here/bin"
351
+ if ! ln -sfn "$vdir/$bin" "$here/bin/$bin" 2>/dev/null; then
352
+ rm -f "$here/bin/$bin"
353
+ cp "$vdir/$bin" "$here/bin/$bin" || refuse "cannot link or copy the engine into $here/bin"
354
+ fi
355
+ # Unpacking the embedded runner script and SDK beside the binary is a no-op
356
+ # until the engine embeds them (no pack JavaScript runs yet).
357
+ exec "$vdir/$bin" "$@"
package/manifest.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "v": 1,
3
- "version": "0.0.0",
4
- "builtAt": "2026-10-01T17:37:42Z",
5
- "commit": "4e710d8",
3
+ "version": "1.61005.3",
4
+ "builtAt": "2026-10-05T18:31:57Z",
5
+ "commit": "3ac2351",
6
6
  "goVersion": "go1.24.13",
7
- "updaterDigest": "3b00a54c0a754de7bcae2eb9e4f98c157f45cb75b23e866f000bd40603af031f",
7
+ "updaterDigest": "13c58fc7dcdac425f220f5b84d2c15e9af019b5869046c664f06c45b39902702",
8
8
  "binaries": {
9
- "linux-x64": {"file": "cn", "sha256": "936a44a86f5f35771842523344fb6450f046a72d57a5624d03f423a857b4231e", "size": 6611128},
10
- "linux-arm64": {"file": "cn", "sha256": "beb4625974869a676eaa908bfc9c64b93e2e36b4d95c422313056cb3082d479b", "size": 6226104},
11
- "darwin-x64": {"file": "cn", "sha256": "791177f2363233590df4f0fb1f65b2d809c4dc9c153cedf2ee5fb83f34f26978", "size": 6766672},
12
- "darwin-arm64": {"file": "cn", "sha256": "56763f3b7eb558e1cc4093af7873616ea0aac3a33eca8f7995672ea275b57bbc", "size": 6369458},
13
- "windows-x64": {"file": "cn.exe", "sha256": "6129cb5515ab9307fbd13fbfaa6a6bd8c284463d6a0498ca0b7d1643f0cae5c8", "size": 6800896}
9
+ "linux-x64": {"file": "cn", "sha256": "e4be04505e5fff899a8eb8416d94c5f847ecbf043874f0143f08f0748dc25009", "size": 11743416},
10
+ "linux-arm64": {"file": "cn", "sha256": "8763455725077581879875143ec70433bdc83c0b87393cdf6cac6dc8cff34108", "size": 10879160},
11
+ "darwin-x64": {"file": "cn", "sha256": "3ff3c2e1eca553b9cf2c64729a2bca7944768045d8f411536a4b31be045111cd", "size": 11988416},
12
+ "darwin-arm64": {"file": "cn", "sha256": "94fe262c147cbd0001f6c6226ad76d8f701c468bf23d273a0a4fad7a186b3376", "size": 11091218},
13
+ "windows-x64": {"file": "cn.exe", "sha256": "0579a6e0b7853fe4eab6e54be70d53e0551398732a0cee0e3d8f2b3dd4409264", "size": 12019712}
14
14
  },
15
15
  "testedPacks": {}
16
16
  }
@@ -0,0 +1,7 @@
1
+ {
2
+ "certificate": {
3
+ "payload": "eyJ2IjoxLCJrZXlJZCI6ImM3NzQwNWM2ZDA4NzExODYiLCJwdWJsaWNLZXkiOiI0UHlTQzRTbG5MakJ1cVY2Qll4eU9XWUtLOWkzV295NkZCQ1ZNckF6clRzIiwidXNlIjoibWFuaWZlc3QiLCJpc3N1ZXIiOiJlYTg1ZjM1NDIxZjM3NWZjIiwibm90QmVmb3JlIjoiMjAyNi0xMC0wM1QxNjozNjozN1oiLCJub3RBZnRlciI6IjIwMjctMTAtMDNUMTY6MzY6MzdaIn0",
4
+ "signature": "ex4GNEE3PIUj3Ue6X2TZnbB5E6G-DVrGNaYdvI13NuOauoJYilB_54TyAH490IS9-IZiu3BKVYpigm3uDTXSBw"
5
+ },
6
+ "signature": "pj-D8AeXayFHBJWSqOMFZKeaEf0Xz2Y0sRkgaPkA7ERgFsnvTRyKAwenli2a22N1WZa0NyW8xw3TP2mLECIWBw"
7
+ }
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@claudinite/cli",
3
- "version": "0.0.0",
4
- "description": "Claudinite engine release manifest",
3
+ "version": "1.61005.3",
4
+ "description": "Claudinite engine release manifest and launcher",
5
5
  "license": "UNLICENSED",
6
- "repository": "github:missingbulb/ClaudiniteEngine"
6
+ "repository": {"type": "git", "url": "git+https://github.com/missingbulb/ClaudiniteEngine.git"},
7
+ "bin": {"cn": "launch"}
7
8
  }