diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dafe4e5..7f7dc2d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,8 +13,6 @@ concurrency: jobs: build: if: github.event.pull_request.draft == false - uses: start9labs/shared-workflows/.github/workflows/build.yml@master - # with: - # FREE_DISK_SPACE: true + uses: Start9Labs/start-technologies/.github/workflows/build.yml@master secrets: DEV_KEY: ${{ secrets.DEV_KEY }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3b83acf..6dcef4a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,9 +7,8 @@ on: jobs: release: - uses: start9labs/shared-workflows/.github/workflows/release.yml@master + uses: Start9Labs/start-technologies/.github/workflows/release.yml@master with: - # FREE_DISK_SPACE: true RELEASE_REGISTRY: ${{ vars.RELEASE_REGISTRY }} S3_S9PKS_BASE_URL: ${{ vars.S3_S9PKS_BASE_URL }} secrets: diff --git a/.github/workflows/tagAndRelease.yml b/.github/workflows/tagAndRelease.yml index 5690d6b..f000851 100644 --- a/.github/workflows/tagAndRelease.yml +++ b/.github/workflows/tagAndRelease.yml @@ -11,10 +11,9 @@ concurrency: jobs: tag: - uses: start9labs/shared-workflows/.github/workflows/tagAndRelease.yml@master + uses: Start9Labs/start-technologies/.github/workflows/tagAndRelease.yml@master with: REFERENCE_REGISTRY: ${{ vars.REFERENCE_REGISTRY }} - # FREE_DISK_SPACE: true RELEASE_REGISTRY: ${{ vars.RELEASE_REGISTRY }} S3_S9PKS_BASE_URL: ${{ vars.S3_S9PKS_BASE_URL }} secrets: diff --git a/AGENTS.md b/AGENTS.md index 6df0a76..c7de79d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,3 +7,14 @@ which provides the packaging guide and agent context one level up. If you're rea bare clone with no workspace, the full guide is at . Work this package's `TODO.md` from top to bottom. Keep `README.md` (architecture, for developers and LLMs) and `instructions.md` (end-user docs) in sync with your changes. + +## This repo + +- **Package id is `simplex-websocket-bridge`.** It runs a headless SimpleX Chat client and exposes the SimpleX network over a token-authenticated WebSocket API (interface id `ws` on host `main`, port 5225). Bearer auth is enforced at the StartOS reverse proxy via `addSsl.auth`; same-box dependents and this package's own actions bypass the proxy by dialing the container bridge IP directly. +- **The `websocket` standalone health check and the `ws` interface are a dependent-facing contract** (see README's file-exchange section). Dependents reference the `websocket` id in a `kind: 'running'` requirement — treat both ids as a small API and update consumers if you rename them. +- **File exchange is a SINGLE `/simplex` mount, not one per subdir.** `utils.ts` re-mounts the `main` volume's `.simplex/media` subpath at `/simplex` (exposing `/simplex/inbound`, `/simplex/tmp`, `/simplex/outbound`) as one mount, because simplex-chat moves completed downloads temp→files with an atomic rename that `EXDEV`-fails across separate bind mounts. Don't split it. +- **Actions drive the running bot over its WebSocket control protocol**, not a shell — `bot-client.ts` opens `ws://:5225` and speaks newline-delimited JSON-RPC (`create-invitation`, `configure`). + +## Inspecting a running install + +To run a command inside the service's container (read its generated config, grep app logs), use `start-cli package attach simplex-websocket-bridge -n simplex-sub -- `. Select the subcontainer by **name** with `-n` (the name passed to `SubContainer.of` in `main.ts` — here `simplex-sub`) or by image with `-i`. Note: `-s/--subcontainer` matches the internal **Guid**, not the name, so passing a name to `-s` fails with "no matching subcontainers". diff --git a/Makefile b/Makefile index 8a1479e..77f24f4 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,3 @@ ARCHES := x86_64 aarch64 # overrides to s9pk.mk must precede the include statement -include s9pk.mk +include node_modules/@start9labs/start-sdk/s9pk.mk diff --git a/README.md b/README.md index 9d1065e..4f23dc3 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ The bundled client is driven over its Websocket using the upstream [SimpleX bot/ | Property | Value | | ------------- | -------------------------------------------------------------- | -| Image | `lundog/simplex-chat` (built from `lundog/simplex-chat-docker`) | +| Image | `lundog/simplex-websocket-bridge` (built from `lundog/simplex-websocket-bridge-docker`) | | Architectures | x86_64, aarch64 | | Command | Image entrypoint — supervises `simplex-chat` and `websocat` | @@ -66,6 +66,8 @@ The Websocket carries only a small inline preview for image/video messages — a **Paths:** a consumer that mounts these subpaths at the *same mountpoints* can use the paths verbatim. This is strictly required only for **outbound** — that path travels over the Websocket and is resolved inside the bridge's container, so it must be valid there. **Inbound** is looser: the Websocket API reports only a filename, which the consumer resolves against its own inbound directory, so the two sides need only share the same host directory. The neutral `/simplex` prefix (rather than `/data/...`) lets consumers mount at identical paths without colliding with their own `/data` volume. +**These paths are set explicitly, not inherited.** `main.ts` passes `SIMPLEX_INBOUND_DIR=/simplex/inbound` and `SIMPLEX_TMP_DIR=/simplex/tmp` into the container. Do not drop them and fall back to the image's defaults: those defaults have moved before (through image 6.5.4 they were `/simplex`; 6.5.5 changed them to `$HOME/.simplex/{files,tmp}`, which is *outside* this mount). A bridge writing outside `/simplex` breaks this contract silently — consumers see an empty `inbound` and no error is raised anywhere. + **Security:** consumers mount only the `media/*` subpaths — never the whole `main` volume or `.simplex/` itself, which hold the SimpleX profile database and keys. `inbound` is read-only so consumers can't alter received files; write access is limited to `outbound`. --- @@ -160,7 +162,7 @@ The bundled `simplex-chat` client behaves exactly as upstream: messages and file ```yaml package_id: simplex-websocket-bridge -image: lundog/simplex-chat +image: lundog/simplex-websocket-bridge architectures: [x86_64, aarch64] volumes: main: /data diff --git a/UPDATING.md b/UPDATING.md index 49fb5cd..4a5418e 100644 --- a/UPDATING.md +++ b/UPDATING.md @@ -2,32 +2,74 @@ SimpleX Websocket Bridge runs the [SimpleX Chat](https://github.com/simplex-chat/simplex-chat) client headless. The runtime is the standalone container image built from -[lundog/simplex-chat-docker](https://github.com/lundog/simplex-chat-docker) and -published to Docker Hub as `lundog/simplex-chat`. "Upstream" here means the -SimpleX Chat release that image bundles; this repo consumes the image via -`dockerTag` and does not build it. +[lundog/simplex-websocket-bridge-docker](https://github.com/lundog/simplex-websocket-bridge-docker) +and published to Docker Hub as `lundog/simplex-websocket-bridge`. "Upstream" here means the +SimpleX Chat release that image bundles; this repo consumes the image via `dockerTag` and does +not build it. + +> [!NOTE] +> Both the image and its source repo were renamed in July 2026 (at image revision `6.5.5-2`), from +> `lundog/simplex-chat` / `lundog/simplex-chat-docker`. The GitHub repo redirects, but the old +> Docker Hub repo does **not** — it is frozen at `6.5.5-1` and gets no new builds. Don't pin it. + +## The tag has two parts + +The tag is `[-]`, e.g. `6.5.5-2`, and the two halves move +independently: + +- **SimpleX version** (`6.5.5`) — the SimpleX Chat release the image bundles. +- **Image revision** (`-2`) — a rebuild of the *same* SimpleX version (an entrypoint or packaging + change in the image repo). An unsuffixed tag is revision 0. + +An unsuffixed tag points at the **newest** revision of that SimpleX version, so `6.5.5` and +`6.5.5-2` are currently the same image. Pin the explicit revision so the pin can't shift underneath +you. ## Determining the upstream version -- **simplex-chat** ([simplex-chat/simplex-chat](https://github.com/simplex-chat/simplex-chat)) — fetch the latest release tag: +**Do not bump from the SimpleX Chat release list alone.** A SimpleX release is only usable once the +bridge image has been rebuilt for it, and that rebuild is a separate, manual step by the image +maintainer — it lags, and sometimes never happens for a given release. Read the image's tag list, +which is the only thing that actually has to exist: - ```sh - gh release view -R simplex-chat/simplex-chat --json tagName -q .tagName - ``` +```sh +curl -fsSL "https://hub.docker.com/v2/repositories/lundog/simplex-websocket-bridge/tags?page_size=50&ordering=last_updated" \ + | jq -r '.results[].name' +``` - The current pin lives in `startos/manifest/index.ts` at - `images.simplex.source.dockerTag` (the version after the `:` in - `lundog/simplex-chat:`). +For context, the newest SimpleX Chat release is: + +```sh +gh release view -R simplex-chat/simplex-chat --json tagName -q .tagName +``` + +If it has no matching image tag, there is nothing to bump here yet — the image must be built first. + +The pin lives in `startos/manifest/index.ts` at `images.simplex.source.dockerTag`. ## Applying the bump -1. In [lundog/simplex-chat-docker](https://github.com/lundog/simplex-chat-docker), - bump the pinned simplex-chat version, then build and publish a matching - multi-arch (amd64 + arm64) tag to `lundog/simplex-chat`. The Dockerfile, - entrypoint supervisor, and the `--files-folder`/`--temp-folder` flags all - live there, not in this repo. -2. Bump `dockerTag` in `startos/manifest/index.ts` to - `lundog/simplex-chat:` (drop the leading `v` from the release tag). -3. Bump the package `version` and update `releaseNotes` in - `startos/versions/current.ts`. Add a migration only if the new version needs - one (see the [packaging guide on versions](https://docs.start9.com/packaging)). +1. If the image hasn't been rebuilt for the SimpleX release you want, that comes first: in + [lundog/simplex-websocket-bridge-docker](https://github.com/lundog/simplex-websocket-bridge-docker), + bump the pinned SimpleX version and publish a multi-arch (amd64 + arm64) tag. The Dockerfile, + the entrypoint supervisor, and the `--files-folder` / `--temp-folder` wiring all live there, not + in this repo. +2. Bump `dockerTag` to `lundog/simplex-websocket-bridge:` (drop the leading `v` from the + SimpleX release tag; keep the explicit `-N` revision). +3. **Re-check the image's file-exchange defaults.** The bridge's inbound and temp directories come + from `SIMPLEX_INBOUND_DIR` / `SIMPLEX_TMP_DIR`, which this package sets **explicitly** in + `startos/main.ts` (to `/simplex/inbound` and `/simplex/tmp`, inside the shared `/simplex` mount + — see `startos/utils.ts` and the README's file-exchange contract). + + We set them precisely because the image's defaults have moved before and will not announce it: + through 6.5.4 the image defaulted to `/simplex`, and 6.5.5 silently changed it to + `$HOME/.simplex/{files,tmp}` — *outside* our mount. A bump that relied on the defaults would send + every received file somewhere no dependent service can see, breaking the file-exchange contract + with no error. + + So on each bump, confirm the image still honors both variables, and that inbound and temp stay + co-located: simplex-chat completes a download with an atomic `rename(2)` from temp into inbound, + which fails with `EXDEV` if they are separate mounts. +4. Bump the package `version` and update `releaseNotes` in `startos/versions/current.ts`. Add a + migration only if the new version needs one (see the + [packaging guide on versions](https://docs.start9.com/packaging)). diff --git a/package-lock.json b/package-lock.json index c1d3b2e..d4b75de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,13 @@ { - "name": "simplex-gateway-startos", + "name": "simplex-websocket-bridge-startos", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "simplex-gateway-startos", + "name": "simplex-websocket-bridge-startos", "dependencies": { "@simplex-chat/types": "^0.7.0", - "@start9labs/start-sdk": "1.5.3", + "@start9labs/start-sdk": "2.0.6", "ws": "^8.18.0" }, "devDependencies": { @@ -15,81 +15,1515 @@ "@types/ws": "^8.5.13", "@vercel/ncc": "^0.38.4", "prettier": "^3.6.2", - "typescript": "^5.9.3" + "typescript": "^6.0.3" } }, - "node_modules/@iarna/toml": { + "node_modules/@nodable/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, + "node_modules/@simplex-chat/types": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@simplex-chat/types/-/types-0.7.0.tgz", + "integrity": "sha512-3VpI7C9CbFCis1S0FyqNe2Bb7aC0iqY3JNJN/xjKaV8layvBGYRwzzHh/OCcN1PSuGT46b3hAgwOCyE+6fY6Ww==", + "license": "AGPL-3.0", + "dependencies": { + "typescript": "^5.9.2" + } + }, + "node_modules/@simplex-chat/types/node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@start9labs/start-sdk": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@start9labs/start-sdk/-/start-sdk-2.0.6.tgz", + "integrity": "sha512-0aTCnCvDZWp3UGqmyB8xQL1A0mWYlIwbTdHyQQkha/aOAzFpTIC6MIwkDCLnXLpoFqhF6btbBPp9hIMKwsRBOw==", + "bundleDependencies": [ + "@start9labs/start-core", + "eslint", + "typescript-eslint" + ], + "license": "MIT", + "dependencies": { + "@iarna/toml": "^3.0.0", + "@noble/curves": "^1.9.7", + "@noble/hashes": "^1.8.0", + "@start9labs/start-core": "file:./node_modules/@start9labs/start-core", + "@types/ini": "^4.1.1", + "deep-equality-data-structures": "^2.0.0", + "eslint": "^9.39.4", + "fast-xml-parser": "~5.7.0", + "ini": "^5.0.0", + "isomorphic-fetch": "^3.0.0", + "mime": "^4.1.0", + "typescript-eslint": "^8.61.0", + "yaml": "^2.8.3", + "zod": "4.4.3", + "zod-deep-partial": "^1.2.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/config-array": { + "version": "0.21.2", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.15", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/core": { + "version": "0.17.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "inBundle": true, + "license": "Python-2.0" + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.15", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "inBundle": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/js": { + "version": "9.39.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/object-schema": { + "version": "2.1.7", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@humanfs/core": { + "version": "0.19.2", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@humanfs/node": { + "version": "0.16.8", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@humanfs/types": { + "version": "0.15.0", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@iarna/toml": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/@start9labs/start-sdk/node_modules/@noble/curves": { + "version": "1.9.7", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@noble/hashes": { + "version": "1.8.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@start9labs/start-core": { + "inBundle": true, + "license": "MIT", + "dependencies": { + "@iarna/toml": "^3.0.0", + "@noble/curves": "^1.9.7", + "@noble/hashes": "^1.8.0", + "deep-equality-data-structures": "^2.0.0", + "isomorphic-fetch": "^3.0.0", + "mime": "^4.1.0", + "yaml": "^2.8.3", + "zod": "4.4.3", + "zod-deep-partial": "^1.4.4" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@start9labs/start-core/node_modules/deep-equality-data-structures": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "object-hash": "^3.0.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@start9labs/start-core/node_modules/zod": { + "version": "4.4.3", + "inBundle": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@types/estree": { + "version": "1.0.9", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/@types/json-schema": { + "version": "7.0.15", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.61.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/type-utils": "8.61.0", + "@typescript-eslint/utils": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.61.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/parser": { + "version": "8.61.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/project-service": { + "version": "8.61.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.61.0", + "@typescript-eslint/types": "^8.61.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/scope-manager": { + "version": "8.61.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.61.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/type-utils": { + "version": "8.61.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/utils": "8.61.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/types": { + "version": "8.61.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.61.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.61.0", + "@typescript-eslint/tsconfig-utils": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.5", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.8.3", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/utils": { + "version": "8.61.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.61.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/acorn": { + "version": "8.16.0", + "inBundle": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/acorn-jsx": { + "version": "5.3.2", + "inBundle": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/ajv": { + "version": "6.15.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/ansi-styles": { + "version": "4.3.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/balanced-match": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/callsites": { + "version": "3.1.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/chalk": { + "version": "4.1.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/color-convert": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/color-name": { + "version": "1.1.4", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/concat-map": { + "version": "0.0.1", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/cross-spawn": { + "version": "7.0.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/debug": { + "version": "4.4.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@start9labs/start-sdk/node_modules/deep-is": { + "version": "0.1.4", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/eslint": { + "version": "9.39.4", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/@start9labs/start-sdk/node_modules/eslint-scope": { + "version": "8.4.0", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.15", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/espree": { + "version": "10.4.0", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/esquery": { + "version": "1.7.0", + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/esrecurse": { + "version": "4.3.0", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/estraverse": { + "version": "5.3.0", + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/esutils": { + "version": "2.0.3", + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/fast-deep-equal": { + "version": "3.1.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/fast-levenshtein": { + "version": "2.0.6", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/fdir": { + "version": "6.5.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/@start9labs/start-sdk/node_modules/file-entry-cache": { + "version": "8.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/flat-cache": { + "version": "4.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/flatted": { + "version": "3.4.2", + "inBundle": true, + "license": "ISC" + }, + "node_modules/@start9labs/start-sdk/node_modules/globals": { + "version": "14.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/has-flag": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/ignore": { + "version": "5.3.2", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/import-fresh": { + "version": "3.3.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/imurmurhash": { + "version": "0.1.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/is-extglob": { + "version": "2.1.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/is-glob": { + "version": "4.0.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/isexe": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/@start9labs/start-sdk/node_modules/isomorphic-fetch": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/json-buffer": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/json-schema-traverse": { + "version": "0.4.1", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/keyv": { + "version": "4.5.4", + "inBundle": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/levn": { + "version": "0.4.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/lodash.merge": { + "version": "4.6.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/mime": { + "version": "4.1.0", + "funding": [ + "https://github.com/sponsors/broofa" + ], + "inBundle": true, + "license": "MIT", + "bin": { + "mime": "bin/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/ms": { + "version": "2.1.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/natural-compare": { + "version": "1.4.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/node-fetch": { + "version": "2.7.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@start9labs/start-sdk/node_modules/object-hash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-td6ZUkz2oS3VeleBcN+m//Q6HlCFCPrnI0FZhrt/h4XqLEdOyYp2u21nd8MdsR+WJy5r9PTDaHTDDfhf4H4l6Q==", - "license": "ISC" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } }, - "node_modules/@noble/curves": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", - "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "node_modules/@start9labs/start-sdk/node_modules/optionator": { + "version": "0.9.4", + "inBundle": true, "license": "MIT", "dependencies": { - "@noble/hashes": "1.8.0" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">= 0.8.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/p-limit": { + "version": "3.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/@start9labs/start-sdk/node_modules/parent-module": { + "version": "1.0.1", + "inBundle": true, "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=6" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/path-exists": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/path-key": { + "version": "3.1.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/picomatch": { + "version": "4.0.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@nodable/entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/nodable" - } - ], + "node_modules/@start9labs/start-sdk/node_modules/prelude-ls": { + "version": "1.2.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/punycode": { + "version": "2.3.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/shebang-command": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/shebang-regex": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/strip-json-comments": { + "version": "3.1.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/supports-color": { + "version": "7.2.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/tinyglobby": { + "version": "0.2.17", + "inBundle": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/tr46": { + "version": "0.0.3", + "inBundle": true, "license": "MIT" }, - "node_modules/@simplex-chat/types": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@simplex-chat/types/-/types-0.7.0.tgz", - "integrity": "sha512-3VpI7C9CbFCis1S0FyqNe2Bb7aC0iqY3JNJN/xjKaV8layvBGYRwzzHh/OCcN1PSuGT46b3hAgwOCyE+6fY6Ww==", - "license": "AGPL-3.0", + "node_modules/@start9labs/start-sdk/node_modules/ts-api-utils": { + "version": "2.5.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/type-check": { + "version": "0.4.0", + "inBundle": true, + "license": "MIT", "dependencies": { - "typescript": "^5.9.2" + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/@start9labs/start-sdk": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@start9labs/start-sdk/-/start-sdk-1.5.3.tgz", - "integrity": "sha512-OyHe9J6hMvyA5ZavcLkxdVQvZcuTH9J9kagV6NDI83eAG/YpJFIq62gP/n/2PPNdHWwNSXVQmSwnsvsV8Gyg+A==", + "node_modules/@start9labs/start-sdk/node_modules/typescript-eslint": { + "version": "8.61.0", + "inBundle": true, "license": "MIT", "dependencies": { - "@iarna/toml": "^3.0.0", - "@noble/curves": "^1.9.7", - "@noble/hashes": "^1.8.0", - "@types/ini": "^4.1.1", - "deep-equality-data-structures": "^2.0.0", - "fast-xml-parser": "~5.7.0", - "ini": "^5.0.0", - "isomorphic-fetch": "^3.0.0", - "mime": "^4.1.0", - "yaml": "^2.8.3", - "zod": "4.3.6", - "zod-deep-partial": "^1.2.0" + "@typescript-eslint/eslint-plugin": "8.61.0", + "@typescript-eslint/parser": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/utils": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/uri-js": { + "version": "4.4.1", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/webidl-conversions": { + "version": "3.0.1", + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/@start9labs/start-sdk/node_modules/whatwg-fetch": { + "version": "3.6.20", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@start9labs/start-sdk/node_modules/whatwg-url": { + "version": "5.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/which": { + "version": "2.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/word-wrap": { + "version": "1.2.5", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/yaml": { + "version": "2.9.0", + "inBundle": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/yocto-queue": { + "version": "0.1.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@start9labs/start-sdk/node_modules/zod-deep-partial": { + "version": "1.4.4", + "inBundle": true, + "license": "MIT", + "peerDependencies": { + "zod": "^4.1.13" } }, "node_modules/@types/ini": { @@ -99,9 +1533,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.19.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", - "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", + "version": "22.20.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.0.tgz", + "integrity": "sha512-QWlFW2wf3nTjC13/DqRnBpR4ZO36VJH/JVBkA/vcnmbTBNQIlnObqyqZE1tUR7+Ni23Lda8R1BxMfbXRpCUx5g==", "dev": true, "license": "MIT", "dependencies": { @@ -128,6 +1562,18 @@ "ncc": "dist/ncc/cli.js" } }, + "node_modules/anynum": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.1.tgz", + "integrity": "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, "node_modules/deep-equality-data-structures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/deep-equality-data-structures/-/deep-equality-data-structures-2.0.0.tgz", @@ -138,9 +1584,9 @@ } }, "node_modules/fast-xml-builder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz", - "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.1.tgz", + "integrity": "sha512-tPb5TTWfgfVx5BNSi2xV0eLr89POeXXn0dXIsCJ9m1narrWxeIyx6je9d7Rce/3NyXLbvuQmLkxq+RuxMWejvw==", "funding": [ { "type": "github", @@ -183,51 +1629,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "license": "MIT", - "dependencies": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "node_modules/mime": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-4.1.0.tgz", - "integrity": "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==", - "funding": [ - "https://github.com/sponsors/broofa" - ], - "license": "MIT", - "bin": { - "mime": "bin/cli.js" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/object-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", @@ -238,9 +1639,9 @@ } }, "node_modules/path-expression-matcher": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", - "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.6.1.tgz", + "integrity": "sha512-h7bxdzhHk8Knyc4Tj+jMaa7fEEoUJy7p1qtbVgkYg1Uhpe5Np5VuGXCRZnkZvU+Q42M1vStt0ifa3ueykRJPmQ==", "funding": [ { "type": "github", @@ -253,9 +1654,9 @@ } }, "node_modules/prettier": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", - "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.4.tgz", + "integrity": "sha512-yWG/o/4oJfo036EKAfK6ACAoDOfHeRHx4tuxkfBZiauURiaSmYwlpOr5LQqKtIkRD2z1PLteme2WoxEnj4tHTg==", "dev": true, "license": "MIT", "bin": { @@ -269,27 +1670,24 @@ } }, "node_modules/strnum": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz", - "integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.1.tgz", + "integrity": "sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" } ], - "license": "MIT" - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" + "license": "MIT", + "dependencies": { + "anynum": "^1.0.1" + } }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -306,28 +1704,6 @@ "dev": true, "license": "MIT" }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", - "license": "MIT" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/ws": { "version": "8.21.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", @@ -364,39 +1740,14 @@ "node": ">=16.0.0" } }, - "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, "node_modules/zod": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", - "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } - }, - "node_modules/zod-deep-partial": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/zod-deep-partial/-/zod-deep-partial-1.4.4.tgz", - "integrity": "sha512-aWkPl7hVStgE01WzbbSxCgX4O+sSpgt8JOjvFUtMTF75VgL6MhWQbiZi+AWGN85SfSTtI9gsOtL1vInoqfDVaA==", - "license": "MIT", - "peerDependencies": { - "zod": "^4.1.13" - } } } } diff --git a/package.json b/package.json index f3cb626..018f401 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "@simplex-chat/types": "^0.7.0", - "@start9labs/start-sdk": "1.5.3", + "@start9labs/start-sdk": "2.0.6", "ws": "^8.18.0" }, "devDependencies": { @@ -15,7 +15,7 @@ "@types/ws": "^8.5.13", "@vercel/ncc": "^0.38.4", "prettier": "^3.6.2", - "typescript": "^5.9.3" + "typescript": "^6.0.3" }, "prettier": { "trailingComma": "all", diff --git a/s9pk.mk b/s9pk.mk deleted file mode 100644 index 675ebc9..0000000 --- a/s9pk.mk +++ /dev/null @@ -1,138 +0,0 @@ -# ** Plumbing. DO NOT EDIT **. -# This file is imported by ./Makefile. Make edits there - -PACKAGE_ID := $(shell awk -F"'" '/id:/ {print $$2}' startos/manifest/index.ts) -INGREDIENTS := $(shell start-cli s9pk list-ingredients 2>/dev/null) -# Resolve the actual git dir so this works inside git worktrees, where .git -# is a file pointing at
/.git/worktrees/ rather than a directory. -GIT_DIR := $(shell git rev-parse --git-dir 2>/dev/null) -GIT_DEPS := $(if $(GIT_DIR),$(GIT_DIR)/HEAD $(GIT_DIR)/index) -ARCHES ?= x86 arm riscv -# TARGETS is the list of leaf make-targets the build matrix fans out over. -# Defaults to the arches; variant packages override (e.g. immich, ollama, vllm -# set this to a list of variant or variant-arch leaf targets). -TARGETS ?= $(ARCHES) -ifdef VARIANT -BASE_NAME := $(PACKAGE_ID)_$(VARIANT) -else -BASE_NAME := $(PACKAGE_ID) -endif - -.PHONY: all arches aarch64 x86_64 riscv64 arm arm64 x86 riscv arch/* clean install check-deps check-init package ingredients -.DELETE_ON_ERROR: -.SECONDARY: - -define SUMMARY - @manifest=$$(start-cli s9pk inspect $(1) manifest); \ - size=$$(du -h $(1) | awk '{print $$1}'); \ - title=$$(printf '%s' "$$manifest" | jq -r .title); \ - version=$$(printf '%s' "$$manifest" | jq -r .version); \ - arches=$$(printf '%s' "$$manifest" | jq -r '[.images[].arch // []] | flatten | unique | join(", ")'); \ - sdkv=$$(printf '%s' "$$manifest" | jq -r .sdkVersion); \ - gitHash=$$(printf '%s' "$$manifest" | jq -r .gitHash | sed -E 's/(.*-modified)$$/\x1b[0;31m\1\x1b[0m/'); \ - printf "\n"; \ - printf "\033[1;32m✅ Build Complete!\033[0m\n"; \ - printf "\n"; \ - printf "\033[1;37m📦 $$title\033[0m \033[36mv$$version\033[0m\n"; \ - printf "───────────────────────────────\n"; \ - printf " \033[1;36mFilename:\033[0m %s\n" "$(1)"; \ - printf " \033[1;36mSize:\033[0m %s\n" "$$size"; \ - printf " \033[1;36mArch:\033[0m %s\n" "$$arches"; \ - printf " \033[1;36mSDK:\033[0m %s\n" "$$sdkv"; \ - printf " \033[1;36mGit:\033[0m %s\n" "$$gitHash"; \ - echo "" -endef - -all: $(TARGETS) - -arches: $(ARCHES) - -# Generic make-variable introspection. Used by the release workflow to -# read $(TARGETS) and fan out one matrix runner per target. `make -s -# print-TARGETS` echoes the list with no other output. -print-%: - @echo '$($*)' - -universal: $(BASE_NAME).s9pk - $(call SUMMARY,$<) - -arch/%: $(BASE_NAME)_%.s9pk - $(call SUMMARY,$<) - -x86 x86_64: arch/x86_64 -arm arm64 aarch64: arch/aarch64 -riscv riscv64: arch/riscv64 - -$(BASE_NAME).s9pk: $(INGREDIENTS) $(GIT_DEPS) - @$(MAKE) --no-print-directory ingredients - @echo " Packing '$@'..." - start-cli s9pk pack -o $@ - -$(BASE_NAME)_%.s9pk: $(INGREDIENTS) $(GIT_DEPS) - @$(MAKE) --no-print-directory ingredients - @echo " Packing '$@'..." - start-cli s9pk pack --arch=$* -o $@ - -ingredients: $(INGREDIENTS) - @echo " Re-evaluating ingredients..." - -install: | check-deps check-init - @HOST=$$(awk -F'/' '/^host:/ {print $$3}' ~/.startos/config.yaml); \ - if [ -z "$$HOST" ]; then \ - echo "Error: You must define \"host: http://server-name.local\" in ~/.startos/config.yaml"; \ - exit 1; \ - fi; \ - if [ -z "$$(ls *.s9pk 2>/dev/null)" ]; then \ - echo "Error: No .s9pk file found. Run 'make' first."; \ - exit 1; \ - fi; \ - S9PK=$$(start-cli s9pk select) || exit 1; \ - printf "\n🚀 Installing %s to %s ...\n" "$$S9PK" "$$HOST"; \ - start-cli package install -s "$$S9PK" - -publish: | all - @REGISTRY=$$(awk -F'/' '/^registry:/ {print $$3}' ~/.startos/config.yaml); \ - if [ -z "$$REGISTRY" ]; then \ - echo "Error: You must define \"registry: https://my-registry.tld\" in ~/.startos/config.yaml"; \ - exit 1; \ - fi; \ - S3BASE=$$(awk -F'/' '/^s9pk-s3base:/ {print $$3}' ~/.startos/config.yaml); \ - if [ -z "$$S3BASE" ]; then \ - echo "Error: You must define \"s3base: https://s9pks.my-s3-bucket.tld\" in ~/.startos/config.yaml"; \ - exit 1; \ - fi; \ - command -v s3cmd >/dev/null || \ - (echo "Error: s3cmd not found. It must be installed to publish using s3." && exit 1); \ - printf "\n🚀 Publishing to %s; indexing on %s ...\n" "$$S3BASE" "$$REGISTRY"; \ - for s9pk in *.s9pk; do \ - age=$$(( $$(date +%s) - $$(stat -c %Y "$$s9pk") )); \ - if [ "$$age" -gt 3600 ]; then \ - printf "\033[1;33m⚠️ %s is %d minutes old. Publish anyway? [y/N] \033[0m" "$$s9pk" "$$((age / 60))"; \ - read -r ans; \ - case "$$ans" in [yY]*) ;; *) echo "Skipping $$s9pk"; continue ;; esac; \ - fi; \ - start-cli s9pk publish "$$s9pk"; \ - done - -check-deps: - @command -v start-cli >/dev/null || \ - (echo "Error: start-cli not found. Please see https://docs.start9.com/latest/developer-guide/sdk/installing-the-sdk" && exit 1) - @command -v npm >/dev/null || \ - (echo "Error: npm not found. Please install Node.js and npm." && exit 1) - -check-init: - @if [ ! -f ~/.startos/developer.key.pem ]; then \ - echo "Initializing StartOS developer environment..."; \ - start-cli init-key; \ - fi - -javascript/index.js: $(shell find startos -type f) tsconfig.json node_modules - npm run check - npm run build - -node_modules: package-lock.json package.json - npm ci - -clean: - @echo "Cleaning up build artifacts..." - @rm -rf $(PACKAGE_ID).s9pk $(PACKAGE_ID)_x86_64.s9pk $(PACKAGE_ID)_aarch64.s9pk $(PACKAGE_ID)_riscv64.s9pk javascript node_modules diff --git a/startos/main.ts b/startos/main.ts index 7e93f9b..2f77b6e 100644 --- a/startos/main.ts +++ b/startos/main.ts @@ -1,11 +1,11 @@ import { sdk } from './sdk' -import { port, mainMounts } from './utils' +import { port, mainMounts, inboundDir, tmpDir } from './utils' import { i18n } from './i18n' export const main = sdk.setupMain(async ({ effects }) => { console.info(i18n('Starting SimpleX Websocket Bridge!')) - const subcontainer = await sdk.SubContainer.of( + const subcontainer = sdk.SubContainer.of( effects, { imageId: 'simplex' }, mainMounts, @@ -18,6 +18,12 @@ export const main = sdk.setupMain(async ({ effects }) => { subcontainer, exec: { command: sdk.useEntrypoint(), + // Pin the file-exchange dirs into the /simplex mount. Without these the + // image falls back to $HOME/.simplex/{files,tmp}, outside that mount. + env: { + SIMPLEX_INBOUND_DIR: inboundDir, + SIMPLEX_TMP_DIR: tmpDir, + }, }, ready: { display: null, // surfaced to users (and dependents) via the 'websocket' health check below diff --git a/startos/manifest/index.ts b/startos/manifest/index.ts index 39466b7..4acc501 100644 --- a/startos/manifest/index.ts +++ b/startos/manifest/index.ts @@ -15,11 +15,13 @@ export const manifest = setupManifest({ volumes: ['main'], images: { // Consume the standalone container image published from - // github.com/lundog/simplex-chat-docker, rather than building locally. - // Bump this tag deliberately when the upstream SimpleX version changes. + // github.com/lundog/simplex-websocket-bridge-docker, rather than building + // locally. Bump this tag deliberately when the upstream SimpleX version + // changes. The `-N` suffix is the image revision (a rebuild of the same + // SimpleX version), which moves independently of SimpleX itself. simplex: { source: { - dockerTag: 'lundog/simplex-chat:6.5.4', + dockerTag: 'lundog/simplex-websocket-bridge:6.5.5-2', }, arch: ['x86_64', 'aarch64'], }, diff --git a/startos/utils.ts b/startos/utils.ts index 86721f9..db1a752 100644 --- a/startos/utils.ts +++ b/startos/utils.ts @@ -2,6 +2,19 @@ import { sdk } from './sdk' export const port = 5225 +/** + * The file-exchange paths the bridge reads and writes, inside the container. + * + * These MUST be passed to the container explicitly (see `main.ts`). The image + * derives its own defaults from `$HOME` (`/data/.simplex/files` and + * `/data/.simplex/tmp`), which land outside the `/simplex` mount below — so + * relying on those defaults puts received files somewhere no consumer can see + * and breaks the file exchange contract. The image used to default to + * `/simplex` itself, which is why this was previously left unset. + */ +export const inboundDir = '/simplex/inbound' +export const tmpDir = '/simplex/tmp' + /** * The `main` volume is mounted wholly at /data (HOME, profile database). * diff --git a/startos/versions/current.ts b/startos/versions/current.ts index c453471..49e51cc 100644 --- a/startos/versions/current.ts +++ b/startos/versions/current.ts @@ -1,48 +1,18 @@ import { IMPOSSIBLE, VersionInfo } from '@start9labs/start-sdk' export const current = VersionInfo.of({ - version: '0.2.0:0', + version: '0.2.1:0', releaseNotes: { - en_US: [ - 'SimpleX Websocket Bridge runs SimpleX Chat headless and exposes the SimpleX network over a token-authenticated Websocket API, so bots, AI agents, scripts, and other StartOS services can send and receive SimpleX messages and files programmatically.', - '', - '- Outside access is gated by per-client bearer tokens, managed in the API Keys action; same-box services connect directly.', - '- Actions to configure the SimpleX profile, create one-time invitation links, and reset the identity.', - '- Shared-volume file exchange for consumer packages via /simplex/inbound and /simplex/outbound.', - '- Bundles simplex-chat v6.5.4.', - ].join('\n'), - es_ES: [ - 'SimpleX Websocket Bridge ejecuta SimpleX Chat sin interfaz y expone la red SimpleX a través de una API Websocket autenticada por token, para que bots, agentes de IA, scripts y otros servicios de StartOS puedan enviar y recibir mensajes y archivos de SimpleX de forma programática.', - '', - '- El acceso externo se protege con tokens bearer por cliente, gestionados en la acción API Keys; los servicios del mismo equipo se conectan directamente.', - '- Acciones para configurar el perfil de SimpleX, crear enlaces de invitación de un solo uso y restablecer la identidad.', - '- Intercambio de archivos mediante volumen compartido para paquetes consumidores a través de /simplex/inbound y /simplex/outbound.', - '- Incluye simplex-chat v6.5.4.', - ].join('\n'), - de_DE: [ - 'SimpleX Websocket Bridge betreibt SimpleX Chat im Headless-Modus und stellt das SimpleX-Netzwerk über eine token-authentifizierte Websocket-API bereit, sodass Bots, KI-Agenten, Skripte und andere StartOS-Dienste SimpleX-Nachrichten und -Dateien programmatisch senden und empfangen können.', - '', - '- Externer Zugriff wird durch clientspezifische Bearer-Token abgesichert, verwaltet in der Aktion „API Keys“; Dienste auf demselben Gerät verbinden sich direkt.', - '- Aktionen zum Konfigurieren des SimpleX-Profils, zum Erstellen einmaliger Einladungslinks und zum Zurücksetzen der Identität.', - '- Dateiaustausch über ein gemeinsames Volume für konsumierende Pakete via /simplex/inbound und /simplex/outbound.', - '- Enthält simplex-chat v6.5.4.', - ].join('\n'), - pl_PL: [ - 'SimpleX Websocket Bridge uruchamia SimpleX Chat w trybie bezgłowym i udostępnia sieć SimpleX poprzez uwierzytelniane tokenem API Websocket, dzięki czemu boty, agenci AI, skrypty i inne usługi StartOS mogą programowo wysyłać i odbierać wiadomości oraz pliki SimpleX.', - '', - '- Dostęp z zewnątrz jest chroniony tokenami bearer dla każdego klienta, zarządzanymi w akcji „API Keys”; usługi na tym samym urządzeniu łączą się bezpośrednio.', - '- Akcje do konfiguracji profilu SimpleX, tworzenia jednorazowych linków zaproszeń i resetowania tożsamości.', - '- Wymiana plików przez współdzielony wolumin dla pakietów konsumujących poprzez /simplex/inbound i /simplex/outbound.', - '- Zawiera simplex-chat v6.5.4.', - ].join('\n'), - fr_FR: [ - 'SimpleX Websocket Bridge exécute SimpleX Chat sans interface et expose le réseau SimpleX via une API Websocket authentifiée par jeton, afin que les bots, agents IA, scripts et autres services StartOS puissent envoyer et recevoir des messages et fichiers SimpleX de façon programmatique.', - '', - "- L'accès externe est protégé par des jetons bearer propres à chaque client, gérés dans l'action « API Keys » ; les services du même appareil se connectent directement.", - "- Des actions pour configurer le profil SimpleX, créer des liens d'invitation à usage unique et réinitialiser l'identité.", - '- Échange de fichiers via un volume partagé pour les paquets consommateurs à travers /simplex/inbound et /simplex/outbound.', - '- Inclut simplex-chat v6.5.4.', - ].join('\n'), + en_US: + 'Updated SimpleX Chat to 6.5.5. Highlights: initial support for supporter badges, and a fix for files without an extension being saved with a trailing dot. Full notes: https://github.com/simplex-chat/simplex-chat/releases/tag/v6.5.5. Also fixes file exchange, which 6.5.5 would otherwise have broken: received files are kept in the shared /simplex mount, where dependent services can reach them. Includes internal updates for start-sdk 2.0.', + es_ES: + 'SimpleX Chat actualizado a 6.5.5. Novedades: compatibilidad inicial con insignias de patrocinador y corrección de archivos sin extensión que se guardaban con un punto final. Notas completas: https://github.com/simplex-chat/simplex-chat/releases/tag/v6.5.5. También corrige el intercambio de archivos, que 6.5.5 habría roto: los archivos recibidos se mantienen en el punto de montaje compartido /simplex, donde los servicios dependientes pueden acceder a ellos. Incluye actualizaciones internas para start-sdk 2.0.', + de_DE: + 'SimpleX Chat auf 6.5.5 aktualisiert. Highlights: erste Unterstützung für Unterstützer-Abzeichen und eine Korrektur für Dateien ohne Erweiterung, die mit einem abschließenden Punkt gespeichert wurden. Vollständige Hinweise: https://github.com/simplex-chat/simplex-chat/releases/tag/v6.5.5. Behebt außerdem den Dateiaustausch, den 6.5.5 andernfalls beschädigt hätte: empfangene Dateien bleiben im gemeinsamen /simplex-Mount, wo abhängige Dienste sie erreichen können. Enthält interne Aktualisierungen für start-sdk 2.0.', + pl_PL: + 'Zaktualizowano SimpleX Chat do 6.5.5. Najważniejsze zmiany: wstępna obsługa odznak wspierających oraz poprawka plików bez rozszerzenia zapisywanych z końcową kropką. Pełne informacje: https://github.com/simplex-chat/simplex-chat/releases/tag/v6.5.5. Naprawia również wymianę plików, którą 6.5.5 w przeciwnym razie by zepsuł: odebrane pliki pozostają we współdzielonym punkcie montowania /simplex, gdzie usługi zależne mogą je odczytać. Zawiera wewnętrzne aktualizacje dla start-sdk 2.0.', + fr_FR: + "SimpleX Chat mis à jour vers 6.5.5. Nouveautés : prise en charge initiale des badges de soutien et correction des fichiers sans extension enregistrés avec un point final. Notes complètes : https://github.com/simplex-chat/simplex-chat/releases/tag/v6.5.5. Corrige également l'échange de fichiers, que 6.5.5 aurait sinon cassé : les fichiers reçus restent dans le montage partagé /simplex, où les services dépendants peuvent y accéder. Inclut des mises à jour internes pour start-sdk 2.0.", }, migrations: { up: async ({ effects }) => {}, diff --git a/tsconfig.json b/tsconfig.json index a2945a5..f032dc1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,4 @@ { - "include": ["startos/**/*.ts", "node_modules/**/startos"], - "compilerOptions": { - "target": "ES2018", - "module": "CommonJS", - "moduleResolution": "node", - "esModuleInterop": true, - "strict": true, - "skipLibCheck": true - } + "extends": "@start9labs/start-sdk/tsconfig.base.json", + "include": ["startos/**/*.ts", "node_modules/**/startos"] }