diff --git a/Makefile b/Makefile
index c5cf66f4ee..ae67144cf3 100644
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,7 @@ include llamafile/BUILD.mk
include llama.cpp/BUILD.mk
include stable-diffusion.cpp/BUILD.mk
include whisper.cpp/BUILD.mk
+include jamfile/BUILD.mk
# the root package is `o//` by default
# building a package also builds its sub-packages
diff --git a/jamfile/.clang-format b/jamfile/.clang-format
new file mode 100644
index 0000000000..e2f7fba042
--- /dev/null
+++ b/jamfile/.clang-format
@@ -0,0 +1,12 @@
+---
+BasedOnStyle: LLVM
+IndentWidth: 4
+ColumnLimit: 100
+---
+Language: Cpp
+AllowShortFunctionsOnASingleLine: false
+AlignTrailingComments: false
+AlignEscapedNewlines: DontAlign
+AlwaysBreakTemplateDeclarations: true
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+---
diff --git a/jamfile/BUILD.mk b/jamfile/BUILD.mk
new file mode 100644
index 0000000000..e715511430
--- /dev/null
+++ b/jamfile/BUILD.mk
@@ -0,0 +1,140 @@
+#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
+#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
+
+PKGS += LLAMA_CPP_JAMFILE
+
+LLAMA_CPP_JAMFILE_FILES := $(wildcard jamfile/*)
+LLAMA_CPP_JAMFILE_HDRS = $(filter %.h,$(LLAMA_CPP_JAMFILE_FILES))
+LLAMA_CPP_JAMFILE_SRCS_C = $(filter %.c,$(LLAMA_CPP_JAMFILE_FILES))
+LLAMA_CPP_JAMFILE_SRCS_CPP = $(filter %.cpp,$(LLAMA_CPP_JAMFILE_FILES))
+LLAMA_CPP_JAMFILE_SRCS = $(LLAMA_CPP_JAMFILE_SRCS_C) $(LLAMA_CPP_JAMFILE_SRCS_CPP)
+
+LLAMA_CPP_JAMFILE_OBJS = \
+ $(LLAMA_CPP_JAMFILE_SRCS_C:%.c=o/$(MODE)/%.o) \
+ $(LLAMA_CPP_JAMFILE_SRCS_CPP:%.cpp=o/$(MODE)/%.o)
+
+
+#o/$(MODE)/jamfile/jamfile.a: $(LLAMA_CPP_JAMFILE_SRCS_C)
+
+### o/$(MODE)/jamfile/sqlite-vec.o: jamfile/sqlite-vec.c
+### o/$(MODE)/jamfile/sqlite-vec.a: o/$(MODE)/jamfile/sqlite-vec.o
+###
+### o/$(MODE)/jamfile/sqlite-csv.o: jamfile/sqlite-csv.c
+### o/$(MODE)/jamfile/sqlite-csv.a: o/$(MODE)/jamfile/sqlite-csv.o
+###
+###
+o/$(MODE)/jamfile/quickjs-llamafile-completion.o: jamfile/quickjs-llamafile-completion.cpp
+o/$(MODE)/jamfile/quickjs-llamafile-completion.a: o/$(MODE)/jamfile/quickjs-llamafile-completion.o
+
+o/$(MODE)/jamfile/quickjs-llamafile.o: jamfile/quickjs-llamafile.c jamfile/quickjs-llamafile-completion.cpp #o/$(MODE)/jamfile/quickjs-llamafile-completion.o
+o/$(MODE)/jamfile/quickjs-llamafile.a: o/$(MODE)/jamfile/quickjs-llamafile.o o/$(MODE)/jamfile/quickjs-llamafile-completion.a
+###
+### o/$(MODE)/jamfile/sqlite-lines.o: jamfile/sqlite-lines.c
+### o/$(MODE)/jamfile/sqlite-lines.a: o/$(MODE)/jamfile/sqlite-lines.o
+###
+### o/$(MODE)/jamfile/sqlite-lembed.o: jamfile/sqlite-lembed.c
+### o/$(MODE)/jamfile/sqlite-lembed.a: o/$(MODE)/jamfile/sqlite-lembed.o o/$(MODE)/llama.cpp/llama.cpp.a
+
+
+# jamfile:assert bytecode
+o/$(MODE)/jamfile/assert.gen.c: jamfile/js_builtins/assert.js o/$(mode)/third_party/quickjs/qjsc
+ o/$(mode)/third_party/quickjs/qjsc -m -o $@ $<
+o/$(MODE)/jamfile/assert.gen.o: o/$(MODE)/jamfile/assert.gen.c
+
+# jamfile:fmt bytecode
+o/$(MODE)/jamfile/fmt.gen.c: jamfile/js_builtins/fmt.js o/$(mode)/third_party/quickjs/qjsc
+ o/$(mode)/third_party/quickjs/qjsc -m -o $@ $<
+o/$(MODE)/jamfile/fmt.gen.o: o/$(MODE)/jamfile/fmt.gen.c
+
+# jamfile:cli bytecode
+o/$(MODE)/jamfile/cli.gen.c: jamfile/js_builtins/cli.js o/$(MODE)/third_party/quickjs/qjsc
+ o/$(mode)/third_party/quickjs/qjsc -m -o $@ $<
+o/$(MODE)/jamfile/cli.gen.o: o/$(MODE)/jamfile/cli.gen.c
+
+# jamfile:colors bytecode
+o/$(MODE)/jamfile/colors.gen.c: jamfile/js_builtins/colors.js o/$(MODE)/third_party/quickjs/qjsc
+ o/$(mode)/third_party/quickjs/qjsc -m -o $@ $<
+o/$(MODE)/jamfile/colors.gen.o: o/$(MODE)/jamfile/colors.gen.c
+
+# jamfile:zod bytecode
+o/$(MODE)/jamfile/zod.gen.c: jamfile/js_builtins/zod.js o/$(mode)/third_party/quickjs/qjsc
+ o/$(mode)/third_party/quickjs/qjsc -m -o $@ $<
+o/$(MODE)/jamfile/zod.gen.o: o/$(MODE)/jamfile/zod.gen.c
+
+# jamfile:yaml bytecode
+o/$(MODE)/jamfile/yaml.gen.c: jamfile/js_builtins/yaml.js o/$(mode)/third_party/quickjs/qjsc
+ o/$(mode)/third_party/quickjs/qjsc -m -o $@ $<
+o/$(MODE)/jamfile/yaml.gen.o: o/$(MODE)/jamfile/yaml.gen.c
+
+
+# jamfile:toml bytecode
+o/$(MODE)/jamfile/toml.gen.c: jamfile/js_builtins/toml.js o/$(mode)/third_party/quickjs/qjsc
+ o/$(mode)/third_party/quickjs/qjsc -m -o $@ $<
+o/$(MODE)/jamfile/toml.gen.o: o/$(MODE)/jamfile/toml.gen.c
+
+
+# jamfile:frontmatter bytecode
+o/$(MODE)/jamfile/frontmatter.gen.c: jamfile/js_builtins/frontmatter.js o/$(mode)/third_party/quickjs/qjsc
+ o/$(mode)/third_party/quickjs/qjsc -m -M jamfile:toml -M jamfile:yaml -o $@ $<
+o/$(MODE)/jamfile/frontmatter.gen.o: o/$(MODE)/jamfile/frontmatter.gen.c
+
+# jamfile:marked bytecode
+o/$(MODE)/jamfile/marked.gen.c: jamfile/js_builtins/marked.js o/$(mode)/third_party/quickjs/qjsc
+ o/$(mode)/third_party/quickjs/qjsc -m -o $@ $<
+o/$(MODE)/jamfile/marked.gen.o: o/$(MODE)/jamfile/marked.gen.c
+
+# jamfile:linkedom bytecode
+o/$(MODE)/jamfile/linkedom.gen.c: jamfile/js_builtins/linkedom.js o/$(mode)/third_party/quickjs/qjsc
+ o/$(mode)/third_party/quickjs/qjsc -m -o $@ $<
+o/$(MODE)/jamfile/linkedom.gen.o: o/$(MODE)/jamfile/linkedom.gen.c
+
+# include the raw contents of the jamfile.d.ts into jamfile for the `jamfile types` command
+o/$(MODE)/jamfile/jamfile-types.c: jamfile/jamfile.d.ts
+ xxd --include $< > $@
+o/$(MODE)/jamfile/jamfile-types.o: o/$(MODE)/jamfile/jamfile-types.c
+
+o/$(MODE)/jamfile/jamfile.a: \
+ o/$(MODE)/jamfile/jamfile-types.o \
+ o/$(MODE)/jamfile/cli.gen.o \
+ o/$(MODE)/jamfile/fmt.gen.o \
+ o/$(MODE)/jamfile/zod.gen.o \
+ o/$(MODE)/jamfile/assert.gen.o \
+ o/$(MODE)/jamfile/colors.gen.o \
+ o/$(MODE)/jamfile/toml.gen.o \
+ o/$(MODE)/jamfile/yaml.gen.o \
+ o/$(MODE)/jamfile/frontmatter.gen.o \
+ o/$(MODE)/jamfile/marked.gen.o \
+ o/$(MODE)/jamfile/linkedom.gen.o \
+ o/$(MODE)/jamfile/quickjs-sqlite.o \
+ o/$(MODE)/jamfile/quickjs-llamafile.o \
+ o/$(MODE)/jamfile/quickjs-llamafile-completion.o \
+ o/$(MODE)/third_party/quickjs/repl.o \
+ o/$(MODE)/third_party/quickjs/cutils.o \
+ o/$(MODE)/third_party/quickjs/libbf.o \
+ o/$(MODE)/third_party/quickjs/quickjs.o \
+ o/$(MODE)/third_party/quickjs/libregexp.o \
+ o/$(MODE)/third_party/quickjs/libunicode.o \
+ o/$(MODE)/third_party/quickjs/quickjs-libc.o
+
+
+o/$(MODE)/jamfile/jamfile: \
+ o/$(MODE)/jamfile/jamfile.a \
+ o/$(MODE)/jamfile/jamfile.1.asc.zip.o \
+ o/$(MODE)/llama.cpp/llama.cpp.a \
+ o/$(MODE)/third_party/sqlite/sqlite3.a \
+ o/$(MODE)/jamfile/quickjs-sqlite.a \
+ o/$(MODE)/jamfile/quickjs-llamafile.a \
+ o/$(MODE)/third_party/sqlite/sqlite-csv.a \
+ o/$(MODE)/third_party/sqlite/sqlite-vec.a
+
+$(LLAMA_CPP_JAMFILE_OBJS): private CCFLAGS += -DSQLITE_CORE
+
+.PHONY: o/$(MODE)/jamfile
+o/$(MODE)/jamfile: \
+ o/$(MODE)/jamfile/jamfile
+
+$(LLAMA_CPP_JAMFILE_OBJS): llama.cpp/BUILD.mk jamfile/BUILD.mk
+.PHONY: jamfile-test-js
+
+jamfile-test-js: o/$(MODE)/jamfile/jamfile jamfile/tests/js/test.js
+ $< run jamfile/tests/js/test.js
\ No newline at end of file
diff --git a/jamfile/doc/embeddings.md b/jamfile/doc/embeddings.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/jamfile/doc/index.md b/jamfile/doc/index.md
new file mode 100644
index 0000000000..d3c2eea06a
--- /dev/null
+++ b/jamfile/doc/index.md
@@ -0,0 +1,293 @@
+# `Jamfile` Documentation
+
+Jamfile is an experimental JavaScript runtime for llamafile, for working with large language models and embeddings models.
+
+This page goes over a quick overview of all that Jamfile has to offer. Additionally, check out these other documentation pages for more examples and goal-oriented guides.
+
+- [Jamfile JavaScript Reference](./reference.md)
+- [Jamfile for generating and querying embeddings](./embeddings.md)
+- [Jamfile for structured output generation](./structured-outputs.md)
+- [Compiling Jamfile programs into a "jam"](./jam.md)
+
+## Jamfile isn't a complete JavaScript runtime yet!
+
+Jamfile isn't like other JavaScript runtimes like Node.js, Deno, or Bun.
+It's scope is much smaller, there isn't plans for Node.js compatability, and many "standard" features like `fetch()`, `Temporal`, or other browser APIs are not supported yet.
+
+However, if you want to have a lighweight scripting engine for working with LLM's across platforms, then Jamfile is great!
+
+
+## Getting Started
+
+### Working with LLM's
+
+You can work with large language models that are in the [GGUF file format](https://huggingface.co/docs/hub/en/gguf) with Jamfile like so:
+
+
+```js
+// llm-sample.js
+import { CompletionModel } from "jamfile:llamafile";
+
+const model = new CompletionModel("./Llama-3.2-1B-Instruct-Q4_0.gguf");
+const prompt = "The meaning of life is:";
+const response = model.complete(prompt);
+console.log(prompt, response);
+```
+
+
+```bash
+jamfile run llm-sample.js
+The meaning of life is:
+...a complex and multifaceted concept that has been debated and explored by philosophers, scientists, theologians, and anyone who has ever set out to understand the mysteries of existence.
+```
+
+You can swap out the the `path` to any GGUF file of any supported LLM.
+
+The `.complete()` function also supports structured output generation, to force an LLM to respond in a specified schema. For example, you can have a model only respond in "math" with the [GBNF format](https://github.com/ggerganov/llama.cpp/blob/master/grammars/README.md):
+
+```js
+// gbnf-sample.js
+import { CompletionModel } from "jamfile:llamafile";
+
+const model = new CompletionModel("./Llama-3.2-1B-Instruct-Q4_0.gguf");
+
+const prompt = `
+Convert this transcription of a math problem into a numerical expression:
+
+Seven hundred and thirty four minus sixty-five divided by fourty five.
+`;
+
+// source: https://github.com/ggerganov/llama.cpp/blob/master/grammars/arithmetic.gbnf
+const schema = `root ::= (expr "=" ws term "\\n")+
+expr ::= term ([-+*/] term)*
+term ::= ident | num | "(" ws expr ")" ws
+ident ::= [a-z] [a-z0-9_]* ws
+num ::= [0-9]+ ws
+ws ::= [ \\t\\n]*\`'`;
+
+const response = model.complete(prompt, {schema});
+console.log(prompt, response);
+```
+
+Or if you want the LLM to respond with an exact JSON Schema, use the [builtin `jamfile:zod` module](./reference.md#jamfile_zod):
+
+
+```js
+// zod-sample.js
+import { z, zodToJsonSchema } from "jamfile:zod";
+import { CompletionModel } from "jamfile:llamafile";
+
+const Country = z.object({
+ name: z.string(),
+ capital: z.string(),
+ languages: z.array(z.string()),
+});
+
+const prompt = `Describe the country of Canada in JSON format:`;
+const schema = zodToJsonSchema(Country);
+
+const model = new CompletionModel("./Llama-3.2-1B-Instruct-Q4_0.gguf");
+const response = model.complete(prompt, { schema });
+
+console.log(response);
+```
+
+
+```
+> jamfile run zod-sample.js
+{"name": "Canada", "capital": "Ottawa", "languages": ["English", "French"]}
+```
+### Working with embeddings
+
+Jamfile can also generate embeddings with [`TextEmbeddingModel`](./reference.md#TextEmbeddingModel).
+
+```js
+import { TextEmbeddingModel } from "jamfile:llamafile";
+
+const model = new TextEmbeddingModel("./mxbai-embed-xsmall-v1-f16.gguf");
+const embedding = model.embed("hello!");
+console.log(
+ `${embedding.length} dimensions, preview: ${embedding.slice(0, 4)}`,
+);
+```
+
+
+```
+jamfile run embedding-sample.js
+384 dimensions, preview: -0.05826485529541969,0.04374322667717934,0.03084852732717991,0.047234565019607544
+```
+
+
+Use the [`jamfile:sqlite`](./reference.md#jamfile_sqlite) module to store and query these embeddings with [`sqlite-vec`](https://github.com/asg017/sqlite-vec).
+
+```js
+import { TextEmbeddingModel } from "jamfile:llamafile";
+import { Database } from "jamfile:sqlite";
+
+// Random NPR news headlines from 2024-01-17
+const documents = [
+ "The Supreme Court upholds a TikTok ban, threatening the app's existence in the U.S.",
+ "CNN settles lawsuit after $5 million defamation verdict",
+ "Immigrants drive Nebraska's economy. Trump's mass deportations pledge is a threat",
+ "President-elect Donald Trump moves his inauguration indoors, citing frigid temperatures",
+];
+
+const model = new TextEmbeddingModel("./mxbai-embed-xsmall-v1-f16.gguf");
+const db = new Database(":memory:");
+
+db.execute(`
+ CREATE VIRTUAL TABLE vec_documents USING vec0(
+ contents_embedding FLOAT[384] distance_metric=cosine,
+ +contents TEXT,
+ );
+`);
+
+for (const document of documents) {
+ const embedding = model.embed(document);
+ db.execute(
+ "INSERT INTO vec_documents(contents_embedding, contents) VALUES(?, ?)",
+ [embedding, document],
+ );
+}
+
+// KNN query the documents on 'social media'
+const results = db.queryAll(
+ `
+ SELECT
+ contents,
+ distance
+ FROM vec_documents
+ WHERE contents_embedding MATCH ?
+ AND k = 3;
+ `,
+ [model.embed("social media")],
+);
+
+for (const row of results) {
+ console.log(row["contents"], row["distance"]);
+}
+```
+
+```
+jamfile run embedding-sample.js
+The Supreme Court upholds a TikTok ban, threatening the app's existence in the U.S. 0.8698796033859253
+CNN settles lawsuit after $5 million defamation verdict 0.9893361926078796
+President-elect Donald Trump moves his inauguration indoors, citing frigid temperatures 0.9990869164466858
+```
+
+### Create CLI scripts
+
+- `Jamfile.args` and `jamfile:cli`
+- json/yaml/toml for config, or `config.js`
+
+### "Compile" a script to a standalone executable
+
+- `zipalign` a simple JS script
+- include embedding, completion model
+- `esbuild` for more
+
+## `Jamfile` Runtime
+
+### Built-In JavaScript Modules
+
+| Module | Description |
+| ----------------------------------------------------------- | ---------------------------------------------------- |
+| [`jamfile:assert`](./reference.md#jamfile_assert) | Assertion functions for testing and verification |
+| [`jamfile:colors`](./reference.md#jamfile_colors) | Color utilites for terminal interfaces |
+| [`jamfile:fmt`](./reference.md#jamfile_fmt) | Format durations or bytes |
+| [`jamfile:frontmatter`](./reference.md#jamfile_frontmatter) | Parse frontmatter from JSON, YAML, or TOML documents |
+| [`jamfile:cli`](./reference.md#jamfile_cli) | Command line parsing utilities |
+| [`jamfile:llamafile`](./reference.md#jamfile_llamafile) | Embeddings and completion models |
+| [`jamfile:linkedom`](./reference.md#jamfile_linkedom) | HTML and XML document parsing and generating |
+| [`jamfile:marked`](./reference.md#jamfile_marked) | Markdown document parsing and generating |
+| [`jamfile:sqlite`](./reference.md#jamfile_sqlite) | SQLite database client |
+| [`jamfile:toml`](./reference.md#jamfile_toml) | Parse and generate TOML documents |
+| [`jamfile:yaml`](./reference.md#jamfile_yaml) | Parse and generate YAML documents |
+| [`jamfile:zod`](./reference.md#jamfile_zod) | Schema validation |
+
+### "Importing" `.sql`, `gbnf`, or `.txt` files
+
+In addition to importing local JavaScript files, you can directly import SQL,
+[GBNF](https://github.com/ggerganov/llama.cpp/blob/master/grammars/README.md),
+or plain text files as strings.
+
+For example, to import a `schema.sql` file that contains SQL table schema, you can do so like so:
+
+```js
+import SCHEMA from "./schema.sql";
+import { Database } from "jamfile:sqlite";
+
+const db = new Database();
+
+db.executeScript(SCHEMA);
+db.execute("INSERT INTO my_table(created_at) VALUES(?)", [new Date()]);
+```
+
+Where `schema.sql` contains:
+
+```sql
+-- schema.sql
+CREATE TABLE IF NOT EXISTS my_table(
+ created_at datetime
+);
+```
+
+This also works for
+[GBNF](https://github.com/ggerganov/llama.cpp/blob/master/grammars/README.md)
+files, which are used to define formal grammars to constraint the output of an
+LLM.
+
+```js
+import schema from "./spellcheck.gbnf";
+import { CompletionModel } from "jamfile:llamafile";
+
+const model = new CompletionModel("gemma-2-2b-it.Q2_K.llamafile");
+
+const response = model.complete("You are a ...", { schema });
+console.log(response);
+```
+
+See [Structured Outputs in `Jamfile`](./structured-outputs.md) for more details.
+
+You can also import plain `.txt` files as strings, for things like system
+prompts or other templates.
+
+```js
+import PROMPT from "./SYSTEM_PROMPT.txt";
+import { CompletionModel } from "jamfile:llamafile";
+
+const model = new CompletionModel("gemma-2-2b-it.Q2_K.llamafile");
+
+const response = model.complete(PROMPT);
+console.log(response);
+```
+
+## The `jamfile` CLI
+
+### `jamfile run`
+
+```bash
+```
+
+#### The `--default-text-embedding-model` flag
+
+#### The `--default-completion-model` flag
+
+### `jamfile types`
+
+The `types` command will print out the contents of `jamfile.d.ts`, a TypeScript declaration file that documents every available JavaScript API in Jamfile's [standard library](./reference.md#built-in-javascript-modules). You can redirect the stream into a `jamfile.d.ts` file like so:
+
+```bash
+jamfile types > jamfile.d.ts
+```
+
+Then in your JavaScript code, you can "reference" this declartion file with the ["types" triple slash directive](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-):
+
+```js
+///
+import { TextEmbeddingModel } from "jamfile:llamafile";
+const model = new TextEmbeddingModel("./mxbai-embed-xsmall-v1-f16.gguf");
+model.embed('contents...');
+```
+
+In most IDEs, the inclusion of `jamfile.d.ts` will allow for autocomplete on Jamfile's JavaScript import statements, function names, parameter types, and more. Think of this as a "no-dependency" way to get autocomplete in your Jamfile scripts, no TypeScript or build step needed.
diff --git a/jamfile/doc/jam.md b/jamfile/doc/jam.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/jamfile/doc/reference.md b/jamfile/doc/reference.md
new file mode 100644
index 0000000000..16fdf5c5eb
--- /dev/null
+++ b/jamfile/doc/reference.md
@@ -0,0 +1,342 @@
+# Jamfile JavaScript Reference
+
+A complete reference to all the JavaScript APIs available in the `Jamfile`
+runtime.
+
+## Built-In JavaScript Modules
+
+| Module | Description | Source |
+| --------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------- |
+| [`jamfile:assert`](#jamfile_assert) | Asserttion functions for testing and verification | [`jsr:@std/assert`](https://jsr.io/@std/assert) |
+| [`jamfile:colors`](#jamfile_colors) | Color utilites for terminal interfaces | [`jsr:@std/colors`](https://jsr.io/@std/colors) |
+| [`jamfile:fmt`](#jamfile_fmt) | Format durations or bytes | [`jsr:@std/fmt`](https://jsr.io/@std/fmt) |
+| [`jamfile:frontmatter`](#jamfile_frontmatter) | Parse frontmatter from JSON, YAML, or TOML documents | [`jsr:@std/frontmatter`](https://jsr.io/@std/frontmatter) |
+| [`jamfile:cli`](#jamfile_cli) | Command line parsing utilities | [`jsr:@std/cli`](https://jsr.io/@std/cli) |
+| [`jamfile:llamafile`](#jamfile_llamafile) | Embeddings and completion models | Custom built |
+| [`jamfile:linkedom`](#jamfile_linkedom) | HTML and XML document parsing and generating | [`npm:linkedom`](https://github.com/WebReflection/linkedom) |
+| [`jamfile:marked`](#jamfile_marked) | Markdown document parsing and generating | [`npm:marked`](https://github.com/markedjs/marked) |
+| [`jamfile:sqlite`](#jamfile_sqlite) | SQLite database client | Custom built |
+| [`jamfile:toml`](#jamfile_toml) | Parse and generate TOML documents | [`jsr:@std/toml`](https://jsr.io/@std/toml) |
+| [`jamfile:yaml`](#jamfile_yaml) | Parse and generate YAML documents | [`jsr:@std/yaml`](https://jsr.io/@std/yaml) |
+| [`jamfile:zod`](#jamfile_zod) | Schema validation | [`npm:zod`](https://zod.dev/) |
+
+
jamfile:colors
+
+Utilities for stylizing text on the command-line with colors, bolding, italics,
+and more. Re-packaged from
+[`jsr:@std/fmt/colors`](https://jsr.io/@std/fmt/doc/colors).
+
+```js
+import { bgBlue, bold, red } from "jamafile:colors";
+
+console.log(bgBlue(red(bold("Hello, World!"))));
+```
+
+jamfile:cli
+
+Utilies for parsing command lnke arguments. Re-packaged from
+[`jsr:std/cli`](https://jsr.io/@std/cli), only the `parseArgs()` function for
+now.
+
+```js
+import { parseArgs } from "jamfile:cli";
+import { assertEquals } from "jamfile:assert";
+
+const args = parseArgs(["--foo", "--bar=baz", "./quux.txt"]);
+assertEquals(args, { "_": ["./quux.txt"], "foo": true, "bar": "baz" });
+```
+
+jamfile:zod
+
+The [zod library](https://zod.dev/) re-packaged into `jamfile` directly, no
+`npm` needed. Also has
+[`zodtoJsonSchema()`](https://github.com/StefanTerdell/zod-to-json-schema)
+bundled in.
+
+```js
+import { z, zodToJsonSchema } from "jamfile:zod";
+
+const Country = z.object({
+ name: z.string(),
+ capital: z.string(),
+ languages: z.array(z.string()),
+});
+
+console.log(zodToJsonSchema(Country));
+```
+
+jamfile:fmt
+
+Utilites for representing time durations and bytes into human-readable formats.
+Re-packaged subset of [`jsr:@std/fmt`](https://jsr.io/@std/fmt), specifically
+[`jsr:@std/fmt/bytes`](https://jsr.io/@std/fmt/doc/bytes) as `formatBytes()` and
+[`jsr:@std/fmt/duration`](https://jsr.io/@std/fmt/doc/duration) as
+`formatDuration()`.
+
+```js
+import { formatBytes, formatDuration } from "jamfile:fmt";
+import { assertEquals } from "jamfile:assert";
+
+assertEquals(formatBytes(3012), "3.01 kB");
+
+assertEquals(
+ formatDuration((60 * 1000) + (1000 * 32) + 4),
+ "1m 32s 4ms",
+);
+```
+
+`formatDuration()` has been modified from the original source, where the 2nd
+parameter `options` has `ignoreZero=true` by default.
+
+jamfile:assert
+
+Utilies for making assertions and verifying runtime data. Re-packaged from
+[`jsr:@std/assert`](https://jsr.io/@std/assert).
+
+```js
+import { assert, assertArrayIncludes, assertEquals } from "jamfile:assert";
+
+assert(true);
+assertEquals(1 + 1, 2);
+assertArrayIncludes([1, 2, 3], [2]);
+```
+
+jamfile:yaml
+`
+
+Utilies for parsing and stringifying YAML documents. Re-packaged from
+[`jsr:@std/yaml`](https://jsr.io/@std/yaml).
+
+```js
+import { stringify } from "jamfile:yaml";
+import { assertEquals } from "jamfile:assert";
+
+assertEquals(stringify({ name: "alex" }), "name: alex\n");
+```
+
+jamfile:toml
+
+Utilies for parsing and stringifying YAML documents. Re-packaged from
+[`jsr:@std/toml`](https://jsr.io/@std/toml).
+
+```js
+import { stringify } from "jamfile:toml";
+import { assertEquals } from "jamfile:assert";
+
+function testToml() {
+ assertEquals(stringify({ name: "alex" }), 'name = "alex"\n');
+}
+```
+
+jamfile:frontmatter
+
+Utilies for parsing and testing JSON, YAML, or TOML frontmatter data from files,
+like markdown. Re-packaged from
+[`jsr:@std/front-matter`](https://jsr.io/@std/front-matter).
+
+```js
+import { extractToml } from "jamfile:frontmatter";
+import { assertEquals } from "jamfile:assert";
+
+assertEquals(
+ extractToml('---toml\nname = "alex"\n---\n# markdown'),
+ {
+ frontMatter: 'name = "alex"',
+ body: "# markdown",
+ attrs: { name: "alex" },
+ },
+);
+```
+
+jamfile:marked
+
+The [`marked`](https://github.com/markedjs/marked) NPM package re-packaged for
+`jamfile`. A good low-level primitive for parsing or generating markdown
+documents.
+
+```js
+import { marked } from "jamfile:marked";
+import { assertEquals } from "jamfile:assert";
+
+assertEquals(marked.parse("# hello"), "hello
\n");
+```
+
+jamfile:linkedom
+
+The [`linkedom`](https://github.com/WebReflection/linkedom) NPM package
+re-packaged for `jamfile`. A good low-level primitive for parsing or generating
+HTML or XML documents.
+
+```js
+import { parseHTML } from "jamfile:linkedom";
+import { assertEquals } from "jamfile:assert";
+
+const { document } = parseHTML('yo
');
+
+assertEquals(
+ Array.from(document.querySelector("div").classList),
+ ["Alex"],
+);
+```
+
+jamfile:sqlite
+
+A custom SQLite JavaScript driver for the Jamfile runtime.
+
+```js
+import { Database } from "jamfile:sqlite";
+import { assertEquals } from "jamfile:assert";
+
+const db = new Database(":memory:");
+
+db.executeScript(`
+ CREATE TABLE items(id, title);
+
+ INSERT INTO items
+ SELECT
+ key,
+ value
+ FROM json_each('["gemma", "llama", "phi"]');
+`);
+
+assertEquals(
+ db.queryValue("select title from items where id = ?", [1]),
+ "llama",
+);
+```
+
+#### `SQLITE_VERSION`
+
+A string representing the SQLite version bundled into Jamfile.
+
+```js
+import { SQLITE_VERSION } from "jamfile:sqlite";
+import { assertEquals } from "jamfile:assert";
+
+assertEquals(SQLITE_VERSION, "3.47.1");
+```
+
+#### `escapeIdentifier(identifier)`
+
+```js
+// TODO
+```
+
+#### `Database`
+
+A JavaScript class that maintains a connection to a SQLite database.
+
+```js
+import { Database } from "jamfile:sqlite";
+const db = new Database();
+```
+
+##### `new Database(path, [options])`
+
+The constructor for the `Database` class will create a new connection to a
+SQLite database on-disk or in-memory.
+
+```js
+```
+
+##### `.queryAll(sql [, params])`
+
+```js
+```
+
+##### `.queryRow(sql [, params])`
+
+```js
+```
+
+##### `.queryValue(sql [, params])`
+
+```js
+```
+
+##### `.execute(sql [, params])`
+
+```js
+```
+
+##### `.executeScript(sql)`
+
+```js
+```
+
+
+
+jamfile:llamafile
+
+```js
+```
+
+#### `TextEmbeddingModel`
+
+```js
+```
+
+##### `new TextEmbeddingModel()`
+
+```js
+```
+
+##### `.tokenize()`
+
+```js
+```
+
+##### `.embed()`
+
+```js
+```
+
+##### `.detokenize()`
+
+```js
+```
+
+#### `CompletionModel`
+
+##### `new CompletionModel()`
+
+##### `.complete(input [, options])`
+
+##### `.tokenize(input)`
+
+##### `.detokenize(input)`
+
+### `qjs:std` and `qjs:os`
+
+## The `Jamfile` Global
+
+The `Jamfile` global variable is always available in `jamfile` scripts.
+
+#### `Jamfile.version`
+
+A string of the current "version" of Jamfile, may change in the future.
+
+```js
+console.log("Jamfile version: ", Jamfile.version);
+```
+
+#### `Jamfile.args`
+
+A string array of the command-line arguments provided in the script run.
+
+```js
+// my-script.js
+console.log(Jamfile.args);
+```
+
+```bash
+jamfile run my-script.js gemma llama phi
+gemma,llama,phi
+```
+
+Do note that `Jamfile.args` does not contain the "script" name as the first
+argument. The first `Jamfile.args[0]` value is the first CLI argument provided
+after the script filename.
+
+Consider using `parseArgs()` inside [`jamfile:cli`](#jamfilecli) to parse these
+CLI arguments in a friendly way.
diff --git a/jamfile/doc/structured-outputs.md b/jamfile/doc/structured-outputs.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/jamfile/examples/spellcheck/document.txt b/jamfile/examples/spellcheck/document.txt
new file mode 100644
index 0000000000..74dc3b5a0a
--- /dev/null
+++ b/jamfile/examples/spellcheck/document.txt
@@ -0,0 +1,6 @@
+The first spell ceckers were "verifiers" instead of "correctors." They
+offered no suggestions for incorrectly spelled words. This was helpful
+for typos but it was not so helpfl for logical or phonetic errors. The
+challenge the developers faced was the difficulty in offering useful
+suggestions for misspelled words. This requires reducing words to a
+sceletal form and applying pattern-matching algorithms.
\ No newline at end of file
diff --git a/jamfile/examples/spellcheck/spellcheck.gbnf b/jamfile/examples/spellcheck/spellcheck.gbnf
new file mode 100644
index 0000000000..af8b314b66
--- /dev/null
+++ b/jamfile/examples/spellcheck/spellcheck.gbnf
@@ -0,0 +1,4 @@
+root ::= good | list
+good ::= "ok"
+list ::= item ( "\n" item )*
+item ::= "- `" [-_0-9A-Za-z]+ "` should be `" [-_0-9A-Za-z]+ "`"
\ No newline at end of file
diff --git a/jamfile/examples/spellcheck/spellcheck.js b/jamfile/examples/spellcheck/spellcheck.js
new file mode 100644
index 0000000000..66805f0fd5
--- /dev/null
+++ b/jamfile/examples/spellcheck/spellcheck.js
@@ -0,0 +1,36 @@
+///
+
+import { CompletionModel } from "jamfile:llamafile";
+import schema from "./spellcheck.gbnf";
+
+const model = new CompletionModel('gemma-2-2b-it.Q2_K.llamafile');
+
+let prompt = (document) => `
+user
+You are a helpful AI assistant that does spell checking and only spell
+checking. For example, if the user says:
+
+It also meas that I keep my opshuns open.
+
+Then the assistant will say:
+
+- \`meas\` should be \`means\`
+- \`opshuns\` should be \`options\`
+
+If there are no mistyped words, the assistant responds with:
+
+ok
+
+Never reply with ok.
+user
+${document}
+assistant
+`;
+
+
+import * as std from "qjs:std";
+
+const document = std.in.readAsString();
+const response = model.complete(prompt(document), { schema });
+
+console.log(response);
\ No newline at end of file
diff --git a/jamfile/examples/sqlite-vec/demo.js b/jamfile/examples/sqlite-vec/demo.js
new file mode 100644
index 0000000000..d94790d245
--- /dev/null
+++ b/jamfile/examples/sqlite-vec/demo.js
@@ -0,0 +1,60 @@
+import {open} from "qjs:std";
+import {TextEmbeddingModel} from "jamfile:llamafile";
+import {Database} from "jamfile:sqlite";
+import {formatDuration} from "jamfile:fmt";
+import {green} from "jamfile:colors";
+
+const README = open('README.md', 'r').readAsString();
+
+const db = new Database();
+const model = new TextEmbeddingModel('dist/.models/mxbai-embed-xsmall-v1-f16.gguf');
+
+db.execute(`
+ CREATE VIRTUAL TABLE vec_chunks USING vec0(
+ +contents TEXT,
+ contents_embedding float[384] distance_metric=cosine
+ );`);
+
+
+function* chunks(arr, n) {
+ for (let i = 0; i < arr.length; i += n) {
+ yield arr.slice(i, i + n);
+ }
+}
+
+const tokens = model.tokenize(README);
+
+const t0 = Date.now();
+const c = Array.from(chunks(tokens, 64));
+for(const chunk of c) {
+ const chunk_embedding = model.embed(chunk);
+ db.execute(
+ 'INSERT INTO vec_chunks(contents, contents_embedding) VALUES (?, ?);',
+ [model.detokenize(chunk), chunk_embedding]
+ );
+}
+const duration = Date.now() - t0;
+
+console.log(`${formatDuration(duration)} for ${c.length} embeddings (${c.length / (duration / 1000)}/second)`)
+
+function search(query) {
+ const rows = db.queryAll(
+ `SELECT
+ rowid,
+ contents
+ FROM vec_chunks
+ WHERE contents_embedding MATCH ?
+ AND k = 10
+ `,
+ [model.embed(query)]
+ );
+
+ console.log(green(query));
+
+ for (const {rowid, contents} of rows) {
+ console.log(contents);
+ }
+}
+
+search('linux CLI Tools ');
+search('money supporting ecosystem ');
diff --git a/jamfile/examples/standlone/.gitignore b/jamfile/examples/standlone/.gitignore
new file mode 100644
index 0000000000..7783aede05
--- /dev/null
+++ b/jamfile/examples/standlone/.gitignore
@@ -0,0 +1 @@
+*.jamfile
\ No newline at end of file
diff --git a/jamfile/examples/standlone/Makefile b/jamfile/examples/standlone/Makefile
new file mode 100644
index 0000000000..597f64b10d
--- /dev/null
+++ b/jamfile/examples/standlone/Makefile
@@ -0,0 +1,25 @@
+Llama-3.2-1B-Instruct-Q4_K_M.gguf:
+ curl -L -o $@ https://huggingface.co/bartowski/Llama-3.2-1B-Instruct-GGUF/resolve/main/$@
+
+mxbai-embed-xsmall-v1-f16.gguf:
+ curl -L -o $@ https://huggingface.co/mixedbread-ai/mxbai-embed-xsmall-v1/resolve/main/gguf/$@
+
+standalone.jamfile: \
+ ../../../o/jamfile/jamfile \
+ Llama-3.2-1B-Instruct-Q4_K_M.gguf \
+ mxbai-embed-xsmall-v1-f16.gguf \
+ standalone.js
+
+ printf "%s\n" \
+ "--default-embedding-model" \
+ "mxbai-embed-xsmall-v1-f16.gguf" \
+ "--default-completion-model" \
+ "Llama-3.2-1B-Instruct-Q4_K_M.gguf" \
+ "run" \
+ "standalone.js" \
+ "..." > .args
+
+ cp ../../../o/jamfile/jamfile $@
+ ../../../o/llamafile/zipalign -j0 $@ $^ .args
+ rm .args
+ chmod u+x $@
diff --git a/jamfile/examples/standlone/README.md b/jamfile/examples/standlone/README.md
new file mode 100644
index 0000000000..9787348a24
--- /dev/null
+++ b/jamfile/examples/standlone/README.md
@@ -0,0 +1,36 @@
+# jamfile sample: standalone
+
+An example of how you can make a standlone single-binary script from a Jamfile JavaScript script.
+
+The `standalone.js` is a sample JavaScript script that generates a a sample embedding and completion result. It could be ran as-is with `jamfile run standlone.js`, but we could bundle the JS script and model weights into a single-file `jamfile` that works on all operating systems.
+
+To do so, run the following command:
+
+```
+make sample.jamfile
+```
+
+That will download an embeddings model (MixedBread xsmall) and a LLM (Lllama 3.2), embedding them into a new `sample.jamfile` file with the `standalone.js` JavaScript script.
+
+You can now execute that `jamfile` directly like so:
+
+
+```
+$ ./standalone.jamfile
+embedding sample: [-0.05826485529541969,0.04374322667717934,0.03084852732717991,0.047234565019607544,-0.05963338911533356,-0.03614785894751549,0.03814202547073364,0.005149350967258215]
+completion sample:
+Here is a single haiku about SpongeBob SquarePants:
+
+Fluffy sponge so bright
+Rainbow colors in his heart
+Joyful underwater
+
+I hope you like it! Let me know if you have any other requests.
+```
+
+The output `standalone.jamfile` is a small `850MB`, which includes the LLM, embeddings model, and `jamfile` executable all in one.
+
+- `jamfile` base: `15MB`
+- `mxbai-embed-xsmall-v1-f16.gguf`: `49MB`
+- `Llama-3.2-1B-Instruct-Q4_K_M.gguf`: `770MB`
+- `standalone.jamfile`: `850MB`
\ No newline at end of file
diff --git a/jamfile/examples/standlone/standalone.js b/jamfile/examples/standlone/standalone.js
new file mode 100755
index 0000000000..865feaa2ff
--- /dev/null
+++ b/jamfile/examples/standlone/standalone.js
@@ -0,0 +1,23 @@
+/**
+ * An example of a standalone jamfile.
+ *
+ * This script performs
+ */
+
+///
+
+import { red } from "jamfile:color";
+import { CompletionModel, TextEmbeddingModel } from "jamfile:llamafile";
+
+const embeddingModel = new TextEmbeddingModel();
+const completionModel = new CompletionModel();
+
+console.log(
+ red("embedding sample: "),
+ JSON.stringify(Array.from(embeddingModel.embed("hello!").slice(0, 8)))
+);
+
+console.log(
+ red("completion sample: "),
+ completionModel.complete("write a single haiku about spongebob squarepants")
+);
\ No newline at end of file
diff --git a/jamfile/examples/structured-output/complete.js b/jamfile/examples/structured-output/complete.js
new file mode 100644
index 0000000000..2514664339
--- /dev/null
+++ b/jamfile/examples/structured-output/complete.js
@@ -0,0 +1,111 @@
+///
+
+import { yellow } from "jamfile:color";
+import {CompletionModel} from "jamfile:completionmodel";
+import { formatDuration } from "jamfile:fmt";
+
+const model = new CompletionModel('Llama-3.2-1B-Instruct-f16.gguf');
+
+console.log(1);
+
+const article = `Bringing Android to XR
+Today, we're introducing Android XR, a new operating system built for this next generation of computing. Created in collaboration with Samsung, Android XR combines years of investment in AI, AR and VR to bring helpful experiences to headsets and glasses.
+
+We’re working to create a vibrant ecosystem of developers and device makers for Android XR, building on the foundation that brought Android to billions. Today’s release is a preview for developers, and by supporting tools like ARCore, Android Studio, Jetpack Compose, Unity, and OpenXR from the beginning, developers can easily start building apps and games for upcoming Android XR devices. For Qualcomm partners like Lynx, Sony and XREAL, we are opening a path for the development of a wide array of Android XR devices to meet the diverse needs of people and businesses. And, we are continuing to collaborate with Magic Leap on XR technology and future products with AR and AI.`;
+
+
+
+//console.log(model.complete(`describe qualities about the county of Canada in JSON format.`));
+
+import { z, zodToJsonSchema } from "jamfile:zod";
+const Country = z.object({
+ name: z.string(),
+ capital: z.string(),
+ languages: z.array(z.string()),
+});
+
+console.log('='.repeat(100));
+
+let prompt = `describe the country of Canada in JSON format, maximum of 3 elements per array: `
+
+let t0;
+
+
+t0 = Date.now();
+console.log(
+ model.complete(
+ prompt,
+ {schema: zodToJsonSchema(Country)}
+ )
+);
+console.log(formatDuration(Date.now() - t0, {ignoreZero: true}))
+
+t0 = Date.now();
+console.log(
+ model.complete(
+ "Describe the person in this sentence: John Doe is 30 years old.",
+ {schema: zodToJsonSchema(z.object({
+ first_name: z.string(),
+ last_name: z.string(),
+ age_in_years: z.number(),
+ }))}
+ )
+);
+console.log(formatDuration(Date.now() - t0, {ignoreZero: true}))
+
+
+console.log(
+ model.complete("What federal employees are mentioned in the following passage? The long-awaited report from DOJ Inspector General Michael Horowitz's office comes nearly four years after a crowd of Donald Trump's supporters stormed the U.S. Capitol on Jan. 6, 2021, to try to prevent Congress from certifying President Biden's election win. The report looks at how the FBI handled its intelligence and informants, known as confidential human sources, ahead of the event.",
+ {
+ schema: zodToJsonSchema(
+ z.object({
+ name: z.string(),
+ occupation: z.string(),
+ organization: z.string(),
+ })
+ )
+ })
+)
+
+console.log(
+ model.complete(`
+
+ What questions does the following passage answer? Respond with a list of question/answer pairs. Provide only relevant question that this passage could answer, not generic ones.
+
+ EXAMPLE: [{\"question\": \"Who delivers presents to children every Christmas?\", \"answer\": \"Santa Clause.\"}]
+
+ PASSAGE: The long-awaited report from DOJ Inspector General Michael Horowitz's office comes nearly four years after a crowd of Donald Trump's supporters stormed the U.S. Capitol on Jan. 6, 2021, to try to prevent Congress from certifying President Biden's election win. The report looks at how the FBI handled its intelligence and informants, known as confidential human sources, ahead of the event.
+ `,
+ {
+ schema: zodToJsonSchema(
+ z.array(z.object({
+ question: z.string(),
+ answer: z.string()
+ }))
+ )
+ })
+)
+
+
+
+const mathReasoningSchema = z.object({
+ steps: z.array(
+ z.object({
+ explanation: z.string(),
+ output: z.string(),
+ })
+ ),
+ final_answer: z.string(),
+}).strict();
+
+prompt = `
+ You are a helpful math tutor. You will be provided with a math problem,
+ and your goal will be to output a step by step solution, along with a final answer.
+ For each step, just provide the output as an equation use the explanation field to detail the reasoning.
+
+ PROMPT: how can I solve 8x + 7 = -23
+`;
+const result = model.complete(prompt, {schema: zodToJsonSchema(mathReasoningSchema)});
+
+console.log(yellow(prompt));
+console.log(result);
diff --git a/jamfile/examples/weather-bot/Makefile b/jamfile/examples/weather-bot/Makefile
new file mode 100644
index 0000000000..36a1b95a17
--- /dev/null
+++ b/jamfile/examples/weather-bot/Makefile
@@ -0,0 +1,6 @@
+
+Llama-3.2-1B-Instruct-Q4_K_M.gguf:
+ curl -L -o $@ https://huggingface.co/bartowski/Llama-3.2-1B-Instruct-GGUF/resolve/main/$@
+
+.PHONY: all
+all: Llama-3.2-1B-Instruct-Q4_K_M.gguf
diff --git a/jamfile/examples/weather-bot/weather.js b/jamfile/examples/weather-bot/weather.js
new file mode 100644
index 0000000000..45134028ab
--- /dev/null
+++ b/jamfile/examples/weather-bot/weather.js
@@ -0,0 +1,67 @@
+/**
+ * A simple bot that takes in weather info from wttr.in and tries to respond
+ * in helpful Engish. Big work in progress!
+ *
+ * run with:
+ *
+ * ```bash
+ * jamfile run weather.js
+ * ```
+ *
+ * Requires curl and a llama 3.2 GGUF - run `make all` to download it.
+ *
+ * TODO:
+ * - Edit prompt more to generate more helpful responses
+ * - Include more weather data in prompt (hourly forecast for the day, etc.)
+ * - Only include useful weather data, not humidity,
+ * - Save more user preferences - available wardrobe, temperature cut-offs, etc
+ * - Move away from popen() + curl
+ */
+
+///
+
+import { CompletionModel } from "jamfile:llamafile";
+import { popen } from "qjs:std";
+import wttrSchema from "./wttr-schema.js";
+
+const MODEL_PATH = './Llama-3.2-1B-Instruct-Q4_K_M.gguf';
+
+function fetchWttr() {
+ const wttrin = popen("curl -s 'wttr.in?format=j1'", 'r').readAsString();
+ return wttrSchema.parse(JSON.parse(wttrin));
+
+}
+
+function createPrompt(data) {
+ return `<|begin_of_text|><|start_header_id|>system<|end_header_id|>
+
+You are an assitant who will greet the user like a butler,
+providing information about the weather.
+
+Use the following data from the given JSON blob to provide information and recommendations in English.
+
+User preferences:
+ - Only give temperatures in Farenheit
+ - Warn if it'll be colder than 60 or warmer than 80
+ - Use a british accent
+ - Add a couple emojis as well
+ - Keep sentences short, use line breaks in between.
+
+
+<|eot_id|><|start_header_id|>user<|end_header_id|>
+
+${JSON.stringify(data.current_condition)}
+
+<|eot_id|><|start_header_id|>assistant<|end_header_id|>`;
+}
+
+
+function main() {
+ const model = new CompletionModel(MODEL_PATH);
+ const data = fetchWttr();
+ const response = model.complete(createPrompt(data));
+
+ console.log(response);
+}
+
+if(import.meta.main) main();
diff --git a/jamfile/examples/weather-bot/wttr-schema.js b/jamfile/examples/weather-bot/wttr-schema.js
new file mode 100644
index 0000000000..7b95430b9e
--- /dev/null
+++ b/jamfile/examples/weather-bot/wttr-schema.js
@@ -0,0 +1,116 @@
+
+import {z} from "jamfile:zod";
+
+/**
+ * Zod schema of https://wttr.in?format=J1,
+ * generated with https://transform.tools/json-to-zod.
+ * */
+export default z.object({
+ current_condition: z.array(
+ z.object({
+ FeelsLikeC: z.string(),
+ FeelsLikeF: z.string(),
+ cloudcover: z.string(),
+ humidity: z.string(),
+ localObsDateTime: z.string(),
+ observation_time: z.string(),
+ precipInches: z.string(),
+ precipMM: z.string(),
+ pressure: z.string(),
+ pressureInches: z.string(),
+ temp_C: z.string(),
+ temp_F: z.string(),
+ uvIndex: z.string(),
+ visibility: z.string(),
+ visibilityMiles: z.string(),
+ weatherCode: z.string(),
+ weatherDesc: z.array(z.object({ value: z.string() })),
+ weatherIconUrl: z.array(z.object({ value: z.string() })),
+ winddir16Point: z.string(),
+ winddirDegree: z.string(),
+ windspeedKmph: z.string(),
+ windspeedMiles: z.string()
+ })
+ ),
+ nearest_area: z.array(
+ z.object({
+ areaName: z.array(z.object({ value: z.string() })),
+ country: z.array(z.object({ value: z.string() })),
+ latitude: z.string(),
+ longitude: z.string(),
+ population: z.string(),
+ region: z.array(z.object({ value: z.string() })),
+ weatherUrl: z.array(z.object({ value: z.string() }))
+ })
+ ),
+ request: z.array(z.object({ query: z.string(), type: z.string() })),
+ weather: z.array(
+ z.object({
+ astronomy: z.array(
+ z.object({
+ moon_illumination: z.string(),
+ moon_phase: z.string(),
+ moonrise: z.string(),
+ moonset: z.string(),
+ sunrise: z.string(),
+ sunset: z.string()
+ })
+ ),
+ avgtempC: z.string(),
+ avgtempF: z.string(),
+ date: z.string(),
+ hourly: z.array(
+ z.object({
+ DewPointC: z.string(),
+ DewPointF: z.string(),
+ FeelsLikeC: z.string(),
+ FeelsLikeF: z.string(),
+ HeatIndexC: z.string(),
+ HeatIndexF: z.string(),
+ WindChillC: z.string(),
+ WindChillF: z.string(),
+ WindGustKmph: z.string(),
+ WindGustMiles: z.string(),
+ chanceoffog: z.string(),
+ chanceoffrost: z.string(),
+ chanceofhightemp: z.string(),
+ chanceofovercast: z.string(),
+ chanceofrain: z.string(),
+ chanceofremdry: z.string(),
+ chanceofsnow: z.string(),
+ chanceofsunshine: z.string(),
+ chanceofthunder: z.string(),
+ chanceofwindy: z.string(),
+ cloudcover: z.string(),
+ diffRad: z.string(),
+ humidity: z.string(),
+ precipInches: z.string(),
+ precipMM: z.string(),
+ pressure: z.string(),
+ pressureInches: z.string(),
+ shortRad: z.string(),
+ tempC: z.string(),
+ tempF: z.string(),
+ time: z.string(),
+ uvIndex: z.string(),
+ visibility: z.string(),
+ visibilityMiles: z.string(),
+ weatherCode: z.string(),
+ weatherDesc: z.array(z.object({ value: z.string() })),
+ weatherIconUrl: z.array(z.object({ value: z.string() })),
+ winddir16Point: z.string(),
+ winddirDegree: z.string(),
+ windspeedKmph: z.string(),
+ windspeedMiles: z.string()
+ })
+ ),
+ maxtempC: z.string(),
+ maxtempF: z.string(),
+ mintempC: z.string(),
+ mintempF: z.string(),
+ sunHour: z.string(),
+ totalSnow_cm: z.string(),
+ uvIndex: z.string()
+ })
+ )
+});
diff --git a/jamfile/jamfile.1 b/jamfile/jamfile.1
new file mode 100644
index 0000000000..83aaa96b21
--- /dev/null
+++ b/jamfile/jamfile.1
@@ -0,0 +1,98 @@
+.Dd December 5, 2023
+.Dt JAMFILE 1
+.Os Llamafile Manual
+.Sh NAME
+.Nm jamfile
+.Nd large language model quantizer
+.Sh SYNOPSIS
+.Nm
+.Op flags...
+.Ar model-f32.gguf
+.Op Ar model-quant.gguf
+.Ar type
+.Op Ar nthreads
+.Sh DESCRIPTION
+.Nm
+converts large language model weights from the float32 or float16
+formats into smaller data types from 2 to 8 bits in size.
+.Sh OPTIONS
+The following flags are available:
+.Bl -tag -width indent
+.It Fl Fl allow-requantize
+Allows requantizing tensors that have already been quantized. Warning: This can severely reduce quality compared to quantizing from 16bit or 32bit
+.It Fl Fl leave-output-tensor
+Will leave output.weight un(re)quantized. Increases model size but may also increase quality, especially when requantizing
+.It Fl Fl pure
+Disable k-quant mixtures and quantize all tensors to the same type
+.El
+.Sh ARGUMENTS
+The following positional arguments are accepted:
+.Bl -tag -width indent
+.It Ev Ar model-f32.gguf
+Is the input file, which contains the unquantized model weights in either the float32 or float16 format.
+.It Ev Ar model-quant.gguf
+Is the output file, which will contain quantized weights in the desired format. If this path isn't specified, it'll default to [inp path]/ggml-model-[ftype].gguf.
+.It Ev Ar type
+Is the desired quantization format, which may be the integer id of a supported quantization type, or its name. See the quantization types section below for acceptable formats.
+.It Ev Ar nthreads
+Number of threads to use during computation (default: nproc/2)
+.El
+.Sh QUANTIZATION TYPES
+The following quantization types are available. This table shows the ID
+of the quantization format, its name, the file size of 7B model weights
+that use it, and finally the amount of quality badness it introduces as
+measured by the llamafile-perplexity tool averaged over 128 chunks with
+the TinyLLaMA 1.1B v1.0 Chat model. Rows are ordered in accordance with
+how recommended the quantization format is for general usage.
+.Pp
+.Bl -dash -compact
+.It
+ 18 Q6_K 5.6gb +0.0446 ppl (q6 kawrakow)
+.It
+ 7 Q8_0 7.2gb +0.0022 ppl (q8 gerganov)
+.It
+ 1 F16 14gb +0.0000 ppl (best but biggest)
+.It
+ 8 Q5_0 4.7gb +0.0817 ppl (q5 gerganov zero)
+.It
+ 17 Q5_K_M 4.8gb +0.0836 ppl (q5 kawrakow medium)
+.It
+ 16 Q5_K_S 4.7gb +0.1049 ppl (q5 kawrakow small)
+.It
+ 15 Q4_K_M 4.1gb +0.3132 ppl (q4 kawrakow medium)
+.It
+ 14 Q4_K_S 3.9gb +0.3408 ppl (q4 kawrakow small)
+.It
+ 13 Q3_K_L 3.6gb +0.5736 ppl (q3 kawrakow large)
+.It
+ 12 Q3_K_M 3.3gb +0.7612 ppl (q3 kawrakow medium)
+.It
+ 11 Q3_K_S 3.0gb +1.3834 ppl (q3 kawrakow small)
+.It
+ 10 Q2_K 2.6gb +4.2359 ppl (tiniest hallucinates most)
+.It
+ 32 BF16 14gb +0.0000 ppl (canonical but cpu/cuda only)
+.It
+ 0 F32 27gb 9.0952 ppl (reference point)
+.It
+ 2 Q4_0 3.9gb +0.3339 ppl (legacy)
+.It
+ 3 Q4_1 4.3gb +0.4163 ppl (legacy)
+.It
+ 9 Q5_1 5.1gb +0.1091 ppl (legacy)
+.It
+ 12 Q3_K alias for Q3_K_M
+.It
+ 15 Q4_K alias for Q4_K_M
+.It
+ 17 Q5_K alias for Q5_K_M
+.It
+COPY Only copy tensors, no quantizing.
+.El
+.Sh SEE ALSO
+.Xr llamafile 1 ,
+.Xr llamafile-imatrix 1 ,
+.Xr llamafile-perplexity 1 ,
+.Xr llava-quantize 1 ,
+.Xr zipalign 1 ,
+.Xr unzip 1
diff --git a/jamfile/jamfile.1.asc b/jamfile/jamfile.1.asc
new file mode 100644
index 0000000000..cb34d68079
--- /dev/null
+++ b/jamfile/jamfile.1.asc
@@ -0,0 +1,80 @@
+JAMFILE(1) General Commands Manual JAMFILE(1)
+
+NNAAMMEE
+ jjaammffiillee - large language model quantizer
+
+SSYYNNOOPPSSIISS
+ jjaammffiillee [flags...] _m_o_d_e_l_-_f_3_2_._g_g_u_f [_m_o_d_e_l_-_q_u_a_n_t_._g_g_u_f] _t_y_p_e [_n_t_h_r_e_a_d_s]
+
+DDEESSCCRRIIPPTTIIOONN
+ jjaammffiillee converts large language model weights from the float32 or float16
+ formats into smaller data types from 2 to 8 bits in size.
+
+OOPPTTIIOONNSS
+ The following flags are available:
+
+ ----aallllooww--rreeqquuaannttiizzee
+ Allows requantizing tensors that have already been quantized.
+ Warning: This can severely reduce quality compared to quantizing
+ from 16bit or 32bit
+
+ ----lleeaavvee--oouuttppuutt--tteennssoorr
+ Will leave output.weight un(re)quantized. Increases model size but
+ may also increase quality, especially when requantizing
+
+ ----ppuurree Disable k-quant mixtures and quantize all tensors to the same type
+
+AARRGGUUMMEENNTTSS
+ The following positional arguments are accepted:
+
+ _m_o_d_e_l_-_f_3_2_._g_g_u_f
+ Is the input file, which contains the unquantized model weights in
+ either the float32 or float16 format.
+
+ _m_o_d_e_l_-_q_u_a_n_t_._g_g_u_f
+ Is the output file, which will contain quantized weights in the
+ desired format. If this path isn't specified, it'll default to [inp
+ path]/ggml-model-[ftype].gguf.
+
+ _t_y_p_e Is the desired quantization format, which may be the integer id of
+ a supported quantization type, or its name. See the quantization
+ types section below for acceptable formats.
+
+ _n_t_h_r_e_a_d_s
+ Number of threads to use during computation (default: nproc/2)
+
+QQUUAANNTTIIZZAATTIIOONN TTYYPPEESS
+ The following quantization types are available. This table shows the ID of
+ the quantization format, its name, the file size of 7B model weights that
+ use it, and finally the amount of quality badness it introduces as measured
+ by the llamafile-perplexity tool averaged over 128 chunks with the
+ TinyLLaMA 1.1B v1.0 Chat model. Rows are ordered in accordance with how
+ recommended the quantization format is for general usage.
+
+ -- 18 Q6_K 5.6gb +0.0446 ppl (q6 kawrakow)
+ -- 7 Q8_0 7.2gb +0.0022 ppl (q8 gerganov)
+ -- 1 F16 14gb +0.0000 ppl (best but biggest)
+ -- 8 Q5_0 4.7gb +0.0817 ppl (q5 gerganov zero)
+ -- 17 Q5_K_M 4.8gb +0.0836 ppl (q5 kawrakow medium)
+ -- 16 Q5_K_S 4.7gb +0.1049 ppl (q5 kawrakow small)
+ -- 15 Q4_K_M 4.1gb +0.3132 ppl (q4 kawrakow medium)
+ -- 14 Q4_K_S 3.9gb +0.3408 ppl (q4 kawrakow small)
+ -- 13 Q3_K_L 3.6gb +0.5736 ppl (q3 kawrakow large)
+ -- 12 Q3_K_M 3.3gb +0.7612 ppl (q3 kawrakow medium)
+ -- 11 Q3_K_S 3.0gb +1.3834 ppl (q3 kawrakow small)
+ -- 10 Q2_K 2.6gb +4.2359 ppl (tiniest hallucinates most)
+ -- 32 BF16 14gb +0.0000 ppl (canonical but cpu/cuda only)
+ -- 0 F32 27gb 9.0952 ppl (reference point)
+ -- 2 Q4_0 3.9gb +0.3339 ppl (legacy)
+ -- 3 Q4_1 4.3gb +0.4163 ppl (legacy)
+ -- 9 Q5_1 5.1gb +0.1091 ppl (legacy)
+ -- 12 Q3_K alias for Q3_K_M
+ -- 15 Q4_K alias for Q4_K_M
+ -- 17 Q5_K alias for Q5_K_M
+ -- COPY Only copy tensors, no quantizing.
+
+SSEEEE AALLSSOO
+ llamafile(1), llamafile-imatrix(1), llamafile-perplexity(1),
+ llava-quantize(1), zipalign(1), unzip(1)
+
+Llamafile Manual December 5, 2023 Llamafile Manual
diff --git a/jamfile/jamfile.c b/jamfile/jamfile.c
new file mode 100644
index 0000000000..8e2ed4a89e
--- /dev/null
+++ b/jamfile/jamfile.c
@@ -0,0 +1,537 @@
+// -*- mode:c++;indent-tabs-mode:nil;c-basic-offset:4;coding:utf-8 -*-
+// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
+#include "third_party/quickjs/cutils.h"
+#include "third_party/quickjs/quickjs.h"
+#include "third_party/quickjs/quickjs-libc.h"
+
+#include "llama.cpp/llama.h"
+#include "llamafile/version.h"
+#include "third_party/sqlite/sqlite3.h"
+#include
+
+#include
+#include
+#include
+#include
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#if !defined(_MSC_VER)
+#include
+#endif
+#include
+#include
+#include
+
+#include "jamfile/jamfile.h"
+#include "third_party/sqlite/sqlite3.h"
+
+#include "jamfile/quickjs-sqlite.h"
+#include "jamfile/quickjs-llamafile.h"
+#include "jamfile/quickjs-llamafile-completion.h"
+#include "llamafile/llamafile.h"
+
+char *JAMFILE_DEFAULT_EMBEDDING_MODEL = NULL;
+char *JAMFILE_DEFAULT_COMPLETION_MODEL = NULL;
+
+// raw jamfile.d.ts contents, for the `jamfile types`
+extern const unsigned char jamfile_jamfile_d_ts[];
+extern const unsigned int jamfile_jamfile_d_ts_len;
+
+// pre-compiled JS bytecode for the interactive REPL, adapted from quickjs project
+extern const uint8_t qjsc_repl[];
+extern const uint32_t qjsc_repl_size;
+
+// pre-compiled JS bytecode for jamfile:colors
+extern const uint8_t qjsc_colors[];
+extern const uint32_t qjsc_colors_size;
+
+// pre-compiled JS bytecode for jamfile:cli
+extern const uint8_t qjsc_cli[];
+extern const uint32_t qjsc_cli_size;
+
+// pre-compiled JS bytecode for jamfile:zod
+extern const uint8_t qjsc_zod[];
+extern const uint32_t qjsc_zod_size;
+
+// pre-compiled JS bytecode for jamfile:fmt
+extern const uint8_t qjsc_fmt[];
+extern const uint32_t qjsc_fmt_size;
+
+// pre-compiled JS bytecode for jamfile:assert
+extern const uint8_t qjsc_assert[];
+extern const uint32_t qjsc_assert_size;
+
+// pre-compiled JS bytecode for jamfile:toml
+extern const uint8_t qjsc_toml[];
+extern const uint32_t qjsc_toml_size;
+
+// pre-compiled JS bytecode for jamfile:yaml
+extern const uint8_t qjsc_yaml[];
+extern const uint32_t qjsc_yaml_size;
+
+// pre-compiled JS bytecode for jamfile:frontmatter
+extern const uint8_t qjsc_frontmatter[];
+extern const uint32_t qjsc_frontmatter_size;
+
+// pre-compiled JS bytecode for jamfile:marked
+extern const uint8_t qjsc_marked[];
+extern const uint32_t qjsc_marked_size;
+
+
+
+// pre-compiled JS bytecode for jamfile:linkedom
+extern const uint8_t qjsc_linkedom[];
+extern const uint32_t qjsc_linkedom_size;
+
+static JSCFunctionListEntry argv0;
+
+// Initially from quickjs-lib.c, but include fallback to llamafile_open
+uint8_t *jama_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename)
+{
+ struct llamafile *f;
+ uint8_t *buf;
+ size_t buf_len;
+ long lret;
+
+ f = llamafile_open_xxx(filename, "rb");
+ if (!f)
+ return NULL;
+ if (!llamafile_seek(f, 0, SEEK_END))
+ goto fail;
+ lret = llamafile_tell(f);
+ if (lret < 0)
+ goto fail;
+ /* XXX: on Linux, ftell() return LONG_MAX for directories */
+ if (lret == LONG_MAX) {
+ errno = EISDIR;
+ goto fail;
+ }
+ buf_len = lret;
+ if (!llamafile_seek(f, 0, SEEK_SET))
+ goto fail;
+ if (ctx)
+ buf = js_malloc(ctx, buf_len + 1);
+ else
+ buf = malloc(buf_len + 1);
+ if (!buf)
+ goto fail;
+ if (llamafile_read(f, buf, buf_len) != buf_len) {
+ errno = EIO;
+ if (ctx)
+ js_free(ctx, buf);
+ else
+ free(buf);
+ fail:
+ llamafile_close(f);
+ return NULL;
+ }
+ buf[buf_len] = '\0';
+ llamafile_close(f);
+ *pbuf_len = buf_len;
+ return buf;
+}
+
+static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
+ const char *filename, int eval_flags)
+{
+ JSValue val;
+ int ret;
+
+ if ((eval_flags & JS_EVAL_TYPE_MASK) == JS_EVAL_TYPE_MODULE) {
+ /* for the modules, we compile then run to be able to set
+ import.meta */
+ val = JS_Eval(ctx, buf, buf_len, filename,
+ eval_flags | JS_EVAL_FLAG_COMPILE_ONLY);
+ if (!JS_IsException(val)) {
+ js_module_set_import_meta(ctx, val, TRUE, TRUE);
+ val = JS_EvalFunction(ctx, val);
+ }
+ val = js_std_await(ctx, val);
+ } else {
+ val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
+ }
+ if (JS_IsException(val)) {
+ js_std_dump_error(ctx);
+ ret = -1;
+ } else {
+ ret = 0;
+ }
+ JS_FreeValue(ctx, val);
+ return ret;
+}
+
+static int eval_file(JSContext *ctx, const char *filename, int module)
+{
+ uint8_t *buf;
+ int ret, eval_flags;
+ size_t buf_len;
+
+ buf = jama_load_file(ctx, &buf_len, filename);
+ if (!buf) {
+ perror(filename);
+ exit(1);
+ }
+
+ if (module < 0) {
+ module = (has_suffix(filename, ".mjs") ||
+ JS_DetectModule((const char *)buf, buf_len));
+ }
+ if (module)
+ eval_flags = JS_EVAL_TYPE_MODULE;
+ else
+ eval_flags = JS_EVAL_TYPE_GLOBAL;
+ ret = eval_buf(ctx, buf, buf_len, filename, eval_flags);
+ js_free(ctx, buf);
+ return ret;
+}
+
+static JSValue js_gc(JSContext *ctx, JSValue this_val,
+ int argc, JSValue *argv)
+{
+ JS_RunGC(JS_GetRuntime(ctx));
+ return JS_UNDEFINED;
+}
+
+static const JSCFunctionListEntry global_obj[] = {
+ JS_CFUNC_DEF("gc", 0, js_gc),
+};
+
+
+void jamfile_define_jamfile_global(JSContext *ctx, int argc, char ** argv) {
+ JSValue global = JS_GetGlobalObject(ctx);
+ JSValue Jamfile = JS_NewObject(ctx);
+
+ JS_SetPropertyStr(ctx, Jamfile, "version", JS_NewString(ctx, JAMFILE_VERSION));
+
+ JSValue args = JS_NewArray(ctx);
+ for(int i = 0; i < argc; i++) {
+ JS_SetPropertyUint32(ctx, args, i, JS_NewString(ctx, argv[i]));
+ }
+ JS_SetPropertyStr(ctx, Jamfile, "args", args);
+
+ JS_SetPropertyStr(ctx, global, "Jamfile", Jamfile);
+ JS_FreeValue(ctx, global);
+}
+
+static JSContext *jamfile_context_new(JSRuntime *rt)
+{
+ JSContext *ctx;
+ ctx = JS_NewContext(rt);
+ if (!ctx)
+ return NULL;
+
+ js_init_module_sqlite(ctx, "jamfile:sqlite");
+ js_init_module_llamafile(ctx, "jamfile:llamafile", JAMFILE_DEFAULT_EMBEDDING_MODEL, JAMFILE_DEFAULT_COMPLETION_MODEL);
+ js_init_module_std(ctx, "qjs:std");
+ js_init_module_os(ctx, "qjs:os");
+ js_init_module_bjson(ctx, "qjs:bjson");
+
+ JSValue global = JS_GetGlobalObject(ctx);
+
+ JSValue console = JS_NewObject(ctx);
+ JS_SetPropertyStr(ctx, console, "log",
+ JS_NewCFunction(ctx, js_print, "log", 1));
+ JS_SetPropertyStr(ctx, global, "console", console);
+
+ JS_SetPropertyFunctionList(ctx, global, global_obj, countof(global_obj));
+ JS_SetPropertyFunctionList(ctx, global, &argv0, 1);
+ JS_FreeValue(ctx, global);
+
+ return ctx;
+}
+
+JSModuleDef *jama_module_loader(JSContext *ctx,
+ const char *module_name, void *opaque)
+{
+ struct {
+ char * name;
+ uint8_t *bytecode;
+ uint32_t bytecode_size;
+ } jama_builtin_modules[] = {
+ {"jamfile:assert", (uint8_t *) qjsc_assert, qjsc_assert_size },
+ {"jamfile:colors", (uint8_t *) qjsc_colors, qjsc_colors_size },
+ {"jamfile:cli", (uint8_t *) qjsc_cli, qjsc_cli_size },
+ {"jamfile:fmt", (uint8_t *) qjsc_fmt, qjsc_fmt_size },
+ {"jamfile:zod", (uint8_t *) qjsc_zod, qjsc_zod_size },
+ {"jamfile:yaml", (uint8_t *) qjsc_yaml, qjsc_yaml_size },
+ {"jamfile:toml", (uint8_t *) qjsc_toml, qjsc_toml_size },
+ {"jamfile:frontmatter", (uint8_t *) qjsc_frontmatter, qjsc_frontmatter_size },
+ {"jamfile:marked", (uint8_t *) qjsc_marked, qjsc_marked_size },
+ {"jamfile:linkedom", (uint8_t *) qjsc_linkedom, qjsc_linkedom_size },
+ };
+ JSModuleDef *m;
+
+ size_t buf_len;
+ uint8_t *buf;
+ JSValue func_val;
+ for(int i = 0; i < countof(jama_builtin_modules); i++) {
+ if(strncmp(module_name, jama_builtin_modules[i].name, strlen(module_name)) == 0) {
+ JSValue obj = JS_ReadObject(ctx, jama_builtin_modules[i].bytecode, jama_builtin_modules[i].bytecode_size, JS_READ_OBJ_BYTECODE);
+
+ assert(!JS_IsException(obj));
+ assert(JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE);
+
+ JSModuleDef *m = JS_VALUE_GET_PTR(obj);
+ JS_FreeValue(ctx, obj);
+ return m;
+ }
+ }
+
+ buf = jama_load_file(ctx, &buf_len, module_name);
+ if (!buf) {
+ JS_ThrowReferenceError(ctx, "could not load module filename '%s'",
+ module_name);
+ return NULL;
+ }
+
+ if(sqlite3_strlike("%.gbnf", module_name, 0)==0
+ || sqlite3_strlike("%.sql", module_name, 0)==0
+ || sqlite3_strlike("%.txt", module_name, 0)==0) {
+
+ sqlite3_str * s = sqlite3_str_new(NULL);
+ sqlite3_str_appendall(s, "export default `");
+ for(int i = 0; i < buf_len; i++) {
+ // TODO also escape ${}"
+ if(buf[i] == '`') {
+ sqlite3_str_appendall(s, "\\`");
+ }
+ else {
+ sqlite3_str_appendchar(s, 1, buf[i]);
+ }
+ }
+ sqlite3_str_appendall(s, "`;");
+ int moduleLength = sqlite3_str_length(s);
+ char * module = sqlite3_str_finish(s);
+ assert(module);
+ func_val = JS_Eval(ctx, module, moduleLength, module_name, JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
+ js_free(ctx, buf);
+ sqlite3_free((void *) module);
+ }
+ else {
+ func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
+ JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
+ js_free(ctx, buf);
+ }
+
+
+ if (JS_IsException(func_val))
+ return NULL;
+ /* XXX: could propagate the exception */
+ js_module_set_import_meta(ctx, func_val, TRUE, FALSE);
+ /* the module is already referenced, so we must free it */
+ m = JS_VALUE_GET_PTR(func_val);
+ JS_FreeValue(ctx, func_val);
+
+ return m;
+}
+
+#define PROG_NAME "jamfile"
+
+void help(void)
+{
+ printf("Jamfile version %s, QuickJS-ng version %s\n"
+ "usage: " PROG_NAME " [options] [file [args]]\n"
+ "-h --help list options\n"
+ "-e --eval EXPR evaluate EXPR\n"
+ "-i --interactive go to interactive mode\n"
+ "-m --module load as ES6 module (default=autodetect)\n"
+ " --script load as ES6 script (default=autodetect)\n"
+ " --memory-limit n limit the memory usage to 'n' Kbytes\n"
+ " --stack-size n limit the stack size to 'n' Kbytes\n"
+ " --unhandled-rejection dump unhandled promise rejections\n"
+ "-q --quit just instantiate the interpreter and quit\n", JAMFILE_VERSION, JS_GetVersion());
+ exit(1);
+}
+
+int cmd_run(int argc, char ** argv) {
+ JSRuntime *rt;
+ JSContext *ctx;
+ JSValue ret;
+ int optind;
+ char *expr = NULL;
+ int interactive = 0;
+ int module = -1;
+ int dump_unhandled_promise_rejection = 0;
+ int64_t memory_limit = -1;
+ int64_t stack_size = -1;
+
+ argv0 = (JSCFunctionListEntry)JS_PROP_STRING_DEF("argv0", argv[0],
+ JS_PROP_C_W_E);
+
+ optind = 1;
+ while (optind < argc && *argv[optind] == '-') {
+ char *arg = argv[optind] + 1;
+ const char *longopt = "";
+ char *opt_arg = NULL;
+ /* a single - is not an option, it also stops argument scanning */
+ if (!*arg)
+ break;
+ optind++;
+ if (*arg == '-') {
+ longopt = arg + 1;
+ opt_arg = strchr(longopt, '=');
+ if (opt_arg)
+ *opt_arg++ = '\0';
+ arg += strlen(arg);
+ /* -- stops argument scanning */
+ if (!*longopt)
+ break;
+ }
+ for (; *arg || *longopt; longopt = "") {
+ char opt = *arg;
+ if (opt) {
+ arg++;
+ if (!opt_arg && *arg)
+ opt_arg = arg;
+ }
+ if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) {
+ help();
+ continue;
+ }
+ if (opt == 'e' || !strcmp(longopt, "eval")) {
+ if (!opt_arg) {
+ if (optind >= argc) {
+ fprintf(stderr, "jamfile: missing expression for -e\n");
+ exit(2);
+ }
+ opt_arg = argv[optind++];
+ }
+ expr = opt_arg;
+ break;
+ }
+ if (opt == 'i' || !strcmp(longopt, "interactive")) {
+ interactive++;
+ continue;
+ }
+ if (opt == 'm' || !strcmp(longopt, "module")) {
+ module = 1;
+ continue;
+ }
+ if (!strcmp(longopt, "script")) {
+ module = 0;
+ continue;
+ }
+ if (!strcmp(longopt, "unhandled-rejection")) {
+ dump_unhandled_promise_rejection = 1;
+ continue;
+ }
+ if (opt) {
+ fprintf(stderr, "jamfile: unknown option '-%c'\n", opt);
+ } else {
+ fprintf(stderr, "jamfile: unknown option '--%s'\n", longopt);
+ }
+ help();
+ }
+ }
+
+
+ rt = JS_NewRuntime();
+
+ if (!rt) {
+ fprintf(stderr, "jamfile: cannot allocate JS runtime\n");
+ exit(2);
+ }
+
+ JS_SetRuntimeOpaque(rt, (void *) 0x420);
+
+ js_std_set_worker_new_context_func(jamfile_context_new);
+ js_std_init_handlers(rt);
+ ctx = jamfile_context_new(rt);
+ if (!ctx) {
+ fprintf(stderr, "jamfile: cannot allocate JS context\n");
+ exit(2);
+ }
+
+ // -1 and +1 to read past the js file arg
+ jamfile_define_jamfile_global(ctx, argc - optind - 1, argv + optind + 1);
+
+ JS_SetModuleLoaderFunc(rt, NULL, jama_module_loader, NULL);
+
+ if (dump_unhandled_promise_rejection) {
+ JS_SetHostPromiseRejectionTracker(rt, js_std_promise_rejection_tracker,
+ NULL);
+ }
+
+ //js_std_add_helpers(ctx, argc - optind, argv + optind);
+
+ if (expr) {
+ if (eval_buf(ctx, expr, strlen(expr), "", 0))
+ goto fail;
+ } else
+ if (optind >= argc) {
+ /* interactive mode */
+ interactive = 1;
+ } else {
+ const char *filename;
+ filename = argv[optind];
+ if (eval_file(ctx, filename, module))
+ goto fail;
+ }
+ if (interactive) {
+ js_std_eval_binary(ctx, qjsc_repl, qjsc_repl_size, 0);
+ }
+ ret = js_std_loop(ctx);
+ if (!JS_IsUndefined(ret)) {
+ js_std_dump_error1(ctx, ret);
+ goto fail;
+ }
+
+ js_std_free_handlers(rt);
+ JS_FreeContext(ctx);
+ JS_FreeRuntime(rt);
+
+
+ return 0;
+ fail:
+ js_std_free_handlers(rt);
+ JS_FreeContext(ctx);
+ JS_FreeRuntime(rt);
+ return 1;
+}
+
+int main(int argc, char **argv) {
+ int rc;
+ sqlite3 *db;
+ sqlite3_stmt *stmt;
+
+ FLAG_log_disable = 1;
+ argc = cosmo_args("/zip/.args", &argv);
+ FLAGS_READY = 1;
+
+ char *modelPath = NULL;
+ for (int i = 1; i < argc; i++) {
+ char *arg = argv[i];
+ if (sqlite3_stricmp(arg, "--default-embedding-model") == 0) {
+ assert(++i <= argc);
+ JAMFILE_DEFAULT_EMBEDDING_MODEL = argv[i];
+ }else if (sqlite3_stricmp(arg, "--default-completion-model") == 0) {
+ assert(++i <= argc);
+ JAMFILE_DEFAULT_COMPLETION_MODEL = argv[i];
+ } else if (sqlite3_stricmp(arg, "--version") == 0 || sqlite3_stricmp(arg, "-v") == 0) {
+ fprintf(stderr,"jamfile %s\n",JAMFILE_VERSION);
+ return 0;
+ } else if (sqlite3_stricmp(arg, "--help") == 0 || sqlite3_stricmp(arg, "-h") == 0) {
+ llamafile_help("/zip/jamfile/jamfile.1.asc");
+ fprintf(stderr, "Usage: jamfile [ run | types ]\n");
+ return 0;
+ } else if(sqlite3_stricmp(arg, "run") == 0) {
+ return cmd_run(argc-i, argv+i);
+ } else if(sqlite3_stricmp(arg, "types") == 0) {
+ fprintf(stdout, "%.*s", jamfile_jamfile_d_ts_len, jamfile_jamfile_d_ts);
+ return 0;
+ }
+ else {
+ printf("Unknown arg %s\n", arg);
+ return 1;
+ }
+ }
+
+ fprintf(stderr, "Usage: jamfile [run | types]\n");
+ return 0;
+}
diff --git a/jamfile/jamfile.d.ts b/jamfile/jamfile.d.ts
new file mode 100644
index 0000000000..0d566081ed
--- /dev/null
+++ b/jamfile/jamfile.d.ts
@@ -0,0 +1,4682 @@
+/**
+ * This will eventually contain the full types of all the modules this JS runtime offers.
+ *
+ * Generating this automatically was too complicated, so will unfortunately have to manage
+ * manually for now.
+ */
+
+
+declare namespace Jamfile {
+ export const version: string;
+}
+declare module "qjs:std" {
+ /**
+ * Exit the process.
+ * @param n - Exit code.
+ */
+ export function exit(n: number): void;
+
+ /**
+ * Evaluate the string `str` as a script (global eval).
+ * @param str - The script to evaluate.
+ * @param options - Optional settings for evaluation.
+ * - `backtrace_barrier` (boolean, default = false): If true, error backtraces do not list the stack frames below the evalScript.
+ * - `async` (boolean, default = false): If true, await is accepted in the script and a promise is returned.
+ * @returns The result of the evaluated script or a promise if `async` is true.
+ */
+ export function evalScript(
+ str: string,
+ options?: { backtrace_barrier?: boolean; async?: boolean }
+ ): any;
+
+ /**
+ * Evaluate the file `filename` as a script (global eval).
+ * @param filename - The path to the file.
+ * @returns The result of the evaluated script.
+ */
+ export function loadScript(filename: string): any;
+
+ /**
+ * Load the file `filename` and return it as a string assuming UTF-8 encoding.
+ * @param filename - The path to the file.
+ * @returns The file content as a string, or null in case of I/O error.
+ */
+ export function loadFile(filename: string): string | null;
+
+ /**
+ * Open a file (wrapper to the libc `fopen()`).
+ * @param filename - The path to the file.
+ * @param flags - The flags for opening the file.
+ * @param errorObj - An optional object where `errno` will be set to the error code, or 0 if no error occurred.
+ * @returns A `FILE` object, or null in case of I/O error.
+ */
+ export function open(
+ filename: string,
+ flags: string,
+ errorObj?: { errno?: number }
+ ): FILE | null;
+
+ /**
+ * Open a process by creating a pipe (wrapper to the libc `popen()`).
+ * @param command - The command to execute.
+ * @param flags - The flags for opening the process.
+ * @param errorObj - An optional object where `errno` will be set to the error code, or 0 if no error occurred.
+ * @returns A `FILE` object, or null in case of I/O error.
+ */
+ export function popen(
+ command: string,
+ flags: string,
+ errorObj?: { errno?: number }
+ ): FILE | null;
+
+ /**
+ * Open a file from a file handle (wrapper to the libc `fdopen()`).
+ * @param fd - The file descriptor.
+ * @param flags - The flags for opening the file.
+ * @param errorObj - An optional object where `errno` will be set to the error code, or 0 if no error occurred.
+ * @returns A `FILE` object, or null in case of I/O error.
+ */
+ export function fdopen(
+ fd: number,
+ flags: string,
+ errorObj?: { errno?: number }
+ ): FILE | null;
+
+ /**
+ * Open a temporary file.
+ * @param errorObj - An optional object where `errno` will be set to the error code, or 0 if no error occurred.
+ * @returns A `FILE` object, or null in case of I/O error.
+ */
+ export function tmpfile(errorObj?: { errno?: number }): FILE | null;
+
+ /**
+ * Outputs the string `str` to stdout.
+ * @param str - The string to output.
+ */
+ export function puts(str: string): void;
+
+ /**
+ * Outputs formatted text to stdout.
+ * @param fmt - The format string.
+ * @param args - Arguments for formatting.
+ */
+ export function printf(fmt: string, ...args: any[]): void;
+
+ /**
+ * Formats text into a string using the libc `sprintf()`.
+ * @param fmt - The format string.
+ * @param args - Arguments for formatting.
+ * @returns The formatted string.
+ */
+ export function sprintf(fmt: string, ...args: any[]): string;
+
+ /** Wrapper to the libc `stdin`. */
+ // TODO syntax error on the name "in"
+ //export const in: FILE;
+
+ /** Wrapper to the libc `stdout`. */
+ export const out: FILE;
+
+ /** Wrapper to the libc `stderr`. */
+ export const err: FILE;
+
+ /** Constants for seek operations. */
+ export const SEEK_SET: number;
+ export const SEEK_CUR: number;
+ export const SEEK_END: number;
+
+ /** Enumeration object containing common error codes. */
+ export const Error: {
+ EINVAL: number;
+ EIO: number;
+ EACCES: number;
+ EEXIST: number;
+ ENOSPC: number;
+ ENOSYS: number;
+ EBUSY: number;
+ ENOENT: number;
+ EPERM: number;
+ EPIPE: number;
+ };
+
+ /**
+ * Return a string that describes the error `errno`.
+ * @param errno - The error code.
+ * @returns The error description.
+ */
+ export function strerror(errno: number): string;
+
+ /**
+ * Manually invoke the cycle removal algorithm.
+ * Useful for specific memory constraints or testing.
+ */
+ export function gc(): void;
+
+ /**
+ * Return the value of the environment variable `name`.
+ * @param name - The name of the environment variable.
+ * @returns The value of the environment variable, or undefined if not defined.
+ */
+ export function getenv(name: string): string | undefined;
+
+ /**
+ * Set the value of the environment variable `name` to the string `value`.
+ * @param name - The name of the environment variable.
+ * @param value - The value to set.
+ */
+ export function setenv(name: string, value: string): void;
+
+ /**
+ * Delete the environment variable `name`.
+ * @param name - The name of the environment variable.
+ */
+ export function unsetenv(name: string): void;
+
+ /**
+ * Return an object containing the environment variables as key-value pairs.
+ * @returns An object with environment variables.
+ */
+ export function getenviron(): Record;
+
+ /**
+ * Download a URL using the curl command line utility.
+ * @param url - The URL to download.
+ * @param options - Optional settings for the download.
+ * - `binary` (boolean, default = false): If true, the response is an ArrayBuffer instead of a string.
+ * - `full` (boolean, default = false): If true, return an object containing properties `response`, `responseHeaders`, and `status`. If `full` is false, only the response is returned if the status is between 200 and 299, otherwise null.
+ * @returns The response content or an object with additional properties based on `options`.
+ */
+ export function urlGet(
+ url: string,
+ options?: { binary?: boolean; full?: boolean }
+ ): string | ArrayBuffer | { response: string | null; responseHeaders: string; status: number };
+
+ /**
+ * Parse `str` using a superset of JSON.parse with extended syntax support.
+ * Supported extensions:
+ * - Single line and multiline comments
+ * - Unquoted properties (ASCII-only Javascript identifiers)
+ * - Trailing comma in array and object definitions
+ * - Single quoted strings
+ * - \f and \v as space characters
+ * - Leading plus in numbers
+ * - Octal (0o prefix) and hexadecimal (0x prefix) numbers
+ * @param str - The string to parse.
+ * @returns The parsed object.
+ */
+ export function parseExtJSON(str: string): any;
+
+ /** Represents a file object. */
+ export interface FILE {
+ /** Close the file. */
+ close(): number;
+
+ /** Outputs the string with the UTF-8 encoding. */
+ puts(str: string): void;
+
+ /** Formatted printf. */
+ printf(fmt: string, ...args: any[]): void;
+
+ /** Flush the buffered file. */
+ flush(): void;
+
+ /** Seek to a given file position. */
+ seek(offset: number | bigint, whence: number): number;
+
+ /** Return the current file position. */
+ tell(): number;
+
+ /** Return the current file position as a bigint. */
+ tello(): bigint;
+
+ /** Return true if end of file. */
+ eof(): boolean;
+
+ /** Return the associated OS handle. */
+ fileno(): number;
+
+ /** Return true if there was an error. */
+ error(): boolean;
+
+ /** Clear the error indication. */
+ clearerr(): void;
+
+ /** Read bytes from the file to an ArrayBuffer. */
+ read(buffer: ArrayBuffer, position: number, length: number): number;
+
+ /** Write bytes to the file from an ArrayBuffer. */
+ write(buffer: ArrayBuffer, position: number, length: number): number;
+
+ /** Return the next line from the file as a string. */
+ getline(): string | null;
+
+ /** Read bytes as a string up to `max_size`. */
+ readAsString(max_size?: number): string | null;
+
+ /** Return the next byte from the file. */
+ getByte(): number;
+
+ /** Write one byte to the file. */
+ putByte(c: number): void;
+ }
+}
+
+
+declare module "qjs:os" {
+ /**
+ * Open a file. Return a handle or < 0 if error.
+ * @param filename The file name.
+ * @param flags POSIX open flags.
+ * @param mode File mode (default = 0o666).
+ */
+ export function open(filename: string, flags: number, mode?: number): number;
+
+ /** POSIX open flags. */
+ export const O_RDONLY: number;
+ export const O_WRONLY: number;
+ export const O_RDWR: number;
+ export const O_APPEND: number;
+ export const O_CREAT: number;
+ export const O_EXCL: number;
+ export const O_TRUNC: number;
+
+ /** Windows-specific flag to open the file in text mode. Default is binary mode. */
+ export const O_TEXT: number;
+
+ /**
+ * Close the file handle.
+ * @param fd The file handle to close.
+ */
+ export function close(fd: number): number;
+
+ /**
+ * Seek in the file.
+ * @param fd The file handle.
+ * @param offset The position to seek to (number or bigint).
+ * @param whence The reference position (use std.SEEK_* constants).
+ */
+ export function seek(fd: number, offset: number | bigint, whence: number): number | bigint;
+
+ /**
+ * Read bytes from a file handle.
+ * @param fd The file handle to read from.
+ * @param buffer The ArrayBuffer to store the read data.
+ * @param offset The starting position in the buffer.
+ * @param length The number of bytes to read.
+ */
+ export function read(fd: number, buffer: ArrayBuffer, offset: number, length: number): number;
+
+ /**
+ * Write bytes to a file handle.
+ * @param fd The file handle to write to.
+ * @param buffer The ArrayBuffer containing the data to write.
+ * @param offset The starting position in the buffer.
+ * @param length The number of bytes to write.
+ */
+ export function write(fd: number, buffer: ArrayBuffer, offset: number, length: number): number;
+
+ /**
+ * Check if the file handle is a TTY (terminal).
+ * @param fd The file handle to check.
+ */
+ export function isatty(fd: number): boolean;
+
+ /**
+ * Get the size of a TTY.
+ * @param fd The TTY file handle.
+ * @returns [width, height] or null if not available.
+ */
+ export function ttyGetWinSize(fd: number): [number, number] | null;
+
+ /**
+ * Set the TTY in raw mode.
+ * @param fd The TTY file handle.
+ */
+ export function ttySetRaw(fd: number): void;
+
+ /**
+ * Remove a file.
+ * @param filename The file name to remove.
+ */
+ export function remove(filename: string): number;
+
+ /**
+ * Rename a file.
+ * @param oldname The current file name.
+ * @param newname The new file name.
+ */
+ export function rename(oldname: string, newname: string): number;
+
+ /**
+ * Get the canonicalized absolute pathname of a path.
+ * @param path The input path.
+ * @returns [path, error code].
+ */
+ export function realpath(path: string): [string, number];
+
+ /**
+ * Get the current working directory.
+ * @returns [directory, error code].
+ */
+ export function getcwd(): [string, number];
+
+ /**
+ * Change the current working directory.
+ * @param path The new working directory.
+ */
+ export function chdir(path: string): number;
+
+ /**
+ * Create a directory.
+ * @param path The directory path.
+ * @param mode The mode for the directory (default = 0o777).
+ */
+ export function mkdir(path: string, mode?: number): number;
+
+ /**
+ * Get file status for a path.
+ * @param path The file path.
+ * @returns [status object, error code].
+ */
+ export function stat(path: string): [FileStatus, number];
+
+ /**
+ * Get file status for a path (without following symlinks).
+ * @param path The file path.
+ * @returns [status object, error code].
+ */
+ export function lstat(path: string): [FileStatus, number];
+
+ /** File status object returned by `stat` and `lstat`. */
+ export interface FileStatus {
+ dev: number;
+ ino: number;
+ mode: number;
+ nlink: number;
+ uid: number;
+ gid: number;
+ rdev: number;
+ size: number;
+ blocks: number;
+ atime: number;
+ mtime: number;
+ ctime: number;
+ }
+
+ /** Constants to interpret the mode property returned by `stat`. */
+ export const S_IFMT: number;
+ export const S_IFIFO: number;
+ export const S_IFCHR: number;
+ export const S_IFDIR: number;
+ export const S_IFBLK: number;
+ export const S_IFREG: number;
+ export const S_IFSOCK: number;
+ export const S_IFLNK: number;
+ export const S_ISGID: number;
+ export const S_ISUID: number;
+
+ /**
+ * Change the access and modification times of a file.
+ * @param path The file path.
+ * @param atime Access time in milliseconds since 1970.
+ * @param mtime Modification time in milliseconds since 1970.
+ */
+ export function utimes(path: string, atime: number, mtime: number): number;
+
+ /**
+ * Create a symbolic link.
+ * @param target The target of the link.
+ * @param linkpath The link path to create.
+ */
+ export function symlink(target: string, linkpath: string): number;
+
+ /**
+ * Read a symbolic link.
+ * @param path The link path.
+ * @returns [link target, error code].
+ */
+ export function readlink(path: string): [string, number];
+
+ /**
+ * Read a directory's contents.
+ * @param path The directory path.
+ * @returns [array of filenames, error code].
+ */
+ export function readdir(path: string): [string[], number];
+
+ /**
+ * Add a read handler to a file handle.
+ * @param fd The file handle.
+ * @param func The function to call when there is data pending (or `null` to remove the handler).
+ */
+ export function setReadHandler(fd: number, func: (() => void) | null): void;
+
+ /**
+ * Add a write handler to a file handle.
+ * @param fd The file handle.
+ * @param func The function to call when data can be written (or `null` to remove the handler).
+ */
+ export function setWriteHandler(fd: number, func: (() => void) | null): void;
+
+ /**
+ * Add a signal handler.
+ * @param signal The signal number.
+ * @param func The function to call when the signal is received (`null` for the default handler, `undefined` to ignore the signal).
+ */
+ export function signal(signal: number, func: (() => void) | null | undefined): void;
+
+ /** POSIX signal numbers. */
+ export const SIGINT: number;
+ export const SIGABRT: number;
+ export const SIGFPE: number;
+ export const SIGILL: number;
+ export const SIGSEGV: number;
+ export const SIGTERM: number;
+
+ /**
+ * Send a signal to a process.
+ * @param pid The process ID.
+ * @param sig The signal to send.
+ */
+ export function kill(pid: number, sig: number): number;
+
+ /**
+ * Execute a process with the given arguments.
+ * @param args The arguments for the process.
+ * @param options Optional execution parameters.
+ * @returns Exit code, process ID, or negated signal number depending on the `block` option.
+ */
+ export function exec(
+ args: string[],
+ options?: {
+ block?: boolean;
+ usePath?: boolean;
+ file?: string;
+ cwd?: string;
+ stdin?: number;
+ stdout?: number;
+ stderr?: number;
+ env?: Record;
+ uid?: number;
+ gid?: number;
+ }
+ ): number;
+
+ /**
+ * Get the current process ID.
+ * @returns The process ID.
+ */
+ export function getpid(): number;
+
+ /**
+ * Wait for a process to change state.
+ * @param pid The process ID to wait for.
+ * @param options Options for the waitpid call (use `WNOHANG` if non-blocking behavior is desired).
+ * @returns [result, status], where `result` is the PID of the child process or -errno, and `status` is the exit status or signal number.
+ */
+ export function waitpid(pid: number, options?: number): [number, number];
+
+ /** Constant for non-blocking waitpid call. */
+ export const WNOHANG: number;
+
+ /**
+ * Duplicate a file descriptor.
+ * @param fd The file descriptor to duplicate.
+ * @returns The new file descriptor, or -errno on failure.
+ */
+ export function dup(fd: number): number;
+
+ /**
+ * Duplicate a file descriptor to a specific target descriptor.
+ * @param oldfd The file descriptor to duplicate.
+ * @param newfd The target descriptor number.
+ * @returns 0 if successful, or -errno on failure.
+ */
+ export function dup2(oldfd: number, newfd: number): number;
+
+ /**
+ * Create a pipe.
+ * @returns [read_fd, write_fd] or `null` in case of error.
+ */
+ export function pipe(): [number, number] | null;
+
+ /**
+ * Sleep for the specified duration.
+ * @param delay_ms The delay in milliseconds.
+ */
+ export function sleep(delay_ms: number): void;
+
+ /**
+ * Sleep asynchronously for the specified duration.
+ * @param delay_ms The delay in milliseconds.
+ * @returns A promise that resolves after the specified delay.
+ */
+ export function sleepAsync(delay_ms: number): Promise;
+
+ /**
+ * Get a high-precision timestamp.
+ * @returns A timestamp in milliseconds with more precision than `Date.now()`.
+ */
+ export function now(): number;
+
+ /**
+ * Call a function after a specified delay.
+ * @param func The function to call.
+ * @param delay The delay in milliseconds.
+ * @returns A timer handle.
+ */
+ export function setTimeout(func: () => void, delay: number): number;
+
+ /**
+ * Cancel a timer.
+ * @param handle The timer handle to cancel.
+ */
+ export function clearTimeout(handle: number): void;
+
+ /**
+ * Get the platform string.
+ * @returns A string representing the platform: "linux", "darwin", "win32", or "js".
+ */
+ export function platform(): "linux" | "darwin" | "win32" | "js";
+
+ /**
+ * Worker constructor for creating a new thread.
+ * @param module_filename The module filename to execute in the new thread.
+ */
+ export class Worker {
+ constructor(module_filename: string);
+
+ /**
+ * Send a message to the corresponding worker.
+ * @param msg The message to send.
+ */
+ postMessage(msg: any): void;
+
+ /**
+ * Set a function to handle received messages.
+ * @param handler A function that receives a single argument containing the message.
+ */
+ onmessage: ((msg: { data: any }) => void) | null;
+
+ /** Represents the parent worker in the created worker. */
+ static parent: Worker;
+ }
+}
+
+
+declare module 'jamfile:yaml' {
+
+ export type SchemaType = "failsafe" | "json" | "core" | "default" | "extended";
+ export type StyleVariant =
+ | "lowercase"
+ | "uppercase"
+ | "camelcase"
+ | "decimal"
+ | "binary"
+ | "octal"
+ | "hexadecimal";
+
+ export type StringifyOptions = {
+ /**
+ * Indentation width to use (in spaces).
+ *
+ * @default {2}
+ */
+ indent?: number;
+ /**
+ * When true, adds an indentation level to array elements.
+ *
+ * @default {true}
+ */
+ arrayIndent?: boolean;
+ /**
+ * Do not throw on invalid types (like function in the safe schema) and skip
+ * pairs and single values with such types.
+ *
+ * @default {false}
+ */
+ skipInvalid?: boolean;
+ /**
+ * Specifies level of nesting, when to switch from block to flow style for
+ * collections. `-1` means block style everywhere.
+ *
+ * @default {-1}
+ */
+ flowLevel?: number;
+ /** Each tag may have own set of styles. - "tag" => "style" map. */
+ styles?: Record;
+ /**
+ * Name of the schema to use.
+ *
+ * @default {"default"}
+ */
+ schema?: SchemaType;
+ /**
+ * If true, sort keys when dumping YAML in ascending, ASCII character order.
+ * If a function, use the function to sort the keys.
+ * If a function is specified, the function must return a negative value
+ * if first argument is less than second argument, zero if they're equal
+ * and a positive value otherwise.
+ *
+ * @default {false}
+ */
+ sortKeys?: boolean | ((a: string, b: string) => number);
+ /**
+ * Set max line width.
+ *
+ * @default {80}
+ */
+ lineWidth?: number;
+ /**
+ * If false, don't convert duplicate objects into references.
+ *
+ * @default {true}
+ */
+ useAnchors?: boolean;
+ /**
+ * If false don't try to be compatible with older yaml versions.
+ * Currently: don't quote "yes", "no" and so on,
+ * as required for YAML 1.1.
+ *
+ * @default {true}
+ */
+ compatMode?: boolean;
+ /**
+ * If true flow sequences will be condensed, omitting the
+ * space between `key: value` or `a, b`. Eg. `'[a,b]'` or `{a:{b:c}}`.
+ * Can be useful when using yaml for pretty URL query params
+ * as spaces are %-encoded.
+ *
+ * @default {false}
+ */
+ condenseFlow?: boolean;
+ };
+
+ export function stringify(data: unknown, options?: StringifyOptions): string;
+
+
+ export interface ParseOptions {
+ /**
+ * Name of the schema to use.
+ *
+ * @default {"default"}
+ */
+ schema?: SchemaType;
+ /**
+ * If `true`, duplicate keys will overwrite previous values. Otherwise,
+ * duplicate keys will throw a {@linkcode SyntaxError}.
+ *
+ * @default {false}
+ */
+ allowDuplicateKeys?: boolean;
+ /**
+ * If defined, a function to call on warning messages taking an
+ * {@linkcode Error} as its only argument.
+ */
+ onWarning?(error: Error): void;
+ }
+
+ export function parse(content: string, options?: ParseOptions): unknown;
+ export function parseAll(content: string, options?: ParseOptions): unknown;
+
+
+}
+
+declare module 'jamfile:toml' {
+
+ export interface StringifyOptions {
+ /**
+ * Define if the keys should be aligned or not.
+ *
+ * @default {false}
+ */
+ keyAlignment?: boolean;
+ }
+
+ export function stringify(obj: Record, options?: StringifyOptions): string;
+
+ export function parse(tomlString: string): Record;
+}
+
+declare module 'jamfile:frontmatter' {
+
+ export type Format = "yaml" | "toml" | "json";
+
+ export function test(str: string, formats?: Format[]): boolean;
+
+ export type Extract = {
+ frontMatter: string;
+ body: string;
+ attrs: T;
+ };
+
+ export function extractJson(text: string): Extract;
+ export function extractToml(text: string): Extract;
+ export function extractYaml(text: string): Extract;
+}
+
+declare module 'jamfile:marked' {
+ export type MarkedToken = (Tokens.Blockquote | Tokens.Br | Tokens.Code | Tokens.Codespan | Tokens.Def | Tokens.Del | Tokens.Em | Tokens.Escape | Tokens.Heading | Tokens.Hr | Tokens.HTML | Tokens.Image | Tokens.Link | Tokens.List | Tokens.ListItem | Tokens.Paragraph | Tokens.Space | Tokens.Strong | Tokens.Table | Tokens.Tag | Tokens.Text);
+ export type Token = (MarkedToken | Tokens.Generic);
+ export namespace Tokens {
+ interface Blockquote {
+ type: "blockquote";
+ raw: string;
+ text: string;
+ tokens: Token[];
+ }
+ interface Br {
+ type: "br";
+ raw: string;
+ }
+ interface Checkbox {
+ checked: boolean;
+ }
+ interface Code {
+ type: "code";
+ raw: string;
+ codeBlockStyle?: "indented";
+ lang?: string;
+ text: string;
+ escaped?: boolean;
+ }
+ interface Codespan {
+ type: "codespan";
+ raw: string;
+ text: string;
+ }
+ interface Def {
+ type: "def";
+ raw: string;
+ tag: string;
+ href: string;
+ title: string;
+ }
+ interface Del {
+ type: "del";
+ raw: string;
+ text: string;
+ tokens: Token[];
+ }
+ interface Em {
+ type: "em";
+ raw: string;
+ text: string;
+ tokens: Token[];
+ }
+ interface Escape {
+ type: "escape";
+ raw: string;
+ text: string;
+ }
+ interface Generic {
+ [index: string]: any;
+ type: string;
+ raw: string;
+ tokens?: Token[];
+ }
+ interface Heading {
+ type: "heading";
+ raw: string;
+ depth: number;
+ text: string;
+ tokens: Token[];
+ }
+ interface Hr {
+ type: "hr";
+ raw: string;
+ }
+ interface HTML {
+ type: "html";
+ raw: string;
+ pre: boolean;
+ text: string;
+ block: boolean;
+ }
+ interface Image {
+ type: "image";
+ raw: string;
+ href: string;
+ title: string | null;
+ text: string;
+ }
+ interface Link {
+ type: "link";
+ raw: string;
+ href: string;
+ title?: string | null;
+ text: string;
+ tokens: Token[];
+ }
+ interface List {
+ type: "list";
+ raw: string;
+ ordered: boolean;
+ start: number | "";
+ loose: boolean;
+ items: ListItem[];
+ }
+ interface ListItem {
+ type: "list_item";
+ raw: string;
+ task: boolean;
+ checked?: boolean;
+ loose: boolean;
+ text: string;
+ tokens: Token[];
+ }
+ interface Paragraph {
+ type: "paragraph";
+ raw: string;
+ pre?: boolean;
+ text: string;
+ tokens: Token[];
+ }
+ interface Space {
+ type: "space";
+ raw: string;
+ }
+ interface Strong {
+ type: "strong";
+ raw: string;
+ text: string;
+ tokens: Token[];
+ }
+ interface Table {
+ type: "table";
+ raw: string;
+ align: Array<"center" | "left" | "right" | null>;
+ header: TableCell[];
+ rows: TableCell[][];
+ }
+ interface TableCell {
+ text: string;
+ tokens: Token[];
+ header: boolean;
+ align: "center" | "left" | "right" | null;
+ }
+ interface TableRow {
+ text: string;
+ }
+ interface Tag {
+ type: "html";
+ raw: string;
+ inLink: boolean;
+ inRawBlock: boolean;
+ text: string;
+ block: boolean;
+ }
+ interface Text {
+ type: "text";
+ raw: string;
+ text: string;
+ tokens?: Token[];
+ escaped?: boolean;
+ }
+ }
+ export type Links = Record>;
+ export type TokensList = Token[] & {
+ links: Links;
+ };
+ /**
+ * Renderer
+ */
+ class _Renderer {
+ options: MarkedOptions;
+ parser: _Parser;
+ constructor(options?: MarkedOptions);
+ space(token: Tokens.Space): string;
+ code({ text, lang, escaped }: Tokens.Code): string;
+ blockquote({ tokens }: Tokens.Blockquote): string;
+ html({ text }: Tokens.HTML | Tokens.Tag): string;
+ heading({ tokens, depth }: Tokens.Heading): string;
+ hr(token: Tokens.Hr): string;
+ list(token: Tokens.List): string;
+ listitem(item: Tokens.ListItem): string;
+ checkbox({ checked }: Tokens.Checkbox): string;
+ paragraph({ tokens }: Tokens.Paragraph): string;
+ table(token: Tokens.Table): string;
+ tablerow({ text }: Tokens.TableRow): string;
+ tablecell(token: Tokens.TableCell): string;
+ /**
+ * span level renderer
+ */
+ strong({ tokens }: Tokens.Strong): string;
+ em({ tokens }: Tokens.Em): string;
+ codespan({ text }: Tokens.Codespan): string;
+ br(token: Tokens.Br): string;
+ del({ tokens }: Tokens.Del): string;
+ link({ href, title, tokens }: Tokens.Link): string;
+ image({ href, title, text }: Tokens.Image): string;
+ text(token: Tokens.Text | Tokens.Escape): string;
+ }
+ /**
+ * TextRenderer
+ * returns only the textual part of the token
+ */
+ class _TextRenderer {
+ strong({ text }: Tokens.Strong): string;
+ em({ text }: Tokens.Em): string;
+ codespan({ text }: Tokens.Codespan): string;
+ del({ text }: Tokens.Del): string;
+ html({ text }: Tokens.HTML | Tokens.Tag): string;
+ text({ text }: Tokens.Text | Tokens.Escape | Tokens.Tag): string;
+ link({ text }: Tokens.Link): string;
+ image({ text }: Tokens.Image): string;
+ br(): string;
+ }
+ /**
+ * Parsing & Compiling
+ */
+ class _Parser {
+ options: MarkedOptions;
+ renderer: _Renderer;
+ textRenderer: _TextRenderer;
+ constructor(options?: MarkedOptions);
+ /**
+ * Static Parse Method
+ */
+ static parse(tokens: Token[], options?: MarkedOptions): string;
+ /**
+ * Static Parse Inline Method
+ */
+ static parseInline(tokens: Token[], options?: MarkedOptions): string;
+ /**
+ * Parse Loop
+ */
+ parse(tokens: Token[], top?: boolean): string;
+ /**
+ * Parse Inline Tokens
+ */
+ parseInline(tokens: Token[], renderer?: _Renderer | _TextRenderer): string;
+ }
+ const other: {
+ codeRemoveIndent: RegExp;
+ outputLinkReplace: RegExp;
+ indentCodeCompensation: RegExp;
+ beginningSpace: RegExp;
+ endingHash: RegExp;
+ startingSpaceChar: RegExp;
+ endingSpaceChar: RegExp;
+ nonSpaceChar: RegExp;
+ newLineCharGlobal: RegExp;
+ tabCharGlobal: RegExp;
+ multipleSpaceGlobal: RegExp;
+ blankLine: RegExp;
+ doubleBlankLine: RegExp;
+ blockquoteStart: RegExp;
+ blockquoteSetextReplace: RegExp;
+ blockquoteSetextReplace2: RegExp;
+ listReplaceTabs: RegExp;
+ listReplaceNesting: RegExp;
+ listIsTask: RegExp;
+ listReplaceTask: RegExp;
+ anyLine: RegExp;
+ hrefBrackets: RegExp;
+ tableDelimiter: RegExp;
+ tableAlignChars: RegExp;
+ tableRowBlankLine: RegExp;
+ tableAlignRight: RegExp;
+ tableAlignCenter: RegExp;
+ tableAlignLeft: RegExp;
+ startATag: RegExp;
+ endATag: RegExp;
+ startPreScriptTag: RegExp;
+ endPreScriptTag: RegExp;
+ startAngleBracket: RegExp;
+ endAngleBracket: RegExp;
+ pedanticHrefTitle: RegExp;
+ unicodeAlphaNumeric: RegExp;
+ escapeTest: RegExp;
+ escapeReplace: RegExp;
+ escapeTestNoEncode: RegExp;
+ escapeReplaceNoEncode: RegExp;
+ unescapeTest: RegExp;
+ caret: RegExp;
+ percentDecode: RegExp;
+ findPipe: RegExp;
+ splitPipe: RegExp;
+ slashPipe: RegExp;
+ carriageReturn: RegExp;
+ spaceLine: RegExp;
+ notSpaceStart: RegExp;
+ endingNewline: RegExp;
+ listItemRegex: (bull: string) => RegExp;
+ nextBulletRegex: (indent: number) => RegExp;
+ hrRegex: (indent: number) => RegExp;
+ fencesBeginRegex: (indent: number) => RegExp;
+ headingBeginRegex: (indent: number) => RegExp;
+ htmlBeginRegex: (indent: number) => RegExp;
+ };
+ const blockNormal: {
+ blockquote: RegExp;
+ code: RegExp;
+ def: RegExp;
+ fences: RegExp;
+ heading: RegExp;
+ hr: RegExp;
+ html: RegExp;
+ lheading: RegExp;
+ list: RegExp;
+ newline: RegExp;
+ paragraph: RegExp;
+ table: RegExp;
+ text: RegExp;
+ };
+ export type BlockKeys = keyof typeof blockNormal;
+ const inlineNormal: {
+ _backpedal: RegExp;
+ anyPunctuation: RegExp;
+ autolink: RegExp;
+ blockSkip: RegExp;
+ br: RegExp;
+ code: RegExp;
+ del: RegExp;
+ emStrongLDelim: RegExp;
+ emStrongRDelimAst: RegExp;
+ emStrongRDelimUnd: RegExp;
+ escape: RegExp;
+ link: RegExp;
+ nolink: RegExp;
+ punctuation: RegExp;
+ reflink: RegExp;
+ reflinkSearch: RegExp;
+ tag: RegExp;
+ text: RegExp;
+ url: RegExp;
+ };
+ export type InlineKeys = keyof typeof inlineNormal;
+ export interface Rules {
+ other: typeof other;
+ block: Record;
+ inline: Record;
+ }
+ /**
+ * Tokenizer
+ */
+ class _Tokenizer {
+ options: MarkedOptions;
+ rules: Rules;
+ lexer: _Lexer;
+ constructor(options?: MarkedOptions);
+ space(src: string): Tokens.Space | undefined;
+ code(src: string): Tokens.Code | undefined;
+ fences(src: string): Tokens.Code | undefined;
+ heading(src: string): Tokens.Heading | undefined;
+ hr(src: string): Tokens.Hr | undefined;
+ blockquote(src: string): Tokens.Blockquote | undefined;
+ list(src: string): Tokens.List | undefined;
+ html(src: string): Tokens.HTML | undefined;
+ def(src: string): Tokens.Def | undefined;
+ table(src: string): Tokens.Table | undefined;
+ lheading(src: string): Tokens.Heading | undefined;
+ paragraph(src: string): Tokens.Paragraph | undefined;
+ text(src: string): Tokens.Text | undefined;
+ escape(src: string): Tokens.Escape | undefined;
+ tag(src: string): Tokens.Tag | undefined;
+ link(src: string): Tokens.Link | Tokens.Image | undefined;
+ reflink(src: string, links: Links): Tokens.Link | Tokens.Image | Tokens.Text | undefined;
+ emStrong(src: string, maskedSrc: string, prevChar?: string): Tokens.Em | Tokens.Strong | undefined;
+ codespan(src: string): Tokens.Codespan | undefined;
+ br(src: string): Tokens.Br | undefined;
+ del(src: string): Tokens.Del | undefined;
+ autolink(src: string): Tokens.Link | undefined;
+ url(src: string): Tokens.Link | undefined;
+ inlineText(src: string): Tokens.Text | undefined;
+ }
+ class _Hooks {
+ options: MarkedOptions;
+ block?: boolean;
+ constructor(options?: MarkedOptions);
+ static passThroughHooks: Set;
+ /**
+ * Process markdown before marked
+ */
+ preprocess(markdown: string): string;
+ /**
+ * Process HTML after marked is finished
+ */
+ postprocess(html: string): string;
+ /**
+ * Process all tokens before walk tokens
+ */
+ processAllTokens(tokens: Token[] | TokensList): Token[] | TokensList;
+ /**
+ * Provide function to tokenize markdown
+ */
+ provideLexer(): typeof _Lexer.lexInline;
+ /**
+ * Provide function to parse tokens
+ */
+ provideParser(): typeof _Parser.parse;
+ }
+ export interface TokenizerThis {
+ lexer: _Lexer;
+ }
+ export type TokenizerExtensionFunction = (this: TokenizerThis, src: string, tokens: Token[] | TokensList) => Tokens.Generic | undefined;
+ export type TokenizerStartFunction = (this: TokenizerThis, src: string) => number | void;
+ export interface TokenizerExtension {
+ name: string;
+ level: "block" | "inline";
+ start?: TokenizerStartFunction;
+ tokenizer: TokenizerExtensionFunction;
+ childTokens?: string[];
+ }
+ export interface RendererThis {
+ parser: _Parser;
+ }
+ export type RendererExtensionFunction = (this: RendererThis, token: Tokens.Generic) => string | false | undefined;
+ export interface RendererExtension {
+ name: string;
+ renderer: RendererExtensionFunction;
+ }
+ export type TokenizerAndRendererExtension = TokenizerExtension | RendererExtension | (TokenizerExtension & RendererExtension);
+ export type HooksApi = Omit<_Hooks, "constructor" | "options" | "block">;
+ export type HooksObject = {
+ [K in keyof HooksApi]?: (this: _Hooks, ...args: Parameters) => ReturnType | Promise>;
+ };
+ export type RendererApi = Omit<_Renderer, "constructor" | "options" | "parser">;
+ export type RendererObject = {
+ [K in keyof RendererApi]?: (this: _Renderer, ...args: Parameters) => ReturnType | false;
+ };
+ export type TokenizerApi = Omit<_Tokenizer, "constructor" | "options" | "rules" | "lexer">;
+ export type TokenizerObject = {
+ [K in keyof TokenizerApi]?: (this: _Tokenizer, ...args: Parameters) => ReturnType | false;
+ };
+ export interface MarkedExtension {
+ /**
+ * True will tell marked to await any walkTokens functions before parsing the tokens and returning an HTML string.
+ */
+ async?: boolean;
+ /**
+ * Enable GFM line breaks. This option requires the gfm option to be true.
+ */
+ breaks?: boolean;
+ /**
+ * Add tokenizers and renderers to marked
+ */
+ extensions?: TokenizerAndRendererExtension[] | null;
+ /**
+ * Enable GitHub flavored markdown.
+ */
+ gfm?: boolean;
+ /**
+ * Hooks are methods that hook into some part of marked.
+ * preprocess is called to process markdown before sending it to marked.
+ * processAllTokens is called with the TokensList before walkTokens.
+ * postprocess is called to process html after marked has finished parsing.
+ * provideLexer is called to provide a function to tokenize markdown.
+ * provideParser is called to provide a function to parse tokens.
+ */
+ hooks?: HooksObject | null;
+ /**
+ * Conform to obscure parts of markdown.pl as much as possible. Don't fix any of the original markdown bugs or poor behavior.
+ */
+ pedantic?: boolean;
+ /**
+ * Type: object Default: new Renderer()
+ *
+ * An object containing functions to render tokens to HTML.
+ */
+ renderer?: RendererObject | null;
+ /**
+ * Shows an HTML error message when rendering fails.
+ */
+ silent?: boolean;
+ /**
+ * The tokenizer defines how to turn markdown text into tokens.
+ */
+ tokenizer?: TokenizerObject | null;
+ /**
+ * The walkTokens function gets called with every token.
+ * Child tokens are called before moving on to sibling tokens.
+ * Each token is passed by reference so updates are persisted when passed to the parser.
+ * The return value of the function is ignored.
+ */
+ walkTokens?: ((token: Token) => void | Promise) | null;
+ }
+ export interface MarkedOptions extends Omit {
+ /**
+ * Hooks are methods that hook into some part of marked.
+ */
+ hooks?: _Hooks | null;
+ /**
+ * Type: object Default: new Renderer()
+ *
+ * An object containing functions to render tokens to HTML.
+ */
+ renderer?: _Renderer | null;
+ /**
+ * The tokenizer defines how to turn markdown text into tokens.
+ */
+ tokenizer?: _Tokenizer | null;
+ /**
+ * Custom extensions
+ */
+ extensions?: null | {
+ renderers: {
+ [name: string]: RendererExtensionFunction;
+ };
+ childTokens: {
+ [name: string]: string[];
+ };
+ inline?: TokenizerExtensionFunction[];
+ block?: TokenizerExtensionFunction[];
+ startInline?: TokenizerStartFunction[];
+ startBlock?: TokenizerStartFunction[];
+ };
+ /**
+ * walkTokens function returns array of values for Promise.all
+ */
+ walkTokens?: null | ((token: Token) => void | Promise | (void | Promise)[]);
+ }
+ /**
+ * Block Lexer
+ */
+ class _Lexer {
+ tokens: TokensList;
+ options: MarkedOptions;
+ state: {
+ inLink: boolean;
+ inRawBlock: boolean;
+ top: boolean;
+ };
+ private tokenizer;
+ private inlineQueue;
+ constructor(options?: MarkedOptions);
+ /**
+ * Expose Rules
+ */
+ static get rules(): {
+ block: {
+ normal: {
+ blockquote: RegExp;
+ code: RegExp;
+ def: RegExp;
+ fences: RegExp;
+ heading: RegExp;
+ hr: RegExp;
+ html: RegExp;
+ lheading: RegExp;
+ list: RegExp;
+ newline: RegExp;
+ paragraph: RegExp;
+ table: RegExp;
+ text: RegExp;
+ };
+ gfm: Record<"code" | "blockquote" | "hr" | "html" | "table" | "text" | "def" | "heading" | "list" | "paragraph" | "fences" | "lheading" | "newline", RegExp>;
+ pedantic: Record<"code" | "blockquote" | "hr" | "html" | "table" | "text" | "def" | "heading" | "list" | "paragraph" | "fences" | "lheading" | "newline", RegExp>;
+ };
+ inline: {
+ normal: {
+ _backpedal: RegExp;
+ anyPunctuation: RegExp;
+ autolink: RegExp;
+ blockSkip: RegExp;
+ br: RegExp;
+ code: RegExp;
+ del: RegExp;
+ emStrongLDelim: RegExp;
+ emStrongRDelimAst: RegExp;
+ emStrongRDelimUnd: RegExp;
+ escape: RegExp;
+ link: RegExp;
+ nolink: RegExp;
+ punctuation: RegExp;
+ reflink: RegExp;
+ reflinkSearch: RegExp;
+ tag: RegExp;
+ text: RegExp;
+ url: RegExp;
+ };
+ gfm: Record<"link" | "code" | "url" | "br" | "del" | "text" | "escape" | "tag" | "reflink" | "nolink" | "_backpedal" | "anyPunctuation" | "autolink" | "blockSkip" | "emStrongLDelim" | "emStrongRDelimAst" | "emStrongRDelimUnd" | "punctuation" | "reflinkSearch", RegExp>;
+ breaks: Record<"link" | "code" | "url" | "br" | "del" | "text" | "escape" | "tag" | "reflink" | "nolink" | "_backpedal" | "anyPunctuation" | "autolink" | "blockSkip" | "emStrongLDelim" | "emStrongRDelimAst" | "emStrongRDelimUnd" | "punctuation" | "reflinkSearch", RegExp>;
+ pedantic: Record<"link" | "code" | "url" | "br" | "del" | "text" | "escape" | "tag" | "reflink" | "nolink" | "_backpedal" | "anyPunctuation" | "autolink" | "blockSkip" | "emStrongLDelim" | "emStrongRDelimAst" | "emStrongRDelimUnd" | "punctuation" | "reflinkSearch", RegExp>;
+ };
+ };
+ /**
+ * Static Lex Method
+ */
+ static lex(src: string, options?: MarkedOptions): TokensList;
+ /**
+ * Static Lex Inline Method
+ */
+ static lexInline(src: string, options?: MarkedOptions): Token[];
+ /**
+ * Preprocessing
+ */
+ lex(src: string): TokensList;
+ /**
+ * Lexing
+ */
+ blockTokens(src: string, tokens?: Token[], lastParagraphClipped?: boolean): Token[];
+ blockTokens(src: string, tokens?: TokensList, lastParagraphClipped?: boolean): TokensList;
+ inline(src: string, tokens?: Token[]): Token[];
+ /**
+ * Lexing/Compiling
+ */
+ inlineTokens(src: string, tokens?: Token[]): Token[];
+ }
+ /**
+ * Gets the original marked default options.
+ */
+ function _getDefaults(): MarkedOptions;
+ let _defaults: MarkedOptions;
+ export type MaybePromise = void | Promise;
+ export class Marked {
+ defaults: MarkedOptions;
+ options: (opt: MarkedOptions) => this;
+ parse: {
+ (src: string, options: MarkedOptions & {
+ async: true;
+ }): Promise;
+ (src: string, options: MarkedOptions & {
+ async: false;
+ }): string;
+ (src: string, options?: MarkedOptions | null): string | Promise;
+ };
+ parseInline: {
+ (src: string, options: MarkedOptions & {
+ async: true;
+ }): Promise;
+ (src: string, options: MarkedOptions & {
+ async: false;
+ }): string;
+ (src: string, options?: MarkedOptions | null): string | Promise;
+ };
+ Parser: typeof _Parser;
+ Renderer: typeof _Renderer;
+ TextRenderer: typeof _TextRenderer;
+ Lexer: typeof _Lexer;
+ Tokenizer: typeof _Tokenizer;
+ Hooks: typeof _Hooks;
+ constructor(...args: MarkedExtension[]);
+ /**
+ * Run callback for every token
+ */
+ walkTokens(tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]): MaybePromise[];
+ use(...args: MarkedExtension[]): this;
+ setOptions(opt: MarkedOptions): this;
+ lexer(src: string, options?: MarkedOptions): TokensList;
+ parser(tokens: Token[], options?: MarkedOptions): string;
+ private parseMarkdown;
+ private onError;
+ }
+ /**
+ * Compiles markdown to HTML asynchronously.
+ *
+ * @param src String of markdown source to be compiled
+ * @param options Hash of options, having async: true
+ * @return Promise of string of compiled HTML
+ */
+ export function marked(src: string, options: MarkedOptions & {
+ async: true;
+ }): Promise;
+ /**
+ * Compiles markdown to HTML.
+ *
+ * @param src String of markdown source to be compiled
+ * @param options Optional hash of options
+ * @return String of compiled HTML. Will be a Promise of string if async is set to true by any extensions.
+ */
+ export function marked(src: string, options: MarkedOptions & {
+ async: false;
+ }): string;
+ export function marked(src: string, options: MarkedOptions & {
+ async: true;
+ }): Promise;
+ export function marked(src: string, options?: MarkedOptions | null): string | Promise;
+ export namespace marked {
+ var options: (options: MarkedOptions) => typeof marked;
+ var setOptions: (options: MarkedOptions) => typeof marked;
+ var getDefaults: typeof _getDefaults;
+ var defaults: MarkedOptions;
+ var use: (...args: MarkedExtension[]) => typeof marked;
+ var walkTokens: (tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]) => MaybePromise[];
+ var parseInline: {
+ (src: string, options: MarkedOptions & {
+ async: true;
+ }): Promise;
+ (src: string, options: MarkedOptions & {
+ async: false;
+ }): string;
+ (src: string, options?: MarkedOptions | null): string | Promise;
+ };
+ var Parser: typeof _Parser;
+ var parser: typeof _Parser.parse;
+ var Renderer: typeof _Renderer;
+ var TextRenderer: typeof _TextRenderer;
+ var Lexer: typeof _Lexer;
+ var lexer: typeof _Lexer.lex;
+ var Tokenizer: typeof _Tokenizer;
+ var Hooks: typeof _Hooks;
+ var parse: typeof marked;
+ }
+ export const options: (options: MarkedOptions) => typeof marked;
+ export const setOptions: (options: MarkedOptions) => typeof marked;
+ export const use: (...args: MarkedExtension[]) => typeof marked;
+ export const walkTokens: (tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]) => MaybePromise[];
+ export const parseInline: {
+ (src: string, options: MarkedOptions & {
+ async: true;
+ }): Promise;
+ (src: string, options: MarkedOptions & {
+ async: false;
+ }): string;
+ (src: string, options?: MarkedOptions | null): string | Promise;
+ };
+ export const parse: typeof marked;
+ export const parser: typeof _Parser.parse;
+ export const lexer: typeof _Lexer.lex;
+
+ export {
+ _Hooks as Hooks,
+ _Lexer as Lexer,
+ _Parser as Parser,
+ _Renderer as Renderer,
+ _TextRenderer as TextRenderer,
+ _Tokenizer as Tokenizer,
+ _defaults as defaults,
+ _getDefaults as getDefaults,
+ };
+}
+/**
+* Read and write data to SQLite databases.
+*
+* @module jamfile:sqlite
+*/
+declare module 'jamfile:sqlite'{
+
+ /**
+ * SQLite library version string
+ */
+ export const SQLITE_VERSION: string;
+
+ export type SqlValue =
+ | number
+ | string
+ | Uint8Array // BLOB or // sqlite-vec bit vector
+ | Float32Array // sqlite-vec float32 vector
+ | Int8Array // sqlite-vec int8 vector
+ | null;
+
+ export type SqlParameterValue =
+ | number
+ | string
+ | null
+ | Uint8Array
+ | ArrayBufferView
+ | Date;
+
+ /**
+ * "Escapes" a astring for usage as an identifier in SQL. Must be wrapped by double quotes.
+ *
+ * Internally uses the "%w" substitution in SQLite's custom printf https://www.sqlite.org/printf.html#percentw
+ *
+ * @param identifier string identifier to escape.
+ */
+ export function escapeIdentifier(identifier: string): string;
+
+ export class Database {
+ /**
+ * Opens a SQLite database.
+ *
+ * @param path The path of the database.
+ */
+ constructor(path: string);
+
+ /**
+ * Execute a SQL query and return the first value of the first row.
+ *
+ * Throws an error in the following cases:
+ * - Preparing the SQL query fails
+ * - The SQL query doesn't return any rows
+ * - The SQL query is not read-only
+ * @param sql
+ * @param params
+ */
+ queryValue(sql: string, params?: SqlParameterValue[]) : SqlValue;
+ queryRow(sql: string, params?: SqlParameterValue[]) : {[key: string]: SqlValue};
+ queryAll(sql: string, params?: SqlParameterValue[]) : {[key: string]: SqlValue}[];
+
+ execute(sql: string, params?: SqlParameterValue[]): void;
+ executeScript(sql: string): void;
+
+ }
+}
+
+
+declare module 'jamfile:llamafile' {
+
+ export class TextEmbeddingModel {
+ constructor(path?:string);
+
+ /**
+ * number of dimensions per embedding, ex 386, 768, 1024, etc
+ */
+ dimensions: number;
+
+ embed(input: string): Float32Array;
+ tokenize(input: string): Int32Array;
+ detokenize(input: Int32Array): string;
+ }
+
+ export type CompletionOptions = {
+ schema: JSONSchema7 | string,
+ parse: (response:string) => T;
+ };
+
+ export class CompletionModel {
+ /**
+ * A string description the "type" of the underyling model.
+ *
+ * Result of the `llama_model_desc()` C function.
+ *
+ */
+ description: string;
+
+ constructor(model_path?: string);
+
+ complete(input: string, options?: CompletionOptions): string | T;
+ tokenize(input: string): Int32Array;
+ detokenize(input: Int32Array): string;
+ }
+}
+
+declare module 'jamfile:cli' {
+ /** Combines recursively all intersection types and returns a new single type.
+ * @internal
+ */
+ type Id = TRecord extends Record
+ ? TRecord extends infer InferredRecord
+ ? { [Key in keyof InferredRecord]: Id }
+ : never
+ : TRecord;
+
+ /** Converts a union type `A | B | C` into an intersection type `A & B & C`.
+ * @internal
+ */
+ type UnionToIntersection =
+ (TValue extends unknown ? (args: TValue) => unknown : never) extends
+ (args: infer R) => unknown ? R extends Record ? R : never
+ : never;
+
+ /** @internal */
+ type BooleanType = boolean | string | undefined;
+ /** @internal */
+ type StringType = string | undefined;
+ /** @internal */
+ type ArgType = StringType | BooleanType;
+
+ /** @internal */
+ type Collectable = string | undefined;
+ /** @internal */
+ type Negatable = string | undefined;
+
+ type UseTypes<
+ TBooleans extends BooleanType,
+ TStrings extends StringType,
+ TCollectable extends Collectable,
+ > = undefined extends (
+ & (false extends TBooleans ? undefined : TBooleans)
+ & TCollectable
+ & TStrings
+ ) ? false
+ : true;
+
+ /**
+ * Creates a record with all available flags with the corresponding type and
+ * default type.
+ * @internal
+ */
+ type Values<
+ TBooleans extends BooleanType,
+ TStrings extends StringType,
+ TCollectable extends Collectable,
+ TNegatable extends Negatable,
+ TDefault extends Record | undefined,
+ TAliases extends Aliases | undefined,
+ > = UseTypes extends true ?
+ & Record
+ & AddAliases<
+ SpreadDefaults<
+ & CollectValues
+ & RecursiveRequired>
+ & CollectUnknownValues<
+ TBooleans,
+ TStrings,
+ TCollectable,
+ TNegatable
+ >,
+ DedotRecord
+ >,
+ TAliases
+ >
+ // deno-lint-ignore no-explicit-any
+ : Record;
+
+ /** @internal */
+ type Aliases = Partial<
+ Record, TAliasNames | ReadonlyArray>
+ >;
+
+ type AddAliases<
+ TArgs,
+ TAliases extends Aliases | undefined,
+ > = {
+ [TArgName in keyof TArgs as AliasNames]: TArgs[TArgName];
+ };
+
+ type AliasNames<
+ TArgName,
+ TAliases extends Aliases | undefined,
+ > = TArgName extends keyof TAliases
+ ? string extends TAliases[TArgName] ? TArgName
+ : TAliases[TArgName] extends string ? TArgName | TAliases[TArgName]
+ : TAliases[TArgName] extends Array
+ ? TArgName | TAliases[TArgName][number]
+ : TArgName
+ : TArgName;
+
+ /**
+ * Spreads all default values of Record `TDefaults` into Record `TArgs`
+ * and makes default values required.
+ *
+ * **Example:**
+ * `SpreadValues<{ foo?: boolean, bar?: number }, { foo: number }>`
+ *
+ * **Result:** `{ foo: boolean | number, bar?: number }`
+ */
+ type SpreadDefaults = TDefaults extends undefined ? TArgs
+ : TArgs extends Record ?
+ & Omit
+ & {
+ [Default in keyof TDefaults]: Default extends keyof TArgs
+ ? (TArgs[Default] & TDefaults[Default] | TDefaults[Default]) extends
+ Record
+ ? NonNullable>
+ : TDefaults[Default] | NonNullable
+ : unknown;
+ }
+ : never;
+
+ /**
+ * Defines the Record for the `default` option to add
+ * auto-suggestion support for IDE's.
+ * @internal
+ */
+ type Defaults = Id<
+ UnionToIntersection<
+ & Record
+ // Dedotted auto suggestions: { foo: { bar: unknown } }
+ & MapTypes
+ & MapTypes
+ // Flat auto suggestions: { "foo.bar": unknown }
+ & MapDefaults
+ & MapDefaults
+ >
+ >;
+
+ type MapDefaults = Partial<
+ Record
+ >;
+
+ type RecursiveRequired = TRecord extends Record ? {
+ [Key in keyof TRecord]-?: RecursiveRequired;
+ }
+ : TRecord;
+
+ /** Same as `MapTypes` but also supports collectable options. */
+ type CollectValues<
+ TArgNames extends ArgType,
+ TType,
+ TCollectable extends Collectable,
+ TNegatable extends Negatable = undefined,
+ > = UnionToIntersection<
+ Extract extends string ?
+ & (Exclude extends never ? Record
+ : MapTypes, TType, TNegatable>)
+ & (Extract extends never ? Record
+ : RecursiveRequired<
+ MapTypes, Array, TNegatable>
+ >)
+ : MapTypes
+ >;
+
+ /** Same as `Record` but also supports dotted and negatable options. */
+ type MapTypes<
+ TArgNames extends ArgType,
+ TType,
+ TNegatable extends Negatable = undefined,
+ > = undefined extends TArgNames ? Record
+ : TArgNames extends `${infer Name}.${infer Rest}` ? {
+ [Key in Name]?: MapTypes<
+ Rest,
+ TType,
+ TNegatable extends `${Name}.${infer Negate}` ? Negate : undefined
+ >;
+ }
+ : TArgNames extends string ? Partial<
+ Record
+ >
+ : Record;
+
+ type CollectUnknownValues<
+ TBooleans extends BooleanType,
+ TStrings extends StringType,
+ TCollectable extends Collectable,
+ TNegatable extends Negatable,
+ > = UnionToIntersection<
+ TCollectable extends TBooleans & TStrings ? Record
+ : DedotRecord<
+ // Unknown collectable & non-negatable args.
+ & Record<
+ Exclude<
+ Extract, string>,
+ Extract
+ >,
+ Array
+ >
+ // Unknown collectable & negatable args.
+ & Record<
+ Exclude<
+ Extract, string>,
+ Extract
+ >,
+ Array | false
+ >
+ >
+ >;
+
+ /** Converts `{ "foo.bar.baz": unknown }` into `{ foo: { bar: { baz: unknown } } }`. */
+ type DedotRecord = Record extends TRecord ? TRecord
+ : TRecord extends Record ? UnionToIntersection<
+ ValueOf<
+ {
+ [Key in keyof TRecord]: Key extends string ? Dedot
+ : never;
+ }
+ >
+ >
+ : TRecord;
+
+ type Dedot = TKey extends
+ `${infer Name}.${infer Rest}` ? { [Key in Name]: Dedot }
+ : { [Key in TKey]: TValue };
+
+ type ValueOf = TValue[keyof TValue];
+
+ /** The value returned from {@linkcode parseArgs}. */
+ export type Args<
+ // deno-lint-ignore no-explicit-any
+ TArgs extends Record = Record,
+ TDoubleDash extends boolean | undefined = undefined,
+ > = Id<
+ & TArgs
+ & {
+ /** Contains all the arguments that didn't have an option associated with
+ * them. */
+ _: Array;
+ }
+ & (boolean extends TDoubleDash ? DoubleDash
+ : true extends TDoubleDash ? Required
+ : Record)
+ >;
+
+ /** @internal */
+ type DoubleDash = {
+ /** Contains all the arguments that appear after the double dash: "--". */
+ "--"?: Array;
+ };
+
+ /** Options for {@linkcode parseArgs}. */
+ export interface ParseOptions<
+ TBooleans extends BooleanType = BooleanType,
+ TStrings extends StringType = StringType,
+ TCollectable extends Collectable = Collectable,
+ TNegatable extends Negatable = Negatable,
+ TDefault extends Record | undefined =
+ | Record
+ | undefined,
+ TAliases extends Aliases | undefined = Aliases | undefined,
+ TDoubleDash extends boolean | undefined = boolean | undefined,
+ > {
+ /**
+ * When `true`, populate the result `_` with everything before the `--` and
+ * the result `['--']` with everything after the `--`.
+ *
+ * @default {false}
+ *
+ * @example
+ * ```ts
+ * // $ deno run example.ts -- a arg1
+ * import { parseArgs } from "@std/cli/parse-args";
+ * console.dir(parseArgs(Deno.args, { "--": false }));
+ * // output: { _: [ "a", "arg1" ] }
+ * console.dir(parseArgs(Deno.args, { "--": true }));
+ * // output: { _: [], --: [ "a", "arg1" ] }
+ * ```
+ */
+ "--"?: TDoubleDash;
+
+ /**
+ * An object mapping string names to strings or arrays of string argument
+ * names to use as aliases.
+ *
+ * @default {{}}
+ */
+ alias?: TAliases;
+
+ /**
+ * A boolean, string or array of strings to always treat as booleans. If
+ * `true` will treat all double hyphenated arguments without equal signs as
+ * `boolean` (e.g. affects `--foo`, not `-f` or `--foo=bar`).
+ * All `boolean` arguments will be set to `false` by default.
+ *
+ * @default {false}
+ */
+ boolean?: TBooleans | ReadonlyArray>;
+
+ /**
+ * An object mapping string argument names to default values.
+ *
+ * @default {{}}
+ */
+ default?: TDefault & Defaults;
+
+ /**
+ * When `true`, populate the result `_` with everything after the first
+ * non-option.
+ *
+ * @default {false}
+ */
+ stopEarly?: boolean;
+
+ /**
+ * A string or array of strings argument names to always treat as strings.
+ *
+ * @default {[]}
+ */
+ string?: TStrings | ReadonlyArray>;
+
+ /**
+ * A string or array of strings argument names to always treat as arrays.
+ * Collectable options can be used multiple times. All values will be
+ * collected into one array. If a non-collectable option is used multiple
+ * times, the last value is used.
+ *
+ * @default {[]}
+ */
+ collect?: TCollectable | ReadonlyArray>;
+
+ /**
+ * A string or array of strings argument names which can be negated
+ * by prefixing them with `--no-`, like `--no-config`.
+ *
+ * @default {[]}
+ */
+ negatable?: TNegatable | ReadonlyArray>;
+
+ /**
+ * A function which is invoked with a command line parameter not defined in
+ * the `options` configuration object. If the function returns `false`, the
+ * unknown option is not added to `parsedArgs`.
+ *
+ * @default {unknown}
+ */
+ unknown?: (arg: string, key?: string, value?: unknown) => unknown;
+ }
+
+ interface NestedMapping {
+ [key: string]: NestedMapping | unknown;
+ }
+
+ /**
+ * Take a set of command line arguments, optionally with a set of options, and
+ * return an object representing the flags found in the passed arguments.
+ *
+ * By default, any arguments starting with `-` or `--` are considered boolean
+ * flags. If the argument name is followed by an equal sign (`=`) it is
+ * considered a key-value pair. Any arguments which could not be parsed are
+ * available in the `_` property of the returned object.
+ *
+ * By default, this module tries to determine the type of all arguments
+ * automatically and the return type of this function will have an index
+ * signature with `any` as value (`{ [x: string]: any }`).
+ *
+ * If the `string`, `boolean` or `collect` option is set, the return value of
+ * this function will be fully typed and the index signature of the return
+ * type will change to `{ [x: string]: unknown }`.
+ *
+ * Any arguments after `'--'` will not be parsed and will end up in `parsedArgs._`.
+ *
+ * Numeric-looking arguments will be returned as numbers unless `options.string`
+ * or `options.boolean` is set for that argument name.
+ *
+ * @param args An array of command line arguments.
+ * @param options Options for the parse function.
+ *
+ * @typeParam TArgs Type of result.
+ * @typeParam TDoubleDash Used by `TArgs` for the result.
+ * @typeParam TBooleans Used by `TArgs` for the result.
+ * @typeParam TStrings Used by `TArgs` for the result.
+ * @typeParam TCollectable Used by `TArgs` for the result.
+ * @typeParam TNegatable Used by `TArgs` for the result.
+ * @typeParam TDefaults Used by `TArgs` for the result.
+ * @typeParam TAliases Used by `TArgs` for the result.
+ * @typeParam TAliasArgNames Used by `TArgs` for the result.
+ * @typeParam TAliasNames Used by `TArgs` for the result.
+ *
+ * @return The parsed arguments.
+ *
+ * @example Usage
+ * ```ts
+ * import { parseArgs } from "@std/cli/parse-args";
+ * import { assertEquals } from "@std/assert";
+ *
+ * // For proper use, one should use `parseArgs(Deno.args)`
+ * assertEquals(parseArgs(["--foo", "--bar=baz", "./quux.txt"]), {
+ * foo: true,
+ * bar: "baz",
+ * _: ["./quux.txt"],
+ * });
+ * ```
+ */
+ export function parseArgs<
+ TArgs extends Values<
+ TBooleans,
+ TStrings,
+ TCollectable,
+ TNegatable,
+ TDefaults,
+ TAliases
+ >,
+ TDoubleDash extends boolean | undefined = undefined,
+ TBooleans extends BooleanType = undefined,
+ TStrings extends StringType = undefined,
+ TCollectable extends Collectable = undefined,
+ TNegatable extends Negatable = undefined,
+ TDefaults extends Record | undefined = undefined,
+ TAliases extends Aliases | undefined = undefined,
+ TAliasArgNames extends string = string,
+ TAliasNames extends string = string,
+ >(
+ args: string[],
+ options?: ParseOptions<
+ TBooleans,
+ TStrings,
+ TCollectable,
+ TNegatable,
+ TDefaults,
+ TAliases,
+ TDoubleDash
+ >,
+ ): Args;
+}
+
+declare module 'jamfile:fmt' {
+
+ /** Options for {@linkcode format}. */
+ export interface FormatDurationOptions {
+ /**
+ * The style for formatting the duration.
+ *
+ * "narrow" for "0d 0h 0m 0s 0ms..."
+ * "digital" for "00:00:00:00:000..."
+ * "full" for "0 days, 0 hours, 0 minutes,..."
+ *
+ * @default {"narrow"}
+ */
+ style?: "narrow" | "digital" | "full";
+ /**
+ * Whether to ignore zero values.
+ * With style="narrow" | "full", all zero values are ignored.
+ * With style="digital", only values in the ends are ignored.
+ *
+ * @default {false}
+ */
+ ignoreZero?: boolean;
+}
+
+ /**
+ * Format milliseconds to time duration.
+ *
+ * @param ms The milliseconds value to format
+ * @param options The options for formatting
+ * @returns The formatted string
+ */
+ export function formatDuration(
+ ms: number,
+ options?: FormatDurationOptions,
+ ): string;
+
+
+ type LocaleOptions = {
+ minimumFractionDigits?: number;
+ maximumFractionDigits?: number;
+ };
+
+ /** Options for {@linkcode format}. */
+ export interface FormatBytesOptions {
+ /**
+ * Uses bits representation.
+ *
+ * @default {false}
+ */
+ bits?: boolean;
+ /**
+ * Uses binary bytes (e.g. kibibyte).
+ *
+ * @default {false}
+ */
+ binary?: boolean;
+ /**
+ * Include plus sign for positive numbers.
+ *
+ * @default {false}
+ */
+ signed?: boolean;
+ /**
+ * Uses localized number formatting. If it is set to true, uses default
+ * locale on the system. If it's set to string, uses that locale. The given
+ * string should be a
+ * {@link https://en.wikipedia.org/wiki/IETF_language_tag | BCP 47 language tag}.
+ * You can also give the list of language tags.
+ */
+ locale?: boolean | string | string[];
+ /**
+ * The minimum number of fraction digits to display. If neither
+ * {@linkcode minimumFractionDigits} or {@linkcode maximumFractionDigits}
+ * are set.
+ *
+ * @default {3}
+ */
+ minimumFractionDigits?: number;
+ /**
+ * The maximum number of fraction digits to display. If neither
+ * {@linkcode minimumFractionDigits} or {@linkcode maximumFractionDigits}
+ * are set.
+ *
+ * @default {3}
+ */
+ maximumFractionDigits?: number;
+ }
+
+ /**
+ * Convert bytes to a human-readable string: 1337 → 1.34 kB
+ *
+ * Based on {@link https://github.com/sindresorhus/pretty-bytes | pretty-bytes}.
+ * A utility for displaying file sizes for humans.
+ *
+ * @param num The bytes value to format
+ * @param options The options for formatting
+ * @returns The formatted string
+ *
+ * @example Basic usage
+ * ```ts
+ * import { formatBytes } from "jamfile:fmt";
+ *
+ * formatBytes(1337); // "1.34 kB"
+ * formatBytes(100); // "100 B"
+ * ```
+ *
+
+ */
+export function formatBytes(
+ num: number,
+ options?: FormatBytesOptions,
+): string;
+}
+
+
+declare module 'jamfile:assert' {
+
+type T = any;
+/**
+ * Make an assertion that `actual` and `expected` are almost equal numbers
+through a given tolerance. It can be used to take into account IEEE-754
+double-precision floating-point representation limitations. If the values
+are not almost equal then throw.
+
+The default tolerance is one hundred thousandth of a percent of the
+expected value.
+ * @param actual The actual value to compare.
+ * @param expected The expected value to compare.
+ * @param tolerance The tolerance to consider the values almost equal. The
+default is one hundred thousandth of a percent of the expected value.
+ * @param msg The optional message to include in the error.
+ */
+export function assertAlmostEquals(actual: number, expected: number, tolerance: number, msg?: string): void;
+
+/**
+ * Make an assertion that `actual` includes the `expected` values. If not then
+an error will be thrown.
+
+Type parameter can be specified to ensure values under comparison have the
+same type.
+ * @param actual The array-like object to check for.
+ * @param expected The array-like object to check for.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertArrayIncludes(actual: any[], expected: any[], msg?: string): void;
+
+/**
+ * Make an assertion that `actual` and `expected` are equal, deeply. If not
+deeply equal, then throw.
+
+Type parameter can be specified to ensure values under comparison have the
+same type.
+
+Note: When comparing `Blob` objects, you should first convert them to
+`Uint8Array` using the `Blob.bytes()` method and then compare their
+contents.
+ * @param actual The actual value to compare.
+ * @param expected The expected value to compare.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertEquals(actual: T, expected: T, msg?: string): void;
+
+/**
+ * Make an assertion that actual is not null or undefined.
+If not then throw.
+ * @param actual The actual value to check.
+ * @param msg The optional message to include in the error if the assertion fails.
+ */
+export function assertExists(actual: T, msg?: string): asserts actual is NonNullable;
+
+type Falsy = false
+| 0
+| 0
+| ""
+| null
+| undefined;
+
+/**
+ * Make an assertion, error will be thrown if `expr` have truthy value.
+ * @param expr The expression to test.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertFalse(expr: unknown, undefined: undefined): asserts expr is Falsy;
+
+/**
+ * Make an assertion that `actual` is greater than or equal to `expected`.
+If not then throw.
+ * @param actual The actual value to compare.
+ * @param expected The expected value to compare.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertGreaterOrEqual(actual: T, expected: T, msg?: string): void;
+
+/**
+ * Make an assertion that `actual` is greater than `expected`.
+If not then throw.
+ * @param actual The actual value to compare.
+ * @param expected The expected value to compare.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertGreater(actual: T, expected: T, msg?: string): void;
+
+/**
+ * Make an assertion that `obj` is an instance of `type`.
+If not then throw.
+ * @param actual The object to check.
+ * @param expectedType The expected class constructor.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertInstanceOf any>(actual: unknown, expectedType: T, undefined: undefined): asserts actual is InstanceType;
+
+/**
+ * Make an assertion that `error` is an `Error`.
+If not then an error will be thrown.
+An error class and a string that should be included in the
+error message can also be asserted.
+ * @param error The error to assert.
+ * @param ErrorClass The optional error class to assert.
+ * @param msgMatches The optional string or RegExp to assert in the error message.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertIsError(error: unknown, ErrorClass: any, msgMatches: string | RegExp, msg?: string): asserts error is E;
+
+/**
+ * Make an assertion that `actual` is less than or equal to `expected`.
+If not then throw.
+ * @param actual The actual value to compare.
+ * @param expected The expected value to compare.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertLessOrEqual(actual: T, expected: T, msg?: string): void;
+
+/**
+ * Make an assertion that `actual` is less than `expected`.
+If not then throw.
+ * @param actual The actual value to compare.
+ * @param expected The expected value to compare.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertLess(actual: T, expected: T, msg?: string): void;
+
+/**
+ * Make an assertion that `actual` match RegExp `expected`. If not
+then throw.
+ * @param actual The actual value to be matched.
+ * @param expected The expected pattern to match.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertMatch(actual: string, expected: RegExp, msg?: string): void;
+
+/**
+ * Make an assertion that `actual` and `expected` are not equal, deeply.
+If not then throw.
+
+Type parameter can be specified to ensure values under comparison have the same type.
+ * @param actual The actual value to compare.
+ * @param expected The expected value to compare.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertNotEquals(actual: T, expected: T, msg?: string): void;
+
+/**
+ * Make an assertion that `obj` is not an instance of `type`.
+If so, then throw.
+ * @param actual The object to check.
+ * @param unexpectedType The class constructor to check against.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertNotInstanceOf(actual: A, unexpectedType: any, msg?: string): asserts actual is Exclude;
+
+/**
+ * Make an assertion that `actual` not match RegExp `expected`. If match
+then throw.
+ * @param actual The actual value to match.
+ * @param expected The expected value to not match.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertNotMatch(actual: string, expected: RegExp, msg?: string): void;
+
+/**
+ * Make an assertion that `actual` and `expected` are not strictly equal, using
+{@linkcode Object.is} for equality comparison. If the values are strictly
+equal then throw.
+ * @param actual The actual value to compare.
+ * @param expected The expected value to compare.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertNotStrictEquals(actual: T, expected: T, msg?: string): void;
+
+/**
+ * Make an assertion that `expected` object is a subset of `actual` object,
+deeply. If not, then throw a diff of the objects, with mismatching
+properties highlighted.
+ * @param actual The actual value to be matched.
+ * @param expected The expected value to match.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertObjectMatch(actual: Record, expected: Record, msg?: string): void;
+
+/**
+ * Executes a function which returns a promise, expecting it to reject.
+
+To assert that a synchronous function throws, use {@linkcode assertThrows}.
+ * @param fn The function to execute.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertRejects(fn: () =>void, msg?: string): Promise;
+
+/**
+ * Executes a function which returns a promise, expecting it to reject.
+If it does not, then it throws. An error class and a string that should be
+included in the error message can also be asserted.
+
+To assert that a synchronous function throws, use {@linkcode assertThrows}.
+ * @param fn The function to execute.
+ * @param ErrorClass The error class to assert.
+ * @param msgIncludes The string that should be included in the error message.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertRejects(fn: () => void, ErrorClass: any, msgIncludes: string, msg?: string): Promise;
+
+
+/**
+ * Make an assertion that `actual` and `expected` are strictly equal, using
+{@linkcode Object.is} for equality comparison. If not, then throw.
+ * @param actual The actual value to compare.
+ * @param expected The expected value to compare.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertStrictEquals(actual: unknown, expected: T, msg?: string): asserts actual is T;
+
+/**
+ * Make an assertion that actual includes expected. If not
+then throw.
+ * @param actual The actual string to check for inclusion.
+ * @param expected The expected string to check for inclusion.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertStringIncludes(actual: string, expected: string, msg?: string): void;
+
+/**
+ * Executes a function, expecting it to throw. If it does not, then it
+throws.
+
+To assert that an asynchronous function rejects, use
+{@linkcode assertRejects}.
+ * @param fn The function to execute.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertThrows(fn: () => void, msg?: string): unknown;
+
+/**
+ * Executes a function, expecting it to throw. If it does not, then it
+throws. An error class and a string that should be included in the
+error message can also be asserted.
+
+To assert that an asynchronous function rejects, use
+{@linkcode assertRejects}.
+ * @param fn The function to execute.
+ * @param ErrorClass The error class to assert.
+ * @param msgIncludes The string that should be included in the error message.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assertThrows(fn: () => void, ErrorClass: any, msgIncludes: string, msg?: string): E;
+
+/**
+ * undefined
+ */
+export function assertThrows(fn: () => void, errorClassOrMsg: any | string, msgIncludesOrMsg?: string, msg?: string):any;
+
+/**
+ * Make an assertion, error will be thrown if `expr` does not have truthy value.
+ * @param expr The expression to test.
+ * @param msg The optional message to display if the assertion fails.
+ */
+export function assert(expr: unknown, undefined: undefined): asserts expr;
+
+/**
+ * Deep equality comparison used in assertions.
+ * @param a The actual value
+ * @param b The expected value
+ */
+export function equal(a: unknown, b: unknown): boolean;
+
+/**
+ * Forcefully throws a failed assertion.
+ * @param msg Optional message to include in the error.
+ */
+export function fail(msg?: string): never;
+
+/**
+ * Use this to stub out methods that will throw when invoked.
+ * @param msg Optional message to include in the error.
+ */
+export function unimplemented(msg?: string): never;
+
+/**
+ * Use this to assert unreachable code.
+ * @param msg Optional message to include in the error.
+ */
+export function unreachable(msg?: string): never;
+
+}
+declare module 'jamfile:color' {
+
+ /**
+ * Enable or disable text color when styling.
+
+ `@std/fmt/colors` automatically detects NO_COLOR environmental variable
+ and disables text color. Use this API only when the automatic detection
+ doesn't work.
+ * @param value The boolean value to enable or disable text color
+ */
+ export function setColorEnabled(value: boolean): void;
+
+ /**
+ * Get whether text color change is enabled or disabled.
+ */
+ export function getColorEnabled(): boolean;
+
+ /**
+ * Reset the text modified.
+ * @param str The text to reset
+ */
+ export function reset(str: string): string;
+
+ /**
+ * Make the text bold.
+ * @param str The text to make bold
+ */
+ export function bold(str: string): string;
+
+ /**
+ * The text emits only a small amount of light.
+ * @param str The text to dim
+ */
+ export function dim(str: string): string;
+
+ /**
+ * Make the text italic.
+ * @param str The text to make italic
+ */
+ export function italic(str: string): string;
+
+ /**
+ * Make the text underline.
+ * @param str The text to underline
+ */
+ export function underline(str: string): string;
+
+ /**
+ * Invert background color and text color.
+ * @param str The text to invert its color
+ */
+ export function inverse(str: string): string;
+
+ /**
+ * Make the text hidden.
+ * @param str The text to hide
+ */
+ export function hidden(str: string): string;
+
+ /**
+ * Put horizontal line through the center of the text.
+ * @param str The text to strike through
+ */
+ export function strikethrough(str: string): string;
+
+ /**
+ * Set text color to black.
+ * @param str The text to make black
+ */
+ export function black(str: string): string;
+
+ /**
+ * Set text color to red.
+ * @param str The text to make red
+ */
+ export function red(str: string): string;
+
+ /**
+ * Set text color to green.
+ * @param str The text to make green
+ */
+ export function green(str: string): string;
+
+ /**
+ * Set text color to yellow.
+ * @param str The text to make yellow
+ */
+ export function yellow(str: string): string;
+
+ /**
+ * Set text color to blue.
+ * @param str The text to make blue
+ */
+ export function blue(str: string): string;
+
+ /**
+ * Set text color to magenta.
+ * @param str The text to make magenta
+ */
+ export function magenta(str: string): string;
+
+ /**
+ * Set text color to cyan.
+ * @param str The text to make cyan
+ */
+ export function cyan(str: string): string;
+
+ /**
+ * Set text color to white.
+ * @param str The text to make white
+ */
+ export function white(str: string): string;
+
+ /**
+ * Set text color to gray.
+ * @param str The text to make gray
+ */
+ export function gray(str: string): string;
+
+ /**
+ * Set text color to bright black.
+ * @param str The text to make bright black
+ */
+ export function brightBlack(str: string): string;
+
+ /**
+ * Set text color to bright red.
+ * @param str The text to make bright red
+ */
+ export function brightRed(str: string): string;
+
+ /**
+ * Set text color to bright green.
+ * @param str The text to make bright green
+ */
+ export function brightGreen(str: string): string;
+
+ /**
+ * Set text color to bright yellow.
+ * @param str The text to make bright yellow
+ */
+ export function brightYellow(str: string): string;
+
+ /**
+ * Set text color to bright blue.
+ * @param str The text to make bright blue
+ */
+ export function brightBlue(str: string): string;
+
+ /**
+ * Set text color to bright magenta.
+ * @param str The text to make bright magenta
+ */
+ export function brightMagenta(str: string): string;
+
+ /**
+ * Set text color to bright cyan.
+ * @param str The text to make bright cyan
+ */
+ export function brightCyan(str: string): string;
+
+ /**
+ * Set text color to bright white.
+ * @param str The text to make bright white
+ */
+ export function brightWhite(str: string): string;
+
+ /**
+ * Set background color to black.
+ * @param str The text to make its background black
+ */
+ export function bgBlack(str: string): string;
+
+ /**
+ * Set background color to red.
+ * @param str The text to make its background red
+ */
+ export function bgRed(str: string): string;
+
+ /**
+ * Set background color to green.
+ * @param str The text to make its background green
+ */
+ export function bgGreen(str: string): string;
+
+ /**
+ * Set background color to yellow.
+ * @param str The text to make its background yellow
+ */
+ export function bgYellow(str: string): string;
+
+ /**
+ * Set background color to blue.
+ * @param str The text to make its background blue
+ */
+ export function bgBlue(str: string): string;
+
+ /**
+ * Set background color to magenta.
+ * @param str The text to make its background magenta
+ */
+ export function bgMagenta(str: string): string;
+
+ /**
+ * Set background color to cyan.
+ * @param str The text to make its background cyan
+ */
+ export function bgCyan(str: string): string;
+
+ /**
+ * Set background color to white.
+ * @param str The text to make its background white
+ */
+ export function bgWhite(str: string): string;
+
+ /**
+ * Set background color to bright black.
+ * @param str The text to make its background bright black
+ */
+ export function bgBrightBlack(str: string): string;
+
+ /**
+ * Set background color to bright red.
+ * @param str The text to make its background bright red
+ */
+ export function bgBrightRed(str: string): string;
+
+ /**
+ * Set background color to bright green.
+ * @param str The text to make its background bright green
+ */
+ export function bgBrightGreen(str: string): string;
+
+ /**
+ * Set background color to bright yellow.
+ * @param str The text to make its background bright yellow
+ */
+ export function bgBrightYellow(str: string): string;
+
+ /**
+ * Set background color to bright blue.
+ * @param str The text to make its background bright blue
+ */
+ export function bgBrightBlue(str: string): string;
+
+ /**
+ * Set background color to bright magenta.
+ * @param str The text to make its background bright magenta
+ */
+ export function bgBrightMagenta(str: string): string;
+
+ /**
+ * Set background color to bright cyan.
+ * @param str The text to make its background bright cyan
+ */
+ export function bgBrightCyan(str: string): string;
+
+ /**
+ * Set background color to bright white.
+ * @param str The text to make its background bright white
+ */
+ export function bgBrightWhite(str: string): string;
+
+ /**
+ * Set text color using paletted 8bit colors.
+ https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
+ * @param str The text color to apply paletted 8bit colors to
+ * @param color The color code
+ */
+ export function rgb8(str: string, color: number): string;
+
+ /**
+ * Set background color using paletted 8bit colors.
+ https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
+ * @param str The text color to apply paletted 8bit background colors to
+ * @param color code
+ */
+ export function bgRgb8(str: string, color: number): string;
+
+ /** RGB 8-bits per channel. Each in range `0->255` or `0x00->0xff` */
+ export interface Rgb {
+ /** Red component value */
+ r: number;
+ /** Green component value */
+ g: number;
+ /** Blue component value */
+ b: number;
+ }
+
+ /**
+ * Set text color using 24bit rgb.
+ `color` can be a number in range `0x000000` to `0xffffff` or
+ an `Rgb`.
+ * @param str The text color to apply 24bit rgb to
+ * @param color The color code
+ */
+ export function rgb24(str: string, color: number | Rgb): string;
+
+ /**
+ * Set background color using 24bit rgb.
+ `color` can be a number in range `0x000000` to `0xffffff` or
+ an `Rgb`.
+ * @param str The text color to apply 24bit rgb to
+ * @param color The color code
+ */
+ export function bgRgb24(str: string, color: number | Rgb): string;
+
+ /**
+ * Remove ANSI escape codes from the string.
+ * @param string The text to remove ANSI escape codes from
+ */
+ export function stripAnsiCode(string: string): string;
+
+}
+
+declare module "jamfile:zod" {
+ export function zodToJsonSchema(zod: ZodType):JSONSchema7;
+
+ type Primitive = string | number | symbol | bigint | boolean | null | undefined;
+type Scalars = Primitive | Primitive[];
+
+namespace util {
+ type AssertEqual = (() => V extends T ? 1 : 2) extends () => V extends U ? 1 : 2 ? true : false;
+ export type isAny = 0 extends 1 & T ? true : false;
+ export const assertEqual: (val: AssertEqual) => AssertEqual;
+ export function assertIs(_arg: T): void;
+ export function assertNever(_x: never): never;
+ export type Omit = Pick>;
+ export type OmitKeys = Pick>;
+ export type MakePartial = Omit & Partial>;
+ export type Exactly = T & Record, never>;
+ export const arrayToEnum: (items: U) => { [k in U[number]]: k; };
+ export const getValidEnumValues: (obj: any) => any[];
+ export const objectValues: (obj: any) => any[];
+ export const objectKeys: ObjectConstructor["keys"];
+ export const find: (arr: T[], checker: (arg: T) => any) => T | undefined;
+ export type identity = objectUtil.identity;
+ export type flatten = objectUtil.flatten;
+ export type noUndefined = T extends undefined ? never : T;
+ export const isInteger: NumberConstructor["isInteger"];
+ export function joinValues(array: T, separator?: string): string;
+ export const jsonStringifyReplacer: (_: string, value: any) => any;
+ export { };
+}
+namespace objectUtil {
+ export type MergeShapes = {
+ [k in Exclude]: U[k];
+ } & V;
+ type optionalKeys = {
+ [k in keyof T]: undefined extends T[k] ? k : never;
+ }[keyof T];
+ type requiredKeys = {
+ [k in keyof T]: undefined extends T[k] ? never : k;
+ }[keyof T];
+ export type addQuestionMarks = {
+ [K in requiredKeys]: T[K];
+ } & {
+ [K in optionalKeys]?: T[K];
+ } & {
+ [k in keyof T]?: unknown;
+ };
+ export type identity = T;
+ export type flatten = identity<{
+ [k in keyof T]: T[k];
+ }>;
+ export type noNeverKeys = {
+ [k in keyof T]: [T[k]] extends [never] ? never : k;
+ }[keyof T];
+ export type noNever = identity<{
+ [k in noNeverKeys]: k extends keyof T ? T[k] : never;
+ }>;
+ export const mergeShapes: (first: U, second: T) => T & U;
+ export type extendShape = {
+ [K in keyof A as K extends keyof B ? never : K]: A[K];
+ } & {
+ [K in keyof B]: B[K];
+ };
+ export { };
+}
+const ZodParsedType: {
+ string: "string";
+ number: "number";
+ bigint: "bigint";
+ boolean: "boolean";
+ symbol: "symbol";
+ undefined: "undefined";
+ object: "object";
+ function: "function";
+ map: "map";
+ nan: "nan";
+ integer: "integer";
+ float: "float";
+ date: "date";
+ null: "null";
+ array: "array";
+ unknown: "unknown";
+ promise: "promise";
+ void: "void";
+ never: "never";
+ set: "set";
+};
+type ZodParsedType = keyof typeof ZodParsedType;
+const getParsedType: (data: any) => ZodParsedType;
+
+type allKeys = T extends any ? keyof T : never;
+type inferFlattenedErrors, U = string> = typeToFlattenedError, U>;
+type typeToFlattenedError = {
+ formErrors: U[];
+ fieldErrors: {
+ [P in allKeys]?: U[];
+ };
+};
+const ZodIssueCode: {
+ invalid_type: "invalid_type";
+ invalid_literal: "invalid_literal";
+ custom: "custom";
+ invalid_union: "invalid_union";
+ invalid_union_discriminator: "invalid_union_discriminator";
+ invalid_enum_value: "invalid_enum_value";
+ unrecognized_keys: "unrecognized_keys";
+ invalid_arguments: "invalid_arguments";
+ invalid_return_type: "invalid_return_type";
+ invalid_date: "invalid_date";
+ invalid_string: "invalid_string";
+ too_small: "too_small";
+ too_big: "too_big";
+ invalid_intersection_types: "invalid_intersection_types";
+ not_multiple_of: "not_multiple_of";
+ not_finite: "not_finite";
+};
+type ZodIssueCode = keyof typeof ZodIssueCode;
+type ZodIssueBase = {
+ path: (string | number)[];
+ message?: string;
+};
+interface ZodInvalidTypeIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.invalid_type;
+ expected: ZodParsedType;
+ received: ZodParsedType;
+}
+interface ZodInvalidLiteralIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.invalid_literal;
+ expected: unknown;
+ received: unknown;
+}
+interface ZodUnrecognizedKeysIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.unrecognized_keys;
+ keys: string[];
+}
+interface ZodInvalidUnionIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.invalid_union;
+ unionErrors: ZodError[];
+}
+interface ZodInvalidUnionDiscriminatorIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.invalid_union_discriminator;
+ options: Primitive[];
+}
+interface ZodInvalidEnumValueIssue extends ZodIssueBase {
+ received: string | number;
+ code: typeof ZodIssueCode.invalid_enum_value;
+ options: (string | number)[];
+}
+interface ZodInvalidArgumentsIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.invalid_arguments;
+ argumentsError: ZodError;
+}
+interface ZodInvalidReturnTypeIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.invalid_return_type;
+ returnTypeError: ZodError;
+}
+interface ZodInvalidDateIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.invalid_date;
+}
+type StringValidation = "email" | "url" | "emoji" | "uuid" | "nanoid" | "regex" | "cuid" | "cuid2" | "ulid" | "datetime" | "date" | "time" | "duration" | "ip" | "cidr" | "base64" | "jwt" | "base64url" | {
+ includes: string;
+ position?: number;
+} | {
+ startsWith: string;
+} | {
+ endsWith: string;
+};
+interface ZodInvalidStringIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.invalid_string;
+ validation: StringValidation;
+}
+interface ZodTooSmallIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.too_small;
+ minimum: number | bigint;
+ inclusive: boolean;
+ exact?: boolean;
+ type: "array" | "string" | "number" | "set" | "date" | "bigint";
+}
+interface ZodTooBigIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.too_big;
+ maximum: number | bigint;
+ inclusive: boolean;
+ exact?: boolean;
+ type: "array" | "string" | "number" | "set" | "date" | "bigint";
+}
+interface ZodInvalidIntersectionTypesIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.invalid_intersection_types;
+}
+interface ZodNotMultipleOfIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.not_multiple_of;
+ multipleOf: number | bigint;
+}
+interface ZodNotFiniteIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.not_finite;
+}
+interface ZodCustomIssue extends ZodIssueBase {
+ code: typeof ZodIssueCode.custom;
+ params?: {
+ [k: string]: any;
+ };
+}
+type DenormalizedError = {
+ [k: string]: DenormalizedError | string[];
+};
+type ZodIssueOptionalMessage = ZodInvalidTypeIssue | ZodInvalidLiteralIssue | ZodUnrecognizedKeysIssue | ZodInvalidUnionIssue | ZodInvalidUnionDiscriminatorIssue | ZodInvalidEnumValueIssue | ZodInvalidArgumentsIssue | ZodInvalidReturnTypeIssue | ZodInvalidDateIssue | ZodInvalidStringIssue | ZodTooSmallIssue | ZodTooBigIssue | ZodInvalidIntersectionTypesIssue | ZodNotMultipleOfIssue | ZodNotFiniteIssue | ZodCustomIssue;
+type ZodIssue = ZodIssueOptionalMessage & {
+ fatal?: boolean;
+ message: string;
+};
+const quotelessJson: (obj: any) => string;
+type recursiveZodFormattedError = T extends [any, ...any[]] ? {
+ [K in keyof T]?: ZodFormattedError;
+} : T extends any[] ? {
+ [k: number]: ZodFormattedError;
+} : T extends object ? {
+ [K in keyof T]?: ZodFormattedError;
+} : unknown;
+type ZodFormattedError = {
+ _errors: U[];
+} & recursiveZodFormattedError>;
+type inferFormattedError, U = string> = ZodFormattedError, U>;
+class ZodError extends Error {
+ issues: ZodIssue[];
+ get errors(): ZodIssue[];
+ constructor(issues: ZodIssue[]);
+ format(): ZodFormattedError;
+ format(mapper: (issue: ZodIssue) => U): ZodFormattedError;
+ static create: (issues: ZodIssue[]) => ZodError;
+ static assert(value: unknown): asserts value is ZodError;
+ toString(): string;
+ get message(): string;
+ get isEmpty(): boolean;
+ addIssue: (sub: ZodIssue) => void;
+ addIssues: (subs?: ZodIssue[]) => void;
+ flatten(): typeToFlattenedError;
+ flatten(mapper?: (issue: ZodIssue) => U): typeToFlattenedError;
+ get formErrors(): typeToFlattenedError;
+}
+type stripPath = T extends any ? util.OmitKeys : never;
+type IssueData = stripPath & {
+ path?: (string | number)[];
+ fatal?: boolean;
+};
+type ErrorMapCtx = {
+ defaultError: string;
+ data: any;
+};
+type ZodErrorMap = (issue: ZodIssueOptionalMessage, _ctx: ErrorMapCtx) => {
+ message: string;
+};
+
+const errorMap: ZodErrorMap;
+//# sourceMappingURL=en.d.ts.map
+
+function setErrorMap(map: ZodErrorMap): void;
+function getErrorMap(): ZodErrorMap;
+
+const makeIssue: (params: {
+ data: any;
+ path: (string | number)[];
+ errorMaps: ZodErrorMap[];
+ issueData: IssueData;
+}) => ZodIssue;
+type ParseParams = {
+ path: (string | number)[];
+ errorMap: ZodErrorMap;
+ async: boolean;
+};
+type ParsePathComponent = string | number;
+type ParsePath = ParsePathComponent[];
+const EMPTY_PATH: ParsePath;
+interface ParseContext {
+ readonly common: {
+ readonly issues: ZodIssue[];
+ readonly contextualErrorMap?: ZodErrorMap;
+ readonly async: boolean;
+ };
+ readonly path: ParsePath;
+ readonly schemaErrorMap?: ZodErrorMap;
+ readonly parent: ParseContext | null;
+ readonly data: any;
+ readonly parsedType: ZodParsedType;
+}
+type ParseInput = {
+ data: any;
+ path: (string | number)[];
+ parent: ParseContext;
+};
+function addIssueToContext(ctx: ParseContext, issueData: IssueData): void;
+type ObjectPair = {
+ key: SyncParseReturnType;
+ value: SyncParseReturnType;
+};
+class ParseStatus {
+ value: "aborted" | "dirty" | "valid";
+ dirty(): void;
+ abort(): void;
+ static mergeArray(status: ParseStatus, results: SyncParseReturnType[]): SyncParseReturnType;
+ static mergeObjectAsync(status: ParseStatus, pairs: {
+ key: ParseReturnType;
+ value: ParseReturnType;
+ }[]): Promise>;
+ static mergeObjectSync(status: ParseStatus, pairs: {
+ key: SyncParseReturnType;
+ value: SyncParseReturnType;
+ alwaysSet?: boolean;
+ }[]): SyncParseReturnType;
+}
+interface ParseResult {
+ status: "aborted" | "dirty" | "valid";
+ data: any;
+}
+type INVALID = {
+ status: "aborted";
+};
+const INVALID: INVALID;
+type DIRTY = {
+ status: "dirty";
+ value: T;
+};
+const DIRTY: (value: T) => DIRTY;
+type OK = {
+ status: "valid";
+ value: T;
+};
+const OK: (value: T) => OK;
+type SyncParseReturnType = OK | DIRTY | INVALID;
+type AsyncParseReturnType = Promise>;
+type ParseReturnType = SyncParseReturnType | AsyncParseReturnType;
+const isAborted: (x: ParseReturnType) => x is INVALID;
+const isDirty: (x: ParseReturnType) => x is OK | DIRTY;
+const isValid: (x: ParseReturnType) => x is OK;
+const isAsync: (x: ParseReturnType) => x is AsyncParseReturnType;
+
+namespace enumUtil {
+ type UnionToIntersectionFn = (T extends unknown ? (k: () => T) => void : never) extends (k: infer Intersection) => void ? Intersection : never;
+ type GetUnionLast = UnionToIntersectionFn