Native Shell
Native Shell:AI 生成的 UI,在你的应用中原生呈现,覆盖每个平台。iOS、Android、macOS、Windows 与 Linux 上的应用、GPUI 应用与网页在运行时加载已签名、沙箱隔离的 TSX 模块并绘制 th
AI 翻译
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A batteries-included scripting runtime in one static binary: download it, run your script.
chirp is Janet, a small, fast Lisp, built together with what real scripts reach for: an HTTPS client and server, JSON, SQLite with full-text search, TOML, YAML, compression, subprocesses, argument parsing, regexes and Markdown. There is one file per platform (Linux x64 and arm64, macOS arm64, Windows x64). It is static, and needs no runtime, package manager or C compiler.
chirp is an unofficial build of Janet. It is not a Janet release and is not made by Janet's maintainers. Please report problems with chirp here, not to Janet.
chirp is young and not yet stable. It is used daily by its authors, but every 0.x release may still change chirp's own interfaces (its command line, yaml, omap) and move the pinned versions of what it bundles. Pin a release if a script must keep working, and read chirp --changelog before updating.
Scripts tend to start small and then need one more thing: an API call, a config file, somewhere to keep state. In most languages that one thing means an install step. Python wants a matching interpreter, a virtualenv and pip. Shell wants curl, jq and sqlite3 to be present, at versions that agree. Stock Janet has no TLS at all, and adding it means a C toolchain and OpenSSL headers on every machine.
chirp removes that step. The batteries are inside the binary, so a script written on a laptop runs unchanged on a fresh server, in a CI job, in a FROM scratch container or on an air-gapped machine. The only setup is copying one file.
chirp --help query searches the docs of every bundled module and of Janet's core, and chirp --changelog says what changed.chirp --self-update installs the latest release only after checking its signature.chirp does not fork Janet or its libraries. It pins upstream versions and bundles them, so Janet's own docs and community apply as they are.
chirp # REPL, like janet
chirp script.janet # run a script, like janet
echo '(print 1)' | chirp # run code from stdin
chirp --version # chirp 0.7.0 (unofficial build, not a Janet release) on Janet …
chirp --help # chirp's entry points, the help topics, then Janet's options
chirp --changelog # what changed in each release, offline
chirp --self-update # replace chirp with the latest signed release (--check only reports)
Inside chirp, every bundled module can be imported without anything on disk:
(import spork-https :as https)
(print ((https/get "https://example.com/") :status))
From 0.2.0, scripts can also keep data in SQLite and read configuration from TOML:
(import sqlite3)
(import tomlin)
(def db (sqlite3/open "notes.db"))
(sqlite3/eval db "CREATE TABLE IF NOT EXISTS notes (body TEXT);")
(print ((tomlin/toml->janet (slurp "config.toml")) :title))
YAML is built in too. yaml/decode and yaml/encode work like json/decode and json/encode, and plain scalars follow the YAML 1.2 Core schema, so no stays a string:
(import yaml)
(def cfg (yaml/decode (slurp "config.yaml") true))
(print (cfg :title))
(print (yaml/encode {:name "chirp" :tags ["a" "b"]}))
A table has no order, so a script that rewrites a JSON or YAML file loses the author's key order. Pass a fourth argument, ordered, to json/decode or yaml/decode (or yaml/decode-all) and every object comes back as an omap, a map that keeps its keys in insertion order. json/encode and yaml/encode write an omap in that order, and a plain table as before:
(import omap)
(import yaml)
(def doc (yaml/decode (slurp "config.yaml") false false true))
(put doc "version" 2) # an existing key keeps its place, a new one goes last
(put doc "obsolete" nil) # nil removes a key
(spit "config.yaml" (yaml/encode doc))
(print (omap/omap? doc) (keys doc)) # keys, get, put, in, pairs, eachp and length work as on a table
An omap is not a table, so table? and dictionary? are false for it and deep= does not compare it; a function that does not know the type fails loudly instead of dropping the order.
From 0.4.0, pcre2 brings Perl-style regular expressions, the syntax that grep, sed and Python documentation use. A pattern is a string, or compiled once with pcre2/compile:
(import pcre2)
(pcre2/match "(?<year>\\d{4})-(?<mon>\\d\\d)" "on 2026-10-27") # {0 "2026-10" 1 "2026" 2 "10" :mon "10" :year "2026"}
(pcre2/replace-all "(\\w+)@(\\w+)" "a@b c@d" "$2:$1") # "b:a d:c"
(pcre2/split ",\\s*" "a, b,c") # @["a" "b" "c"]
(pcre2/find-all "\\d+" "1 22 333") # an array of matches
Matching is bounded by counts instead of time (:match-limit, :depth-limit and :heap-limit, all with defaults), so a pattern that backtracks without end stops with an error that names the limit, the same way on every machine. chirp --help query pcre2 lists the functions and their options.
From 0.4.0, md4c renders Markdown to HTML. The default is plain CommonMark; :github adds tables, strikethrough, task lists, autolinks, admonitions and footnotes, and each extension can also be set on its own:
(import md4c)
(md4c/to-html "# Hi\n\n*a* `b`") # "<h1>Hi</h1>\n<p><em>a</em> <code>b</code></p>\n"
(md4c/to-html (slurp "README.md") {:github true}) # the body only, without <html> or <head>
Raw HTML in the input is passed through, as CommonMark says, so pass :no-html true for text you do not trust. chirp --help query md4c lists the options.
From 0.4.0, lexbor parses HTML the way a browser does and finds elements with CSS selectors, for example to check what a deployed site serves:
(import lexbor)
(def page (lexbor/parse (slurp "out/site/index.html")))
(map |(lexbor/attr $ "href") (lexbor/select page "nav a[href]")) # in document order
(lexbor/text (lexbor/select-first page "h1")) # nil when nothing matches
A node is a handle into its document, so it can be searched in turn ((lexbor/select node "li")), and lexbor/html gives its markup back. chirp --help query lexbor lists the functions.
From 0.7.0, gzip reads and writes .gz data and tar lists, extracts and creates tar archives, gzipped or not, so a release can be fetched and unpacked on a host without tar:
(import spork-https :as https)
(import tar)
(def s (https/open-stream "https://github.com/roobie/chirp/archive/refs/heads/main.tar.gz"))
(tar/extract s "chirp-main" {:strip 1}) # streamed; refuses entries that would land outside
(:close s)
(tar/create "notes.tar.gz" ["notes"]) # gzipped, from the name
chirp --help read archives covers both, including what extraction refuses.
chirp -h lists the help topics, chirp --help query '<words>' searches them and the docstrings of every bundled module offline, and chirp --help read <id> prints a result in full. The text is inside the binary. chirp --help serve shows the same help in a browser at http://127.0.0.1:3111/.
Each component is pinned to an exact upstream commit in pins.jdn. None of them is forked.
| Component | What it adds | License |
|---|---|---|
| Janet | the language and runtime | MIT |
| spork | the standard library extras, including spork/http and spork/zip (zlib and zip, via miniz) | MIT |
| jsec | TLS and DTLS streams for ev, certificates, crypto | ISC |
| spork-https | an HTTPS client and server on top of spork/http | ISC |
| janet-lang/sqlite3 | sqlite3, Janet bindings to an embedded SQLite (the amalgamation, so no system library is needed), with FTS5 full-text search enabled; from 0.2.0 | MIT (binding), public domain (SQLite) |
| tomlin | tomlin, a TOML parser written in Janet; from 0.2.0 | MIT |
| libyaml | yaml, YAML parsing and emitting: chirp's own small binding over libyaml 0.2.5, with Core schema scalars, anchors, aliases and merge keys; from 0.3.0 | MIT |
| PCRE2 | pcre2, Perl-style regular expressions: chirp's own small binding over PCRE2 10.49 (interpreter only, no JIT), with named groups, replacement with group references and split; from 0.4.0 | BSD-3-Clause with the PCRE2 exception |
| md4c |
Every release ships a NOTICES-<target>.txt with the full license texts of everything linked into that target's binary.
Releases are on the releases page. Each release has:
| Asset | For |
|---|---|
chirp-<version>-linux-x64 | Linux x86-64, static (musl), any distribution |
chirp-<version>-linux-arm64 | Linux arm64, static (musl), any distribution |
chirp-<version>-macos-arm64 | macOS 11+ on Apple silicon |
chirp-<version>-windows-x64.exe | Windows x64 |
NOTICES-<target>.txt | third-party license texts for that binary |
SHA256SUMS | the sha256 of every asset |
SHA256SUMS.sig | Ed25519 signature of SHA256SUMS, checked by chirp --self-update |
On Linux and macOS, make the binary executable with chmod +x. macOS binaries are signed ad hoc, not by an Apple developer ID, so a downloaded one is quarantined. After verifying it, remove the quarantine flag with xattr -d com.apple.quarantine chirp-<version>-macos-arm64.
Every binary is built twice by CI, in different directories on different runners, and the release is only published when both builds produce the same sha256. Two checks tell you that a download is the file CI built.
The checksum. Download SHA256SUMS next to the binary, then run:
sha256sum -c SHA256SUMS --ignore-missing # Linux
shasum -a 256 -c SHA256SUMS --ignore-missing # macOS
The build provenance. GitHub attests which workflow run and commit produced each asset. With the GitHub CLI:
gh attestation verify chirp-<version>-linux-x64 --repo roobie/chirp
Because the build is reproducible, you can also rebuild a release from its tag with sh tools/build/container.sh <target> <outdir> (this needs Docker) and compare the hashes.
chirp checks certificates by default. At startup it uses SSL_CERT_FILE if that is set. Otherwise it looks for the system's CA bundle in the usual Linux and macOS locations, and chirp --version shows which bundle it found.
Windows has no CA bundle file, so for now HTTPS on Windows needs SSL_CERT_FILE. Point it at a PEM bundle, for example the curl CA bundle or the ca-bundle.crt that ships with Git for Windows (in ucrt64 in current versions, mingw64 in older ones):
$env:SSL_CERT_FILE = "C:\Program Files\Git\ucrt64\etc\ssl\certs\ca-bundle.crt"
A later release will embed a pinned CA bundle as a fallback.
From 0.2.0, chirp layers two fixes over the bundled spork-https client, without forking it:
User-Agent header sends User-Agent: chirp/<version>, because some services, GitHub's API among them, reject requests without one. A User-Agent you set is sent unchanged.:tls-opts {:ca "ca.pem"} makes the client trust that CA, as the spork-https docs describe. jsec's client otherwise ignores :ca and falls back to the system store.The server is unchanged.
The build needs Docker. It runs in a container image pinned by digest in pins.jdn (Alpine plus the packages in tools/build/packages.txt), which Docker pulls from a public registry. zig cross-compiles every target from Linux:
sh tools/build/container.sh linux-x64 out/ # or linux-arm64, macos-arm64, windows-x64
The targets are defined in tools/build/config.jdn.
The website is generated by chirp from this repo's Markdown: chirp site/build.janet writes it to out/site/. The chirp must bundle md4c, from 0.4.0. The pages workflow publishes it after each release. chirp site/check.janet <dir|url> checks a built or deployed site with lexbor, by its structure rather than its text: navigation, unique ids, links and their fragments, the stylesheet, and the commit and chirp version in each footer. The workflow runs it on out/site before upload, and on the live site after deploy.
chirp's own code is under the MIT license. Bundled components keep their own licenses; see the table above and the release notices.
md4c, Markdown to HTML: chirp's own small binding over md4c 0.6.0's renderer, CommonMark by default with GitHub's extensions on request; from 0.4.0 |
| MIT |
| lexbor | lexbor, HTML parsing and CSS selectors: chirp's own small binding over lexbor 3.0.1's HTML, DOM and selectors modules; from 0.4.0 | Apache-2.0 |
| chirp itself | gzip, gzip framing over spork's miniz, whole or in pieces, and tar, tar archives in Janet, extracted safely; from 0.7.0 | MIT |
| chirp itself | omap, an insertion-ordered map that yaml and json can decode to and encode from; written in C for chirp, with json-omap, a copy of spork's JSON decoder that builds it; from 0.3.0 | MIT |
| OpenSSL 3 | statically linked under jsec | Apache-2.0 |