From f9bad01ed7a06988bdd02bddaac14baad841d6d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Bene=C5=A1?= Date: Fri, 9 Oct 2026 21:59:03 +0000 Subject: [PATCH] LLeMbas CLI 1.0.0 The first public release of LLeMbas CLI: a terminal coding agent and project manager for any LLM API, with permission modes, git snapshots, memory and skills, knowledge bases, MCP, voice, and a link to a LLeMbas instance whose web UI can work its sessions too. Signed Linux binaries for x64 and arm64. Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/ci.yml | 18 + .github/workflows/ci.yml | 34 + .github/workflows/release.yml | 65 + .gitignore | 8 + .gitleaksignore | 4 + CHANGELOG.md | 14 + LICENSE | 21 + LICENSES.txt | 1326 +++++++++++++++++ README.md | 45 + SECURITY.md | 57 + THIRD_PARTY.md | 62 + assets/banner.svg | 78 + bun.lock | 486 ++++++ bunfig.toml | 12 + get.sh | 227 +++ harness/README.md | 67 + harness/VERSION | 1 + harness/acp.md | 467 ++++++ harness/conformance/always.json | 70 + harness/conformance/arity.json | 61 + harness/conformance/chunk.json | 70 + harness/conformance/edit.json | 86 ++ harness/conformance/effort.json | 54 + harness/conformance/envelope.json | 73 + harness/conformance/hardline.json | 181 +++ harness/conformance/permission.json | 290 ++++ harness/conformance/plain.json | 88 ++ harness/conformance/split.json | 206 +++ harness/conformance/think.json | 81 + harness/conformance/unidiff.json | 89 ++ harness/loop.json | 17 + harness/models/schema.json | 33 + harness/permission/arity.json | 170 +++ harness/permission/defaults.json | 76 + harness/permission/hardline.json | 222 +++ harness/permission/modes.json | 38 + harness/prompts/blocks/agents-git.md | 3 + harness/prompts/blocks/agents-keep.md | 3 + harness/prompts/blocks/agents-missing.md | 8 + harness/prompts/blocks/memory.md | 5 + harness/prompts/blocks/skills-empty.md | 4 + harness/prompts/blocks/skills.md | 11 + harness/prompts/family/anthropic.md | 7 + harness/prompts/family/gemini.md | 15 + harness/prompts/family/gpt.md | 20 + harness/prompts/family/local.md | 10 + harness/prompts/index.json | 168 +++ harness/prompts/modes/auto.md | 1 + harness/prompts/modes/edit.md | 1 + harness/prompts/modes/manual.md | 1 + harness/prompts/modes/plan.md | 10 + harness/prompts/modes/unattended.md | 1 + harness/prompts/personality/concise.md | 1 + harness/prompts/personality/formal.md | 1 + harness/prompts/personality/funny.md | 1 + harness/prompts/personality/optimistic.md | 1 + harness/prompts/personality/pragmatic.md | 1 + harness/prompts/personality/socratic.md | 1 + harness/prompts/system/default.md | 47 + harness/prompts/system/identity.md | 2 + harness/prompts/tasks/changelog.md | 18 + harness/prompts/tasks/compact.md | 28 + harness/prompts/tasks/continue.md | 3 + harness/prompts/tasks/init.md | 18 + harness/prompts/tasks/review.md | 17 + harness/purpose.json | 8 + harness/quirks.json | 17 + harness/tools/apply_patch.json | 32 + harness/tools/ask_user.json | 81 + harness/tools/bash.json | 53 + harness/tools/bash_kill.json | 26 + harness/tools/bash_list.json | 19 + harness/tools/bash_output.json | 31 + harness/tools/decisions.json | 37 + harness/tools/edit.json | 39 + harness/tools/glob.json | 29 + harness/tools/grep.json | 40 + harness/tools/knowledge_get.json | 29 + harness/tools/knowledge_search.json | 30 + harness/tools/list.json | 29 + harness/tools/memory.json | 86 ++ harness/tools/multiedit.json | 48 + harness/tools/note_manage.json | 52 + harness/tools/note_view.json | 28 + harness/tools/notes_search.json | 23 + harness/tools/plan_submit.json | 27 + harness/tools/read.json | 37 + harness/tools/session_search.json | 47 + harness/tools/settings.json | 46 + harness/tools/skill_manage.json | 97 ++ harness/tools/skill_view.json | 31 + harness/tools/skills_list.json | 22 + harness/tools/task.json | 48 + harness/tools/tasks.json | 47 + harness/tools/todo.json | 47 + harness/tools/view_image.json | 25 + harness/tools/web_fetch.json | 34 + harness/tools/web_search.json | 32 + harness/tools/write.json | 32 + install.sh | 340 +++++ package.json | 40 + schema/config.schema.json | 1043 +++++++++++++ schema/connections.schema.json | 567 +++++++ scripts/build.ts | 71 + scripts/ci.sh | 70 + scripts/dist.ts | 69 + scripts/drive.ts | 115 ++ scripts/harness.ts | 35 + scripts/licenses.ts | 60 + scripts/schema.ts | 9 + scripts/smoke.ts | 195 +++ src/acp/agent.ts | 1167 +++++++++++++++ src/acp/hub.ts | 340 +++++ src/acp/link.ts | 172 +++ src/acp/pending.ts | 61 + src/acp/prompt.ts | 187 +++ src/acp/rpc.ts | 162 ++ src/acp/share.ts | 560 +++++++ src/acp/shellrc.ts | 202 +++ src/acp/turns.ts | 206 +++ src/app.ts | 680 +++++++++ src/bus/index.ts | 116 ++ src/cli.ts | 561 +++++++ src/config/jsonschema.ts | 59 + src/config/load.ts | 449 ++++++ src/config/paths.ts | 36 + src/config/schema.ts | 312 ++++ src/config/settings.ts | 188 +++ src/config/substitute.ts | 47 + src/config/write.ts | 15 + src/doctor.ts | 59 + src/duration.ts | 9 + src/git/branch.ts | 61 + src/git/commit.ts | 79 + src/git/release.ts | 228 +++ src/git/repo.ts | 50 + src/git/run.ts | 23 + src/git/snapshot.ts | 193 +++ src/git/worktree.ts | 57 + src/harness.ts | 84 ++ src/headless.ts | 169 +++ src/lembas/client.ts | 349 +++++ src/lembas/login.ts | 465 ++++++ src/lembas/personal.ts | 142 ++ src/lembas/webui.ts | 219 +++ src/library/chunks.ts | 44 + src/library/cli.ts | 117 ++ src/library/embed.ts | 60 + src/library/ingest.ts | 115 ++ src/library/store.ts | 300 ++++ src/mcp/index.ts | 545 +++++++ src/mcp/oauth.ts | 221 +++ src/memory/store.ts | 172 +++ src/memory/threats.ts | 82 + src/permission/arity.ts | 21 + src/permission/bash.ts | 146 ++ src/permission/evaluate.ts | 347 +++++ src/permission/hardline.ts | 174 +++ src/permission/wildcard.ts | 19 + src/project/agents.ts | 76 + src/project/attach.ts | 90 ++ src/project/board.ts | 97 ++ src/project/commands.ts | 69 + src/project/files.ts | 103 ++ src/project/image.ts | 51 + src/project/init.ts | 71 + src/project/root.ts | 129 ++ src/project/safe.ts | 26 + src/prompt/assemble.ts | 252 ++++ src/prompt/personality.ts | 25 + src/prompt/text.d.ts | 8 + src/provider/anthropic.ts | 228 +++ src/provider/common.ts | 160 ++ src/provider/discover.ts | 53 + src/provider/effort.ts | 79 + src/provider/gemini.ts | 316 ++++ src/provider/http.ts | 139 ++ src/provider/index.ts | 70 + src/provider/learned.ts | 69 + src/provider/ollama.ts | 178 +++ src/provider/openai-chat.ts | 296 ++++ src/provider/refs.ts | 84 ++ src/provider/responses.ts | 174 +++ src/provider/sse.ts | 87 ++ src/provider/think.ts | 85 ++ src/provider/tokens.ts | 6 + src/provider/types.ts | 89 ++ src/reload.ts | 55 + src/search/ddg.ts | 47 + src/search/fetch.ts | 118 ++ src/search/firecrawl.ts | 47 + src/search/index.ts | 54 + src/search/searxng.ts | 24 + src/search/webui.ts | 41 + src/service.ts | 231 +++ src/session/capacity.ts | 33 + src/session/commands.ts | 187 +++ src/session/context.ts | 62 + src/session/engine.ts | 769 ++++++++++ src/session/store.ts | 224 +++ src/session/title.ts | 66 + src/session/turns.ts | 135 ++ src/settings.ts | 104 ++ src/skill/index.ts | 224 +++ src/tool/apply_patch.ts | 175 +++ src/tool/bash.ts | 147 ++ src/tool/edit.ts | 48 + src/tool/jobs.ts | 86 ++ src/tool/library.ts | 142 ++ src/tool/memory.ts | 41 + src/tool/multiedit.ts | 50 + src/tool/names.ts | 39 + src/tool/patch.ts | 204 +++ src/tool/plan_exit.ts | 51 + src/tool/project_tools.ts | 67 + src/tool/question.ts | 147 ++ src/tool/read.ts | 80 + src/tool/registry.ts | 62 + src/tool/replace-text.ts | 9 + src/tool/replace.ts | 526 +++++++ src/tool/search.ts | 149 ++ src/tool/session_search.ts | 160 ++ src/tool/settings.ts | 74 + src/tool/skills.ts | 299 ++++ src/tool/task.ts | 36 + src/tool/todo.ts | 40 + src/tool/tool.ts | 175 +++ src/tool/unidiff.ts | 165 ++ src/tool/view_image.ts | 22 + src/tool/web.ts | 83 ++ src/tool/write.ts | 66 + src/tui/app.tsx | 563 +++++++ src/tui/clipboard.ts | 61 + src/tui/commands.ts | 1098 ++++++++++++++ src/tui/components/dialog.tsx | 111 ++ src/tui/components/firstrun.tsx | 101 ++ src/tui/components/messages.tsx | 248 +++ src/tui/components/permission.tsx | 209 +++ src/tui/components/plancard.tsx | 92 ++ src/tui/components/prompt.tsx | 294 ++++ src/tui/components/question.tsx | 119 ++ src/tui/components/setup.tsx | 121 ++ src/tui/components/spinner.tsx | 77 + src/tui/components/status.tsx | 54 + src/tui/components/todos.tsx | 35 + src/tui/components/welcome.tsx | 33 + src/tui/context.ts | 24 + src/tui/diffclip.ts | 38 + src/tui/history.ts | 64 + src/tui/icons.ts | 45 + src/tui/index.tsx | 176 +++ src/tui/palette.ts | 423 ++++++ src/tui/state.ts | 429 ++++++ src/tui/theme.ts | 45 + src/uninstall.ts | 113 ++ src/update/index.ts | 274 ++++ src/update/source.ts | 115 ++ src/update/sshsig.ts | 77 + src/update/version.ts | 39 + src/version.ts | 10 + src/voice/audio.ts | 294 ++++ src/voice/index.ts | 197 +++ src/voice/speech.ts | 112 ++ src/voice/text.ts | 97 ++ tests/acp-v2.test.ts | 713 +++++++++ tests/acp.test.ts | 435 ++++++ tests/anthropic.test.ts | 115 ++ tests/approval.test.ts | 49 + tests/board.test.ts | 54 + tests/budget.test.ts | 67 + tests/capacity.test.ts | 69 + tests/checkpoint-branch.test.ts | 162 ++ tests/clipboard.test.ts | 49 + tests/config.test.ts | 179 +++ tests/conformance.test.ts | 21 + tests/conformance.ts | 84 ++ tests/context.test.ts | 97 ++ tests/cutoff.test.ts | 139 ++ tests/diffclip.test.ts | 40 + tests/doctor.test.ts | 46 + tests/e2e.test.ts | 289 ++++ tests/fake-provider.ts | 60 + tests/fixtures/mcp/server.ts | 48 + tests/fixtures/mcp/tricky.ts | 18 + .../sse/bonsai-effort-refused-in-stream.sse | 75 + tests/fixtures/sse/gpt-oss-first-turn.sse | 186 +++ .../gpt-oss-peg-native-failure-mid-reply.sse | 42 + .../sse/llama-swap-model-unloaded.sse | 296 ++++ .../sse/qwen35-answer-only-in-reasoning.sse | 236 +++ .../qwen35-first-turn-with-swap-banner.sse | 140 ++ .../sse/vllm-anthropic-thinking-tool.sse | 99 ++ .../sse/vllm-responses-reasoning-tool.sse | 105 ++ tests/fixtures/voice/mic.ts | 22 + tests/fixtures/voice/piper.ts | 12 + tests/fixtures/voice/player.ts | 5 + tests/fixtures/web/ddg-bun.html | 632 ++++++++ tests/fixtures/web/searxng-bun.json | 41 + tests/gemini-ollama.test.ts | 225 +++ tests/get.test.ts | 170 +++ tests/harness.test.ts | 179 +++ tests/hermes-layer.test.ts | 209 +++ tests/hermes-review.test.ts | 126 ++ tests/hub.test.ts | 509 +++++++ tests/images.test.ts | 64 + tests/install.test.ts | 132 ++ tests/instructions.test.ts | 33 + tests/jobs-wake.test.ts | 72 + tests/jsonschema.test.ts | 115 ++ tests/lembas-library.test.ts | 78 + tests/lembas-login.test.ts | 404 +++++ tests/library.test.ts | 168 +++ tests/mcp-oauth.test.ts | 83 ++ tests/mcp-review.test.ts | 129 ++ tests/mcp.test.ts | 198 +++ tests/memory.test.ts | 98 ++ tests/model-kind.test.ts | 7 + tests/models.test.ts | 81 + tests/names.test.ts | 75 + tests/permission-hardening.test.ts | 181 +++ tests/permission.test.ts | 113 ++ tests/personal.test.ts | 236 +++ tests/plan.test.ts | 68 + tests/project.test.ts | 90 ++ tests/provider-refs.test.ts | 232 +++ tests/provider.test.ts | 185 +++ tests/purpose.test.ts | 64 + tests/release.test.ts | 120 ++ tests/replay.test.ts | 133 ++ tests/responses.test.ts | 83 ++ tests/sessions-delete.test.ts | 404 +++++ tests/settings.test.ts | 219 +++ tests/setup.ts | 9 + tests/shellrc.test.ts | 166 +++ tests/skill-revisions.test.ts | 53 + tests/snapshot.test.ts | 51 + tests/steer.test.ts | 149 ++ tests/subagent.test.ts | 154 ++ tests/theme.test.ts | 74 + tests/titles.test.ts | 143 ++ tests/tls.test.ts | 45 + tests/tools.test.ts | 207 +++ tests/trust-hardening.test.ts | 51 + tests/tui/app.test.tsx | 988 ++++++++++++ tests/tui/dialog.test.tsx | 38 + tests/tui/diffwrap.test.tsx | 64 + tests/tui/firstrun.test.tsx | 95 ++ tests/tui/harness.tsx | 49 + tests/tui/setup.test.tsx | 49 + tests/uninstall.test.ts | 84 ++ tests/units.test.ts | 182 +++ tests/update.test.ts | 206 +++ tests/voice.test.ts | 260 ++++ tests/web.test.ts | 140 ++ third_party/bun-1.4.2-LICENSE.md | 84 ++ tsconfig.json | 20 + 355 files changed, 47028 insertions(+) create mode 100644 .gitea/workflows/ci.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml create mode 100644 .gitignore create mode 100644 .gitleaksignore create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 LICENSES.txt create mode 100644 README.md create mode 100644 SECURITY.md create mode 100644 THIRD_PARTY.md create mode 100644 assets/banner.svg create mode 100644 bun.lock create mode 100644 bunfig.toml create mode 100755 get.sh create mode 100644 harness/README.md create mode 100644 harness/VERSION create mode 100644 harness/acp.md create mode 100644 harness/conformance/always.json create mode 100644 harness/conformance/arity.json create mode 100644 harness/conformance/chunk.json create mode 100644 harness/conformance/edit.json create mode 100644 harness/conformance/effort.json create mode 100644 harness/conformance/envelope.json create mode 100644 harness/conformance/hardline.json create mode 100644 harness/conformance/permission.json create mode 100644 harness/conformance/plain.json create mode 100644 harness/conformance/split.json create mode 100644 harness/conformance/think.json create mode 100644 harness/conformance/unidiff.json create mode 100644 harness/loop.json create mode 100644 harness/models/schema.json create mode 100644 harness/permission/arity.json create mode 100644 harness/permission/defaults.json create mode 100644 harness/permission/hardline.json create mode 100644 harness/permission/modes.json create mode 100644 harness/prompts/blocks/agents-git.md create mode 100644 harness/prompts/blocks/agents-keep.md create mode 100644 harness/prompts/blocks/agents-missing.md create mode 100644 harness/prompts/blocks/memory.md create mode 100644 harness/prompts/blocks/skills-empty.md create mode 100644 harness/prompts/blocks/skills.md create mode 100644 harness/prompts/family/anthropic.md create mode 100644 harness/prompts/family/gemini.md create mode 100644 harness/prompts/family/gpt.md create mode 100644 harness/prompts/family/local.md create mode 100644 harness/prompts/index.json create mode 100644 harness/prompts/modes/auto.md create mode 100644 harness/prompts/modes/edit.md create mode 100644 harness/prompts/modes/manual.md create mode 100644 harness/prompts/modes/plan.md create mode 100644 harness/prompts/modes/unattended.md create mode 100644 harness/prompts/personality/concise.md create mode 100644 harness/prompts/personality/formal.md create mode 100644 harness/prompts/personality/funny.md create mode 100644 harness/prompts/personality/optimistic.md create mode 100644 harness/prompts/personality/pragmatic.md create mode 100644 harness/prompts/personality/socratic.md create mode 100644 harness/prompts/system/default.md create mode 100644 harness/prompts/system/identity.md create mode 100644 harness/prompts/tasks/changelog.md create mode 100644 harness/prompts/tasks/compact.md create mode 100644 harness/prompts/tasks/continue.md create mode 100644 harness/prompts/tasks/init.md create mode 100644 harness/prompts/tasks/review.md create mode 100644 harness/purpose.json create mode 100644 harness/quirks.json create mode 100644 harness/tools/apply_patch.json create mode 100644 harness/tools/ask_user.json create mode 100644 harness/tools/bash.json create mode 100644 harness/tools/bash_kill.json create mode 100644 harness/tools/bash_list.json create mode 100644 harness/tools/bash_output.json create mode 100644 harness/tools/decisions.json create mode 100644 harness/tools/edit.json create mode 100644 harness/tools/glob.json create mode 100644 harness/tools/grep.json create mode 100644 harness/tools/knowledge_get.json create mode 100644 harness/tools/knowledge_search.json create mode 100644 harness/tools/list.json create mode 100644 harness/tools/memory.json create mode 100644 harness/tools/multiedit.json create mode 100644 harness/tools/note_manage.json create mode 100644 harness/tools/note_view.json create mode 100644 harness/tools/notes_search.json create mode 100644 harness/tools/plan_submit.json create mode 100644 harness/tools/read.json create mode 100644 harness/tools/session_search.json create mode 100644 harness/tools/settings.json create mode 100644 harness/tools/skill_manage.json create mode 100644 harness/tools/skill_view.json create mode 100644 harness/tools/skills_list.json create mode 100644 harness/tools/task.json create mode 100644 harness/tools/tasks.json create mode 100644 harness/tools/todo.json create mode 100644 harness/tools/view_image.json create mode 100644 harness/tools/web_fetch.json create mode 100644 harness/tools/web_search.json create mode 100644 harness/tools/write.json create mode 100755 install.sh create mode 100644 package.json create mode 100644 schema/config.schema.json create mode 100644 schema/connections.schema.json create mode 100644 scripts/build.ts create mode 100755 scripts/ci.sh create mode 100644 scripts/dist.ts create mode 100644 scripts/drive.ts create mode 100644 scripts/harness.ts create mode 100644 scripts/licenses.ts create mode 100644 scripts/schema.ts create mode 100644 scripts/smoke.ts create mode 100644 src/acp/agent.ts create mode 100644 src/acp/hub.ts create mode 100644 src/acp/link.ts create mode 100644 src/acp/pending.ts create mode 100644 src/acp/prompt.ts create mode 100644 src/acp/rpc.ts create mode 100644 src/acp/share.ts create mode 100644 src/acp/shellrc.ts create mode 100644 src/acp/turns.ts create mode 100644 src/app.ts create mode 100644 src/bus/index.ts create mode 100644 src/cli.ts create mode 100644 src/config/jsonschema.ts create mode 100644 src/config/load.ts create mode 100644 src/config/paths.ts create mode 100644 src/config/schema.ts create mode 100644 src/config/settings.ts create mode 100644 src/config/substitute.ts create mode 100644 src/config/write.ts create mode 100644 src/doctor.ts create mode 100644 src/duration.ts create mode 100644 src/git/branch.ts create mode 100644 src/git/commit.ts create mode 100644 src/git/release.ts create mode 100644 src/git/repo.ts create mode 100644 src/git/run.ts create mode 100644 src/git/snapshot.ts create mode 100644 src/git/worktree.ts create mode 100644 src/harness.ts create mode 100644 src/headless.ts create mode 100644 src/lembas/client.ts create mode 100644 src/lembas/login.ts create mode 100644 src/lembas/personal.ts create mode 100644 src/lembas/webui.ts create mode 100644 src/library/chunks.ts create mode 100644 src/library/cli.ts create mode 100644 src/library/embed.ts create mode 100644 src/library/ingest.ts create mode 100644 src/library/store.ts create mode 100644 src/mcp/index.ts create mode 100644 src/mcp/oauth.ts create mode 100644 src/memory/store.ts create mode 100644 src/memory/threats.ts create mode 100644 src/permission/arity.ts create mode 100644 src/permission/bash.ts create mode 100644 src/permission/evaluate.ts create mode 100644 src/permission/hardline.ts create mode 100644 src/permission/wildcard.ts create mode 100644 src/project/agents.ts create mode 100644 src/project/attach.ts create mode 100644 src/project/board.ts create mode 100644 src/project/commands.ts create mode 100644 src/project/files.ts create mode 100644 src/project/image.ts create mode 100644 src/project/init.ts create mode 100644 src/project/root.ts create mode 100644 src/project/safe.ts create mode 100644 src/prompt/assemble.ts create mode 100644 src/prompt/personality.ts create mode 100644 src/prompt/text.d.ts create mode 100644 src/provider/anthropic.ts create mode 100644 src/provider/common.ts create mode 100644 src/provider/discover.ts create mode 100644 src/provider/effort.ts create mode 100644 src/provider/gemini.ts create mode 100644 src/provider/http.ts create mode 100644 src/provider/index.ts create mode 100644 src/provider/learned.ts create mode 100644 src/provider/ollama.ts create mode 100644 src/provider/openai-chat.ts create mode 100644 src/provider/refs.ts create mode 100644 src/provider/responses.ts create mode 100644 src/provider/sse.ts create mode 100644 src/provider/think.ts create mode 100644 src/provider/tokens.ts create mode 100644 src/provider/types.ts create mode 100644 src/reload.ts create mode 100644 src/search/ddg.ts create mode 100644 src/search/fetch.ts create mode 100644 src/search/firecrawl.ts create mode 100644 src/search/index.ts create mode 100644 src/search/searxng.ts create mode 100644 src/search/webui.ts create mode 100644 src/service.ts create mode 100644 src/session/capacity.ts create mode 100644 src/session/commands.ts create mode 100644 src/session/context.ts create mode 100644 src/session/engine.ts create mode 100644 src/session/store.ts create mode 100644 src/session/title.ts create mode 100644 src/session/turns.ts create mode 100644 src/settings.ts create mode 100644 src/skill/index.ts create mode 100644 src/tool/apply_patch.ts create mode 100644 src/tool/bash.ts create mode 100644 src/tool/edit.ts create mode 100644 src/tool/jobs.ts create mode 100644 src/tool/library.ts create mode 100644 src/tool/memory.ts create mode 100644 src/tool/multiedit.ts create mode 100644 src/tool/names.ts create mode 100644 src/tool/patch.ts create mode 100644 src/tool/plan_exit.ts create mode 100644 src/tool/project_tools.ts create mode 100644 src/tool/question.ts create mode 100644 src/tool/read.ts create mode 100644 src/tool/registry.ts create mode 100644 src/tool/replace-text.ts create mode 100644 src/tool/replace.ts create mode 100644 src/tool/search.ts create mode 100644 src/tool/session_search.ts create mode 100644 src/tool/settings.ts create mode 100644 src/tool/skills.ts create mode 100644 src/tool/task.ts create mode 100644 src/tool/todo.ts create mode 100644 src/tool/tool.ts create mode 100644 src/tool/unidiff.ts create mode 100644 src/tool/view_image.ts create mode 100644 src/tool/web.ts create mode 100644 src/tool/write.ts create mode 100644 src/tui/app.tsx create mode 100644 src/tui/clipboard.ts create mode 100644 src/tui/commands.ts create mode 100644 src/tui/components/dialog.tsx create mode 100644 src/tui/components/firstrun.tsx create mode 100644 src/tui/components/messages.tsx create mode 100644 src/tui/components/permission.tsx create mode 100644 src/tui/components/plancard.tsx create mode 100644 src/tui/components/prompt.tsx create mode 100644 src/tui/components/question.tsx create mode 100644 src/tui/components/setup.tsx create mode 100644 src/tui/components/spinner.tsx create mode 100644 src/tui/components/status.tsx create mode 100644 src/tui/components/todos.tsx create mode 100644 src/tui/components/welcome.tsx create mode 100644 src/tui/context.ts create mode 100644 src/tui/diffclip.ts create mode 100644 src/tui/history.ts create mode 100644 src/tui/icons.ts create mode 100644 src/tui/index.tsx create mode 100644 src/tui/palette.ts create mode 100644 src/tui/state.ts create mode 100644 src/tui/theme.ts create mode 100644 src/uninstall.ts create mode 100644 src/update/index.ts create mode 100644 src/update/source.ts create mode 100644 src/update/sshsig.ts create mode 100644 src/update/version.ts create mode 100644 src/version.ts create mode 100644 src/voice/audio.ts create mode 100644 src/voice/index.ts create mode 100644 src/voice/speech.ts create mode 100644 src/voice/text.ts create mode 100644 tests/acp-v2.test.ts create mode 100644 tests/acp.test.ts create mode 100644 tests/anthropic.test.ts create mode 100644 tests/approval.test.ts create mode 100644 tests/board.test.ts create mode 100644 tests/budget.test.ts create mode 100644 tests/capacity.test.ts create mode 100644 tests/checkpoint-branch.test.ts create mode 100644 tests/clipboard.test.ts create mode 100644 tests/config.test.ts create mode 100644 tests/conformance.test.ts create mode 100644 tests/conformance.ts create mode 100644 tests/context.test.ts create mode 100644 tests/cutoff.test.ts create mode 100644 tests/diffclip.test.ts create mode 100644 tests/doctor.test.ts create mode 100644 tests/e2e.test.ts create mode 100644 tests/fake-provider.ts create mode 100644 tests/fixtures/mcp/server.ts create mode 100644 tests/fixtures/mcp/tricky.ts create mode 100644 tests/fixtures/sse/bonsai-effort-refused-in-stream.sse create mode 100644 tests/fixtures/sse/gpt-oss-first-turn.sse create mode 100644 tests/fixtures/sse/gpt-oss-peg-native-failure-mid-reply.sse create mode 100644 tests/fixtures/sse/llama-swap-model-unloaded.sse create mode 100644 tests/fixtures/sse/qwen35-answer-only-in-reasoning.sse create mode 100644 tests/fixtures/sse/qwen35-first-turn-with-swap-banner.sse create mode 100644 tests/fixtures/sse/vllm-anthropic-thinking-tool.sse create mode 100644 tests/fixtures/sse/vllm-responses-reasoning-tool.sse create mode 100644 tests/fixtures/voice/mic.ts create mode 100644 tests/fixtures/voice/piper.ts create mode 100644 tests/fixtures/voice/player.ts create mode 100644 tests/fixtures/web/ddg-bun.html create mode 100644 tests/fixtures/web/searxng-bun.json create mode 100644 tests/gemini-ollama.test.ts create mode 100644 tests/get.test.ts create mode 100644 tests/harness.test.ts create mode 100644 tests/hermes-layer.test.ts create mode 100644 tests/hermes-review.test.ts create mode 100644 tests/hub.test.ts create mode 100644 tests/images.test.ts create mode 100644 tests/install.test.ts create mode 100644 tests/instructions.test.ts create mode 100644 tests/jobs-wake.test.ts create mode 100644 tests/jsonschema.test.ts create mode 100644 tests/lembas-library.test.ts create mode 100644 tests/lembas-login.test.ts create mode 100644 tests/library.test.ts create mode 100644 tests/mcp-oauth.test.ts create mode 100644 tests/mcp-review.test.ts create mode 100644 tests/mcp.test.ts create mode 100644 tests/memory.test.ts create mode 100644 tests/model-kind.test.ts create mode 100644 tests/models.test.ts create mode 100644 tests/names.test.ts create mode 100644 tests/permission-hardening.test.ts create mode 100644 tests/permission.test.ts create mode 100644 tests/personal.test.ts create mode 100644 tests/plan.test.ts create mode 100644 tests/project.test.ts create mode 100644 tests/provider-refs.test.ts create mode 100644 tests/provider.test.ts create mode 100644 tests/purpose.test.ts create mode 100644 tests/release.test.ts create mode 100644 tests/replay.test.ts create mode 100644 tests/responses.test.ts create mode 100644 tests/sessions-delete.test.ts create mode 100644 tests/settings.test.ts create mode 100644 tests/setup.ts create mode 100644 tests/shellrc.test.ts create mode 100644 tests/skill-revisions.test.ts create mode 100644 tests/snapshot.test.ts create mode 100644 tests/steer.test.ts create mode 100644 tests/subagent.test.ts create mode 100644 tests/theme.test.ts create mode 100644 tests/titles.test.ts create mode 100644 tests/tls.test.ts create mode 100644 tests/tools.test.ts create mode 100644 tests/trust-hardening.test.ts create mode 100644 tests/tui/app.test.tsx create mode 100644 tests/tui/dialog.test.tsx create mode 100644 tests/tui/diffwrap.test.tsx create mode 100644 tests/tui/firstrun.test.tsx create mode 100644 tests/tui/harness.tsx create mode 100644 tests/tui/setup.test.tsx create mode 100644 tests/uninstall.test.ts create mode 100644 tests/units.test.ts create mode 100644 tests/update.test.ts create mode 100644 tests/voice.test.ts create mode 100644 tests/web.test.ts create mode 100644 third_party/bun-1.4.2-LICENSE.md create mode 100644 tsconfig.json diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..254e46d --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,18 @@ +# Every push to main or dev, and every pull request: scripts/ci.sh, the same gate a release passes. +name: ci +on: + push: + branches: [main, dev] + pull_request: + +jobs: + check: + # A runner of its own, registered with this label: a public repository's pull requests run + # here, so not on a shared runner that can reach anything else. + runs-on: lembas-cli-ci + timeout-minutes: 20 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # the secret scan reads the whole history + - run: scripts/ci.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..480139f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +# Every push and pull request on the public repository: scripts/ci.sh, the gate a release passes — +# types, tests, the compiled binary in a terminal, the licences, the shell scripts, and the +# history for secrets. CI=1 makes a missing shellcheck or gitleaks a failure, not a skip. +name: ci +on: + push: + branches: [main, dev] + pull_request: + +permissions: + contents: read + +jobs: + check: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # the secret scan reads the whole history + persist-credentials: false + - name: shellcheck, ripgrep + run: sudo apt-get update -qq && sudo apt-get install -y -qq shellcheck ripgrep + - name: gitleaks + env: + GITLEAKS: "8.30.1" + run: | + curl -fsSL -o gitleaks.tgz "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS}/gitleaks_${GITLEAKS}_linux_x64.tar.gz" + curl -fsSL -o sums.txt "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS}/gitleaks_${GITLEAKS}_checksums.txt" + echo "$(grep " gitleaks_${GITLEAKS}_linux_x64.tar.gz\$" sums.txt | cut -d' ' -f1) gitleaks.tgz" | sha256sum -c - + tar -xzf gitleaks.tgz gitleaks && sudo install -m 0755 gitleaks /usr/local/bin/gitleaks && rm -f gitleaks gitleaks.tgz sums.txt + - run: scripts/ci.sh + env: + CI: "1" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..1831202 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,65 @@ +# The GitHub Release for a tag, made from the Gitea release of the same tag. LLeMbas CLI is developed +# on Gitea (git.houmeres.sk/LLeMbas/LLeMbas-CLI), which mirrors its commits and tags here; a mirror carries no Releases, +# and GitHub's are what get.sh and the updater read by default. So when a tag arrives this waits for +# Gitea's release to have its files, checks them exactly as get.sh would — SHA256SUMS signed by the +# release key, naming this version, every file matching — and publishes the same files and notes. +# Nothing is built here: the binaries are the ones signed on Gitea. +name: release +on: + push: + tags: ["v*"] + # By hand, for a tag that arrived without starting this (the first mirror push brings every tag at + # once, and GitHub starts no workflow for more than three tags in one push). + workflow_dispatch: + inputs: + tag: + description: "The tag, e.g. v1.0.0" + required: true + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + timeout-minutes: 60 + env: + GITEA: https://git.houmeres.sk + # The repository on Gitea (the same name as on GitHub, $GITHUB_REPOSITORY). + REPO: LLeMbas/LLeMbas-CLI + TAG: ${{ inputs.tag || github.ref_name }} + PUBKEY: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDSZO3Byow7R3ZpOH3MCvpPIga2pZBzhfX5wXfNP1cLa" + steps: + - name: Wait for the Gitea release and its files + run: | + # The tag is mirrored as soon as it is pushed; the release and its files come minutes later. + for i in $(seq 1 50); do + if curl -fsSL "$GITEA/api/v1/repos/$REPO/releases/tags/$TAG" -o release.json && + jq -e '[.assets[].name] | index("SHA256SUMS.sig") and index("SHA256SUMS") and index("lembas-linux-x64.gz")' release.json >/dev/null; then + exit 0 + fi + sleep 60 + done + echo "no Gitea release for $TAG with its files after 50 minutes" >&2 + exit 1 + - name: Download and check the files + run: | + mkdir files + for name in $(jq -r '.assets[].name' release.json); do + curl -fsSL -o "files/$name" "$GITEA/$REPO/releases/download/$TAG/$name" + done + cd files + # Signed in the namespace lembas-release. + printf 'lembas-release %s\n' "$PUBKEY" > ../allowed + ssh-keygen -Y verify -f ../allowed -I lembas-release -n lembas-release -s SHA256SUMS.sig < SHA256SUMS || { echo "SHA256SUMS is not signed by the release key" >&2; exit 1; } + [ "$(sed -n -E 's/^# lembas //p' SHA256SUMS | head -n1)" = "${TAG#v}" ] || { echo "SHA256SUMS is not for $TAG" >&2; exit 1; } + grep -v '^#' SHA256SUMS | sha256sum -c --strict - + for f in *; do case "$f" in SHA256SUMS | SHA256SUMS.sig) continue ;; esac; grep -q " $f\$" SHA256SUMS || { echo "$f is not in SHA256SUMS" >&2; exit 1; }; done + - name: Publish the GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: | + jq -r .body release.json > notes.md + pre="" + case "$TAG" in *-beta.*) pre="--prerelease" ;; esac + gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --verify-tag --title "$(jq -r .name release.json)" --notes-file notes.md $pre files/* diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..67a641d --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +node_modules/ +dist/ +*.log +.env +.env.* +# LLeMbas CLI's own per-user project state (.agent, or .lembas beside another tool's .agent) +.agent/local/ +.lembas/local/ diff --git a/.gitleaksignore b/.gitleaksignore new file mode 100644 index 0000000..af6b3ba --- /dev/null +++ b/.gitleaksignore @@ -0,0 +1,4 @@ +# A made-up Stripe-shaped key that tests/memory.test.ts feeds the memory threat scanner, which must +# catch it. Not a credential. (gitleaks fingerprints: the commit that added it, and the file now.) +4625d26e94f900833e053346619f2b212f6416e6:tests/memory.test.ts:stripe-access-token:95 +tests/memory.test.ts:stripe-access-token:95 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3f5a9e1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +All notable changes to LLeMbas CLI. The format follows +[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project uses +[Semantic Versioning](https://semver.org/). + +## [Unreleased] + +## [1.0.0] — 2026-10-09 + +The first public release of LLeMbas CLI: a terminal coding agent and project manager for any LLM +API, with permission modes, git snapshots, memory and skills, knowledge bases, MCP, voice, and a +link to a LLeMbas instance whose web UI can work its sessions too. Signed Linux binaries for x64 +and arm64. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fc2a71d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Jaroslav Beneš + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LICENSES.txt b/LICENSES.txt new file mode 100644 index 0000000..3612073 --- /dev/null +++ b/LICENSES.txt @@ -0,0 +1,1326 @@ +LLeMbas CLI — the licences of what its release binaries contain. +Generated by scripts/licenses.ts; `lembas --licenses` prints this. + + +============================================================================== +LLeMbas CLI +============================================================================== +MIT License + +Copyright (c) 2026 Jaroslav Beneš + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +LLeMbas CLI builds on OpenCode, Hermes Agent and LLeMbas; see THIRD_PARTY.md in its source. + +============================================================================== +@mixmark-io/domino 2.2.0 — BSD-2-Clause +============================================================================== +--- LICENSE --- +Copyright (c) 2011 The Mozilla Foundation. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +============================================================================== +@modelcontextprotocol/sdk 1.30.1 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2024 Anthropic, PBC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +@opentui/core 0.5.12 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2025 opentui + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +@opentui/core-linux-x64 0.5.12 — MIT +(libopentui.so: OpenTUI's native library, with Ghostty's terminal code, Little CMS, libwebp, stb, Wuffs and Meta's Yoga layout compiled in; their notices follow.) +============================================================================== +--- AUTHORS-LIBWEBP --- +Contributors: +- Aidan O'Loan (aidanol at gmail dot com) +- Alan Browning (browning at google dot com) +- Alexandru Ardelean (ardeleanalex at gmail dot com) +- Anuraag Agrawal (anuraaga at gmail dot com) +- Arthur Eubanks (aeubanks at google dot com) +- Brian Ledger (brianpl at google dot com) +- Charles Munger (clm at google dot com) +- Cheng Yi (cyi at google dot com) +- Christian Duvivier (cduvivier at google dot com) +- Christopher Degawa (ccom at randomderp dot com) +- Clement Courbet (courbet at google dot com) +- devtools-clrobot at google dot com (devtools-clrobot@google dot com) +- Djordje Pesut (djordje dot pesut at imgtec dot com) +- Frank (1433351828 at qq dot com) +- Frank Barchard (fbarchard at google dot com) +- Henner Zeller (hzeller at google dot com) +- Hui Su (huisu at google dot com) +- H. Vetinari (h dot vetinari at gmx dot com) +- Ilya Kurdyukov (jpegqs at gmail dot com) +- Ingvar Stepanyan (rreverser at google dot com) +- Istvan Stefan (Istvan dot Stefan at arm dot com) +- James Zern (jzern at google dot com) +- Jan Engelhardt (jengelh at medozas dot de) +- Jehan (jehan at girinstud dot io) +- Jeremy Maitin-Shepard (jbms at google dot com) +- Johann Koenig (johann dot koenig at duck dot com) +- Jonathan Grant (jgrantinfotech at gmail dot com) +- Jonliu1993 (13720414433 at 163 dot com) +- Jovan Zelincevic (jovan dot zelincevic at imgtec dot com) +- Jyrki Alakuijala (jyrki at google dot com) +- Konstantin Ivlev (tomskside at gmail dot com) +- Lode Vandevenne (lode at google dot com) +- Lou Quillio (louquillio at google dot com) +- Mans Rullgard (mans at mansr dot com) +- Marcin Kowalczyk (qrczak at google dot com) +- Martin Olsson (mnemo at minimum dot se) +- Maryla Ustarroz-Calonge (maryla at google dot com) +- Masahiro Hanada (hanada at atmark-techno dot com) +- Mikołaj Zalewski (mikolajz at google dot com) +- Mislav Bradac (mislavm at google dot com) +- natewood (natewood at fb dot com) +- Nico Weber (thakis at chromium dot org) +- Noel Chromium (noel at chromium dot org) +- Nozomi Isozaki (nontan at pixiv dot co dot jp) +- Oliver Wolff (oliver dot wolff at qt dot io) +- Owen Rodley (orodley at google dot com) +- Ozkan Sezer (sezeroz at gmail dot com) +- Parag Salasakar (img dot mips1 at gmail dot com) +- Pascal Massimino (pascal dot massimino at gmail dot com) +- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org) +- Pierre Joye (pierre dot php at gmail dot com) +- Roberto Alanis (alanisbaez at google dot com) +- Sam Clegg (sbc at chromium dot org) +- Scott Hancher (seh at google dot com) +- Scott LaVarnway (slavarnway at google dot com) +- Scott Talbot (s at chikachow dot org) +- Slobodan Prijic (slobodan dot prijic at imgtec dot com) +- Somnath Banerjee (somnath dot banerjee at gmail dot com) +- Sriraman Tallam (tmsriram at google dot com) +- Tamar Levy (tamar dot levy at intel dot com) +- Thiago Perrotta (tperrotta at google dot com) +- Timothy Gu (timothygu99 at gmail dot com) +- Urvang Joshi (urvang at google dot com) +- Vikas Arora (vikasa at google dot com) +- Vincent Rabaud (vrabaud at google dot com) +- Vlad Tsyrklevich (vtsyrklevich at chromium dot org) +- Wan-Teh Chang (wtc at google dot com) +- wrv (wrv at utexas dot edu) +- Yang Zhang (yang dot zhang at arm dot com) +- Yannis Guyon (yguyon at google dot com) +- Zhi An Ng (zhin at chromium dot org) + +--- LICENSE --- +MIT License + +Copyright (c) 2025 opentui + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- LICENSE-GHOSTTY --- +MIT License + +Copyright (c) 2024 Mitchell Hashimoto, Ghostty contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------- +uucode +------------------------------------------------------------------------------- + +MIT License + +Copyright (c) 2026 Jacob Sandlund + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------- +uucode UTF-8 decoder +------------------------------------------------------------------------------- + +From https://bjoern.hoehrmann.de/utf-8/decoder/dfa/ + +Copyright (c) 2008-2009 Bjoern Hoehrmann + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------- +Unicode data +------------------------------------------------------------------------------- + +UNICODE LICENSE V3 + +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1991-2025 Unicode, Inc. + +NOTICE TO USER: Carefully read the following legal agreement. BY +DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR +SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT +DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of data files and any associated documentation (the "Data Files") or +software and any associated documentation (the "Software") to deal in the +Data Files or Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Data Files or Software, and to permit persons to whom the +Data Files or Software are furnished to do so, provided that either (a) +this copyright and permission notice appear with all copies of the Data +Files or Software, or (b) this copyright and permission notice appear in +associated Documentation. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF +THIRD PARTY RIGHTS. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE +BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA +FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in these Data Files or Software without prior written +authorization of the copyright holder. + +--- LICENSE-LCMS2 --- +MIT License + +Copyright (c) 2023 Marti Maria Saguer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- LICENSE-LIBWEBP --- +Copyright (c) 2010, Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Google nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--- LICENSE-STB --- +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- LICENSE-WUFFS --- +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + +--- PATENTS-LIBWEBP --- +Additional IP Rights Grant (Patents) +------------------------------------ + +"These implementations" means the copyrightable works that implement the WebM +codecs distributed by Google as part of the WebM Project. + +Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge, +royalty-free, irrevocable (except as stated in this section) patent license to +make, have made, use, offer to sell, sell, import, transfer, and otherwise +run, modify and propagate the contents of these implementations of WebM, where +such license applies only to those patent claims, both currently owned by +Google and acquired in the future, licensable by Google that are necessarily +infringed by these implementations of WebM. This grant does not include claims +that would be infringed only as a consequence of further modification of these +implementations. If you or your agent or exclusive licensee institute or order +or agree to the institution of patent litigation or any other patent +enforcement activity against any entity (including a cross-claim or +counterclaim in a lawsuit) alleging that any of these implementations of WebM +or any code incorporated within any of these implementations of WebM +constitute direct or contributory patent infringement, or inducement of +patent infringement, then any patent rights granted to you under this License +for these implementations of WebM shall terminate as of the date such +litigation is filed. + +============================================================================== +@opentui/solid 0.5.12 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2025 opentui + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +ajv 8.20.0 — MIT +============================================================================== +--- LICENSE --- +The MIT License (MIT) + +Copyright (c) 2015-2021 Evgeny Poberezkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +ajv-formats 3.0.1 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2020 Evgeny Poberezkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +content-type 1.0.5 — MIT +============================================================================== +--- LICENSE --- +(The MIT License) + +Copyright (c) 2015 Douglas Christopher Wilson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +============================================================================== +cross-spawn 7.0.6 — MIT +============================================================================== +--- LICENSE --- +The MIT License (MIT) + +Copyright (c) 2018 Made With MOXY Lda + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +============================================================================== +diff 9.0.0 — BSD-3-Clause +============================================================================== +--- LICENSE --- +BSD 3-Clause License + +Copyright (c) 2009-2015, Kevin Decker +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +============================================================================== +entities 7.0.1 — BSD-2-Clause +============================================================================== +--- LICENSE --- +Copyright (c) Felix Böhm +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +============================================================================== +eventsource 3.0.7 — MIT +============================================================================== +--- LICENSE --- +The MIT License + +Copyright (c) EventSource GitHub organisation + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +============================================================================== +eventsource-parser 3.1.1 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2026 Espen Hovlandsdal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +fast-deep-equal 3.1.3 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2017 Evgeny Poberezkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +fast-uri 3.1.8 — BSD-3-Clause +============================================================================== +--- LICENSE --- +Copyright (c) 2011-2021, Gary Court until https://github.com/garycourt/uri-js/commit/a1acf730b4bba3f1097c9f52e7d9d3aba8cdcaae +Copyright (c) 2021-present The Fastify team +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * The names of any contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + * * * + +The complete list of contributors can be found at: +- https://github.com/garycourt/uri-js/graphs/contributors + +============================================================================== +fuzzysort 3.1.0 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2018 Stephen Kamenar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +isexe 2.0.0 — ISC +============================================================================== +--- LICENSE --- +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +============================================================================== +json-schema-traverse 1.0.0 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2017 Evgeny Poberezkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +path-key 3.1.1 — MIT +============================================================================== +--- license --- +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +============================================================================== +pkce-challenge 5.0.1 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2019 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +shebang-command 2.0.0 — MIT +============================================================================== +--- license --- +MIT License + +Copyright (c) Kevin Mårtensson (github.com/kevva) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +============================================================================== +shebang-regex 3.0.0 — MIT +============================================================================== +--- license --- +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +============================================================================== +solid-js 1.9.15 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2016-2025 Ryan Carniato + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +turndown 7.2.4 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2017 Dom Christie + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +web-tree-sitter 0.25.10 — MIT +============================================================================== +--- LICENSE --- +The MIT License (MIT) + +Copyright (c) 2018-2024 Max Brunsfeld + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +which 2.0.2 — ISC +============================================================================== +--- LICENSE --- +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +============================================================================== +yaml 2.9.1 — ISC +============================================================================== +--- LICENSE --- +Copyright Eemeli Aro + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +============================================================================== +zod 4.6.5 — MIT +============================================================================== +--- LICENSE --- +MIT License + +Copyright (c) 2025 Colin McDonnell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================== +zod-to-json-schema 3.25.2 — ISC +============================================================================== +--- LICENSE --- +ISC License + +Copyright (c) 2020, Stefan Terdell + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +============================================================================== +Yoga (in libopentui.so) — MIT +============================================================================== +Copyright (c) Meta Platforms, Inc. and affiliates. Licensed under the MIT license: https://github.com/facebook/yoga/blob/main/LICENSE + +============================================================================== +Tree-sitter grammars (OpenTUI's syntax highlighting: javascript, typescript, markdown, zig) — MIT +============================================================================== +https://github.com/tree-sitter/tree-sitter-javascript, https://github.com/tree-sitter/tree-sitter-typescript, https://github.com/tree-sitter-grammars/tree-sitter-markdown, https://github.com/tree-sitter-grammars/tree-sitter-zig — each MIT. + +============================================================================== +Bun 1.4.2 (the runtime compiled into the binary) +============================================================================== +Bun itself is MIT-licensed. + +## JavaScriptCore + +Bun statically links JavaScriptCore (and WebKit) which is LGPL-2 licensed. WebCore files from WebKit are also licensed under LGPL2. Per LGPL2: + +> (1) If you statically link against an LGPL’d library, you must also provide your application in an object (not necessarily source) format, so that a user has the opportunity to modify the library and relink the application. + +You can find the patched version of WebKit used by Bun here: . If you would like to relink Bun with changes: + +- `git clone https://github.com/oven-sh/WebKit vendor/WebKit` +- `bun sync-webkit-source` (checks out the version pinned in `WEBKIT_VERSION` in `scripts/build/deps/webkit.ts`) +- `bun run build:local` + +This compiles JavaScriptCore, compiles Bun’s `.cpp` bindings for JavaScriptCore (which are the object files using JavaScriptCore) and outputs a new `bun` binary with your changes. + +## Linked libraries + +Bun statically links these libraries: + +| Library | License | +|---------|---------| +| [`boringssl`](https://boringssl.googlesource.com/boringssl/) | [several licenses](https://boringssl.googlesource.com/boringssl/+/refs/heads/master/LICENSE) | +| [`brotli`](https://github.com/google/brotli) | MIT | +| [`libarchive`](https://github.com/libarchive/libarchive) | [several licenses](https://github.com/libarchive/libarchive/blob/master/COPYING) | +| [`lol-html`](https://github.com/cloudflare/lol-html/tree/master/c-api) | BSD 3-Clause | +| [`ls-hpack`](https://github.com/litespeedtech/ls-hpack) | MIT | +| [`ls-qpack`](https://github.com/litespeedtech/ls-qpack) | MIT | +| [`lsquic`](https://github.com/litespeedtech/lsquic) | MIT (portions derived from [Chromium proto-quic](https://github.com/litespeedtech/lsquic/blob/master/LICENSE.chrome), BSD 3-Clause) | +| [`mimalloc`](https://github.com/microsoft/mimalloc) | MIT | +| [`picohttp`](https://github.com/h2o/picohttpparser) | dual-licensed under the Perl License or the MIT License | +| [`zstd`](https://github.com/facebook/zstd) | dual-licensed under the BSD License or GPLv2 license | +| [`simdutf`](https://github.com/simdutf/simdutf) | Apache 2.0 | +| [`tinycc`](https://github.com/tinycc/tinycc) | LGPL v2.1 | +| [`uSockets`](https://github.com/uNetworking/uSockets) | Apache 2.0 | +| [`zlib-ng`](https://github.com/zlib-ng/zlib-ng) | zlib | +| [`c-ares`](https://github.com/c-ares/c-ares) | MIT licensed | +| [`libicu`](https://github.com/unicode-org/icu) 78 | [license here](https://github.com/unicode-org/icu/blob/main/icu4c/LICENSE) | +| [`libbase64`](https://github.com/aklomp/base64/blob/master/LICENSE) | BSD 2-Clause | +| [`libuv`](https://github.com/libuv/libuv) (on Windows) | MIT | +| [`libdeflate`](https://github.com/ebiggers/libdeflate) | MIT | +| [`libjpeg-turbo`](https://github.com/libjpeg-turbo/libjpeg-turbo) | [BSD 3-Clause / IJG / zlib](https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/LICENSE.md) | +| [`libspng`](https://github.com/randy408/libspng) | BSD 2-Clause | +| [`libwebp`](https://github.com/webmproject/libwebp) | BSD 3-Clause | +| [`highway`](https://github.com/google/highway) | Apache 2.0 | +| [`uucode`](https://github.com/jacobsandlund/uucode) | MIT | +| A fork of [`uWebsockets`](https://github.com/jarred-sumner/uwebsockets) | Apache 2.0 licensed | +| Parts of [Tigerbeetle's IO code](https://github.com/tigerbeetle/tigerbeetle/blob/532c8b70b9142c17e07737ab6d3da68d7500cbca/src/io/windows.zig#L1) | Apache 2.0 licensed | +| `__cxa_thread_atexit` fallback from [LLVM libc++abi](https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/libcxxabi/src/cxa_thread_atexit.cpp) | Apache 2.0 with LLVM exception | + +## Polyfills + +For compatibility reasons, the following packages are embedded into Bun's binary and injected if imported. + +| Package | License | +|---------|---------| +| [`acorn`](https://github.com/acornjs/acorn) | MIT | +| [`acorn-walk`](https://github.com/acornjs/acorn) | MIT | +| [`assert`](https://npmjs.com/package/assert) | MIT | +| [`browserify-zlib`](https://npmjs.com/package/browserify-zlib) | MIT | +| [`buffer`](https://npmjs.com/package/buffer) | MIT | +| [`constants-browserify`](https://npmjs.com/package/constants-browserify) | MIT | +| [`crypto-browserify`](https://npmjs.com/package/crypto-browserify) | MIT | +| [`domain-browser`](https://npmjs.com/package/domain-browser) | MIT | +| [`events`](https://npmjs.com/package/events) | MIT | +| [`https-browserify`](https://npmjs.com/package/https-browserify) | MIT | +| [`os-browserify`](https://npmjs.com/package/os-browserify) | MIT | +| [`path-browserify`](https://npmjs.com/package/path-browserify) | MIT | +| [`process`](https://npmjs.com/package/process) | MIT | +| [`punycode`](https://npmjs.com/package/punycode) | MIT | +| [`querystring-es3`](https://npmjs.com/package/querystring-es3) | MIT | +| [`stream-browserify`](https://npmjs.com/package/stream-browserify) | MIT | +| [`stream-http`](https://npmjs.com/package/stream-http) | MIT | +| [`string_decoder`](https://npmjs.com/package/string_decoder) | MIT | +| [`timers-browserify`](https://npmjs.com/package/timers-browserify) | MIT | +| [`tty-browserify`](https://npmjs.com/package/tty-browserify) | MIT | +| [`url`](https://npmjs.com/package/url) | MIT | +| [`util`](https://npmjs.com/package/util) | MIT | +| [`vm-browserify`](https://npmjs.com/package/vm-browserify) | MIT | + +## Additional credits + +- Bun's JS transpiler, CSS lexer, and Node.js module resolver source code is a port of [@evanw](https://github.com/evanw)’s [esbuild](https://github.com/evanw/esbuild) project. +- Credit to [@kipply](https://github.com/kipply) for the name "Bun"! + +Relinking: LLeMbas CLI's whole source is public, so the binary can be rebuilt against a modified Bun (and so a modified JavaScriptCore) with `bun run build` — https://github.com/oven-sh/bun at bun-v1.4.2, https://github.com/oven-sh/WebKit for its JavaScriptCore. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c2037b2 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +

+ LLeMbas CLI — terminal coding agent +

+ +# LLeMbas CLI + +A terminal coding agent and project manager: the `lembas` command. It talks to any LLM API +(OpenAI-compatible servers such as llama.cpp, vLLM or LM Studio, the OpenAI Responses API, +Anthropic, Gemini, Ollama), works in your project with four permission modes and a git snapshot of +every turn, remembers what it learns across sessions, and can sign in to a +[LLeMbas](https://github.com/LLeMbas/LLeMbas) server to use its models, library and search — and +let its web UI work the same sessions. Linux, x64 and arm64. + +## Install + +```sh +curl -fsSL https://github.com/LLeMbas/LLeMbas-CLI/releases/latest/download/get.sh | bash +``` + +Or download a binary from [Releases](https://github.com/LLeMbas/LLeMbas-CLI/releases). Every +release's `SHA256SUMS` is signed with the release key, and `get.sh` checks the signature and the +checksum before installing anything ([SECURITY.md](SECURITY.md) shows how to check by hand). + +## First steps + +```sh +cd your-project && lembas # the TUI +lembas login https://your-server # sign in to a LLeMbas server and use its models +``` + +Without a server, add a connection to `~/.config/lembas/connections.yaml` and set `model:` in +`~/.config/lembas/config.yaml`. + +`lembas` updates itself (`lembas update` does it now); `lembas uninstall` removes it, and +`--purge` takes settings and sessions too. + +## Links + +- Documentation: and +- Changelog: +- The server: + +## Licence + +MIT — see [LICENSE](LICENSE) and [THIRD_PARTY.md](THIRD_PARTY.md). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..97eca34 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,57 @@ +# Security + +## Reporting a problem + +Please report a vulnerability privately, not in a public issue: on GitHub, **Security → Report a +vulnerability** on [LLeMbas/LLeMbas-CLI](https://github.com/LLeMbas/LLeMbas-CLI/security). + +Say what it is, how to reproduce it, and which version (`lembas --version`). You will get an +answer within a week. Fixes go out as a release, and the CHANGELOG says what was fixed once the release is out. + +## Supported versions + +Only the newest release. LLeMbas +CLI updates itself (`update.auto`), so staying on it is the default. + +## What counts + +LLeMbas CLI runs commands and changes files for a language model, so the model's output — and +everything the model reads: files, web pages, tool results, MCP servers — is treated as +untrusted. A report is most useful when it shows one of these: + +- a tool call that runs, or changes something, **without the approval** the permission mode and + rules say it needs — including a way past the hardline list (refused in every mode) or a write + to a protected path (`~/.ssh`, `~/.gnupg`, `connections.yaml`); +- something a repository can do **before the user trusts it**, or in read-only mode, beyond being + read; or anything that weakens a global-only setting from a project; +- a way for the agent to change a setting it must not (permission rules, the hardline, MCP + servers, connections, the update source or key, `settings_tool`), or to loosen the permission + mode without being asked every time; +- an update that installs without a valid signature from the release key, an older release + installed as an update, or files written outside where the installer and uninstaller say; +- secrets — API keys, OAuth tokens — written somewhere readable, logged, or sent to a host other + than the one they belong to. + +A model doing something unwise **with** the user's approval, or in `unrestricted` mode, is how +LLeMbas CLI is meant to work, not a vulnerability; ways to make that clearer are still welcome as +ordinary issues ([GitHub Issues](https://github.com/LLeMbas/LLeMbas-CLI/issues)). + +## Verifying a release + +Each release's `SHA256SUMS` is signed with the release key, an SSH ed25519 key used for nothing +else: + +``` +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDSZO3Byow7R3ZpOH3MCvpPIga2pZBzhfX5wXfNP1cLa +SHA256:aPrR1ptc5sIwmyJgmqtu1iXmciq466Wv9kZNfm8Ddmg +``` + +`get.sh` and the updater check it before installing anything. By hand: + +```sh +echo "lembas-release ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDSZO3Byow7R3ZpOH3MCvpPIga2pZBzhfX5wXfNP1cLa" > allowed +ssh-keygen -Y verify -f allowed -I lembas-release -n lembas-release -s SHA256SUMS.sig < SHA256SUMS +sha256sum -c --ignore-missing SHA256SUMS +``` + +Tags and commits are signed too (SSH signatures, shown as verified on the forge). diff --git a/THIRD_PARTY.md b/THIRD_PARTY.md new file mode 100644 index 0000000..ee8b6a2 --- /dev/null +++ b/THIRD_PARTY.md @@ -0,0 +1,62 @@ +# Third-party code and text + +LLeMbas CLI is MIT licensed. It takes code, prompt +text and design from the projects below. Every file lifted or ported from one of +them says so in its header, naming the upstream path. + +| Project | Licence | Copyright | What LLeMbas CLI takes | +|---|---|---|---| +| [OpenCode](https://github.com/anomalyco/opencode) | MIT | © 2025 opencode | Project data system (AGENTS.md / CLAUDE.md discovery, per-project directory), permission rules and bash arity, question tool, `@` / `/` autocomplete, shadow-git snapshots, per-model-family system prompts, MCP (prompts as commands, server instructions, the OAuth callback and token store) | +| [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) | MIT | © 2024 Anthropic, PBC | The MCP client, used as a dependency (and its example OAuth server, in the tests) | +| [OpenTUI](https://github.com/anomalyco/opentui) | MIT | © 2025 opentui | The terminal rendering engine, used as a dependency | +| [Hermes Agent](https://github.com/NousResearch/hermes-agent) | MIT | © 2025 Nous Research | Persistent memory, skills, session search, the prompt-injection patterns, MCP client shape, voice mode (silence auto-stop, spoken-text normalisation, the silence-phrase filter), the default skin and tool-line style, prompt guidance blocks, dangerous-command patterns | +| [LLeMbas](https://github.com/LLeMbas/LLeMbas) | MIT | © Jaroslav Beneš | Connection and model settings, reasoning-effort handling for llama.cpp, the ask-user design, prompt text, the library's chunker, the personality presets and their headings, the unified-diff applier (`src/tool/unidiff.ts`), the capacity rule, the per-prompt budgets and editing a command before allowing it. The two share one harness design (`harness/`) | + +The MIT licence texts of OpenCode, OpenTUI and Hermes Agent require their +copyright notice to travel with substantial portions of their code. Their full +notices: + +``` +MIT License — Copyright (c) 2025 opencode +MIT License — Copyright (c) 2025 opentui +MIT License — Copyright (c) 2025 Nous Research + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +``` + +## Inside the release binaries + +A release binary is LLeMbas CLI's code bundled with the npm packages it uses, OpenTUI's native +library, and the Bun runtime, compiled into one file. **[LICENSES.txt](LICENSES.txt)** has every +licence that comes with that — generated from what the bundle actually contains by +`bun run licenses`, checked by CI, published with each release, and printed by +`lembas --licenses`. In short: + +- **npm packages** (29): MIT, ISC, BSD-2-Clause and BSD-3-Clause — among them OpenTUI, Solid, + the MCP SDK, zod, yaml, turndown (with domino), diff, fuzzysort and ajv. +- **`libopentui.so`**, OpenTUI's native library (MIT), with Ghostty's terminal code (MIT), + Little CMS (MIT), libwebp (BSD-3-Clause, with Google's patent grant), stb (MIT / public domain), + Wuffs (Apache-2.0) and Meta's Yoga layout (MIT) compiled in; tree-sitter grammars for its syntax + highlighting (MIT). +- **Bun** (MIT), which statically links JavaScriptCore and parts of WebKit under the **LGPL 2**, + and other libraries under permissive licences ([Bun's own list](third_party/bun-1.4.2-LICENSE.md)). + The LGPL asks that a user can relink the program against a modified library: LLeMbas CLI's whole + source is public, so the binary can be rebuilt against a modified Bun (and so a modified + JavaScriptCore) with `bun run build`. Bun's sources: at + `bun-v1.4.2`; its JavaScriptCore: . diff --git a/assets/banner.svg b/assets/banner.svg new file mode 100644 index 0000000..d040e82 --- /dev/null +++ b/assets/banner.svg @@ -0,0 +1,78 @@ + + LLeMbas CLI + The LLeMbas CLI: a pixel mallorn leaf in a terminal window beside the + wordmark and a lembas prompt. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..c3270a7 --- /dev/null +++ b/bun.lock @@ -0,0 +1,486 @@ +{ + "lockfileVersion": 2, + "configVersion": 1, + "workspaces": { + "": { + "name": "lembas-cli", + "dependencies": { + "@modelcontextprotocol/sdk": "1.30.1", + "@opentui/core": "0.5.12", + "@opentui/solid": "0.5.12", + "diff": "9.0.0", + "fuzzysort": "3.1.0", + "solid-js": "1.9.15", + "turndown": "7.2.4", + "yaml": "2.9.1", + "zod": "4.6.5", + }, + "devDependencies": { + "@types/bun": "1.4.2", + "@types/turndown": "5.0.6", + "@xterm/addon-unicode11": "0.9.0", + "@xterm/headless": "6.0.0", + "typescript": "7.0.2", + }, + }, + }, + "packages": { + "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], + + "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], + + "@babel/compat-data": ["@babel/compat-data@7.29.7", "", {}, "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg=="], + + "@babel/core": ["@babel/core@7.28.0", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.6", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ=="], + + "@babel/generator": ["@babel/generator@7.29.8", "", { "dependencies": { "@babel/parser": "^7.29.8", "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg=="], + + "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" } }, "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw=="], + + "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.29.7", "", { "dependencies": { "@babel/compat-data": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g=="], + + "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-member-expression-to-functions": "^7.29.7", "@babel/helper-optimise-call-expression": "^7.29.7", "@babel/helper-replace-supers": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", "@babel/traverse": "^7.29.7", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg=="], + + "@babel/helper-globals": ["@babel/helper-globals@7.29.7", "", {}, "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA=="], + + "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg=="], + + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g=="], + + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg=="], + + "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" } }, "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong=="], + + "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.29.7", "", {}, "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw=="], + + "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.29.7", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.29.7", "@babel/helper-optimise-call-expression": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ=="], + + "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/helper-validator-option": ["@babel/helper-validator-option@7.29.7", "", {}, "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw=="], + + "@babel/helpers": ["@babel/helpers@7.29.7", "", { "dependencies": { "@babel/template": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg=="], + + "@babel/parser": ["@babel/parser@7.29.9", "", { "dependencies": { "@babel/types": "^7.29.8" }, "bin": "./bin/babel-parser.js" }, "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA=="], + + "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A=="], + + "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA=="], + + "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.29.7", "", { "dependencies": { "@babel/helper-module-transforms": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ=="], + + "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.29.9", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", "@babel/plugin-syntax-typescript": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-FFwIwzU+7SCOuxxV4YtJql6T9981ZVTm+FHO5GhVsRqCTdy0WwrEZh3l42ARpXruJUDGOptdduHW6Zr7pNPLNg=="], + + "@babel/preset-typescript": ["@babel/preset-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ=="], + + "@babel/template": ["@babel/template@7.29.7", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg=="], + + "@babel/traverse": ["@babel/traverse@7.29.8", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.8", "@babel/helper-globals": "^7.29.7", "@babel/parser": "^7.29.8", "@babel/template": "^7.29.7", "@babel/types": "^7.29.8", "debug": "^4.3.1" } }, "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg=="], + + "@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + + "@hono/node-server": ["@hono/node-server@2.1.1", "", { "peerDependencies": { "hono": "^4" } }, "sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.6.0", "", {}, "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@mixmark-io/domino": ["@mixmark-io/domino@2.2.0", "", {}, "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="], + + "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.30.1", "", { "dependencies": { "@hono/node-server": "^1.19.9 || ^2.0.5", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-H2HxLvC3HDNybePJaLdSrU1hhUK5iQw+WvV1b01myFyI7sdVGe1u/IPTE5D9fGCiJDVtgMV/lmFkQXLmQyIFYA=="], + + "@opentui/core": ["@opentui/core@0.5.12", "", { "dependencies": { "bun-ffi-structs": "0.3.1", "diff": "9.0.0", "marked": "17.0.1", "string-width": "7.2.0", "strip-ansi": "7.1.2" }, "optionalDependencies": { "@opentui/core-darwin-arm64": "0.5.12", "@opentui/core-darwin-x64": "0.5.12", "@opentui/core-linux-arm64": "0.5.12", "@opentui/core-linux-arm64-musl": "0.5.12", "@opentui/core-linux-x64": "0.5.12", "@opentui/core-linux-x64-musl": "0.5.12", "@opentui/core-win32-arm64": "0.5.12", "@opentui/core-win32-x64": "0.5.12" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-ZXBE5gmvdovmV8zJQrOQf6E44v1tJRDEgrM2MYhEglzgXZ+smIUp95O8zeRYGsuIzQIiMPMgQqKtTJuzvAb7BQ=="], + + "@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.5.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-YdVnP0tAyerBNl0mIcmQEOotPeZzW1VnSXKBl5cyZ5e6nDd2Y+ui/8eRPpn1oqcamf1NCnzS4ohMgejOvna8Zg=="], + + "@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.5.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-uRrQJdHmLUSj3PV23QPi3WSimYTTxcXnVouxF6U4xMXlOv4N3SxnHfVwMRQkPqbGOfvVWHeLE6FdK4C+ubU0sQ=="], + + "@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.5.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-XeKhuIaEtgipvuPHbl4qPOBj+Ut+2zObmsxMVM1jDcjz/FatG9PGeGQPx1G1SnvH2AgpT4K+eCu7DUF0+yIqoQ=="], + + "@opentui/core-linux-arm64-musl": ["@opentui/core-linux-arm64-musl@0.5.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-VZ2sNMw1d/r1SLPjUbOP9LKscKz1CQjID8adTL6gG8Lrrq+mYcIUxutyB+P/eG0J/7oRZLPR6OMt7dUOap6RTg=="], + + "@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.5.12", "", { "os": "linux", "cpu": "x64" }, "sha512-eZiCjEzwbb6qClPPfk32Nha9xmr9obt69Xj0+9SKsXxWLBKkjQEGOMRoh/R9ObaQF4aq8If1xV3VEY0sD9W9vg=="], + + "@opentui/core-linux-x64-musl": ["@opentui/core-linux-x64-musl@0.5.12", "", { "os": "linux", "cpu": "x64" }, "sha512-WWW0hVBoSYZ3D6AgZ4u2Y5/u/IyIq2pDb+4yI3WgJ70Wyt6ofHy+6kRGRgbXFn1p+rPInAHjCXD2v6C7iEKSrA=="], + + "@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.5.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-aLbm6870Ybls6CYL4zMOCImTBPLZHZMUXJFGqMI44lIWxitkAtT6zg5lYA4oRqFRzzryDclxr29+hDgT3p3Blw=="], + + "@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.5.12", "", { "os": "win32", "cpu": "x64" }, "sha512-KTwtwpfd2zF9opVh3SyRJYDd1o3Xv4XL8OZb8Zi+CqWUel6Y2IDCiVivCv8fGJt3J7wOIXXtuZI9ZUkLyKJCiQ=="], + + "@opentui/solid": ["@opentui/solid@0.5.12", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.5.12", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.12", "entities": "7.0.1", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.12" } }, "sha512-hAiVlVMtT7AkHGblKwcW1YAuXtxkSy1XSf/RRc4j3IlG3mTNX0bhJdnGOo3Xw14EqeZMp41Mcp5WzHAzMm/DzA=="], + + "@types/bun": ["@types/bun@1.4.2", "", { "dependencies": { "bun-types": "1.4.2" } }, "sha512-GimotNn7+ZV0uVArItBbriZsR1oNf0+WTzPkdcFrzShI7k2norL0uzEaJT8T33dWr7O/c9ZDuAFQrctKCi72oQ=="], + + "@types/node": ["@types/node@26.6.3", "", { "dependencies": { "undici-types": "~8.9.0" } }, "sha512-dsqMQQoeTLqu9wynDD00q573mNzso3IdQOAfHRJqLCcmCFPoGo9A1bDpUcv/9tnKpErQWv9uKeGfl37EIS02Yg=="], + + "@types/turndown": ["@types/turndown@5.0.6", "", {}, "sha512-ru00MoyeeouE5BX4gRL+6m/BsDfbRayOskWqUvh7CLGW+UXxHQItqALa38kKnOiZPqJrtzJUgAC2+F0rL1S4Pg=="], + + "@typescript/typescript-aix-ppc64": ["@typescript/typescript-aix-ppc64@7.0.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ=="], + + "@typescript/typescript-darwin-arm64": ["@typescript/typescript-darwin-arm64@7.0.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA=="], + + "@typescript/typescript-darwin-x64": ["@typescript/typescript-darwin-x64@7.0.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA=="], + + "@typescript/typescript-freebsd-arm64": ["@typescript/typescript-freebsd-arm64@7.0.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ=="], + + "@typescript/typescript-freebsd-x64": ["@typescript/typescript-freebsd-x64@7.0.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw=="], + + "@typescript/typescript-linux-arm": ["@typescript/typescript-linux-arm@7.0.2", "", { "os": "linux", "cpu": "arm" }, "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ=="], + + "@typescript/typescript-linux-arm64": ["@typescript/typescript-linux-arm64@7.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ=="], + + "@typescript/typescript-linux-loong64": ["@typescript/typescript-linux-loong64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ=="], + + "@typescript/typescript-linux-mips64el": ["@typescript/typescript-linux-mips64el@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA=="], + + "@typescript/typescript-linux-ppc64": ["@typescript/typescript-linux-ppc64@7.0.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA=="], + + "@typescript/typescript-linux-riscv64": ["@typescript/typescript-linux-riscv64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ=="], + + "@typescript/typescript-linux-s390x": ["@typescript/typescript-linux-s390x@7.0.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw=="], + + "@typescript/typescript-linux-x64": ["@typescript/typescript-linux-x64@7.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A=="], + + "@typescript/typescript-netbsd-arm64": ["@typescript/typescript-netbsd-arm64@7.0.2", "", { "os": "none", "cpu": "arm64" }, "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA=="], + + "@typescript/typescript-netbsd-x64": ["@typescript/typescript-netbsd-x64@7.0.2", "", { "os": "none", "cpu": "x64" }, "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA=="], + + "@typescript/typescript-openbsd-arm64": ["@typescript/typescript-openbsd-arm64@7.0.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ=="], + + "@typescript/typescript-openbsd-x64": ["@typescript/typescript-openbsd-x64@7.0.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg=="], + + "@typescript/typescript-sunos-x64": ["@typescript/typescript-sunos-x64@7.0.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g=="], + + "@typescript/typescript-win32-arm64": ["@typescript/typescript-win32-arm64@7.0.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ=="], + + "@typescript/typescript-win32-x64": ["@typescript/typescript-win32-x64@7.0.2", "", { "os": "win32", "cpu": "x64" }, "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g=="], + + "@xterm/addon-unicode11": ["@xterm/addon-unicode11@0.9.0", "", {}, "sha512-FxDnYcyuXhNl+XSqGZL/t0U9eiNb/q3EWT5rYkQT/zuig8Gz/VagnQANKHdDWFM2lTMk9ly0EFQxxxtZUoRetw=="], + + "@xterm/headless": ["@xterm/headless@6.0.0", "", {}, "sha512-5Yj1QINYCyzrZtf8OFIHi47iQtI+0qYFPHmouEfG8dHNxbZ9Tb9YGSuLcsEwj9Z+OL75GJqPyJbyoFer80a2Hw=="], + + "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], + + "ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], + + "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], + + "ansi-regex": ["ansi-regex@6.3.0", "", {}, "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ=="], + + "babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.40.10", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-lxve6Y02YiZTldB7efKpnbf1BH00XCFZNYYW235jSGsYaJNFtHrYlKV6/O+miHbjqpIr9FTe5+0no4hofAMbfA=="], + + "babel-plugin-module-resolver": ["babel-plugin-module-resolver@5.0.2", "", { "dependencies": { "find-babel-config": "^2.1.1", "glob": "^9.3.3", "pkg-up": "^3.1.0", "reselect": "^4.1.7", "resolve": "^1.22.8" } }, "sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg=="], + + "babel-preset-solid": ["babel-preset-solid@1.9.12", "", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.40.6" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^1.9.12" }, "optionalPeers": ["solid-js"] }, "sha512-LLqnuKVDlKpyBlMPcH6qEvs/wmS9a+NczppxJ3ryS/c0O5IiSFOIBQi9GzyiGDSbcJpx4Gr87jyFTos1MyEuWg=="], + + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "baseline-browser-mapping": ["baseline-browser-mapping@2.11.26", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-GLQdD3y6UF8iVuMJl5fHgE4jdn/ua7n+toKfLgNlg3BqQtOZjpy68T8Tup8/wGWZCDlm7KMg7tPb4MPn7oN0TQ=="], + + "body-parser": ["body-parser@2.3.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^2.0.0", "debug": "^4.4.3", "http-errors": "^2.0.1", "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", "qs": "^6.15.2", "raw-body": "^3.0.2", "type-is": "^2.1.0" } }, "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw=="], + + "brace-expansion": ["brace-expansion@2.1.7", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g=="], + + "browserslist": ["browserslist@4.29.1", "", { "dependencies": { "baseline-browser-mapping": "^2.11.25", "caniuse-lite": "^1.0.30001810", "electron-to-chromium": "^1.5.438", "node-releases": "^2.0.57", "update-browserslist-db": "^1.3.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-AUdjuRyCNGUYtqpqfTmWyM4fXay8yIQhmLnvYe/THMGfT9B/34X7xQd3ifKxwyNPPpowVBjLb+64BN9Rn1mizw=="], + + "bun-ffi-structs": ["bun-ffi-structs@0.3.1", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-3gM7PpVWLyrwxWjcilSiGuhWanhZivvo6l0u573NziPH6f/gwk6McbaYgn7oJWov6pKGRTDbrg94W5DcJsKTtQ=="], + + "bun-types": ["bun-types@1.4.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-bxV1FgK7yBIzjRe5zBozIM4Bem11ZJcCXSrjWRG3YWLt8yFDePu4cLjpebO8OvPeIE9trbyPF4fuj3Cia4Fj3w=="], + + "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], + + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + + "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + + "caniuse-lite": ["caniuse-lite@1.0.30001812", "", {}, "sha512-qN+QNNBr93TCmFrmte0bBCjSDMuRvt78VlHT99qIGPszm4QsqCX8lnyWUFkHi8B7ZBAPq8SH+UqyXNy/odMdng=="], + + "content-disposition": ["content-disposition@1.1.0", "", {}, "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g=="], + + "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], + + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + + "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + + "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], + + "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], + + "diff": ["diff@9.0.0", "", {}, "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw=="], + + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + + "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], + + "electron-to-chromium": ["electron-to-chromium@1.5.439", "", {}, "sha512-qu6QIPXhsb+CRcAiTMNjR4A1y/7tCYKkKjr5CZXRVih6qkDf79peZ2BpEU3qoDBNCRrcy3Mra3X9nG5oruuA7Q=="], + + "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + + "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + + "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], + + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], + + "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="], + + "eventsource-parser": ["eventsource-parser@3.1.1", "", {}, "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ=="], + + "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], + + "express-rate-limit": ["express-rate-limit@8.7.0", "", { "dependencies": { "debug": "^4.4.3", "ip-address": "^10.2.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fast-uri": ["fast-uri@3.1.8", "", {}, "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg=="], + + "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], + + "find-babel-config": ["find-babel-config@2.1.2", "", { "dependencies": { "json5": "^2.2.3" } }, "sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg=="], + + "find-up": ["find-up@3.0.0", "", { "dependencies": { "locate-path": "^3.0.0" } }, "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg=="], + + "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], + + "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], + + "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "fuzzysort": ["fuzzysort@3.1.0", "", {}, "sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ=="], + + "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], + + "get-east-asian-width": ["get-east-asian-width@1.7.0", "", {}, "sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q=="], + + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + + "glob": ["glob@9.3.5", "", { "dependencies": { "fs.realpath": "^1.0.0", "minimatch": "^8.0.2", "minipass": "^4.2.4", "path-scurry": "^1.6.1" } }, "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q=="], + + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], + + "hono": ["hono@4.13.9", "", {}, "sha512-7dMkQmZoC4E6F7AtaQSPhlWAdnBti+j7rreMZl8QB4jFiEhP9TWbGWUMi8WYzBCgmgulxuvLQupKqo+Co6Omyg=="], + + "html-entities": ["html-entities@2.3.3", "", {}, "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA=="], + + "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + + "iconv-lite": ["iconv-lite@0.7.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "ip-address": ["ip-address@10.7.2", "", {}, "sha512-7H/2gFSIitxc0hG3nOI1glS8QLo/EHBFFLk8vEUjXY/xu0AdL8jZ9U1IzO2PUm0d2D/ofQcAifb0g6OBkt8U7w=="], + + "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], + + "is-core-module": ["is-core-module@2.17.0", "", { "dependencies": { "hasown": "^2.0.4" } }, "sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA=="], + + "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], + + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "jose": ["jose@6.2.12", "", {}, "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw=="], + + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], + + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "json-schema-typed": ["json-schema-typed@8.0.2", "", {}, "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA=="], + + "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + + "locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="], + + "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], + + "marked": ["marked@17.0.1", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg=="], + + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + + "media-typer": ["media-typer@1.1.1", "", {}, "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ=="], + + "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], + + "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "minimatch": ["minimatch@8.0.7", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg=="], + + "minipass": ["minipass@4.2.8", "", {}, "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "negotiator": ["negotiator@1.1.0", "", { "dependencies": { "content-type": "^2.1.0" } }, "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg=="], + + "node-releases": ["node-releases@2.0.57", "", {}, "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], + + "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], + + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + + "p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + + "p-locate": ["p-locate@3.0.0", "", { "dependencies": { "p-limit": "^2.0.0" } }, "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="], + + "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], + + "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], + + "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], + + "path-exists": ["path-exists@3.0.0", "", {}, "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], + + "path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + + "path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="], + + "pkg-up": ["pkg-up@3.1.0", "", { "dependencies": { "find-up": "^3.0.0" } }, "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA=="], + + "proxy-addr": ["proxy-addr@2.0.8", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ=="], + + "qs": ["qs@6.16.0", "", { "dependencies": { "es-define-property": "^1.0.1", "side-channel": "^1.1.1" } }, "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA=="], + + "range-parser": ["range-parser@1.3.0", "", {}, "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw=="], + + "raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], + + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + + "reselect": ["reselect@4.1.8", "", {}, "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="], + + "resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="], + + "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], + + "s-js": ["s-js@0.4.9", "", {}, "sha512-RtpOm+cM6O0sHg6IA70wH+UC3FZcND+rccBZpBAHzlUgNO2Bm5BN+FnM8+OBxzXdwpKWFwX11JGF0MFRkhSoIQ=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], + + "seroval": ["seroval@1.5.6", "", {}, "sha512-rVQVWjjSvlINzaQPZH5JFqsqEsIWdTxY3iJZCnTL/5gQbXIRooVZKI60tVCkOVfzcRPejboxO2t0P89dg5mQaA=="], + + "seroval-plugins": ["seroval-plugins@1.5.6", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-HXuLAX2pu/UByPpaeo/TaMfvMIi+1QqIoPJYCcAtU8QkVNwgR6MPlGuCQTErV1JwraaMbYaWVIBX7mppzGLATQ=="], + + "serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], + + "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "side-channel": ["side-channel@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4", "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ=="], + + "side-channel-list": ["side-channel-list@1.0.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" } }, "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w=="], + + "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], + + "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + + "solid-js": ["solid-js@1.9.15", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.5.4", "seroval-plugins": "~1.5.4" } }, "sha512-EeiY2xfpZJqPLjXspVEKjAII4yv8NyG//NxZ3IpOFHdUNnnTyL0uJOeS9LWGvA7cFCz5y94cjFwYlmw5Luncsg=="], + + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + + "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], + + "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], + + "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], + + "turndown": ["turndown@7.2.4", "", { "dependencies": { "@mixmark-io/domino": "^2.2.0" } }, "sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ=="], + + "type-is": ["type-is@2.1.0", "", { "dependencies": { "content-type": "^2.0.0", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA=="], + + "typescript": ["typescript@7.0.2", "", { "optionalDependencies": { "@typescript/typescript-aix-ppc64": "7.0.2", "@typescript/typescript-darwin-arm64": "7.0.2", "@typescript/typescript-darwin-x64": "7.0.2", "@typescript/typescript-freebsd-arm64": "7.0.2", "@typescript/typescript-freebsd-x64": "7.0.2", "@typescript/typescript-linux-arm": "7.0.2", "@typescript/typescript-linux-arm64": "7.0.2", "@typescript/typescript-linux-loong64": "7.0.2", "@typescript/typescript-linux-mips64el": "7.0.2", "@typescript/typescript-linux-ppc64": "7.0.2", "@typescript/typescript-linux-riscv64": "7.0.2", "@typescript/typescript-linux-s390x": "7.0.2", "@typescript/typescript-linux-x64": "7.0.2", "@typescript/typescript-netbsd-arm64": "7.0.2", "@typescript/typescript-netbsd-x64": "7.0.2", "@typescript/typescript-openbsd-arm64": "7.0.2", "@typescript/typescript-openbsd-x64": "7.0.2", "@typescript/typescript-sunos-x64": "7.0.2", "@typescript/typescript-win32-arm64": "7.0.2", "@typescript/typescript-win32-x64": "7.0.2" }, "bin": { "tsc": "bin/tsc" } }, "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA=="], + + "undici-types": ["undici-types@8.9.0", "", {}, "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg=="], + + "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], + + "update-browserslist-db": ["update-browserslist-db@1.3.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ=="], + + "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], + + "web-tree-sitter": ["web-tree-sitter@0.25.10", "", { "peerDependencies": { "@types/emscripten": "^1.40.0" }, "optionalPeers": ["@types/emscripten"] }, "sha512-Y09sF44/13XvgVKgO2cNDw5rGk6s26MgoZPXLESvMXeefBf7i6/73eFurre0IsTW6E14Y0ArIzhUMmjoc7xyzA=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + + "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + + "yaml": ["yaml@2.9.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw=="], + + "zod": ["zod@4.6.5", "", {}, "sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q=="], + + "zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], + + "babel-plugin-jsx-dom-expressions/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="], + + "body-parser/content-type": ["content-type@2.1.0", "", {}, "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag=="], + + "negotiator/content-type": ["content-type@2.1.0", "", {}, "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag=="], + + "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], + + "path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "path-scurry/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "type-is/content-type": ["content-type@2.1.0", "", {}, "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag=="], + } +} diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 0000000..f21995c --- /dev/null +++ b/bunfig.toml @@ -0,0 +1,12 @@ +preload = ["@opentui/solid/preload"] + +[install] +exact = true +# Supply-chain guard, as OpenCode does: only resolve versions published at least 3 days ago. +minimumReleaseAge = 259200 + +[test] +# On a small machine running several sessions at once, 5 s per test is too tight. +timeout = 20000 +preload = ["@opentui/solid/preload", "./tests/setup.ts"] +root = "./tests" diff --git a/get.sh b/get.sh new file mode 100755 index 0000000..ce1ab43 --- /dev/null +++ b/get.sh @@ -0,0 +1,227 @@ +#!/usr/bin/env bash +# LLeMbas CLI (the `lembas` command) from nothing: the newest release's binary for this machine, its SHA256SUMS checked +# against the release key's signature and the binary against SHA256SUMS, installed by the +# release's own install.sh. Running it again updates (the binary also updates itself). +# +# curl -fsSL https://github.com/LLeMbas/LLeMbas-CLI/releases/latest/download/get.sh | bash +# curl -fsSL <…>/get.sh | bash -s -- --aliases # options go on to install.sh +# curl -fsSL <…>/get.sh | bash -s -- --uninstall # remove it (--purge: settings too) +# +# Nothing unsigned is installed unless asked for: when no release can be found or fetched, it +# stops and says so — it does not quietly build whatever the main branch holds instead. +# +# Environment: +# LEMBAS_FORGE where releases come from (default https://github.com); a Gitea or Forgejo +# (https://git.example.org) is told apart by its API +# LEMBAS_SLUG owner/name of the repository (default LLeMbas/LLeMbas-CLI) +# LEMBAS_CHANNEL stable (default) or beta: also vX.Y.Z-beta.N, whichever is newest +# LEMBAS_REF a release tag (v1.2.3) to install instead of the newest; or a branch (main), +# which is built from source +# LEMBAS_PUBKEY the ssh-ed25519 key SHA256SUMS.sig must be signed with (a build of your own) +# LEMBAS_VERIFY signature (default) or checksum: no signature asked for (an unsigned source) +# LEMBAS_TOKEN for a private repository on the forge +# LEMBAS_FROM source: clone and build instead (needs git; fetches Bun if it is missing) +# LEMBAS_REPO what to clone for a source build (default: the forge's .git) +# LEMBAS_SRC where a source build keeps the source (default ~/.local/share/lembas/src) +# LEMBAS_API the releases API, when it is not where the forge's name says +# +# A release needs curl, sha256sum, gzip and ssh-keygen (openssh-client). Nothing runs as root. +# Linux only: x86-64 and arm64. +set -euo pipefail + +FORGE="${LEMBAS_FORGE:-https://github.com}" +FORGE="${FORGE%/}" +# The same owner/name on GitHub and on the Gitea it is made on. +SLUG="${LEMBAS_SLUG:-LLeMbas/LLeMbas-CLI}" +CHANNEL="${LEMBAS_CHANNEL:-stable}" +VERIFY="${LEMBAS_VERIFY:-signature}" +# The release key (its private half signs every release's SHA256SUMS). +PUBKEY="${LEMBAS_PUBKEY:-ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDSZO3Byow7R3ZpOH3MCvpPIga2pZBzhfX5wXfNP1cLa}" +TMP="" + +# Everything is inside functions called on the last line: a download cut short runs nothing at all. +say() { printf '%s\n' "$*"; } +die() { printf 'get.sh: %s\n' "$*" >&2; exit 1; } +cleanup() { [ -z "$TMP" ] || rm -rf "$TMP"; } +trap cleanup EXIT + +api_base() { + if [ -n "${LEMBAS_API:-}" ]; then echo "${LEMBAS_API%/}" + elif [ "$FORGE" = https://github.com ]; then echo https://api.github.com + else echo "$FORGE/api/v1" + fi +} + +# curl with the token, when there is one (GitHub and Gitea both take Bearer). The token goes to curl +# through a file descriptor, never on its command line, where other users could read it. +get() { + if [ -n "${LEMBAS_TOKEN:-}" ]; then curl -fsSL -H @<(printf 'Authorization: Bearer %s\n' "$LEMBAS_TOKEN") "$@" + else curl -fsSL "$@" + fi +} + +# Piped into bash, this script's stdin is the script itself; questions are asked on the terminal. +run_installer() { + local installer="$1" + shift + if [ -r /dev/tty ] && { : /dev/null; then + bash "$installer" ${1+"$@"} &2; return 1; } + case "$(uname -m)" in + x86_64) if grep -qw avx2 /proc/cpuinfo 2>/dev/null; then echo lembas-linux-x64; else echo lembas-linux-x64-baseline; fi ;; + aarch64 | arm64) echo lembas-linux-arm64 ;; + *) echo "get.sh: no LLeMbas CLI build for $(uname -m) (x86-64 and arm64 only)" >&2; return 1 ;; + esac +} + +# The tag to install: LEMBAS_REF when it is a tag, else the newest release tag of the channel by +# version (vX.Y.Z; for beta also vX.Y.Z-beta.N, a beta below its own release). Fails when the +# releases cannot be listed — a rate limit, a private repository without a token, no network. +release_tag() { + local ref="${LEMBAS_REF:-}" json tags + if [ -n "$ref" ]; then + echo "$ref" + return 0 + fi + json="$(get "$(api_base)/repos/$SLUG/releases?per_page=50&limit=50")" || return 1 + tags="$(printf '%s' "$json" | tr ',' '\n' | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')" + if [ "$CHANNEL" = beta ]; then tags="$(printf '%s\n' "$tags" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+(-beta\.[0-9]+)?$' || true)" + else tags="$(printf '%s\n' "$tags" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' || true)" + fi + # Sorted as versions, with a release above its own betas: v1.2.0 → 1.2.0.zz, v1.2.0-beta.3 → 1.2.0.beta.3. + printf '%s\n' "$tags" | sed '/^$/d' | sed -E 's/^v//; s/-beta\.([0-9]+)$/.beta.\1/; /beta/!s/$/.zz/' | sort -V | tail -n1 | + sed -E 's/\.zz$//; s/\.beta\.([0-9]+)$/-beta.\1/; s/^/v/' +} + +# SHA256SUMS signed by the release key, checked with ssh-keygen; and it names the version it is for. +check_signature() { + local dir="$1" tag="$2" + if [ "$VERIFY" = checksum ]; then + say " (LEMBAS_VERIFY=checksum: the release's signature is not checked)" + else + command -v ssh-keygen >/dev/null 2>&1 || { + echo "get.sh: ssh-keygen is not installed, so the release's signature cannot be checked — nothing installed." >&2 + echo "get.sh: install openssh-client (sudo apt install openssh-client), or set LEMBAS_VERIFY=checksum to trust the checksums alone." >&2 + return 1 + } + [ -s "$dir/SHA256SUMS.sig" ] || { echo "get.sh: the release is not signed (no SHA256SUMS.sig) — nothing installed (LEMBAS_VERIFY=checksum to accept that)" >&2; return 1; } + # Signed in the namespace lembas-release. + printf 'lembas-release %s\n' "$PUBKEY" >"$dir/allowed" + if ! ssh-keygen -Y verify -f "$dir/allowed" -I lembas-release -n lembas-release -s "$dir/SHA256SUMS.sig" <"$dir/SHA256SUMS" >/dev/null 2>&1; then + echo "get.sh: SHA256SUMS is not signed by the release key — nothing installed" >&2 + return 1 + fi + say " signature good (release key)" + fi + # The signed list says which version it is for: an old release's files under a new tag are refused. + local version + version="$(sed -n -E 's/^# lembas (.*)$/\1/p' "$dir/SHA256SUMS" | head -n1)" + if [ -n "$version" ] && [ "v$version" != "$tag" ]; then + echo "get.sh: release $tag carries the files of $version — nothing installed" >&2 + return 1 + fi +} + +# Fetch a release's SHA256SUMS (+ signature) and the named files into $TMP, and check them all. +fetch_checked() { + local tag="$1" f base + shift + base="$FORGE/$SLUG/releases/download/$tag" + for f in "$@" SHA256SUMS; do + get -o "$TMP/$f" "$base/$f" || { echo "get.sh: could not download $f from release $tag" >&2; return 1; } + done + get -o "$TMP/SHA256SUMS.sig" "$base/SHA256SUMS.sig" 2>/dev/null || rm -f "$TMP/SHA256SUMS.sig" + check_signature "$TMP" "$tag" || return 1 + # Every file must be listed exactly once, and match. + for f in "$@"; do + [ "$(grep -c " $f\$" "$TMP/SHA256SUMS")" = 1 ] || { echo "get.sh: SHA256SUMS does not list $f once — nothing installed" >&2; return 1; } + (cd "$TMP" && grep " $f\$" SHA256SUMS | sha256sum -c --quiet - >/dev/null 2>&1) || { echo "get.sh: checksums did not match — nothing installed" >&2; return 1; } + done +} + +from_release() { + local tag="$1" asset said + shift + asset="$(asset_for_machine)" || exit 1 + for tool in curl sha256sum gzip; do + command -v "$tool" >/dev/null 2>&1 || die "needs $tool (sudo apt install $tool)" + done + TMP="$(mktemp -d)" + say "LLeMbas CLI $tag ($asset)…" + fetch_checked "$tag" "$asset.gz" install.sh || exit 1 + gzip -dc "$TMP/$asset.gz" >"$TMP/lembas" + chmod 755 "$TMP/lembas" + # And the binary is the version the tag says. + said="$("$TMP/lembas" --version 2>/dev/null || true)" + [ "v$said" = "$tag" ] || die "release $tag's binary says it is ${said:-nothing} — nothing installed" + run_installer "$TMP/install.sh" --binary "$TMP/lembas" ${1+"$@"} || exit 1 +} + +# Where the binary keeps its data, as it works it out: under LEMBAS_HOME (tests), else +# XDG_DATA_HOME when it is absolute (the XDG spec ignores a relative one), else ~/.local/share. +data_parent() { + local root="${LEMBAS_HOME:-}" + if [ -n "$root" ]; then printf '%s/share' "$root" + else case "${XDG_DATA_HOME:-}" in /*) printf '%s' "$XDG_DATA_HOME" ;; *) printf '%s/.local/share' "$HOME" ;; esac + fi +} + +from_source() { + local repo="${LEMBAS_REPO:-$FORGE/$SLUG.git}" + local ref="${LEMBAS_REF:-main}" + local src="${LEMBAS_SRC:-$(data_parent)/lembas/src}" + + command -v git >/dev/null 2>&1 || die "needs git (sudo apt install git)" + + if [ -d "$src/.git" ]; then + say "Updating $src ($ref)…" + # Only ever fast-forwards: local changes in the source are the user's, and are not discarded. + git -C "$src" fetch --quiet --tags origin "$ref" + git -C "$src" checkout --quiet "$ref" 2>/dev/null || git -C "$src" checkout --quiet -B "$ref" "origin/$ref" + git -C "$src" merge --quiet --ff-only FETCH_HEAD || die "$src has changes of its own; update it by hand" + elif [ -e "$src" ] && [ -n "$(ls -A "$src" 2>/dev/null)" ]; then + die "$src exists and is not a git checkout; set LEMBAS_SRC to somewhere else" + else + say "Cloning $repo ($ref) into $src…" + mkdir -p "$(dirname "$src")" + git clone --quiet --branch "$ref" "$repo" "$src" + fi + run_installer "$src/install.sh" ${1+"$@"} +} + +# --uninstall: the installed binary does it; without one, the newest release's install.sh — checked +# like any release file, since it is what removes things. +uninstall() { + local bin="$HOME/.local/bin/lembas" args=() a tag + for a in "$@"; do [ "$a" = --uninstall ] || args+=("$a"); done + if [ -x "$bin" ] && "$bin" --version >/dev/null 2>&1; then + if [ -r /dev/tty ] && { : /dev/null; then "$bin" uninstall ${args[@]+"${args[@]}"} .json` | One tool each: name, `scope`, `risk`, `exclusive`, `block` (how a call is shown: `shell`, `edit`, `read`, `search`, `web`, `task`, `hidden`, `tool`), `purpose`, former names (`aliases`, per project), renamed arguments, the description and the JSON Schema of its parameters — exactly what a model is sent | +| `prompts/` | The prompt texts; `prompts/index.json` says which are shared and which LLeMbas fragment each one is. `prompts/personality/` holds the personality presets both offer | +| `permission/hardline.json` | The floor: commands refused in every mode, protected paths, and how a command is spelled plainly before it is checked again | +| `permission/arity.json` | How much of a command an "always allow" covers | +| `permission/defaults.json` | The rules every session starts from | +| `permission/modes.json` | The four modes — manual, edit, auto, plan — as what each does with each risk class | +| `models/schema.json` | Model metadata: context, output limit, efforts, vision, tools, notes, capacity | +| `loop.json` | How one prompt runs: the step backstop, budgets, wrap-up, nudges, parallel calls, capacity | +| `quirks.json` | What real servers do, and how both harnesses cope | +| `conformance/.json` | Cases with their expected results, run by both test suites | +| `acp.md` | The link between them: ACP plus every `_lembas/*` method, field and capability | + +## Vocabulary + +- **Risk classes:** `read`, `write`, `execute`, `interact`. **Reading and writing are never one + tool** among the shared ones, so a read-only helper is given exactly the readers. +- **Modes:** `manual`, `edit`, `auto`, `plan` (`unrestricted` is read as `auto`). +- **Scopes:** `shared` — both projects implement it; `cli` or `llembas` — only that one. The same + two names key what is per project elsewhere: a tool's `aliases`, `loop.json`'s budgets, a + protected path's `scope`. +- A tool's other names, per project, are listed in its `aliases` and work as the tool. + +## 1.0.0 + +The spec as described here: the shared tools with their scopes, risk classes, call blocks and +aliases; the prompt texts and the six personality presets; the permission floor, arity table, +default rules and the four modes; model metadata; the loop; the quirks of real servers; the +conformance cases; and `acp.md`, the link between the two projects (`_lembas` protocol 2, every +feature beyond protocol 1 gated on its capability string). + +## Variables in a description + +A description may hold `{{name}}` where the two projects differ in a fact, not in design — a +timeout's default, whether commands may run in the background, which subagents exist. The tool's +`variables` says what each one means; each project fills them before sending the description, and +none may reach a model unfilled. + +## Changing it + +1. Change the spec first, and bump `VERSION`: **patch** for a text or a new conformance case, + **minor** for a new tool, rule or field, **major** for a rename or a removed tool. +2. A fix comes with a **conformance case** that fails without it. In LLeMbas CLI, + `bun run harness record` fills in the expected result of a new case from the implementation, + and `bun run harness record --all` shows every case whose result would change. +3. Implement it in both projects — in the same session, or with an open item recorded against the + other. A bug found in one is searched for in the other. +4. Nothing here names a host, a path on a server or anybody's setup: both projects are public. + +Licence: MIT, as LLeMbas CLI. Files that came from elsewhere say so in their `source` field +(Hermes Agent's hardline patterns, OpenCode's arity table) or in an HTML comment (prompt texts). diff --git a/harness/VERSION b/harness/VERSION new file mode 100644 index 0000000..3eefcb9 --- /dev/null +++ b/harness/VERSION @@ -0,0 +1 @@ +1.0.0 diff --git a/harness/acp.md b/harness/acp.md new file mode 100644 index 0000000..4d20225 --- /dev/null +++ b/harness/acp.md @@ -0,0 +1,467 @@ +# The `_lembas` extension of ACP + +How LLeMbas (the web UI) and LLeMbas CLI (on a device) talk over the link: the Agent Client +Protocol, plus the `_lembas/*` methods and `_meta.lembas` fields below. LLeMbas CLI is the +**agent**; LLeMbas is the **client**. The device dials out (`wss:///api/devices/link`, +the device token in the `Authorization` header) and one WebSocket message is one JSON-RPC 2.0 +message; `lembas serve --stdio` speaks the same protocol on stdin/stdout, one message a line, to an +editor (which gets plain ACP: none of the `_lembas` notifications, no question or plan cards). + +This file is part of the harness spec: LLeMbas vendors it with the rest, and a +change to the protocol is a change here first, then in both projects. + +## Versions and discovery + +- **`protocol`** (`_meta.lembas.protocol` in `initialize`, `protocol` in `_lembas/hello`): + **2**. CLI `src/acp/agent.ts:LEMBAS_PROTOCOL`, LLeMbas + `api/devices.py:PROTOCOL`. +- **Discovery** (`/.well-known/lembas.json`) says `protocol: 1` **and** `protocols: [1, 2]` — + `protocol` stays 1 on purpose, because a client that compares it for equality at login must + still get in. The CLI reads `protocols` (falling back to `protocol` where it is absent) at + login and again **every time the link dials**, keeps it with the login, and says protocol 2 in + `hello` and `initialize` only to an instance that lists 2; to any other it says 1 (an instance that + speaks only 1 closes a link whose hello says 2 with **4400**). A link closed with 4400 stops — it is not + redialled — saying *the instance and this CLI speak different link protocols — update one of them*. +- **A protocol 1 peer keeps working.** Every feature beyond protocol 1 is named by a **capability + string** in `initialize`'s `_meta.lembas.capabilities`, and **LLeMbas never calls a method, nor + relies on a field, the device did not list**. The CLI logs in to an instance whose discovery says + protocol 1 or 2. +- A client says it is LLeMbas with `clientCapabilities._meta.lembas` in `initialize`, and which + protocol it speaks with `_meta.lembas.protocol` (absent: 1 — a protocol 1 client sends `lembas: true`). + Only such a client gets `_lembas/event`; only one that says protocol **2 or later** gets + `_lembas/question` and `_lembas/plan`, and one that then answers them with method-not-found is + treated as protocol 1 for the rest of the link. + +| Capability | What it promises | +|---|---| +| `directories` | `_lembas/directories` | +| `configure` | `_lembas/configure` | +| `steer` | `_lembas/steer`; `unsent` in a prompt's answer | +| `terminal` | `_lembas/terminal/*` (only with `remote.terminal: true`) | +| `sessions` | a session id lasts (opened from the store again); terminal sessions announced (`announce`, `left`, `history`) | +| `status` | `_lembas/session/status` | +| `delete` | `_lembas/session/delete`; `_lembas/session/deleted` | +| `compact` | `_lembas/session/compact` | +| `title` | `_lembas/session/title` | +| `files` | `_lembas/files/search`; `@path` in a prompt expanded | +| `commands` | `available_commands_update`, `_lembas/commands`; `/name` in a prompt expanded | +| `attachments` | `image` and `resource` blocks in `session/prompt`; `attachments` on prompt events and history | +| `ask` | `_lembas/question` | +| `plan` | `_lembas/plan` | +| `model` | the `model` event; `_meta.lembas.connection` in `initialize` | +| `turns` | `_meta.lembas.turnId` on `session/prompt`, deduplicated; `turnId` on `prompt`/`task` events; turn fields in `status` | +| `shell` | `shell` and `integration` in `_lembas/terminal/open`'s answer (listed only with `terminal`) | + +## Standard ACP, as used here + +### `initialize` — client → agent + +Params: `{ protocolVersion: 1, clientCapabilities: { _meta?: { lembas?: { protocol: 2 } | true } } }`. + +Result: + +```json +{ + "protocolVersion": 1, + "agentCapabilities": { + "loadSession": false, + "promptCapabilities": { "image": true, "audio": false, "embeddedContext": true }, + "mcpCapabilities": { "http": false, "sse": false } + }, + "authMethods": [], + "agentInfo": { "name": "LLeMbas CLI", "version": "1.0.0" }, + "_meta": { "lembas": { + "protocol": 2, + "harness_spec": "1.0.0", + "limits": { "roots": ["~/work"], "max_mode": "edit" }, + "connection": "example", + "capabilities": ["directories", "configure", "…"] + } } +} +``` + +`limits` is `null` on `serve --stdio`. `connection` is the device's name for the instance — the +login's connection — or `null`; an instance that does not speak protocol 2 recognises its own +models by it, as `/`, while the `model` event and `announce` say it directly +(`instance`). + +**How the device names an instance's models.** An instance that speaks protocol 2 serves every model +as `/` (`deepseek/deepseek-flash`), and that served id **is the device's ref** for +it — each provider is, as the person sees it, a connection of its own, backed by the instance +(requests still go to its `/v1`, with the served id). Exceptions: a connection of the device's own +with the provider's name keeps the short form, and the instance's model is then +`//`; with two instances serving one provider, the one logged in to first +keeps the short form and the other's are `//`; an instance that does not +speak protocol 2 serves bare ids, which stay `/`. The provider is the model's `provider` field where the +instance gives one, else — only from an instance whose discovery lists protocol 2 — the part of the +id before its first `/`; an id with a `/` from any other instance is just an id (`/`). The old forms (`/`, +`//`) still name the same model. `lembas_model` in `session/new` and +`model` in `_lembas/configure` are the instance's served name, as it serves it. + +### `session/new` — client → agent + +Params: `{ cwd: , mcpServers?: [], _meta?: { mode?, lembas_model?, model?, effort? } }`. +`cwd` must be a directory inside `remote.roots`, in a trusted project when `remote.require_trust` +(the default) — otherwise `-32602` with the reason. `mode` is lowered to `remote.max_mode`. +`lembas_model` is the instance's name of a model (it becomes `/` here); `model` +a ref of the device's own; `effort` a level or `"off"`. + +Result: `{ sessionId: "ses_…", modes: { currentModeId, availableModes }, _meta: { lembas: { model, mode, effort } } }`. +The id is the device's store id and lasts: a session the client names later that is not in memory +is opened from the store under the same rules (capability `sessions`). With capability `commands`, +an `available_commands_update` follows the answer. + +### `session/prompt` — client → agent + +Params: `{ sessionId, prompt: ContentBlock[], _meta?: { lembas?: { turnId?: string } } }`. + +Blocks (capability `attachments` for the last two kinds): + +| Block | Becomes | +|---|---| +| `{ type: "text", text }` | the prompt's text (blocks joined by a blank line) | +| `{ type: "resource_link", uri }` | `(see )` in the text | +| `{ type: "image", data: , mimeType, uri? }` | written under the session's attachment directory and attached by path, as the TUI does with a pasted image: an image part for a vision model, a line saying it is there for any other. `mimeType`: `image/png`, `image/jpeg`, `image/webp`, `image/gif` | +| `{ type: "resource", resource: { uri, mimeType?, text } }` | written there and attached like an `@file` (line-numbered, counted as read) | +| `{ type: "resource", resource: { uri, mimeType?, blob: } }` | written there and referenced by path (`(binary file, N bytes)`), or attached as an image when it is one | + +Limits: 10 MB a block and 25 MB a prompt, decoded; over either, `-32602` with a sentence. The +attachment directory is `~/.local/state/lembas/attachments//`, removed with the session; +each upload gets a name of its own there (`